Merge pull request #3335 from davidhewitt/3.12-ffi-immortal
update object.h definitions for Python 3.12
This commit is contained in:
commit
6c25b7355e
|
@ -0,0 +1 @@
|
|||
Update FFI definitions of `object.h` for Python 3.12 and up.
|
|
@ -0,0 +1 @@
|
|||
Fix reference counting of immortal objects on Python 3.12 betas.
|
|
@ -1,4 +1,6 @@
|
|||
use crate::object;
|
||||
#[cfg(Py_3_8)]
|
||||
use crate::vectorcallfunc;
|
||||
use crate::{PyObject, Py_ssize_t};
|
||||
use std::mem;
|
||||
use std::os::raw::{c_char, c_int, c_uint, c_ulong, c_void};
|
||||
|
@ -112,14 +114,6 @@ mod bufferinfo {
|
|||
#[cfg(not(Py_3_11))]
|
||||
pub use self::bufferinfo::*;
|
||||
|
||||
#[cfg(Py_3_8)]
|
||||
pub type vectorcallfunc = unsafe extern "C" fn(
|
||||
callable: *mut PyObject,
|
||||
args: *const *mut PyObject,
|
||||
nargsf: libc::size_t,
|
||||
kwnames: *mut PyObject,
|
||||
) -> *mut PyObject;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct PyNumberMethods {
|
||||
|
@ -275,7 +269,7 @@ pub struct PyTypeObject {
|
|||
pub tp_version_tag: c_uint,
|
||||
pub tp_finalize: Option<object::destructor>,
|
||||
#[cfg(Py_3_8)]
|
||||
pub tp_vectorcall: Option<super::vectorcallfunc>,
|
||||
pub tp_vectorcall: Option<vectorcallfunc>,
|
||||
#[cfg(Py_3_12)]
|
||||
pub tp_watched: c_char,
|
||||
#[cfg(any(all(PyPy, Py_3_8, not(Py_3_10)), all(not(PyPy), Py_3_8, not(Py_3_9))))]
|
||||
|
|
|
@ -259,8 +259,6 @@ macro_rules! opaque_struct {
|
|||
pub use self::abstract_::*;
|
||||
pub use self::bltinmodule::*;
|
||||
pub use self::boolobject::*;
|
||||
#[cfg(Py_3_11)]
|
||||
pub use self::buffer::*;
|
||||
pub use self::bytearrayobject::*;
|
||||
pub use self::bytesobject::*;
|
||||
pub use self::ceval::*;
|
||||
|
@ -293,6 +291,8 @@ pub use self::objimpl::*;
|
|||
pub use self::osmodule::*;
|
||||
#[cfg(not(any(PyPy, Py_LIMITED_API, Py_3_10)))]
|
||||
pub use self::pyarena::*;
|
||||
#[cfg(Py_3_11)]
|
||||
pub use self::pybuffer::*;
|
||||
pub use self::pycapsule::*;
|
||||
pub use self::pyerrors::*;
|
||||
pub use self::pyframe::*;
|
||||
|
@ -320,8 +320,6 @@ mod abstract_;
|
|||
// skipped ast.h
|
||||
mod bltinmodule;
|
||||
mod boolobject;
|
||||
#[cfg(Py_3_11)]
|
||||
mod buffer;
|
||||
mod bytearrayobject;
|
||||
mod bytesobject;
|
||||
// skipped cellobject.h
|
||||
|
@ -372,8 +370,9 @@ mod osmodule;
|
|||
// skipped py_curses.h
|
||||
#[cfg(not(any(PyPy, Py_LIMITED_API, Py_3_10)))]
|
||||
mod pyarena;
|
||||
#[cfg(Py_3_11)]
|
||||
mod pybuffer;
|
||||
mod pycapsule;
|
||||
// skipped pydecimal.h
|
||||
// skipped pydtrace.h
|
||||
mod pyerrors;
|
||||
// skipped pyexpat.h
|
||||
|
@ -387,6 +386,7 @@ mod pylifecycle;
|
|||
mod pymem;
|
||||
mod pyport;
|
||||
mod pystate;
|
||||
// skipped pystats.h
|
||||
mod pythonrun;
|
||||
// skipped pystrhex.h
|
||||
// skipped pystrcmp.h
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// FFI note: this file changed a lot between 3.6 and 3.10.
|
||||
// Some missing definitions may not be marked "skipped".
|
||||
use crate::pyport::{Py_hash_t, Py_ssize_t};
|
||||
use std::mem;
|
||||
use std::os::raw::{c_char, c_int, c_uint, c_ulong, c_void};
|
||||
|
@ -14,11 +12,24 @@ pub use crate::cpython::object::PyTypeObject;
|
|||
// _PyObject_HEAD_EXTRA: conditionally defined in PyObject_HEAD_INIT
|
||||
// _PyObject_EXTRA_INIT: conditionally defined in PyObject_HEAD_INIT
|
||||
|
||||
#[cfg(Py_3_12)]
|
||||
pub const _Py_IMMORTAL_REFCNT: Py_ssize_t = {
|
||||
if cfg!(target_pointer_width = "64") {
|
||||
c_uint::MAX as Py_ssize_t
|
||||
} else {
|
||||
// for 32-bit systems, use the lower 30 bits (see comment in CPython's object.h)
|
||||
(c_uint::MAX >> 2) as Py_ssize_t
|
||||
}
|
||||
};
|
||||
|
||||
pub const PyObject_HEAD_INIT: PyObject = PyObject {
|
||||
#[cfg(py_sys_config = "Py_TRACE_REFS")]
|
||||
_ob_next: std::ptr::null_mut(),
|
||||
#[cfg(py_sys_config = "Py_TRACE_REFS")]
|
||||
_ob_prev: std::ptr::null_mut(),
|
||||
#[cfg(Py_3_12)]
|
||||
ob_refcnt: PyObjectObRefcnt { ob_refcnt: 1 },
|
||||
#[cfg(not(Py_3_12))]
|
||||
ob_refcnt: 1,
|
||||
#[cfg(PyPy)]
|
||||
ob_pypy_link: 0,
|
||||
|
@ -28,6 +39,27 @@ pub const PyObject_HEAD_INIT: PyObject = PyObject {
|
|||
// skipped PyObject_VAR_HEAD
|
||||
// skipped Py_INVALID_SIZE
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
#[cfg(Py_3_12)]
|
||||
/// This union is anonymous in CPython, so the name was given by PyO3 because
|
||||
/// Rust unions need a name.
|
||||
pub union PyObjectObRefcnt {
|
||||
pub ob_refcnt: Py_ssize_t,
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub ob_refcnt_split: [crate::PY_UINT32_T; 2],
|
||||
}
|
||||
|
||||
#[cfg(Py_3_12)]
|
||||
impl std::fmt::Debug for PyObjectObRefcnt {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", unsafe { self.ob_refcnt })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(Py_3_12))]
|
||||
pub type PyObjectObRefcnt = Py_ssize_t;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct PyObject {
|
||||
|
@ -35,14 +67,13 @@ pub struct PyObject {
|
|||
pub _ob_next: *mut PyObject,
|
||||
#[cfg(py_sys_config = "Py_TRACE_REFS")]
|
||||
pub _ob_prev: *mut PyObject,
|
||||
pub ob_refcnt: Py_ssize_t,
|
||||
pub ob_refcnt: PyObjectObRefcnt,
|
||||
#[cfg(PyPy)]
|
||||
pub ob_pypy_link: Py_ssize_t,
|
||||
pub ob_type: *mut PyTypeObject,
|
||||
}
|
||||
|
||||
// skipped _PyObject_CAST
|
||||
// skipped _PyObject_CAST_CONST
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
|
@ -52,18 +83,21 @@ pub struct PyVarObject {
|
|||
}
|
||||
|
||||
// skipped _PyVarObject_CAST
|
||||
// skipped _PyVarObject_CAST_CONST
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn Py_Is(x: *mut PyObject, y: *mut PyObject) -> c_int {
|
||||
(x == y).into()
|
||||
}
|
||||
|
||||
// skipped _Py_REFCNT: defined in Py_REFCNT
|
||||
#[inline]
|
||||
#[cfg(Py_3_12)]
|
||||
pub unsafe fn Py_REFCNT(ob: *mut PyObject) -> Py_ssize_t {
|
||||
(*ob).ob_refcnt.ob_refcnt
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(not(Py_3_12))]
|
||||
pub unsafe fn Py_REFCNT(ob: *mut PyObject) -> Py_ssize_t {
|
||||
assert!(!ob.is_null());
|
||||
(*ob).ob_refcnt
|
||||
}
|
||||
|
||||
|
@ -72,9 +106,14 @@ pub unsafe fn Py_TYPE(ob: *mut PyObject) -> *mut PyTypeObject {
|
|||
(*ob).ob_type
|
||||
}
|
||||
|
||||
// PyLong_Type defined in longobject.rs
|
||||
// PyBool_Type defined in boolobject.rs
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn Py_SIZE(ob: *mut PyObject) -> Py_ssize_t {
|
||||
(*(ob as *mut PyVarObject)).ob_size
|
||||
debug_assert_ne!((*ob).ob_type, std::ptr::addr_of_mut!(crate::PyLong_Type));
|
||||
debug_assert_ne!((*ob).ob_type, std::ptr::addr_of_mut!(crate::PyBool_Type));
|
||||
(*ob.cast::<PyVarObject>()).ob_size
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -82,6 +121,18 @@ pub unsafe fn Py_IS_TYPE(ob: *mut PyObject, tp: *mut PyTypeObject) -> c_int {
|
|||
(Py_TYPE(ob) == tp) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[cfg(all(Py_3_12, target_pointer_width = "64"))]
|
||||
pub unsafe fn _Py_IsImmortal(op: *mut PyObject) -> c_int {
|
||||
(((*op).ob_refcnt.ob_refcnt as crate::PY_INT32_T) < 0) as c_int
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
#[cfg(all(Py_3_12, target_pointer_width = "32"))]
|
||||
pub unsafe fn _Py_IsImmortal(op: *mut PyObject) -> c_int {
|
||||
((*op).ob_refcnt.ob_refcnt == _Py_IMMORTAL_REFCNT) as c_int
|
||||
}
|
||||
|
||||
// skipped _Py_SET_REFCNT
|
||||
// skipped Py_SET_REFCNT
|
||||
// skipped _Py_SET_TYPE
|
||||
|
@ -89,82 +140,51 @@ pub unsafe fn Py_IS_TYPE(ob: *mut PyObject, tp: *mut PyTypeObject) -> c_int {
|
|||
// skipped _Py_SET_SIZE
|
||||
// skipped Py_SET_SIZE
|
||||
|
||||
pub type unaryfunc = unsafe extern "C" fn(arg1: *mut PyObject) -> *mut PyObject;
|
||||
|
||||
pub type binaryfunc =
|
||||
unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut PyObject) -> *mut PyObject;
|
||||
|
||||
pub type ternaryfunc = unsafe extern "C" fn(
|
||||
arg1: *mut PyObject,
|
||||
arg2: *mut PyObject,
|
||||
arg3: *mut PyObject,
|
||||
) -> *mut PyObject;
|
||||
|
||||
pub type inquiry = unsafe extern "C" fn(arg1: *mut PyObject) -> c_int;
|
||||
|
||||
pub type lenfunc = unsafe extern "C" fn(arg1: *mut PyObject) -> Py_ssize_t;
|
||||
|
||||
pub type ssizeargfunc =
|
||||
unsafe extern "C" fn(arg1: *mut PyObject, arg2: Py_ssize_t) -> *mut PyObject;
|
||||
|
||||
pub type unaryfunc = unsafe extern "C" fn(*mut PyObject) -> *mut PyObject;
|
||||
pub type binaryfunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject) -> *mut PyObject;
|
||||
pub type ternaryfunc =
|
||||
unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> *mut PyObject;
|
||||
pub type inquiry = unsafe extern "C" fn(*mut PyObject) -> c_int;
|
||||
pub type lenfunc = unsafe extern "C" fn(*mut PyObject) -> Py_ssize_t;
|
||||
pub type ssizeargfunc = unsafe extern "C" fn(*mut PyObject, Py_ssize_t) -> *mut PyObject;
|
||||
pub type ssizessizeargfunc =
|
||||
unsafe extern "C" fn(arg1: *mut PyObject, arg2: Py_ssize_t, arg3: Py_ssize_t) -> *mut PyObject;
|
||||
unsafe extern "C" fn(*mut PyObject, Py_ssize_t, Py_ssize_t) -> *mut PyObject;
|
||||
pub type ssizeobjargproc = unsafe extern "C" fn(*mut PyObject, Py_ssize_t, *mut PyObject) -> c_int;
|
||||
pub type ssizessizeobjargproc =
|
||||
unsafe extern "C" fn(*mut PyObject, Py_ssize_t, Py_ssize_t, arg4: *mut PyObject) -> c_int;
|
||||
pub type objobjargproc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> c_int;
|
||||
|
||||
pub type ssizeobjargproc =
|
||||
unsafe extern "C" fn(arg1: *mut PyObject, arg2: Py_ssize_t, arg3: *mut PyObject) -> c_int;
|
||||
|
||||
pub type ssizessizeobjargproc = unsafe extern "C" fn(
|
||||
arg1: *mut PyObject,
|
||||
arg2: Py_ssize_t,
|
||||
arg3: Py_ssize_t,
|
||||
arg4: *mut PyObject,
|
||||
) -> c_int;
|
||||
|
||||
pub type objobjargproc =
|
||||
unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject) -> c_int;
|
||||
|
||||
pub type objobjproc = unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int;
|
||||
pub type objobjproc = unsafe extern "C" fn(*mut PyObject, *mut PyObject) -> c_int;
|
||||
pub type visitproc = unsafe extern "C" fn(object: *mut PyObject, arg: *mut c_void) -> c_int;
|
||||
pub type traverseproc =
|
||||
unsafe extern "C" fn(slf: *mut PyObject, visit: visitproc, arg: *mut c_void) -> c_int;
|
||||
|
||||
pub type freefunc = unsafe extern "C" fn(arg1: *mut c_void);
|
||||
pub type destructor = unsafe extern "C" fn(arg1: *mut PyObject);
|
||||
pub type getattrfunc =
|
||||
unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut c_char) -> *mut PyObject;
|
||||
pub type getattrofunc =
|
||||
unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut PyObject) -> *mut PyObject;
|
||||
pub type setattrfunc =
|
||||
unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut c_char, arg3: *mut PyObject) -> c_int;
|
||||
pub type setattrofunc =
|
||||
unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject) -> c_int;
|
||||
pub type reprfunc = unsafe extern "C" fn(arg1: *mut PyObject) -> *mut PyObject;
|
||||
pub type hashfunc = unsafe extern "C" fn(arg1: *mut PyObject) -> Py_hash_t;
|
||||
pub type richcmpfunc =
|
||||
unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut PyObject, arg3: c_int) -> *mut PyObject;
|
||||
pub type getiterfunc = unsafe extern "C" fn(arg1: *mut PyObject) -> *mut PyObject;
|
||||
pub type iternextfunc = unsafe extern "C" fn(arg1: *mut PyObject) -> *mut PyObject;
|
||||
pub type descrgetfunc = unsafe extern "C" fn(
|
||||
arg1: *mut PyObject,
|
||||
arg2: *mut PyObject,
|
||||
arg3: *mut PyObject,
|
||||
pub type freefunc = unsafe extern "C" fn(*mut c_void);
|
||||
pub type destructor = unsafe extern "C" fn(*mut PyObject);
|
||||
pub type getattrfunc = unsafe extern "C" fn(*mut PyObject, *mut c_char) -> *mut PyObject;
|
||||
pub type getattrofunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject) -> *mut PyObject;
|
||||
pub type setattrfunc = unsafe extern "C" fn(*mut PyObject, *mut c_char, *mut PyObject) -> c_int;
|
||||
pub type setattrofunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> c_int;
|
||||
pub type reprfunc = unsafe extern "C" fn(*mut PyObject) -> *mut PyObject;
|
||||
pub type hashfunc = unsafe extern "C" fn(*mut PyObject) -> Py_hash_t;
|
||||
pub type richcmpfunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, c_int) -> *mut PyObject;
|
||||
pub type getiterfunc = unsafe extern "C" fn(*mut PyObject) -> *mut PyObject;
|
||||
pub type iternextfunc = unsafe extern "C" fn(*mut PyObject) -> *mut PyObject;
|
||||
pub type descrgetfunc =
|
||||
unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> *mut PyObject;
|
||||
pub type descrsetfunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> c_int;
|
||||
pub type initproc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> c_int;
|
||||
pub type newfunc =
|
||||
unsafe extern "C" fn(*mut PyTypeObject, *mut PyObject, *mut PyObject) -> *mut PyObject;
|
||||
pub type allocfunc = unsafe extern "C" fn(*mut PyTypeObject, Py_ssize_t) -> *mut PyObject;
|
||||
|
||||
#[cfg(Py_3_8)]
|
||||
pub type vectorcallfunc = unsafe extern "C" fn(
|
||||
callable: *mut PyObject,
|
||||
args: *const *mut PyObject,
|
||||
nargsf: libc::size_t,
|
||||
kwnames: *mut PyObject,
|
||||
) -> *mut PyObject;
|
||||
pub type descrsetfunc =
|
||||
unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject) -> c_int;
|
||||
pub type initproc =
|
||||
unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject) -> c_int;
|
||||
pub type newfunc = unsafe extern "C" fn(
|
||||
arg1: *mut PyTypeObject,
|
||||
arg2: *mut PyObject,
|
||||
arg3: *mut PyObject,
|
||||
) -> *mut PyObject;
|
||||
pub type allocfunc =
|
||||
unsafe extern "C" fn(arg1: *mut PyTypeObject, arg2: Py_ssize_t) -> *mut PyObject;
|
||||
#[cfg(Py_3_11)]
|
||||
pub type getbufferproc =
|
||||
unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut crate::Py_buffer, arg3: c_int) -> c_int;
|
||||
#[cfg(Py_3_11)]
|
||||
pub type releasebufferproc = unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut crate::Py_buffer);
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
|
@ -220,9 +240,32 @@ extern "C" {
|
|||
#[cfg(any(Py_3_10, all(Py_3_9, not(Py_LIMITED_API))))]
|
||||
#[cfg_attr(PyPy, link_name = "PyPyType_GetModuleState")]
|
||||
pub fn PyType_GetModuleState(arg1: *mut PyTypeObject) -> *mut c_void;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#[cfg(Py_3_11)]
|
||||
#[cfg_attr(PyPy, link_name = "PyPyType_GetName")]
|
||||
pub fn PyType_GetName(arg1: *mut PyTypeObject) -> *mut PyObject;
|
||||
|
||||
#[cfg(Py_3_11)]
|
||||
#[cfg_attr(PyPy, link_name = "PyPyType_GetQualName")]
|
||||
pub fn PyType_GetQualName(arg1: *mut PyTypeObject) -> *mut PyObject;
|
||||
|
||||
#[cfg(Py_3_12)]
|
||||
#[cfg_attr(PyPy, link_name = "PyPyType_FromMetaclass")]
|
||||
pub fn PyType_FromMetaclass(
|
||||
metaclass: *mut PyTypeObject,
|
||||
module: *mut PyObject,
|
||||
spec: *mut PyType_Spec,
|
||||
bases: *mut PyObject,
|
||||
) -> *mut PyObject;
|
||||
|
||||
#[cfg(Py_3_12)]
|
||||
#[cfg_attr(PyPy, link_name = "PyPyObject_GetTypeData")]
|
||||
pub fn PyObject_GetTypeData(obj: *mut PyObject, cls: *mut PyTypeObject) -> *mut c_void;
|
||||
|
||||
#[cfg(Py_3_12)]
|
||||
#[cfg_attr(PyPy, link_name = "PyPyObject_GetTypeDataSize")]
|
||||
pub fn PyObject_GetTypeDataSize(cls: *mut PyTypeObject) -> Py_ssize_t;
|
||||
|
||||
#[cfg_attr(PyPy, link_name = "PyPyType_IsSubtype")]
|
||||
pub fn PyType_IsSubtype(a: *mut PyTypeObject, b: *mut PyTypeObject) -> c_int;
|
||||
}
|
||||
|
@ -246,9 +289,7 @@ extern "C" {
|
|||
|
||||
extern "C" {
|
||||
pub fn PyType_GetFlags(arg1: *mut PyTypeObject) -> c_ulong;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#[cfg_attr(PyPy, link_name = "PyPyType_Ready")]
|
||||
pub fn PyType_Ready(t: *mut PyTypeObject) -> c_int;
|
||||
#[cfg_attr(PyPy, link_name = "PyPyType_GenericAlloc")]
|
||||
|
@ -337,6 +378,15 @@ extern "C" {
|
|||
// Flag bits for printing:
|
||||
pub const Py_PRINT_RAW: c_int = 1; // No string quotes etc.
|
||||
|
||||
#[cfg(all(Py_3_12, not(Py_LIMITED_API)))]
|
||||
pub const _Py_TPFLAGS_STATIC_BUILTIN: c_ulong = 1 << 1;
|
||||
|
||||
#[cfg(all(Py_3_12, not(Py_LIMITED_API)))]
|
||||
pub const Py_TPFLAGS_MANAGED_WEAKREF: c_ulong = 1 << 3;
|
||||
|
||||
#[cfg(all(Py_3_11, not(Py_LIMITED_API)))]
|
||||
pub const Py_TPFLAGS_MANAGED_DICT: c_ulong = 1 << 4;
|
||||
|
||||
#[cfg(all(Py_3_10, not(Py_LIMITED_API)))]
|
||||
pub const Py_TPFLAGS_SEQUENCE: c_ulong = 1 << 5;
|
||||
|
||||
|
@ -356,7 +406,7 @@ pub const Py_TPFLAGS_HEAPTYPE: c_ulong = 1 << 9;
|
|||
pub const Py_TPFLAGS_BASETYPE: c_ulong = 1 << 10;
|
||||
|
||||
/// Set if the type implements the vectorcall protocol (PEP 590)
|
||||
#[cfg(all(Py_3_8, not(Py_LIMITED_API)))]
|
||||
#[cfg(any(Py_3_12, all(Py_3_8, not(Py_LIMITED_API))))]
|
||||
pub const Py_TPFLAGS_HAVE_VECTORCALL: c_ulong = 1 << 11;
|
||||
// skipped non-limited _Py_TPFLAGS_HAVE_VECTORCALL
|
||||
|
||||
|
@ -374,15 +424,14 @@ const Py_TPFLAGS_HAVE_STACKLESS_EXTENSION: c_ulong = 0;
|
|||
#[cfg(Py_3_8)]
|
||||
pub const Py_TPFLAGS_METHOD_DESCRIPTOR: c_ulong = 1 << 17;
|
||||
|
||||
/// 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 */
|
||||
pub const Py_TPFLAGS_IS_ABSTRACT: c_ulong = 1 << 20;
|
||||
|
||||
// skipped non-limited / 3.10 Py_TPFLAGS_HAVE_AM_SEND
|
||||
#[cfg(Py_3_12)]
|
||||
pub const Py_TPFLAGS_ITEMS_AT_END: c_ulong = 1 << 23;
|
||||
|
||||
/* These flags are used to determine if a type is a subclass. */
|
||||
pub const Py_TPFLAGS_LONG_SUBCLASS: c_ulong = 1 << 24;
|
||||
|
@ -394,37 +443,161 @@ pub const Py_TPFLAGS_DICT_SUBCLASS: c_ulong = 1 << 29;
|
|||
pub const Py_TPFLAGS_BASE_EXC_SUBCLASS: c_ulong = 1 << 30;
|
||||
pub const Py_TPFLAGS_TYPE_SUBCLASS: c_ulong = 1 << 31;
|
||||
|
||||
pub const Py_TPFLAGS_DEFAULT: c_ulong =
|
||||
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | Py_TPFLAGS_HAVE_VERSION_TAG;
|
||||
pub const Py_TPFLAGS_DEFAULT: c_ulong = if cfg!(Py_3_10) {
|
||||
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION
|
||||
} else {
|
||||
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | Py_TPFLAGS_HAVE_VERSION_TAG
|
||||
};
|
||||
|
||||
pub const Py_TPFLAGS_HAVE_FINALIZE: c_ulong = 1;
|
||||
pub const Py_TPFLAGS_HAVE_VERSION_TAG: c_ulong = 1 << 18;
|
||||
|
||||
// skipped _Py_RefTotal
|
||||
// skipped _Py_NegativeRefCount
|
||||
#[cfg(all(py_sys_config = "Py_REF_DEBUG", not(Py_LIMITED_API)))]
|
||||
extern "C" {
|
||||
pub fn _Py_NegativeRefCount(filename: *const c_char, lineno: c_int, op: *mut PyObject);
|
||||
#[cfg(Py_3_12)]
|
||||
#[link_name = "_Py_IncRefTotal_DO_NOT_USE_THIS"]
|
||||
fn _Py_INC_REFTOTAL();
|
||||
#[cfg(Py_3_12)]
|
||||
#[link_name = "_Py_DecRefTotal_DO_NOT_USE_THIS"]
|
||||
fn _Py_DEC_REFTOTAL();
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#[cfg_attr(PyPy, link_name = "_PyPy_Dealloc")]
|
||||
pub fn _Py_Dealloc(arg1: *mut PyObject);
|
||||
|
||||
#[cfg_attr(PyPy, link_name = "PyPy_IncRef")]
|
||||
pub fn Py_IncRef(o: *mut PyObject);
|
||||
#[cfg_attr(PyPy, link_name = "PyPy_DecRef")]
|
||||
pub fn Py_DecRef(o: *mut PyObject);
|
||||
|
||||
#[cfg(Py_3_10)]
|
||||
#[cfg_attr(PyPy, link_name = "_PyPy_IncRef")]
|
||||
pub fn _Py_IncRef(o: *mut PyObject);
|
||||
#[cfg(Py_3_10)]
|
||||
#[cfg_attr(PyPy, link_name = "_PyPy_DecRef")]
|
||||
pub fn _Py_DecRef(o: *mut PyObject);
|
||||
}
|
||||
|
||||
// Reference counting macros.
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
pub unsafe fn Py_INCREF(op: *mut PyObject) {
|
||||
if cfg!(py_sys_config = "Py_REF_DEBUG") {
|
||||
Py_IncRef(op)
|
||||
} else {
|
||||
(*op).ob_refcnt += 1
|
||||
#[cfg(any(
|
||||
all(Py_LIMITED_API, Py_3_12),
|
||||
all(
|
||||
py_sys_config = "Py_REF_DEBUG",
|
||||
Py_3_10,
|
||||
not(all(Py_3_12, not(Py_LIMITED_API)))
|
||||
)
|
||||
))]
|
||||
{
|
||||
return _Py_IncRef(op);
|
||||
}
|
||||
|
||||
#[cfg(all(py_sys_config = "Py_REF_DEBUG", not(Py_3_10)))]
|
||||
{
|
||||
return Py_IncRef(op);
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
not(Py_LIMITED_API),
|
||||
all(Py_LIMITED_API, not(Py_3_12)),
|
||||
all(py_sys_config = "Py_REF_DEBUG", Py_3_12, not(Py_LIMITED_API))
|
||||
))]
|
||||
{
|
||||
#[cfg(all(Py_3_12, target_pointer_width = "64"))]
|
||||
{
|
||||
let cur_refcnt = (*op).ob_refcnt.ob_refcnt_split[crate::PY_BIG_ENDIAN];
|
||||
let new_refcnt = cur_refcnt.wrapping_add(1);
|
||||
if new_refcnt == 0 {
|
||||
return;
|
||||
}
|
||||
(*op).ob_refcnt.ob_refcnt_split[crate::PY_BIG_ENDIAN] = new_refcnt;
|
||||
}
|
||||
|
||||
#[cfg(all(Py_3_12, target_pointer_width = "32"))]
|
||||
{
|
||||
if _Py_IsImmortal(op) != 0 {
|
||||
return;
|
||||
}
|
||||
(*op).ob_refcnt.ob_refcnt += 1
|
||||
}
|
||||
|
||||
#[cfg(not(Py_3_12))]
|
||||
{
|
||||
(*op).ob_refcnt += 1
|
||||
}
|
||||
|
||||
// Skipped _Py_INCREF_STAT_INC - if anyone wants this, please file an issue
|
||||
// or submit a PR supporting Py_STATS build option and pystats.h
|
||||
|
||||
#[cfg(all(py_sys_config = "Py_REF_DEBUG", Py_3_12))]
|
||||
_Py_INC_REFTOTAL();
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[inline(always)]
|
||||
#[cfg_attr(
|
||||
all(py_sys_config = "Py_REF_DEBUG", Py_3_12, not(Py_LIMITED_API)),
|
||||
track_caller
|
||||
)]
|
||||
pub unsafe fn Py_DECREF(op: *mut PyObject) {
|
||||
if cfg!(py_sys_config = "Py_REF_DEBUG") {
|
||||
Py_DecRef(op)
|
||||
} else {
|
||||
(*op).ob_refcnt -= 1;
|
||||
if (*op).ob_refcnt == 0 {
|
||||
_Py_Dealloc(op)
|
||||
#[cfg(any(
|
||||
all(Py_LIMITED_API, Py_3_12),
|
||||
all(
|
||||
py_sys_config = "Py_REF_DEBUG",
|
||||
Py_3_10,
|
||||
not(all(Py_3_12, not(Py_LIMITED_API)))
|
||||
)
|
||||
))]
|
||||
{
|
||||
return _Py_DecRef(op);
|
||||
}
|
||||
|
||||
#[cfg(all(py_sys_config = "Py_REF_DEBUG", not(Py_3_10)))]
|
||||
{
|
||||
return Py_DecRef(op);
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
not(Py_LIMITED_API),
|
||||
all(Py_LIMITED_API, not(Py_3_12)),
|
||||
all(py_sys_config = "Py_REF_DEBUG", Py_3_12, not(Py_LIMITED_API))
|
||||
))]
|
||||
{
|
||||
#[cfg(Py_3_12)]
|
||||
if _Py_IsImmortal(op) != 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skipped _Py_DECREF_STAT_INC - if anyone needs this, please file an issue
|
||||
// or submit a PR supporting Py_STATS build option and pystats.h
|
||||
|
||||
#[cfg(all(py_sys_config = "Py_REF_DEBUG", Py_3_12))]
|
||||
_Py_DEC_REFTOTAL();
|
||||
|
||||
#[cfg(Py_3_12)]
|
||||
{
|
||||
(*op).ob_refcnt.ob_refcnt -= 1;
|
||||
|
||||
#[cfg(py_sys_config = "Py_REF_DEBUG")]
|
||||
if (*op).ob_refcnt.ob_refcnt < 0 {
|
||||
let location = std::panic::Location::caller();
|
||||
_Py_NegativeRefcount(location.file(), location.line(), op);
|
||||
}
|
||||
|
||||
if (*op).ob_refcnt.ob_refcnt == 0 {
|
||||
_Py_Dealloc(op);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(Py_3_12))]
|
||||
{
|
||||
(*op).ob_refcnt -= 1;
|
||||
|
||||
if (*op).ob_refcnt == 0 {
|
||||
_Py_Dealloc(op);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -453,14 +626,9 @@ pub unsafe fn Py_XDECREF(op: *mut PyObject) {
|
|||
}
|
||||
|
||||
extern "C" {
|
||||
#[cfg_attr(PyPy, link_name = "PyPy_IncRef")]
|
||||
pub fn Py_IncRef(o: *mut PyObject);
|
||||
#[cfg_attr(PyPy, link_name = "PyPy_DecRef")]
|
||||
pub fn Py_DecRef(o: *mut PyObject);
|
||||
|
||||
#[cfg(Py_3_10)]
|
||||
#[cfg(all(Py_3_10, Py_LIMITED_API))]
|
||||
pub fn Py_NewRef(obj: *mut PyObject) -> *mut PyObject;
|
||||
#[cfg(Py_3_10)]
|
||||
#[cfg(all(Py_3_10, Py_LIMITED_API))]
|
||||
pub fn Py_XNewRef(obj: *mut PyObject) -> *mut PyObject;
|
||||
}
|
||||
|
||||
|
@ -480,6 +648,18 @@ pub unsafe fn _Py_XNewRef(obj: *mut PyObject) -> *mut PyObject {
|
|||
obj
|
||||
}
|
||||
|
||||
#[cfg(all(Py_3_10, not(Py_LIMITED_API)))]
|
||||
#[inline]
|
||||
pub unsafe fn Py_NewRef(obj: *mut PyObject) -> *mut PyObject {
|
||||
_Py_NewRef(obj)
|
||||
}
|
||||
|
||||
#[cfg(all(Py_3_10, not(Py_LIMITED_API)))]
|
||||
#[inline]
|
||||
pub unsafe fn Py_XNewRef(obj: *mut PyObject) -> *mut PyObject {
|
||||
_Py_XNewRef(obj)
|
||||
}
|
||||
|
||||
#[cfg_attr(windows, link(name = "pythonXY"))]
|
||||
extern "C" {
|
||||
#[cfg_attr(PyPy, link_name = "_PyPy_NoneStruct")]
|
||||
|
@ -554,5 +734,5 @@ pub unsafe fn PyType_Check(op: *mut PyObject) -> c_int {
|
|||
|
||||
#[inline]
|
||||
pub unsafe fn PyType_CheckExact(op: *mut PyObject) -> c_int {
|
||||
(Py_TYPE(op) == ptr::addr_of_mut!(PyType_Type)) as c_int
|
||||
Py_IS_TYPE(op, ptr::addr_of_mut!(PyType_Type))
|
||||
}
|
||||
|
|
|
@ -53,6 +53,9 @@ impl Py_buffer {
|
|||
}
|
||||
}
|
||||
|
||||
pub type getbufferproc = unsafe extern "C" fn(*mut PyObject, *mut crate::Py_buffer, c_int) -> c_int;
|
||||
pub type releasebufferproc = unsafe extern "C" fn(*mut PyObject, *mut crate::Py_buffer);
|
||||
|
||||
/* Return 1 if the getbuffer function is available, otherwise return 0. */
|
||||
extern "C" {
|
||||
#[cfg(not(PyPy))]
|
|
@ -1,3 +1,9 @@
|
|||
pub type PY_UINT32_T = u32;
|
||||
pub type PY_UINT64_T = u64;
|
||||
|
||||
pub type PY_INT32_T = i32;
|
||||
pub type PY_INT64_T = i64;
|
||||
|
||||
pub type Py_uintptr_t = ::libc::uintptr_t;
|
||||
pub type Py_intptr_t = ::libc::intptr_t;
|
||||
pub type Py_ssize_t = ::libc::ssize_t;
|
||||
|
@ -7,3 +13,13 @@ pub type Py_uhash_t = ::libc::size_t;
|
|||
|
||||
pub const PY_SSIZE_T_MIN: Py_ssize_t = std::isize::MIN as Py_ssize_t;
|
||||
pub const PY_SSIZE_T_MAX: Py_ssize_t = std::isize::MAX as Py_ssize_t;
|
||||
|
||||
#[cfg(target_endian = "big")]
|
||||
pub const PY_BIG_ENDIAN: usize = 1;
|
||||
#[cfg(target_endian = "big")]
|
||||
pub const PY_LITTLE_ENDIAN: usize = 0;
|
||||
|
||||
#[cfg(target_endian = "little")]
|
||||
pub const PY_BIG_ENDIAN: usize = 0;
|
||||
#[cfg(target_endian = "little")]
|
||||
pub const PY_LITTLE_ENDIAN: usize = 1;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
//!
|
||||
//! [capi]: https://docs.python.org/3/c-api/index.html
|
||||
|
||||
#[cfg(all(not(Py_LIMITED_API), test))]
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
// reexport raw bindings exposed in pyo3_ffi
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
use crate::ffi::*;
|
||||
use crate::{types::PyDict, AsPyPointer, IntoPy, Py, PyAny, Python};
|
||||
use crate::{AsPyPointer, Python};
|
||||
|
||||
use crate::types::PyString;
|
||||
#[cfg(not(Py_3_12))]
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
use crate::{
|
||||
types::{PyDict, PyString},
|
||||
IntoPy, Py, PyAny,
|
||||
};
|
||||
#[cfg(not(any(Py_3_12, Py_LIMITED_API)))]
|
||||
use libc::wchar_t;
|
||||
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
#[cfg_attr(target_arch = "wasm32", ignore)] // DateTime import fails on wasm for mysterious reasons
|
||||
#[test]
|
||||
fn test_datetime_fromtimestamp() {
|
||||
|
@ -25,6 +30,7 @@ fn test_datetime_fromtimestamp() {
|
|||
})
|
||||
}
|
||||
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
#[cfg_attr(target_arch = "wasm32", ignore)] // DateTime import fails on wasm for mysterious reasons
|
||||
#[test]
|
||||
fn test_date_fromtimestamp() {
|
||||
|
@ -45,6 +51,7 @@ fn test_date_fromtimestamp() {
|
|||
})
|
||||
}
|
||||
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
#[cfg_attr(target_arch = "wasm32", ignore)] // DateTime import fails on wasm for mysterious reasons
|
||||
#[test]
|
||||
fn test_utc_timezone() {
|
||||
|
@ -65,6 +72,7 @@ fn test_utc_timezone() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
#[cfg(feature = "macros")]
|
||||
#[cfg_attr(target_arch = "wasm32", ignore)] // DateTime import fails on wasm for mysterious reasons
|
||||
fn test_timezone_from_offset() {
|
||||
|
@ -82,6 +90,7 @@ fn test_timezone_from_offset() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
#[cfg(feature = "macros")]
|
||||
#[cfg_attr(target_arch = "wasm32", ignore)] // DateTime import fails on wasm for mysterious reasons
|
||||
fn test_timezone_from_offset_and_name() {
|
||||
|
@ -105,6 +114,7 @@ fn test_timezone_from_offset_and_name() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
fn ascii_object_bitfield() {
|
||||
let ob_base: PyObject = unsafe { std::mem::zeroed() };
|
||||
|
||||
|
@ -152,6 +162,7 @@ fn ascii_object_bitfield() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
#[cfg_attr(Py_3_10, allow(deprecated))]
|
||||
fn ascii() {
|
||||
Python::with_gil(|py| {
|
||||
|
@ -193,6 +204,7 @@ fn ascii() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
#[cfg_attr(Py_3_10, allow(deprecated))]
|
||||
fn ucs4() {
|
||||
Python::with_gil(|py| {
|
||||
|
@ -236,6 +248,7 @@ fn ucs4() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
#[cfg_attr(target_arch = "wasm32", ignore)] // DateTime import fails on wasm for mysterious reasons
|
||||
#[cfg(not(PyPy))]
|
||||
fn test_get_tzinfo() {
|
||||
|
@ -276,3 +289,40 @@ fn test_get_tzinfo() {
|
|||
);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inc_dec_ref() {
|
||||
Python::with_gil(|py| {
|
||||
let obj = py.eval("object()", None, None).unwrap();
|
||||
|
||||
let ref_count = obj.get_refcnt();
|
||||
let ptr = obj.as_ptr();
|
||||
|
||||
unsafe { Py_INCREF(ptr) };
|
||||
|
||||
assert_eq!(obj.get_refcnt(), ref_count + 1);
|
||||
|
||||
unsafe { Py_DECREF(ptr) };
|
||||
|
||||
assert_eq!(obj.get_refcnt(), ref_count);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(Py_3_12)]
|
||||
fn test_inc_dec_ref_immortal() {
|
||||
Python::with_gil(|py| {
|
||||
let obj = py.None();
|
||||
|
||||
let ref_count = obj.get_refcnt(py);
|
||||
let ptr = obj.as_ptr();
|
||||
|
||||
unsafe { Py_INCREF(ptr) };
|
||||
|
||||
assert_eq!(obj.get_refcnt(py), ref_count);
|
||||
|
||||
unsafe { Py_DECREF(ptr) };
|
||||
|
||||
assert_eq!(obj.get_refcnt(py), ref_count);
|
||||
})
|
||||
}
|
||||
|
|
|
@ -591,14 +591,14 @@ mod tests {
|
|||
fn test_set_item_refcnt() {
|
||||
Python::with_gil(|py| {
|
||||
let cnt;
|
||||
let obj = py.eval("object()", None, None).unwrap();
|
||||
{
|
||||
let _pool = unsafe { crate::GILPool::new() };
|
||||
let none = py.None();
|
||||
cnt = none.get_refcnt(py);
|
||||
let _dict = [(10, none)].into_py_dict(py);
|
||||
cnt = obj.get_refcnt();
|
||||
let _dict = [(10, obj)].into_py_dict(py);
|
||||
}
|
||||
{
|
||||
assert_eq!(cnt, py.None().get_refcnt(py));
|
||||
assert_eq!(cnt, obj.get_refcnt());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -155,31 +155,30 @@ mod tests {
|
|||
#[test]
|
||||
fn iter_item_refcnt() {
|
||||
Python::with_gil(|py| {
|
||||
let obj;
|
||||
let none;
|
||||
let count;
|
||||
{
|
||||
let obj = py.eval("object()", None, None).unwrap();
|
||||
let list = {
|
||||
let _pool = unsafe { GILPool::new() };
|
||||
let l = PyList::empty(py);
|
||||
none = py.None();
|
||||
l.append(10).unwrap();
|
||||
l.append(&none).unwrap();
|
||||
count = none.get_refcnt(py);
|
||||
obj = l.to_object(py);
|
||||
}
|
||||
let list = PyList::empty(py);
|
||||
list.append(10).unwrap();
|
||||
list.append(obj).unwrap();
|
||||
count = obj.get_refcnt();
|
||||
list.to_object(py)
|
||||
};
|
||||
|
||||
{
|
||||
let _pool = unsafe { GILPool::new() };
|
||||
let inst = obj.as_ref(py);
|
||||
let inst = list.as_ref(py);
|
||||
let mut it = inst.iter().unwrap();
|
||||
|
||||
assert_eq!(
|
||||
10_i32,
|
||||
it.next().unwrap().unwrap().extract::<'_, i32>().unwrap()
|
||||
);
|
||||
assert!(it.next().unwrap().unwrap().is_none());
|
||||
assert!(it.next().unwrap().unwrap().is(obj));
|
||||
assert!(it.next().is_none());
|
||||
}
|
||||
assert_eq!(count, none.get_refcnt(py));
|
||||
assert_eq!(count, obj.get_refcnt());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -395,18 +395,18 @@ mod tests {
|
|||
#[test]
|
||||
fn test_set_item_refcnt() {
|
||||
Python::with_gil(|py| {
|
||||
let obj = py.eval("object()", None, None).unwrap();
|
||||
let cnt;
|
||||
{
|
||||
let _pool = unsafe { crate::GILPool::new() };
|
||||
let v = vec![2];
|
||||
let ob = v.to_object(py);
|
||||
let list: &PyList = ob.downcast(py).unwrap();
|
||||
let none = py.None();
|
||||
cnt = none.get_refcnt(py);
|
||||
list.set_item(0, none).unwrap();
|
||||
cnt = obj.get_refcnt();
|
||||
list.set_item(0, obj).unwrap();
|
||||
}
|
||||
|
||||
assert_eq!(cnt, py.None().get_refcnt(py));
|
||||
assert_eq!(cnt, obj.get_refcnt());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -431,15 +431,15 @@ mod tests {
|
|||
fn test_insert_refcnt() {
|
||||
Python::with_gil(|py| {
|
||||
let cnt;
|
||||
let obj = py.eval("object()", None, None).unwrap();
|
||||
{
|
||||
let _pool = unsafe { crate::GILPool::new() };
|
||||
let list = PyList::empty(py);
|
||||
let none = py.None();
|
||||
cnt = none.get_refcnt(py);
|
||||
list.insert(0, none).unwrap();
|
||||
cnt = obj.get_refcnt();
|
||||
list.insert(0, obj).unwrap();
|
||||
}
|
||||
|
||||
assert_eq!(cnt, py.None().get_refcnt(py));
|
||||
assert_eq!(cnt, obj.get_refcnt());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -457,14 +457,14 @@ mod tests {
|
|||
fn test_append_refcnt() {
|
||||
Python::with_gil(|py| {
|
||||
let cnt;
|
||||
let obj = py.eval("object()", None, None).unwrap();
|
||||
{
|
||||
let _pool = unsafe { crate::GILPool::new() };
|
||||
let list = PyList::empty(py);
|
||||
let none = py.None();
|
||||
cnt = none.get_refcnt(py);
|
||||
list.append(none).unwrap();
|
||||
cnt = obj.get_refcnt();
|
||||
list.append(obj).unwrap();
|
||||
}
|
||||
assert_eq!(cnt, py.None().get_refcnt(py));
|
||||
assert_eq!(cnt, obj.get_refcnt());
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue