pyo3_ffi/
object.rs

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