1use crate::pyport::{Py_hash_t, Py_ssize_t};
2use std::mem;
3use std::os::raw::{c_char, c_int, c_uint, c_ulong, c_void};
4use std::ptr;
5
6#[cfg(Py_LIMITED_API)]
7opaque_struct!(PyTypeObject);
8
9#[cfg(not(Py_LIMITED_API))]
10pub use crate::cpython::object::PyTypeObject;
11
12// _PyObject_HEAD_EXTRA: conditionally defined in PyObject_HEAD_INIT
13// _PyObject_EXTRA_INIT: conditionally defined in PyObject_HEAD_INIT
14
15#[cfg(Py_3_12)]
16pub const _Py_IMMORTAL_REFCNT: Py_ssize_t = {
17 if cfg!(target_pointer_width = "64") {
18 c_uint::MAX as Py_ssize_t
19 } else {
20 // for 32-bit systems, use the lower 30 bits (see comment in CPython's object.h)
21 (c_uint::MAX >> 2) as Py_ssize_t
22 }
23};
24
25pub const PyObject_HEAD_INIT: PyObject = PyObject {
26 #[cfg(py_sys_config = "Py_TRACE_REFS")]
27 _ob_next: std::ptr::null_mut(),
28 #[cfg(py_sys_config = "Py_TRACE_REFS")]
29 _ob_prev: std::ptr::null_mut(),
30 #[cfg(Py_3_12)]
31 ob_refcnt: PyObjectObRefcnt { ob_refcnt: 1 },
32 #[cfg(not(Py_3_12))]
33 ob_refcnt: 1,
34 #[cfg(PyPy)]
35 ob_pypy_link: 0,
36 ob_type: std::ptr::null_mut(),
37};
38
39// skipped PyObject_VAR_HEAD
40// skipped Py_INVALID_SIZE
41
42#[repr(C)]
43#[derive(Copy, Clone)]
44#[cfg(Py_3_12)]
45/// This union is anonymous in CPython, so the name was given by PyO3 because
46/// Rust unions need a name.
47pub union PyObjectObRefcnt {
48 pub ob_refcnt: Py_ssize_t,
49 #[cfg(target_pointer_width = "64")]
50 pub ob_refcnt_split: [crate::PY_UINT32_T; 2],
51}
52
53#[cfg(Py_3_12)]
54impl std::fmt::Debug for PyObjectObRefcnt {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 write!(f, "{}", unsafe { self.ob_refcnt })
57 }
58}
59
60#[cfg(not(Py_3_12))]
61pub type PyObjectObRefcnt = Py_ssize_t;
62
63#[repr(C)]
64#[derive(Copy, Clone, Debug)]
65pub struct PyObject {
66 #[cfg(py_sys_config = "Py_TRACE_REFS")]
67 pub _ob_next: *mut PyObject,
68 #[cfg(py_sys_config = "Py_TRACE_REFS")]
69 pub _ob_prev: *mut PyObject,
70 pub ob_refcnt: PyObjectObRefcnt,
71 #[cfg(PyPy)]
72 pub ob_pypy_link: Py_ssize_t,
73 pub ob_type: *mut PyTypeObject,
74}
75
76// skipped _PyObject_CAST
77
78#[repr(C)]
79#[derive(Debug, Copy, Clone)]
80pub struct PyVarObject {
81 pub ob_base: PyObject,
82 pub ob_size: Py_ssize_t,
83}
84
85// skipped _PyVarObject_CAST
86
87#[inline]
88pub unsafe fn Py_Is(x: *mut PyObject, y: *mut PyObject) -> c_int {
89 (x == y).into()
90}
91
92#[inline]
93#[cfg(Py_3_12)]
94pub unsafe fn Py_REFCNT(ob: *mut PyObject) -> Py_ssize_t {
95 (*ob).ob_refcnt.ob_refcnt
96}
97
98#[inline]
99#[cfg(not(Py_3_12))]
100pub unsafe fn Py_REFCNT(ob: *mut PyObject) -> Py_ssize_t {
101 (*ob).ob_refcnt
102}
103
104#[inline]
105pub unsafe fn Py_TYPE(ob: *mut PyObject) -> *mut PyTypeObject {
106 (*ob).ob_type
107}
108
109// PyLong_Type defined in longobject.rs
110// PyBool_Type defined in boolobject.rs
111
112#[inline]
113pub unsafe fn Py_SIZE(ob: *mut PyObject) -> Py_ssize_t {
114 debug_assert_ne!((*ob).ob_type, std::ptr::addr_of_mut!(crate::PyLong_Type));
115 debug_assert_ne!((*ob).ob_type, std::ptr::addr_of_mut!(crate::PyBool_Type));
116 (*ob.cast::<PyVarObject>()).ob_size
117}
118
119#[inline]
120pub unsafe fn Py_IS_TYPE(ob: *mut PyObject, tp: *mut PyTypeObject) -> c_int {
121 (Py_TYPE(ob) == tp) as c_int
122}
123
124#[inline(always)]
125#[cfg(all(Py_3_12, target_pointer_width = "64"))]
126pub unsafe fn _Py_IsImmortal(op: *mut PyObject) -> c_int {
127 (((*op).ob_refcnt.ob_refcnt as crate::PY_INT32_T) < 0) as c_int
128}
129
130#[inline(always)]
131#[cfg(all(Py_3_12, target_pointer_width = "32"))]
132pub unsafe fn _Py_IsImmortal(op: *mut PyObject) -> c_int {
133 ((*op).ob_refcnt.ob_refcnt == _Py_IMMORTAL_REFCNT) as c_int
134}
135
136// skipped _Py_SET_REFCNT
137// skipped Py_SET_REFCNT
138// skipped _Py_SET_TYPE
139// skipped Py_SET_TYPE
140// skipped _Py_SET_SIZE
141// skipped Py_SET_SIZE
142
143pub type unaryfunc = unsafe extern "C" fn(*mut PyObject) -> *mut PyObject;
144pub type binaryfunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject) -> *mut PyObject;
145pub type ternaryfunc =
146 unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> *mut PyObject;
147pub type inquiry = unsafe extern "C" fn(*mut PyObject) -> c_int;
148pub type lenfunc = unsafe extern "C" fn(*mut PyObject) -> Py_ssize_t;
149pub type ssizeargfunc = unsafe extern "C" fn(*mut PyObject, Py_ssize_t) -> *mut PyObject;
150pub type ssizessizeargfunc =
151 unsafe extern "C" fn(*mut PyObject, Py_ssize_t, Py_ssize_t) -> *mut PyObject;
152pub type ssizeobjargproc = unsafe extern "C" fn(*mut PyObject, Py_ssize_t, *mut PyObject) -> c_int;
153pub type ssizessizeobjargproc =
154 unsafe extern "C" fn(*mut PyObject, Py_ssize_t, Py_ssize_t, arg4: *mut PyObject) -> c_int;
155pub type objobjargproc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> c_int;
156
157pub type objobjproc = unsafe extern "C" fn(*mut PyObject, *mut PyObject) -> c_int;
158pub type visitproc = unsafe extern "C" fn(object: *mut PyObject, arg: *mut c_void) -> c_int;
159pub type traverseproc =
160 unsafe extern "C" fn(slf: *mut PyObject, visit: visitproc, arg: *mut c_void) -> c_int;
161
162pub type freefunc = unsafe extern "C" fn(*mut c_void);
163pub type destructor = unsafe extern "C" fn(*mut PyObject);
164pub type getattrfunc = unsafe extern "C" fn(*mut PyObject, *mut c_char) -> *mut PyObject;
165pub type getattrofunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject) -> *mut PyObject;
166pub type setattrfunc = unsafe extern "C" fn(*mut PyObject, *mut c_char, *mut PyObject) -> c_int;
167pub type setattrofunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> c_int;
168pub type reprfunc = unsafe extern "C" fn(*mut PyObject) -> *mut PyObject;
169pub type hashfunc = unsafe extern "C" fn(*mut PyObject) -> Py_hash_t;
170pub type richcmpfunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, c_int) -> *mut PyObject;
171pub type getiterfunc = unsafe extern "C" fn(*mut PyObject) -> *mut PyObject;
172pub type iternextfunc = unsafe extern "C" fn(*mut PyObject) -> *mut PyObject;
173pub type descrgetfunc =
174 unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> *mut PyObject;
175pub type descrsetfunc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> c_int;
176pub type initproc = unsafe extern "C" fn(*mut PyObject, *mut PyObject, *mut PyObject) -> c_int;
177pub type newfunc =
178 unsafe extern "C" fn(*mut PyTypeObject, *mut PyObject, *mut PyObject) -> *mut PyObject;
179pub type allocfunc = unsafe extern "C" fn(*mut PyTypeObject, Py_ssize_t) -> *mut PyObject;
180
181#[cfg(Py_3_8)]
182pub type vectorcallfunc = unsafe extern "C" fn(
183 callable: *mut PyObject,
184 args: *const *mut PyObject,
185 nargsf: libc::size_t,
186 kwnames: *mut PyObject,
187) -> *mut PyObject;
188
189#[repr(C)]
190#[derive(Copy, Clone)]
191pub struct PyType_Slot {
192 pub slot: c_int,
193 pub pfunc: *mut c_void,
194}
195
196impl Default for PyType_Slot {
197 fn default() -> PyType_Slot {
198 unsafe { mem::zeroed() }
199 }
200}
201
202#[repr(C)]
203#[derive(Copy, Clone)]
204pub struct PyType_Spec {
205 pub name: *const c_char,
206 pub basicsize: c_int,
207 pub itemsize: c_int,
208 pub flags: c_uint,
209 pub slots: *mut PyType_Slot,
210}
211
212impl Default for PyType_Spec {
213 fn default() -> PyType_Spec {
214 unsafe { mem::zeroed() }
215 }
216}
217
218extern "C" {
219 #[cfg_attr(PyPy, link_name = "PyPyType_FromSpec")]
220 pub fn PyType_FromSpec(arg1: *mut PyType_Spec) -> *mut PyObject;
221
222 #[cfg_attr(PyPy, link_name = "PyPyType_FromSpecWithBases")]
223 pub fn PyType_FromSpecWithBases(arg1: *mut PyType_Spec, arg2: *mut PyObject) -> *mut PyObject;
224
225 #[cfg_attr(PyPy, link_name = "PyPyType_GetSlot")]
226 pub fn PyType_GetSlot(arg1: *mut PyTypeObject, arg2: c_int) -> *mut c_void;
227
228 #[cfg(any(Py_3_10, all(Py_3_9, not(Py_LIMITED_API))))]
229 #[cfg_attr(PyPy, link_name = "PyPyType_FromModuleAndSpec")]
230 pub fn PyType_FromModuleAndSpec(
231 module: *mut PyObject,
232 spec: *mut PyType_Spec,
233 bases: *mut PyObject,
234 ) -> *mut PyObject;
235
236 #[cfg(any(Py_3_10, all(Py_3_9, not(Py_LIMITED_API))))]
237 #[cfg_attr(PyPy, link_name = "PyPyType_GetModule")]
238 pub fn PyType_GetModule(arg1: *mut PyTypeObject) -> *mut PyObject;
239
240 #[cfg(any(Py_3_10, all(Py_3_9, not(Py_LIMITED_API))))]
241 #[cfg_attr(PyPy, link_name = "PyPyType_GetModuleState")]
242 pub fn PyType_GetModuleState(arg1: *mut PyTypeObject) -> *mut c_void;
243
244 #[cfg(Py_3_11)]
245 #[cfg_attr(PyPy, link_name = "PyPyType_GetName")]
246 pub fn PyType_GetName(arg1: *mut PyTypeObject) -> *mut PyObject;
247
248 #[cfg(Py_3_11)]
249 #[cfg_attr(PyPy, link_name = "PyPyType_GetQualName")]
250 pub fn PyType_GetQualName(arg1: *mut PyTypeObject) -> *mut PyObject;
251
252 #[cfg(Py_3_12)]
253 #[cfg_attr(PyPy, link_name = "PyPyType_FromMetaclass")]
254 pub fn PyType_FromMetaclass(
255 metaclass: *mut PyTypeObject,
256 module: *mut PyObject,
257 spec: *mut PyType_Spec,
258 bases: *mut PyObject,
259 ) -> *mut PyObject;
260
261 #[cfg(Py_3_12)]
262 #[cfg_attr(PyPy, link_name = "PyPyObject_GetTypeData")]
263 pub fn PyObject_GetTypeData(obj: *mut PyObject, cls: *mut PyTypeObject) -> *mut c_void;
264
265 #[cfg(Py_3_12)]
266 #[cfg_attr(PyPy, link_name = "PyPyObject_GetTypeDataSize")]
267 pub fn PyObject_GetTypeDataSize(cls: *mut PyTypeObject) -> Py_ssize_t;
268
269 #[cfg_attr(PyPy, link_name = "PyPyType_IsSubtype")]
270 pub fn PyType_IsSubtype(a: *mut PyTypeObject, b: *mut PyTypeObject) -> c_int;
271}
272
273#[inline]
274pub unsafe fn PyObject_TypeCheck(ob: *mut PyObject, tp: *mut PyTypeObject) -> c_int {
275 (Py_TYPE(ob) == tp || PyType_IsSubtype(a:Py_TYPE(ob), b:tp) != 0) as c_int
276}
277
278#[cfg_attr(windows, link(name = "pythonXY"))]
279extern "C" {
280 /// built-in 'type'
281 #[cfg_attr(PyPy, link_name = "PyPyType_Type")]
282 pub static mut PyType_Type: PyTypeObject;
283 /// built-in 'object'
284 #[cfg_attr(PyPy, link_name = "PyPyBaseObject_Type")]
285 pub static mut PyBaseObject_Type: PyTypeObject;
286 /// built-in 'super'
287 pub static mut PySuper_Type: PyTypeObject;
288}
289
290extern "C" {
291 pub fn PyType_GetFlags(arg1: *mut PyTypeObject) -> c_ulong;
292
293 #[cfg_attr(PyPy, link_name = "PyPyType_Ready")]
294 pub fn PyType_Ready(t: *mut PyTypeObject) -> c_int;
295 #[cfg_attr(PyPy, link_name = "PyPyType_GenericAlloc")]
296 pub fn PyType_GenericAlloc(t: *mut PyTypeObject, nitems: Py_ssize_t) -> *mut PyObject;
297 #[cfg_attr(PyPy, link_name = "PyPyType_GenericNew")]
298 pub fn PyType_GenericNew(
299 t: *mut PyTypeObject,
300 args: *mut PyObject,
301 kwds: *mut PyObject,
302 ) -> *mut PyObject;
303 pub fn PyType_ClearCache() -> c_uint;
304 #[cfg_attr(PyPy, link_name = "PyPyType_Modified")]
305 pub fn PyType_Modified(t: *mut PyTypeObject);
306
307 #[cfg_attr(PyPy, link_name = "PyPyObject_Repr")]
308 pub fn PyObject_Repr(o: *mut PyObject) -> *mut PyObject;
309 #[cfg_attr(PyPy, link_name = "PyPyObject_Str")]
310 pub fn PyObject_Str(o: *mut PyObject) -> *mut PyObject;
311 #[cfg_attr(PyPy, link_name = "PyPyObject_ASCII")]
312 pub fn PyObject_ASCII(arg1: *mut PyObject) -> *mut PyObject;
313 #[cfg_attr(PyPy, link_name = "PyPyObject_Bytes")]
314 pub fn PyObject_Bytes(arg1: *mut PyObject) -> *mut PyObject;
315 #[cfg_attr(PyPy, link_name = "PyPyObject_RichCompare")]
316 pub fn PyObject_RichCompare(
317 arg1: *mut PyObject,
318 arg2: *mut PyObject,
319 arg3: c_int,
320 ) -> *mut PyObject;
321 #[cfg_attr(PyPy, link_name = "PyPyObject_RichCompareBool")]
322 pub fn PyObject_RichCompareBool(arg1: *mut PyObject, arg2: *mut PyObject, arg3: c_int)
323 -> c_int;
324 #[cfg_attr(PyPy, link_name = "PyPyObject_GetAttrString")]
325 pub fn PyObject_GetAttrString(arg1: *mut PyObject, arg2: *const c_char) -> *mut PyObject;
326 #[cfg_attr(PyPy, link_name = "PyPyObject_SetAttrString")]
327 pub fn PyObject_SetAttrString(
328 arg1: *mut PyObject,
329 arg2: *const c_char,
330 arg3: *mut PyObject,
331 ) -> c_int;
332 #[cfg_attr(PyPy, link_name = "PyPyObject_HasAttrString")]
333 pub fn PyObject_HasAttrString(arg1: *mut PyObject, arg2: *const c_char) -> c_int;
334 #[cfg_attr(PyPy, link_name = "PyPyObject_GetAttr")]
335 pub fn PyObject_GetAttr(arg1: *mut PyObject, arg2: *mut PyObject) -> *mut PyObject;
336 #[cfg_attr(PyPy, link_name = "PyPyObject_SetAttr")]
337 pub fn PyObject_SetAttr(arg1: *mut PyObject, arg2: *mut PyObject, arg3: *mut PyObject)
338 -> c_int;
339 #[cfg_attr(PyPy, link_name = "PyPyObject_HasAttr")]
340 pub fn PyObject_HasAttr(arg1: *mut PyObject, arg2: *mut PyObject) -> c_int;
341 #[cfg_attr(PyPy, link_name = "PyPyObject_SelfIter")]
342 pub fn PyObject_SelfIter(arg1: *mut PyObject) -> *mut PyObject;
343
344 #[cfg_attr(PyPy, link_name = "PyPyObject_GenericGetAttr")]
345 pub fn PyObject_GenericGetAttr(arg1: *mut PyObject, arg2: *mut PyObject) -> *mut PyObject;
346 #[cfg_attr(PyPy, link_name = "PyPyObject_GenericSetAttr")]
347 pub fn PyObject_GenericSetAttr(
348 arg1: *mut PyObject,
349 arg2: *mut PyObject,
350 arg3: *mut PyObject,
351 ) -> c_int;
352 #[cfg(not(all(Py_LIMITED_API, not(Py_3_10))))]
353 pub fn PyObject_GenericGetDict(arg1: *mut PyObject, arg2: *mut c_void) -> *mut PyObject;
354 pub fn PyObject_GenericSetDict(
355 arg1: *mut PyObject,
356 arg2: *mut PyObject,
357 arg3: *mut c_void,
358 ) -> c_int;
359 #[cfg_attr(PyPy, link_name = "PyPyObject_Hash")]
360 pub fn PyObject_Hash(arg1: *mut PyObject) -> Py_hash_t;
361 #[cfg_attr(PyPy, link_name = "PyPyObject_HashNotImplemented")]
362 pub fn PyObject_HashNotImplemented(arg1: *mut PyObject) -> Py_hash_t;
363 #[cfg_attr(PyPy, link_name = "PyPyObject_IsTrue")]
364 pub fn PyObject_IsTrue(arg1: *mut PyObject) -> c_int;
365 #[cfg_attr(PyPy, link_name = "PyPyObject_Not")]
366 pub fn PyObject_Not(arg1: *mut PyObject) -> c_int;
367 #[cfg_attr(PyPy, link_name = "PyPyCallable_Check")]
368 pub fn PyCallable_Check(arg1: *mut PyObject) -> c_int;
369 #[cfg_attr(PyPy, link_name = "PyPyObject_ClearWeakRefs")]
370 pub fn PyObject_ClearWeakRefs(arg1: *mut PyObject);
371
372 #[cfg_attr(PyPy, link_name = "PyPyObject_Dir")]
373 pub fn PyObject_Dir(arg1: *mut PyObject) -> *mut PyObject;
374 pub fn Py_ReprEnter(arg1: *mut PyObject) -> c_int;
375 pub fn Py_ReprLeave(arg1: *mut PyObject);
376}
377
378// Flag bits for printing:
379pub const Py_PRINT_RAW: c_int = 1; // No string quotes etc.
380
381#[cfg(all(Py_3_12, not(Py_LIMITED_API)))]
382pub const _Py_TPFLAGS_STATIC_BUILTIN: c_ulong = 1 << 1;
383
384#[cfg(all(Py_3_12, not(Py_LIMITED_API)))]
385pub const Py_TPFLAGS_MANAGED_WEAKREF: c_ulong = 1 << 3;
386
387#[cfg(all(Py_3_11, not(Py_LIMITED_API)))]
388pub const Py_TPFLAGS_MANAGED_DICT: c_ulong = 1 << 4;
389
390#[cfg(all(Py_3_10, not(Py_LIMITED_API)))]
391pub const Py_TPFLAGS_SEQUENCE: c_ulong = 1 << 5;
392
393#[cfg(all(Py_3_10, not(Py_LIMITED_API)))]
394pub const Py_TPFLAGS_MAPPING: c_ulong = 1 << 6;
395
396#[cfg(Py_3_10)]
397pub const Py_TPFLAGS_DISALLOW_INSTANTIATION: c_ulong = 1 << 7;
398
399#[cfg(Py_3_10)]
400pub const Py_TPFLAGS_IMMUTABLETYPE: c_ulong = 1 << 8;
401
402/// Set if the type object is dynamically allocated
403pub const Py_TPFLAGS_HEAPTYPE: c_ulong = 1 << 9;
404
405/// Set if the type allows subclassing
406pub const Py_TPFLAGS_BASETYPE: c_ulong = 1 << 10;
407
408/// Set if the type implements the vectorcall protocol (PEP 590)
409#[cfg(any(Py_3_12, all(Py_3_8, not(Py_LIMITED_API))))]
410pub const Py_TPFLAGS_HAVE_VECTORCALL: c_ulong = 1 << 11;
411// skipped non-limited _Py_TPFLAGS_HAVE_VECTORCALL
412
413/// Set if the type is 'ready' -- fully initialized
414pub const Py_TPFLAGS_READY: c_ulong = 1 << 12;
415
416/// Set while the type is being 'readied', to prevent recursive ready calls
417pub const Py_TPFLAGS_READYING: c_ulong = 1 << 13;
418
419/// Objects support garbage collection (see objimp.h)
420pub const Py_TPFLAGS_HAVE_GC: c_ulong = 1 << 14;
421
422const Py_TPFLAGS_HAVE_STACKLESS_EXTENSION: c_ulong = 0;
423
424#[cfg(Py_3_8)]
425pub const Py_TPFLAGS_METHOD_DESCRIPTOR: c_ulong = 1 << 17;
426
427pub const Py_TPFLAGS_VALID_VERSION_TAG: c_ulong = 1 << 19;
428
429/* Type is abstract and cannot be instantiated */
430pub const Py_TPFLAGS_IS_ABSTRACT: c_ulong = 1 << 20;
431
432// skipped non-limited / 3.10 Py_TPFLAGS_HAVE_AM_SEND
433#[cfg(Py_3_12)]
434pub const Py_TPFLAGS_ITEMS_AT_END: c_ulong = 1 << 23;
435
436/* These flags are used to determine if a type is a subclass. */
437pub const Py_TPFLAGS_LONG_SUBCLASS: c_ulong = 1 << 24;
438pub const Py_TPFLAGS_LIST_SUBCLASS: c_ulong = 1 << 25;
439pub const Py_TPFLAGS_TUPLE_SUBCLASS: c_ulong = 1 << 26;
440pub const Py_TPFLAGS_BYTES_SUBCLASS: c_ulong = 1 << 27;
441pub const Py_TPFLAGS_UNICODE_SUBCLASS: c_ulong = 1 << 28;
442pub const Py_TPFLAGS_DICT_SUBCLASS: c_ulong = 1 << 29;
443pub const Py_TPFLAGS_BASE_EXC_SUBCLASS: c_ulong = 1 << 30;
444pub const Py_TPFLAGS_TYPE_SUBCLASS: c_ulong = 1 << 31;
445
446pub const Py_TPFLAGS_DEFAULT: c_ulong = if cfg!(Py_3_10) {
447 Py_TPFLAGS_HAVE_STACKLESS_EXTENSION
448} else {
449 Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | Py_TPFLAGS_HAVE_VERSION_TAG
450};
451
452pub const Py_TPFLAGS_HAVE_FINALIZE: c_ulong = 1;
453pub const Py_TPFLAGS_HAVE_VERSION_TAG: c_ulong = 1 << 18;
454
455extern "C" {
456 #[cfg(all(py_sys_config = "Py_REF_DEBUG", not(Py_LIMITED_API)))]
457 pub fn _Py_NegativeRefcount(filename: *const c_char, lineno: c_int, op: *mut PyObject);
458 #[cfg(all(Py_3_12, py_sys_config = "Py_REF_DEBUG", not(Py_LIMITED_API)))]
459 fn _Py_INCREF_IncRefTotal();
460 #[cfg(all(Py_3_12, py_sys_config = "Py_REF_DEBUG", not(Py_LIMITED_API)))]
461 fn _Py_DECREF_DecRefTotal();
462
463 #[cfg_attr(PyPy, link_name = "_PyPy_Dealloc")]
464 pub fn _Py_Dealloc(arg1: *mut PyObject);
465
466 #[cfg_attr(PyPy, link_name = "PyPy_IncRef")]
467 pub fn Py_IncRef(o: *mut PyObject);
468 #[cfg_attr(PyPy, link_name = "PyPy_DecRef")]
469 pub fn Py_DecRef(o: *mut PyObject);
470
471 #[cfg(Py_3_10)]
472 #[cfg_attr(PyPy, link_name = "_PyPy_IncRef")]
473 pub fn _Py_IncRef(o: *mut PyObject);
474 #[cfg(Py_3_10)]
475 #[cfg_attr(PyPy, link_name = "_PyPy_DecRef")]
476 pub fn _Py_DecRef(o: *mut PyObject);
477}
478
479#[inline(always)]
480pub unsafe fn Py_INCREF(op: *mut PyObject) {
481 #[cfg(any(
482 all(Py_LIMITED_API, Py_3_12),
483 all(
484 py_sys_config = "Py_REF_DEBUG",
485 Py_3_10,
486 not(all(Py_3_12, not(Py_LIMITED_API)))
487 )
488 ))]
489 {
490 _Py_IncRef(op);
491 }
492
493 #[cfg(all(py_sys_config = "Py_REF_DEBUG", not(Py_3_10)))]
494 {
495 return Py_IncRef(op);
496 }
497
498 #[cfg(any(
499 all(Py_LIMITED_API, not(Py_3_12)),
500 all(
501 not(Py_LIMITED_API),
502 any(
503 not(py_sys_config = "Py_REF_DEBUG"),
504 all(py_sys_config = "Py_REF_DEBUG", Py_3_12),
505 )
506 ),
507 ))]
508 {
509 #[cfg(all(Py_3_12, target_pointer_width = "64"))]
510 {
511 let cur_refcnt = (*op).ob_refcnt.ob_refcnt_split[crate::PY_BIG_ENDIAN];
512 let new_refcnt = cur_refcnt.wrapping_add(1);
513 if new_refcnt == 0 {
514 return;
515 }
516 (*op).ob_refcnt.ob_refcnt_split[crate::PY_BIG_ENDIAN] = new_refcnt;
517 }
518
519 #[cfg(all(Py_3_12, target_pointer_width = "32"))]
520 {
521 if _Py_IsImmortal(op) != 0 {
522 return;
523 }
524 (*op).ob_refcnt.ob_refcnt += 1
525 }
526
527 #[cfg(not(Py_3_12))]
528 {
529 (*op).ob_refcnt += 1
530 }
531
532 // Skipped _Py_INCREF_STAT_INC - if anyone wants this, please file an issue
533 // or submit a PR supporting Py_STATS build option and pystats.h
534
535 #[cfg(all(py_sys_config = "Py_REF_DEBUG", Py_3_12))]
536 _Py_INCREF_IncRefTotal();
537 }
538}
539
540#[inline(always)]
541#[cfg_attr(
542 all(py_sys_config = "Py_REF_DEBUG", Py_3_12, not(Py_LIMITED_API)),
543 track_caller
544)]
545pub unsafe fn Py_DECREF(op: *mut PyObject) {
546 #[cfg(any(
547 all(Py_LIMITED_API, Py_3_12),
548 all(
549 py_sys_config = "Py_REF_DEBUG",
550 Py_3_10,
551 not(all(Py_3_12, not(Py_LIMITED_API)))
552 )
553 ))]
554 {
555 _Py_DecRef(op);
556 }
557
558 #[cfg(all(py_sys_config = "Py_REF_DEBUG", not(Py_3_10)))]
559 {
560 return Py_DecRef(op);
561 }
562
563 #[cfg(any(
564 all(Py_LIMITED_API, not(Py_3_12)),
565 all(
566 not(Py_LIMITED_API),
567 any(
568 not(py_sys_config = "Py_REF_DEBUG"),
569 all(py_sys_config = "Py_REF_DEBUG", Py_3_12),
570 )
571 ),
572 ))]
573 {
574 #[cfg(Py_3_12)]
575 if _Py_IsImmortal(op) != 0 {
576 return;
577 }
578
579 // Skipped _Py_DECREF_STAT_INC - if anyone needs this, please file an issue
580 // or submit a PR supporting Py_STATS build option and pystats.h
581
582 #[cfg(all(py_sys_config = "Py_REF_DEBUG", Py_3_12))]
583 _Py_DECREF_DecRefTotal();
584
585 #[cfg(Py_3_12)]
586 {
587 (*op).ob_refcnt.ob_refcnt -= 1;
588
589 #[cfg(py_sys_config = "Py_REF_DEBUG")]
590 if (*op).ob_refcnt.ob_refcnt < 0 {
591 let location = std::panic::Location::caller();
592 let filename = std::ffi::CString::new(location.file()).unwrap();
593 _Py_NegativeRefcount(filename.as_ptr(), location.line() as i32, op);
594 }
595
596 if (*op).ob_refcnt.ob_refcnt == 0 {
597 _Py_Dealloc(op);
598 }
599 }
600
601 #[cfg(not(Py_3_12))]
602 {
603 (*op).ob_refcnt -= 1;
604
605 if (*op).ob_refcnt == 0 {
606 _Py_Dealloc(op);
607 }
608 }
609 }
610}
611
612#[inline]
613pub unsafe fn Py_CLEAR(op: *mut *mut PyObject) {
614 let tmp: *mut PyObject = *op;
615 if !tmp.is_null() {
616 *op = ptr::null_mut();
617 Py_DECREF(op:tmp);
618 }
619}
620
621#[inline]
622pub unsafe fn Py_XINCREF(op: *mut PyObject) {
623 if !op.is_null() {
624 Py_INCREF(op)
625 }
626}
627
628#[inline]
629pub unsafe fn Py_XDECREF(op: *mut PyObject) {
630 if !op.is_null() {
631 Py_DECREF(op)
632 }
633}
634
635extern "C" {
636 #[cfg(all(Py_3_10, Py_LIMITED_API))]
637 pub fn Py_NewRef(obj: *mut PyObject) -> *mut PyObject;
638 #[cfg(all(Py_3_10, Py_LIMITED_API))]
639 pub fn Py_XNewRef(obj: *mut PyObject) -> *mut PyObject;
640}
641
642// Technically these macros are only available in the C header from 3.10 and up, however their
643// implementation works on all supported Python versions so we define these macros on all
644// versions for simplicity.
645
646#[inline]
647pub unsafe fn _Py_NewRef(obj: *mut PyObject) -> *mut PyObject {
648 Py_INCREF(op:obj);
649 obj
650}
651
652#[inline]
653pub unsafe fn _Py_XNewRef(obj: *mut PyObject) -> *mut PyObject {
654 Py_XINCREF(op:obj);
655 obj
656}
657
658#[cfg(all(Py_3_10, not(Py_LIMITED_API)))]
659#[inline]
660pub unsafe fn Py_NewRef(obj: *mut PyObject) -> *mut PyObject {
661 _Py_NewRef(obj)
662}
663
664#[cfg(all(Py_3_10, not(Py_LIMITED_API)))]
665#[inline]
666pub unsafe fn Py_XNewRef(obj: *mut PyObject) -> *mut PyObject {
667 _Py_XNewRef(obj)
668}
669
670#[cfg_attr(windows, link(name = "pythonXY"))]
671extern "C" {
672 #[cfg_attr(PyPy, link_name = "_PyPy_NoneStruct")]
673 static mut _Py_NoneStruct: PyObject;
674}
675
676#[inline]
677pub unsafe fn Py_None() -> *mut PyObject {
678 ptr::addr_of_mut!(_Py_NoneStruct)
679}
680
681#[inline]
682pub unsafe fn Py_IsNone(x: *mut PyObject) -> c_int {
683 Py_Is(x, y:Py_None())
684}
685
686// skipped Py_RETURN_NONE
687
688#[cfg_attr(windows, link(name = "pythonXY"))]
689extern "C" {
690 #[cfg_attr(PyPy, link_name = "_PyPy_NotImplementedStruct")]
691 static mut _Py_NotImplementedStruct: PyObject;
692}
693
694#[inline]
695pub unsafe fn Py_NotImplemented() -> *mut PyObject {
696 ptr::addr_of_mut!(_Py_NotImplementedStruct)
697}
698
699// skipped Py_RETURN_NOTIMPLEMENTED
700
701/* Rich comparison opcodes */
702pub const Py_LT: c_int = 0;
703pub const Py_LE: c_int = 1;
704pub const Py_EQ: c_int = 2;
705pub const Py_NE: c_int = 3;
706pub const Py_GT: c_int = 4;
707pub const Py_GE: c_int = 5;
708
709#[cfg(Py_3_10)]
710#[repr(C)]
711#[derive(Copy, Clone, Debug, PartialEq, Eq)]
712pub enum PySendResult {
713 PYGEN_RETURN = 0,
714 PYGEN_ERROR = -1,
715 PYGEN_NEXT = 1,
716}
717
718// skipped Py_RETURN_RICHCOMPARE
719
720#[inline]
721#[cfg(Py_LIMITED_API)]
722pub unsafe fn PyType_HasFeature(t: *mut PyTypeObject, f: c_ulong) -> c_int {
723 ((PyType_GetFlags(t) & f) != 0) as c_int
724}
725
726#[inline]
727#[cfg(not(Py_LIMITED_API))]
728pub unsafe fn PyType_HasFeature(t: *mut PyTypeObject, f: c_ulong) -> c_int {
729 (((*t).tp_flags & f) != 0) as c_int
730}
731
732#[inline]
733pub unsafe fn PyType_FastSubclass(t: *mut PyTypeObject, f: c_ulong) -> c_int {
734 PyType_HasFeature(t, f)
735}
736
737#[inline]
738pub unsafe fn PyType_Check(op: *mut PyObject) -> c_int {
739 PyType_FastSubclass(t:Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS)
740}
741
742#[inline]
743pub unsafe fn PyType_CheckExact(op: *mut PyObject) -> c_int {
744 Py_IS_TYPE(ob:op, tp:ptr::addr_of_mut!(PyType_Type))
745}
746