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