pyo3_ffi/cpython/
object.rs

1#[cfg(Py_3_8)]
2use crate::vectorcallfunc;
3#[cfg(Py_3_11)]
4use crate::PyModuleDef;
5use crate::{object, PyGetSetDef, PyMemberDef, PyMethodDef, PyObject, Py_ssize_t};
6use std::mem;
7use std::os::raw::{c_char, c_int, c_uint, c_ulong, c_void};
8
9// skipped _Py_NewReference
10// skipped _Py_ForgetReference
11// skipped _Py_GetRefTotal
12
13// skipped _Py_Identifier
14
15// skipped _Py_static_string_init
16// skipped _Py_static_string
17// skipped _Py_IDENTIFIER
18
19#[cfg(not(Py_3_11))] // moved to src/buffer.rs from Python
20mod bufferinfo {
21    use crate::Py_ssize_t;
22    use std::os::raw::{c_char, c_int, c_void};
23    use std::ptr;
24
25    #[repr(C)]
26    #[derive(Copy, Clone)]
27    pub struct Py_buffer {
28        pub buf: *mut c_void,
29        /// Owned reference
30        pub obj: *mut crate::PyObject,
31        pub len: Py_ssize_t,
32        pub itemsize: Py_ssize_t,
33        pub readonly: c_int,
34        pub ndim: c_int,
35        pub format: *mut c_char,
36        pub shape: *mut Py_ssize_t,
37        pub strides: *mut Py_ssize_t,
38        pub suboffsets: *mut Py_ssize_t,
39        pub internal: *mut c_void,
40        #[cfg(PyPy)]
41        pub flags: c_int,
42        #[cfg(PyPy)]
43        pub _strides: [Py_ssize_t; PyBUF_MAX_NDIM as usize],
44        #[cfg(PyPy)]
45        pub _shape: [Py_ssize_t; PyBUF_MAX_NDIM as usize],
46    }
47
48    impl Py_buffer {
49        #[allow(clippy::new_without_default)]
50        pub const fn new() -> Self {
51            Py_buffer {
52                buf: ptr::null_mut(),
53                obj: ptr::null_mut(),
54                len: 0,
55                itemsize: 0,
56                readonly: 0,
57                ndim: 0,
58                format: ptr::null_mut(),
59                shape: ptr::null_mut(),
60                strides: ptr::null_mut(),
61                suboffsets: ptr::null_mut(),
62                internal: ptr::null_mut(),
63                #[cfg(PyPy)]
64                flags: 0,
65                #[cfg(PyPy)]
66                _strides: [0; PyBUF_MAX_NDIM as usize],
67                #[cfg(PyPy)]
68                _shape: [0; PyBUF_MAX_NDIM as usize],
69            }
70        }
71    }
72
73    pub type getbufferproc = unsafe extern "C" fn(
74        arg1: *mut crate::PyObject,
75        arg2: *mut Py_buffer,
76        arg3: c_int,
77    ) -> c_int;
78    pub type releasebufferproc =
79        unsafe extern "C" fn(arg1: *mut crate::PyObject, arg2: *mut Py_buffer);
80
81    /// Maximum number of dimensions
82    pub const PyBUF_MAX_NDIM: c_int = if cfg!(PyPy) { 36 } else { 64 };
83
84    /* Flags for getting buffers */
85    pub const PyBUF_SIMPLE: c_int = 0;
86    pub const PyBUF_WRITABLE: c_int = 0x0001;
87    /* we used to include an E, backwards compatible alias */
88    pub const PyBUF_WRITEABLE: c_int = PyBUF_WRITABLE;
89    pub const PyBUF_FORMAT: c_int = 0x0004;
90    pub const PyBUF_ND: c_int = 0x0008;
91    pub const PyBUF_STRIDES: c_int = 0x0010 | PyBUF_ND;
92    pub const PyBUF_C_CONTIGUOUS: c_int = 0x0020 | PyBUF_STRIDES;
93    pub const PyBUF_F_CONTIGUOUS: c_int = 0x0040 | PyBUF_STRIDES;
94    pub const PyBUF_ANY_CONTIGUOUS: c_int = 0x0080 | PyBUF_STRIDES;
95    pub const PyBUF_INDIRECT: c_int = 0x0100 | PyBUF_STRIDES;
96
97    pub const PyBUF_CONTIG: c_int = PyBUF_ND | PyBUF_WRITABLE;
98    pub const PyBUF_CONTIG_RO: c_int = PyBUF_ND;
99
100    pub const PyBUF_STRIDED: c_int = PyBUF_STRIDES | PyBUF_WRITABLE;
101    pub const PyBUF_STRIDED_RO: c_int = PyBUF_STRIDES;
102
103    pub const PyBUF_RECORDS: c_int = PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT;
104    pub const PyBUF_RECORDS_RO: c_int = PyBUF_STRIDES | PyBUF_FORMAT;
105
106    pub const PyBUF_FULL: c_int = PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT;
107    pub const PyBUF_FULL_RO: c_int = PyBUF_INDIRECT | PyBUF_FORMAT;
108
109    pub const PyBUF_READ: c_int = 0x100;
110    pub const PyBUF_WRITE: c_int = 0x200;
111}
112
113#[cfg(not(Py_3_11))]
114pub use self::bufferinfo::*;
115
116#[repr(C)]
117#[derive(Copy, Clone)]
118pub struct PyNumberMethods {
119    pub nb_add: Option<object::binaryfunc>,
120    pub nb_subtract: Option<object::binaryfunc>,
121    pub nb_multiply: Option<object::binaryfunc>,
122    pub nb_remainder: Option<object::binaryfunc>,
123    pub nb_divmod: Option<object::binaryfunc>,
124    pub nb_power: Option<object::ternaryfunc>,
125    pub nb_negative: Option<object::unaryfunc>,
126    pub nb_positive: Option<object::unaryfunc>,
127    pub nb_absolute: Option<object::unaryfunc>,
128    pub nb_bool: Option<object::inquiry>,
129    pub nb_invert: Option<object::unaryfunc>,
130    pub nb_lshift: Option<object::binaryfunc>,
131    pub nb_rshift: Option<object::binaryfunc>,
132    pub nb_and: Option<object::binaryfunc>,
133    pub nb_xor: Option<object::binaryfunc>,
134    pub nb_or: Option<object::binaryfunc>,
135    pub nb_int: Option<object::unaryfunc>,
136    pub nb_reserved: *mut c_void,
137    pub nb_float: Option<object::unaryfunc>,
138    pub nb_inplace_add: Option<object::binaryfunc>,
139    pub nb_inplace_subtract: Option<object::binaryfunc>,
140    pub nb_inplace_multiply: Option<object::binaryfunc>,
141    pub nb_inplace_remainder: Option<object::binaryfunc>,
142    pub nb_inplace_power: Option<object::ternaryfunc>,
143    pub nb_inplace_lshift: Option<object::binaryfunc>,
144    pub nb_inplace_rshift: Option<object::binaryfunc>,
145    pub nb_inplace_and: Option<object::binaryfunc>,
146    pub nb_inplace_xor: Option<object::binaryfunc>,
147    pub nb_inplace_or: Option<object::binaryfunc>,
148    pub nb_floor_divide: Option<object::binaryfunc>,
149    pub nb_true_divide: Option<object::binaryfunc>,
150    pub nb_inplace_floor_divide: Option<object::binaryfunc>,
151    pub nb_inplace_true_divide: Option<object::binaryfunc>,
152    pub nb_index: Option<object::unaryfunc>,
153    pub nb_matrix_multiply: Option<object::binaryfunc>,
154    pub nb_inplace_matrix_multiply: Option<object::binaryfunc>,
155}
156
157#[repr(C)]
158#[derive(Clone)]
159pub struct PySequenceMethods {
160    pub sq_length: Option<object::lenfunc>,
161    pub sq_concat: Option<object::binaryfunc>,
162    pub sq_repeat: Option<object::ssizeargfunc>,
163    pub sq_item: Option<object::ssizeargfunc>,
164    pub was_sq_slice: *mut c_void,
165    pub sq_ass_item: Option<object::ssizeobjargproc>,
166    pub was_sq_ass_slice: *mut c_void,
167    pub sq_contains: Option<object::objobjproc>,
168    pub sq_inplace_concat: Option<object::binaryfunc>,
169    pub sq_inplace_repeat: Option<object::ssizeargfunc>,
170}
171
172#[repr(C)]
173#[derive(Clone, Default)]
174pub struct PyMappingMethods {
175    pub mp_length: Option<object::lenfunc>,
176    pub mp_subscript: Option<object::binaryfunc>,
177    pub mp_ass_subscript: Option<object::objobjargproc>,
178}
179
180#[cfg(Py_3_10)]
181pub type sendfunc = unsafe extern "C" fn(
182    iter: *mut PyObject,
183    value: *mut PyObject,
184    result: *mut *mut PyObject,
185) -> object::PySendResult;
186
187#[repr(C)]
188#[derive(Clone, Default)]
189pub struct PyAsyncMethods {
190    pub am_await: Option<object::unaryfunc>,
191    pub am_aiter: Option<object::unaryfunc>,
192    pub am_anext: Option<object::unaryfunc>,
193    #[cfg(Py_3_10)]
194    pub am_send: Option<sendfunc>,
195}
196
197#[repr(C)]
198#[derive(Clone, Default)]
199pub struct PyBufferProcs {
200    pub bf_getbuffer: Option<crate::getbufferproc>,
201    pub bf_releasebuffer: Option<crate::releasebufferproc>,
202}
203
204pub type printfunc =
205    unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut ::libc::FILE, arg3: c_int) -> c_int;
206
207#[repr(C)]
208#[derive(Debug, Copy, Clone)]
209pub struct PyTypeObject {
210    #[cfg(all(PyPy, not(Py_3_9)))]
211    pub ob_refcnt: Py_ssize_t,
212    #[cfg(all(PyPy, not(Py_3_9)))]
213    pub ob_pypy_link: Py_ssize_t,
214    #[cfg(all(PyPy, not(Py_3_9)))]
215    pub ob_type: *mut PyTypeObject,
216    #[cfg(all(PyPy, not(Py_3_9)))]
217    pub ob_size: Py_ssize_t,
218    #[cfg(not(all(PyPy, not(Py_3_9))))]
219    pub ob_base: object::PyVarObject,
220    #[cfg(GraalPy)]
221    pub ob_size: Py_ssize_t,
222    pub tp_name: *const c_char,
223    pub tp_basicsize: Py_ssize_t,
224    pub tp_itemsize: Py_ssize_t,
225    pub tp_dealloc: Option<object::destructor>,
226    #[cfg(not(Py_3_8))]
227    pub tp_print: Option<printfunc>,
228    #[cfg(Py_3_8)]
229    pub tp_vectorcall_offset: Py_ssize_t,
230    pub tp_getattr: Option<object::getattrfunc>,
231    pub tp_setattr: Option<object::setattrfunc>,
232    pub tp_as_async: *mut PyAsyncMethods,
233    pub tp_repr: Option<object::reprfunc>,
234    pub tp_as_number: *mut PyNumberMethods,
235    pub tp_as_sequence: *mut PySequenceMethods,
236    pub tp_as_mapping: *mut PyMappingMethods,
237    pub tp_hash: Option<object::hashfunc>,
238    pub tp_call: Option<object::ternaryfunc>,
239    pub tp_str: Option<object::reprfunc>,
240    pub tp_getattro: Option<object::getattrofunc>,
241    pub tp_setattro: Option<object::setattrofunc>,
242    pub tp_as_buffer: *mut PyBufferProcs,
243    pub tp_flags: c_ulong,
244    pub tp_doc: *const c_char,
245    pub tp_traverse: Option<object::traverseproc>,
246    pub tp_clear: Option<object::inquiry>,
247    pub tp_richcompare: Option<object::richcmpfunc>,
248    pub tp_weaklistoffset: Py_ssize_t,
249    pub tp_iter: Option<object::getiterfunc>,
250    pub tp_iternext: Option<object::iternextfunc>,
251    pub tp_methods: *mut PyMethodDef,
252    pub tp_members: *mut PyMemberDef,
253    pub tp_getset: *mut PyGetSetDef,
254    pub tp_base: *mut PyTypeObject,
255    pub tp_dict: *mut object::PyObject,
256    pub tp_descr_get: Option<object::descrgetfunc>,
257    pub tp_descr_set: Option<object::descrsetfunc>,
258    pub tp_dictoffset: Py_ssize_t,
259    pub tp_init: Option<object::initproc>,
260    pub tp_alloc: Option<object::allocfunc>,
261    pub tp_new: Option<object::newfunc>,
262    pub tp_free: Option<object::freefunc>,
263    pub tp_is_gc: Option<object::inquiry>,
264    pub tp_bases: *mut object::PyObject,
265    pub tp_mro: *mut object::PyObject,
266    pub tp_cache: *mut object::PyObject,
267    pub tp_subclasses: *mut object::PyObject,
268    pub tp_weaklist: *mut object::PyObject,
269    pub tp_del: Option<object::destructor>,
270    pub tp_version_tag: c_uint,
271    pub tp_finalize: Option<object::destructor>,
272    #[cfg(Py_3_8)]
273    pub tp_vectorcall: Option<vectorcallfunc>,
274    #[cfg(Py_3_12)]
275    pub tp_watched: c_char,
276    #[cfg(any(all(PyPy, Py_3_8, not(Py_3_10)), all(not(PyPy), Py_3_8, not(Py_3_9))))]
277    pub tp_print: Option<printfunc>,
278    #[cfg(all(PyPy, not(Py_3_10)))]
279    pub tp_pypy_flags: std::os::raw::c_long,
280    #[cfg(py_sys_config = "COUNT_ALLOCS")]
281    pub tp_allocs: Py_ssize_t,
282    #[cfg(py_sys_config = "COUNT_ALLOCS")]
283    pub tp_frees: Py_ssize_t,
284    #[cfg(py_sys_config = "COUNT_ALLOCS")]
285    pub tp_maxalloc: Py_ssize_t,
286    #[cfg(py_sys_config = "COUNT_ALLOCS")]
287    pub tp_prev: *mut PyTypeObject,
288    #[cfg(py_sys_config = "COUNT_ALLOCS")]
289    pub tp_next: *mut PyTypeObject,
290}
291
292#[cfg(Py_3_11)]
293#[repr(C)]
294#[derive(Clone)]
295pub struct _specialization_cache {
296    pub getitem: *mut PyObject,
297    #[cfg(Py_3_12)]
298    pub getitem_version: u32,
299    #[cfg(Py_3_13)]
300    pub init: *mut PyObject,
301}
302
303#[repr(C)]
304#[derive(Clone)]
305pub struct PyHeapTypeObject {
306    pub ht_type: PyTypeObject,
307    pub as_async: PyAsyncMethods,
308    pub as_number: PyNumberMethods,
309    pub as_mapping: PyMappingMethods,
310    pub as_sequence: PySequenceMethods,
311    pub as_buffer: PyBufferProcs,
312    pub ht_name: *mut object::PyObject,
313    pub ht_slots: *mut object::PyObject,
314    pub ht_qualname: *mut object::PyObject,
315    #[cfg(not(PyPy))]
316    pub ht_cached_keys: *mut c_void,
317    #[cfg(Py_3_9)]
318    pub ht_module: *mut object::PyObject,
319    #[cfg(Py_3_11)]
320    pub _ht_tpname: *mut c_char,
321    #[cfg(Py_3_11)]
322    pub _spec_cache: _specialization_cache,
323}
324
325impl Default for PyHeapTypeObject {
326    #[inline]
327    fn default() -> Self {
328        unsafe { mem::zeroed() }
329    }
330}
331
332#[inline]
333pub unsafe fn PyHeapType_GET_MEMBERS(etype: *mut PyHeapTypeObject) -> *mut PyMemberDef {
334    let py_type = object::Py_TYPE(etype as *mut object::PyObject);
335    let ptr = etype.offset((*py_type).tp_basicsize);
336    ptr as *mut PyMemberDef
337}
338
339// skipped _PyType_Name
340// skipped _PyType_Lookup
341// skipped _PyType_LookupId
342// skipped _PyObject_LookupSpecial
343// skipped _PyType_CalculateMetaclass
344// skipped _PyType_GetDocFromInternalDoc
345// skipped _PyType_GetTextSignatureFromInternalDoc
346
347extern "C" {
348    #[cfg(Py_3_11)]
349    #[cfg_attr(PyPy, link_name = "PyPyType_GetModuleByDef")]
350    pub fn PyType_GetModuleByDef(ty: *mut PyTypeObject, def: *mut PyModuleDef) -> *mut PyObject;
351
352    #[cfg(Py_3_12)]
353    pub fn PyType_GetDict(o: *mut PyTypeObject) -> *mut PyObject;
354
355    #[cfg_attr(PyPy, link_name = "PyPyObject_Print")]
356    pub fn PyObject_Print(o: *mut PyObject, fp: *mut ::libc::FILE, flags: c_int) -> c_int;
357
358    // skipped _Py_BreakPoint
359    // skipped _PyObject_Dump
360    // skipped _PyObject_IsFreed
361    // skipped _PyObject_IsAbstract
362    // skipped _PyObject_GetAttrId
363    // skipped _PyObject_SetAttrId
364    // skipped _PyObject_LookupAttr
365    // skipped _PyObject_LookupAttrId
366    // skipped _PyObject_GetMethod
367
368    #[cfg(not(PyPy))]
369    pub fn _PyObject_GetDictPtr(obj: *mut PyObject) -> *mut *mut PyObject;
370    #[cfg(not(PyPy))]
371    pub fn _PyObject_NextNotImplemented(arg1: *mut PyObject) -> *mut PyObject;
372    pub fn PyObject_CallFinalizer(arg1: *mut PyObject);
373    #[cfg_attr(PyPy, link_name = "PyPyObject_CallFinalizerFromDealloc")]
374    pub fn PyObject_CallFinalizerFromDealloc(arg1: *mut PyObject) -> c_int;
375
376    // skipped _PyObject_GenericGetAttrWithDict
377    // skipped _PyObject_GenericSetAttrWithDict
378    // skipped _PyObject_FunctionStr
379}
380
381// skipped Py_SETREF
382// skipped Py_XSETREF
383
384#[cfg_attr(windows, link(name = "pythonXY"))]
385extern "C" {
386    pub static mut _PyNone_Type: PyTypeObject;
387    pub static mut _PyNotImplemented_Type: PyTypeObject;
388}
389
390// skipped _Py_SwappedOp
391
392// skipped _PyDebugAllocatorStats
393// skipped _PyObject_DebugTypeStats
394// skipped _PyObject_ASSERT_FROM
395// skipped _PyObject_ASSERT_WITH_MSG
396// skipped _PyObject_ASSERT
397// skipped _PyObject_ASSERT_FAILED_MSG
398// skipped _PyObject_AssertFailed
399// skipped _PyObject_CheckConsistency
400
401// skipped _PyTrash_thread_deposit_object
402// skipped _PyTrash_thread_destroy_chain
403// skipped _PyTrash_begin
404// skipped _PyTrash_end
405// skipped _PyTrash_cond
406// skipped PyTrash_UNWIND_LEVEL
407// skipped Py_TRASHCAN_BEGIN_CONDITION
408// skipped Py_TRASHCAN_END
409// skipped Py_TRASHCAN_BEGIN
410// skipped Py_TRASHCAN_SAFE_BEGIN
411// skipped Py_TRASHCAN_SAFE_END