Expand on the C api definitions (#2409)

* Expand on the C api

* Fix Ci

* Fix PyCodeObject structure

* Add descrobjects

* Add None and NotImplemented type objects

* Update pyo3-ffi/src/cpython/object.rs

Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>

* Fix PyPy definitions

* Fix CI

* Fix CI

* Fix CI

* Fix CI

* Fix CI

* Fix CI

Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
This commit is contained in:
Bruno Kolenbrander 2022-06-04 19:22:18 +02:00 committed by GitHub
parent b2c4c0f48c
commit 728d35aa7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 436 additions and 44 deletions

View File

@ -2,6 +2,23 @@ use crate::object::*;
use crate::pyport::Py_ssize_t;
use std::os::raw::{c_char, c_int};
#[cfg(not(any(PyPy, Py_LIMITED_API)))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyByteArrayObject {
pub ob_base: PyVarObject,
pub ob_alloc: Py_ssize_t,
pub ob_bytes: *mut c_char,
pub ob_start: *mut c_char,
#[cfg(Py_3_9)]
pub ob_exports: Py_ssize_t,
#[cfg(not(Py_3_9))]
pub ob_exports: c_int,
}
#[cfg(any(PyPy, Py_LIMITED_API))]
opaque_struct!(PyByteArrayObject);
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg_attr(PyPy, link_name = "PyPyByteArray_Type")]

View File

@ -1,6 +1,19 @@
use crate::object::PyObject;
use crate::pyport::Py_ssize_t;
use std::os::raw::c_int;
use crate::object::*;
use crate::Py_ssize_t;
use std::os::raw::{c_char, c_int};
#[cfg(not(any(PyPy, Py_LIMITED_API)))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyBytesObject {
pub ob_base: PyVarObject,
#[cfg(PyPy)]
pub ob_shash: crate::Py_hash_t,
pub ob_sval: [c_char; 1],
}
#[cfg(any(PyPy, Py_LIMITED_API))]
opaque_struct!(PyBytesObject);
extern "C" {
pub fn _PyBytes_Resize(bytes: *mut *mut PyObject, newsize: Py_ssize_t) -> c_int;

View File

@ -1,8 +1,8 @@
use crate::object::*;
use crate::pyport::Py_ssize_t;
#[cfg(not(PyPy))]
use std::os::raw::c_uchar;
use std::os::raw::{c_char, c_int, c_void};
#[allow(unused_imports)]
use std::os::raw::{c_char, c_int, c_uchar, c_void};
// skipped _Py_CODEUNIT
// skipped _Py_OPCODE
@ -11,7 +11,7 @@ use std::os::raw::{c_char, c_int, c_void};
#[cfg(all(Py_3_8, not(PyPy)))]
opaque_struct!(_PyOpcache);
#[cfg(not(PyPy))]
#[cfg(all(not(PyPy), Py_3_8, not(Py_3_11)))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyCodeObject {
@ -30,10 +30,13 @@ pub struct PyCodeObject {
pub co_varnames: *mut PyObject,
pub co_freevars: *mut PyObject,
pub co_cellvars: *mut PyObject,
pub co_cell2arg: *mut c_uchar,
pub co_cell2arg: *mut Py_ssize_t,
pub co_filename: *mut PyObject,
pub co_name: *mut PyObject,
#[cfg(not(Py_3_10))]
pub co_lnotab: *mut PyObject,
#[cfg(Py_3_10)]
pub co_linetable: *mut PyObject,
pub co_zombieframe: *mut c_void,
pub co_weakreflist: *mut PyObject,
pub co_extra: *mut c_void,
@ -47,9 +50,51 @@ pub struct PyCodeObject {
pub co_opcache_size: c_uchar,
}
#[cfg(PyPy)]
#[cfg(all(not(PyPy), Py_3_11))]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyCodeObject {
pub ob_base: PyVarObject,
pub co_consts: *mut PyObject,
pub co_names: *mut PyObject,
pub co_exceptiontable: *mut PyObject,
pub co_flags: c_int,
pub co_warmup: c_int,
pub co_argcount: c_int,
pub co_posonlyargcount: c_int,
pub co_kwonlyargcount: c_int,
pub co_stacksize: c_int,
pub co_firstlineno: c_int,
pub co_nlocalsplus: c_int,
pub co_nlocals: c_int,
pub co_nplaincellvars: c_int,
pub co_ncellvars: c_int,
pub co_nfreevars: c_int,
pub co_localsplusnames: *mut PyObject,
pub co_localspluskinds: *mut PyObject,
pub co_filename: *mut PyObject,
pub co_name: *mut PyObject,
pub co_qualname: *mut PyObject,
pub co_linetable: *mut PyObject,
pub co_weakreflist: *mut PyObject,
pub co_extra: *mut c_void,
pub co_code_adaptive: [c_char; 1],
}
#[cfg(all(not(PyPy), Py_3_7, not(Py_3_8)))]
opaque_struct!(PyCodeObject);
#[cfg(PyPy)]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct PyCodeObject {
pub ob_base: PyObject,
pub co_name: *mut PyObject,
pub co_filename: *mut PyObject,
pub co_argcount: c_int,
pub co_flags: c_int,
}
/* Masks for co_flags */
pub const CO_OPTIMIZED: c_int = 0x0001;
pub const CO_NEWLOCALS: c_int = 0x0002;
@ -94,11 +139,17 @@ pub unsafe fn PyCode_Check(op: *mut PyObject) -> c_int {
}
#[inline]
#[cfg(not(PyPy))]
#[cfg(all(not(PyPy), Py_3_10, not(Py_3_11)))]
pub unsafe fn PyCode_GetNumFree(op: *mut PyCodeObject) -> Py_ssize_t {
crate::PyTuple_GET_SIZE((*op).co_freevars)
}
#[inline]
#[cfg(all(not(Py_3_10), Py_3_11, not(PyPy)))]
pub unsafe fn PyCode_GetNumFree(op: *mut PyCodeObject) -> c_int {
(*op).co_nfreevars
}
extern "C" {
#[cfg(PyPy)]
#[link_name = "PyPyCode_Check"]

View File

@ -4,6 +4,10 @@ use std::os::raw::c_int;
opaque_struct!(PyDictKeysObject);
#[cfg(Py_3_11)]
opaque_struct!(PyDictValues);
#[cfg(not(PyPy))]
#[repr(C)]
#[derive(Debug)]
// Not moved because dict.rs uses PyDictObject extensively.
@ -12,7 +16,19 @@ pub struct PyDictObject {
pub ma_used: Py_ssize_t,
pub ma_version_tag: u64,
pub ma_keys: *mut PyDictKeysObject,
#[cfg(not(Py_3_11))]
pub ma_values: *mut *mut PyObject,
#[cfg(Py_3_11)]
pub ma_values: *mut PyDictValues,
}
#[cfg(PyPy)]
#[repr(C)]
#[derive(Debug)]
pub struct PyDictObject {
pub ob_base: PyObject,
// a private place to put keys during PyDict_Next
_tmpkeys: *mut PyObject,
}
extern "C" {

View File

@ -0,0 +1,64 @@
use crate::object::*;
use crate::{PyCFunctionObject, PyMethodDefPointer, METH_METHOD, METH_STATIC};
use std::os::raw::c_int;
pub struct PyCMethodObject {
pub func: PyCFunctionObject,
pub mm_class: *mut PyTypeObject,
}
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
pub static mut PyCMethod_Type: PyTypeObject;
}
#[inline]
pub unsafe fn PyCMethod_CheckExact(op: *mut PyObject) -> c_int {
(Py_TYPE(op) == addr_of_mut_shim!(PyCMethod_Type)) as c_int
}
#[inline]
pub unsafe fn PyCMethod_Check(op: *mut PyObject) -> c_int {
PyObject_TypeCheck(op, addr_of_mut_shim!(PyCMethod_Type))
}
#[inline]
pub unsafe fn PyCFunction_GET_FUNCTION(func: *mut PyObject) -> PyMethodDefPointer {
debug_assert_eq!(PyCMethod_Check(func), 1);
let func = func.cast::<PyCFunctionObject>();
(*(*func).m_ml).ml_meth
}
#[inline]
pub unsafe fn PyCFunction_GET_SELF(func: *mut PyObject) -> *mut PyObject {
debug_assert_eq!(PyCMethod_Check(func), 1);
let func = func.cast::<PyCFunctionObject>();
if (*(*func).m_ml).ml_flags & METH_STATIC != 0 {
std::ptr::null_mut()
} else {
(*func).m_self
}
}
#[inline]
pub unsafe fn PyCFunction_GET_FLAGS(func: *mut PyObject) -> c_int {
debug_assert_eq!(PyCMethod_Check(func), 1);
let func = func.cast::<PyCFunctionObject>();
(*(*func).m_ml).ml_flags
}
#[inline]
pub unsafe fn PyCFunction_GET_CLASS(func: *mut PyObject) -> *mut PyTypeObject {
debug_assert_eq!(PyCMethod_Check(func), 1);
let func = func.cast::<PyCFunctionObject>();
if (*(*func).m_ml).ml_flags & METH_METHOD != 0 {
let func = func.cast::<PyCMethodObject>();
(*func).mm_class
} else {
std::ptr::null_mut()
}
}

View File

@ -17,6 +17,9 @@ pub(crate) mod import;
pub(crate) mod initconfig;
// skipped interpreteridobject.h
pub(crate) mod listobject;
#[cfg(all(Py_3_9, not(PyPy)))]
pub(crate) mod methodobject;
pub(crate) mod object;
pub(crate) mod pydebug;
pub(crate) mod pyerrors;
@ -44,6 +47,8 @@ pub use self::import::*;
#[cfg(all(Py_3_8, not(PyPy)))]
pub use self::initconfig::*;
pub use self::listobject::*;
#[cfg(all(Py_3_9, not(PyPy)))]
pub use self::methodobject::*;
pub use self::object::*;
pub use self::pydebug::*;
pub use self::pyerrors::*;

View File

@ -364,8 +364,11 @@ extern "C" {
// skipped Py_SETREF
// skipped Py_XSETREF
// skipped _PyNone_Type
// skipped _PyNotImplemented_Type
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
pub static mut _PyNone_Type: PyTypeObject;
pub static mut _PyNotImplemented_Type: PyTypeObject;
}
// skipped _Py_SwappedOp

View File

@ -93,10 +93,10 @@ pub struct PyCompactUnicodeObject {
#[repr(C)]
pub union PyUnicodeObjectData {
any: *mut c_void,
latin1: *mut Py_UCS1,
ucs2: *mut Py_UCS2,
ucs4: *mut Py_UCS4,
pub any: *mut c_void,
pub latin1: *mut Py_UCS1,
pub ucs2: *mut Py_UCS2,
pub ucs4: *mut Py_UCS4,
}
#[repr(C)]

View File

@ -2,13 +2,14 @@ use crate::methodobject::PyMethodDef;
use crate::object::{PyObject, PyTypeObject};
use crate::structmember::PyMemberDef;
use std::os::raw::{c_char, c_int, c_void};
use std::ptr;
pub type getter = unsafe extern "C" fn(slf: *mut PyObject, closure: *mut c_void) -> *mut PyObject;
pub type setter =
unsafe extern "C" fn(slf: *mut PyObject, value: *mut PyObject, closure: *mut c_void) -> c_int;
#[repr(C)]
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct PyGetSetDef {
pub name: *mut c_char,
pub get: Option<getter>,
@ -17,19 +18,94 @@ pub struct PyGetSetDef {
pub closure: *mut c_void,
}
// skipped non-limited wrapperfunc
// skipped non-limited wrapperfunc_kwds
// skipped non-limited struct wrapperbase
// skipped non-limited PyWrapperFlag_KEYWORDS
impl Default for PyGetSetDef {
fn default() -> PyGetSetDef {
PyGetSetDef {
name: ptr::null_mut(),
get: None,
set: None,
doc: ptr::null_mut(),
closure: ptr::null_mut(),
}
}
}
#[cfg(not(Py_LIMITED_API))]
pub type wrapperfunc = Option<
unsafe extern "C" fn(
slf: *mut PyObject,
args: *mut PyObject,
wrapped: *mut c_void,
) -> *mut PyObject,
>;
#[cfg(not(Py_LIMITED_API))]
pub type wrapperfunc_kwds = Option<
unsafe extern "C" fn(
slf: *mut PyObject,
args: *mut PyObject,
wrapped: *mut c_void,
kwds: *mut PyObject,
) -> *mut PyObject,
>;
#[cfg(not(Py_LIMITED_API))]
#[repr(C)]
pub struct wrapperbase {
pub name: *const c_char,
pub offset: c_int,
pub function: *mut c_void,
pub wrapper: wrapperfunc,
pub doc: *const c_char,
pub flags: c_int,
pub name_strobj: *mut PyObject,
}
#[cfg(not(Py_LIMITED_API))]
pub const PyWrapperFlag_KEYWORDS: c_int = 1;
#[cfg(not(Py_LIMITED_API))]
#[repr(C)]
pub struct PyDescrObject {
pub ob_base: PyObject,
pub d_type: *mut PyTypeObject,
pub d_name: *mut PyObject,
pub d_qualname: *mut PyObject,
}
// skipped non-limited PyDescrObject
// skipped non-limited PyDescr_COMMON
// skipped non-limited PyDescr_TYPE
// skipped non-limited PyDescr_NAME
// skipped non-limited PyMethodDescrObject
// skipped non-limited PyMemberDescrObject
// skipped non-limited PyGetSetDescrObject
// skipped non-limited PyWrapperDescrObject
#[cfg(not(Py_LIMITED_API))]
#[repr(C)]
pub struct PyMethodDescrObject {
pub d_common: PyDescrObject,
pub d_method: *mut PyMethodDef,
#[cfg(all(not(PyPy), Py_3_8))]
pub vectorcall: Option<crate::vectorcallfunc>,
}
#[cfg(not(Py_LIMITED_API))]
#[repr(C)]
pub struct PyMemberDescrObject {
pub d_common: PyDescrObject,
pub d_member: *mut PyGetSetDef,
}
#[cfg(not(Py_LIMITED_API))]
#[repr(C)]
pub struct PyGetSetDescrObject {
pub d_common: PyDescrObject,
pub d_getset: *mut PyGetSetDef,
}
#[cfg(not(Py_LIMITED_API))]
#[repr(C)]
pub struct PyWrapperDescrObject {
pub d_common: PyDescrObject,
pub d_base: *mut wrapperbase,
pub d_wrapped: *mut c_void,
}
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {

View File

@ -2,7 +2,57 @@ use std::os::raw::c_int;
use crate::object::{PyObject, PyTypeObject, Py_TYPE};
// skipped PyFunctionObject
#[cfg(all(not(PyPy), not(Py_LIMITED_API), not(Py_3_10)))]
#[repr(C)]
pub struct PyFunctionObject {
pub ob_base: PyObject,
pub func_code: *mut PyObject,
pub func_globals: *mut PyObject,
pub func_defaults: *mut PyObject,
pub func_kwdefaults: *mut PyObject,
pub func_closure: *mut PyObject,
pub func_doc: *mut PyObject,
pub func_name: *mut PyObject,
pub func_dict: *mut PyObject,
pub func_weakreflist: *mut PyObject,
pub func_module: *mut PyObject,
pub func_annotations: *mut PyObject,
pub func_qualname: *mut PyObject,
#[cfg(Py_3_8)]
pub vectorcall: Option<crate::vectorcallfunc>,
}
#[cfg(all(not(PyPy), not(Py_LIMITED_API), Py_3_10))]
#[repr(C)]
pub struct PyFunctionObject {
pub ob_base: PyObject,
pub func_globals: *mut PyObject,
pub func_builtins: *mut PyObject,
pub func_name: *mut PyObject,
pub func_qualname: *mut PyObject,
pub func_code: *mut PyObject,
pub func_defaults: *mut PyObject,
pub func_kwdefaults: *mut PyObject,
pub func_closure: *mut PyObject,
pub func_doc: *mut PyObject,
pub func_dict: *mut PyObject,
pub func_weakreflist: *mut PyObject,
pub func_module: *mut PyObject,
pub func_annotations: *mut PyObject,
pub vectorcall: Option<crate::vectorcallfunc>,
#[cfg(Py_3_11)]
pub func_version: u32,
}
#[cfg(all(PyPy, not(Py_LIMITED_API)))]
#[repr(C)]
pub struct PyFunctionObject {
pub ob_base: PyObject,
pub func_name: *mut PyObject,
}
#[cfg(all(not(PyPy), Py_LIMITED_API))]
opaque_struct!(PyFunctionObject);
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {

View File

@ -2,10 +2,11 @@ use crate::object::*;
use crate::pyport::Py_ssize_t;
use std::os::raw::{c_char, c_int};
// skipped non-limited _PyManagedBuffer_Type
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
#[cfg(not(Py_LIMITED_API))]
pub static mut _PyManagedBuffer_Type: PyTypeObject;
#[cfg_attr(PyPy, link_name = "PyPyMemoryView_Type")]
pub static mut PyMemoryView_Type: PyTypeObject;
}

View File

@ -1,8 +1,20 @@
use crate::object::{PyObject, PyTypeObject, Py_TYPE};
#[cfg(Py_3_9)]
use crate::PyObject_TypeCheck;
use std::mem;
use std::os::raw::{c_char, c_int};
use std::os::raw::{c_char, c_int, c_void};
use std::{mem, ptr};
#[cfg(all(Py_3_9, not(Py_LIMITED_API)))]
pub struct PyCFunctionObject {
pub ob_base: PyObject,
pub m_ml: *mut PyMethodDef,
pub m_self: *mut PyObject,
pub m_module: *mut PyObject,
#[cfg(not(PyPy))]
pub m_weakreflist: *mut PyObject,
#[cfg(not(PyPy))]
pub vectorcall: Option<crate::vectorcallfunc>,
}
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
@ -75,7 +87,7 @@ extern "C" {
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct PyMethodDef {
pub ml_name: *const c_char,
pub ml_meth: PyMethodDefPointer,
@ -83,6 +95,19 @@ pub struct PyMethodDef {
pub ml_doc: *const c_char,
}
impl Default for PyMethodDef {
fn default() -> PyMethodDef {
PyMethodDef {
ml_name: ptr::null(),
ml_meth: PyMethodDefPointer {
Void: ptr::null_mut(),
},
ml_flags: 0,
ml_doc: ptr::null(),
}
}
}
/// Function types used to implement Python callables.
///
/// This function pointer must be accompanied by the correct [ml_flags](PyMethodDef::ml_flags),
@ -92,7 +117,7 @@ pub struct PyMethodDef {
///
/// [1]: https://docs.python.org/3/c-api/structures.html#implementing-functions-and-methods
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Eq)]
pub union PyMethodDefPointer {
/// This variant corresponds with [`METH_VARARGS`] *or* [`METH_NOARGS`] *or* [`METH_O`].
pub PyCFunction: PyCFunction,
@ -111,6 +136,31 @@ pub union PyMethodDefPointer {
/// This variant corresponds with [`METH_METHOD`] | [`METH_FASTCALL`] | [`METH_KEYWORDS`].
#[cfg(all(Py_3_9, not(Py_LIMITED_API)))]
pub PyCMethod: PyCMethod,
Void: *mut c_void,
}
impl PyMethodDefPointer {
pub fn as_ptr(&self) -> *mut c_void {
unsafe { self.Void }
}
pub fn is_null(&self) -> bool {
self.as_ptr().is_null()
}
}
impl PartialEq for PyMethodDefPointer {
fn eq(&self, other: &Self) -> bool {
unsafe { self.Void == other.Void }
}
}
impl std::fmt::Pointer for PyMethodDefPointer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let ptr = unsafe { self.Void };
std::fmt::Pointer::fmt(&ptr, f)
}
}
// TODO: This can be a const assert on Rust 1.57

View File

@ -66,12 +66,21 @@ pub const PyModuleDef_HEAD_INIT: PyModuleDef_Base = PyModuleDef_Base {
};
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct PyModuleDef_Slot {
pub slot: c_int,
pub value: *mut c_void,
}
impl Default for PyModuleDef_Slot {
fn default() -> PyModuleDef_Slot {
PyModuleDef_Slot {
slot: 0,
value: std::ptr::null_mut(),
}
}
}
pub const Py_mod_create: c_int = 1;
pub const Py_mod_exec: c_int = 2;

View File

@ -371,10 +371,12 @@ pub const Py_TPFLAGS_HAVE_GC: c_ulong = 1 << 14;
const Py_TPFLAGS_HAVE_STACKLESS_EXTENSION: c_ulong = 0;
// skipped Py_TPFLAGS_METHOD_DESCRIPTOR
#[cfg(Py_3_8)]
pub const Py_TPFLAGS_METHOD_DESCRIPTOR: c_ulong = 1 << 17;
/// Objects support type attribute cache
/// This flag does nothing in Python 3.10+
pub const Py_TPFLAGS_HAVE_VERSION_TAG: c_ulong = 1 << 18;
pub const Py_TPFLAGS_VALID_VERSION_TAG: c_ulong = 1 << 19;
/* Type is abstract and cannot be instantiated */

View File

@ -29,9 +29,20 @@ pub struct PySetObject {
pub weakreflist: *mut PyObject,
}
// skipped PySet_GET_SIZE
// skipped
#[inline]
#[cfg(all(not(PyPy), not(Py_LIMITED_API)))]
pub unsafe fn PySet_GET_SIZE(so: *mut PyObject) -> Py_ssize_t {
debug_assert_eq!(PyAnySet_Check(so), 1);
let so = so.cast::<PySetObject>();
(*so).used
}
// skipped _PySet_Dummy
#[cfg(not(Py_LIMITED_API))]
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
pub static mut _PySet_Dummy: *mut PyObject;
}
extern "C" {
#[cfg(not(Py_LIMITED_API))]

View File

@ -1,9 +1,10 @@
use crate::object::PyObject;
use crate::pyport::Py_ssize_t;
use std::os::raw::{c_char, c_int};
use std::ptr;
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct PyMemberDef {
pub name: *mut c_char,
pub type_code: c_int,
@ -12,6 +13,18 @@ pub struct PyMemberDef {
pub doc: *mut c_char,
}
impl Default for PyMemberDef {
fn default() -> PyMemberDef {
PyMemberDef {
name: ptr::null_mut(),
type_code: 0,
offset: 0,
flags: 0,
doc: ptr::null_mut(),
}
}
}
/* Types */
pub const T_SHORT: c_int = 0;
pub const T_INT: c_int = 1;

View File

@ -1,13 +1,24 @@
use crate::object::*;
use std::os::raw::c_int;
#[cfg(not(PyPy))]
#[cfg(all(not(PyPy), Py_LIMITED_API))]
opaque_struct!(PyWeakReference);
#[cfg(all(not(PyPy), not(Py_LIMITED_API)))]
pub struct PyWeakReference {
pub ob_base: PyObject,
pub wr_object: *mut PyObject,
pub wr_callback: *mut PyObject,
pub hash: crate::Py_hash_t,
pub wr_prev: *mut PyWeakReference,
pub wr_next: *mut PyWeakReference,
}
#[cfg_attr(windows, link(name = "pythonXY"))]
extern "C" {
static mut _PyWeakref_RefType: PyTypeObject;
static mut _PyWeakref_ProxyType: PyTypeObject;
static mut _PyWeakref_CallableProxyType: PyTypeObject;
pub static mut _PyWeakref_RefType: PyTypeObject;
pub static mut _PyWeakref_ProxyType: PyTypeObject;
pub static mut _PyWeakref_CallableProxyType: PyTypeObject;
#[cfg(PyPy)]
#[link_name = "PyPyWeakref_CheckRef"]