1use crate::vectorcallfunc;
2use crate::{object, PyGetSetDef, PyMemberDef, PyMethodDef, PyObject, Py_ssize_t};
3use std::ffi::{c_char, c_int, c_uint, c_void};
4use std::mem;
5
6#[cfg(not(Py_3_11))] mod bufferinfo {
23 use crate::Py_ssize_t;
24 use std::ffi::{c_char, c_int, c_void};
25 use std::ptr;
26
27 #[repr(C)]
28 #[derive(Copy, Clone)]
29 pub struct Py_buffer {
30 pub buf: *mut c_void,
31 pub obj: *mut crate::PyObject,
33 pub len: Py_ssize_t,
34 pub itemsize: Py_ssize_t,
35 pub readonly: c_int,
36 pub ndim: c_int,
37 pub format: *mut c_char,
38 pub shape: *mut Py_ssize_t,
39 pub strides: *mut Py_ssize_t,
40 pub suboffsets: *mut Py_ssize_t,
41 pub internal: *mut c_void,
42 #[cfg(PyPy)]
43 pub flags: c_int,
44 #[cfg(PyPy)]
45 pub _strides: [Py_ssize_t; PyBUF_MAX_NDIM as usize],
46 #[cfg(PyPy)]
47 pub _shape: [Py_ssize_t; PyBUF_MAX_NDIM as usize],
48 }
49
50 impl Py_buffer {
51 #[allow(clippy::new_without_default)]
52 pub const fn new() -> Self {
53 Py_buffer {
54 buf: ptr::null_mut(),
55 obj: ptr::null_mut(),
56 len: 0,
57 itemsize: 0,
58 readonly: 0,
59 ndim: 0,
60 format: ptr::null_mut(),
61 shape: ptr::null_mut(),
62 strides: ptr::null_mut(),
63 suboffsets: ptr::null_mut(),
64 internal: ptr::null_mut(),
65 #[cfg(PyPy)]
66 flags: 0,
67 #[cfg(PyPy)]
68 _strides: [0; PyBUF_MAX_NDIM as usize],
69 #[cfg(PyPy)]
70 _shape: [0; PyBUF_MAX_NDIM as usize],
71 }
72 }
73 }
74
75 pub type getbufferproc = unsafe extern "C" fn(
76 arg1: *mut crate::PyObject,
77 arg2: *mut Py_buffer,
78 arg3: c_int,
79 ) -> c_int;
80 pub type releasebufferproc =
81 unsafe extern "C" fn(arg1: *mut crate::PyObject, arg2: *mut Py_buffer);
82
83 pub const PyBUF_MAX_NDIM: c_int = if cfg!(PyPy) { 36 } else { 64 };
85
86 pub const PyBUF_SIMPLE: c_int = 0;
88 pub const PyBUF_WRITABLE: c_int = 0x0001;
89 pub const PyBUF_WRITEABLE: c_int = PyBUF_WRITABLE;
91 pub const PyBUF_FORMAT: c_int = 0x0004;
92 pub const PyBUF_ND: c_int = 0x0008;
93 pub const PyBUF_STRIDES: c_int = 0x0010 | PyBUF_ND;
94 pub const PyBUF_C_CONTIGUOUS: c_int = 0x0020 | PyBUF_STRIDES;
95 pub const PyBUF_F_CONTIGUOUS: c_int = 0x0040 | PyBUF_STRIDES;
96 pub const PyBUF_ANY_CONTIGUOUS: c_int = 0x0080 | PyBUF_STRIDES;
97 pub const PyBUF_INDIRECT: c_int = 0x0100 | PyBUF_STRIDES;
98
99 pub const PyBUF_CONTIG: c_int = PyBUF_ND | PyBUF_WRITABLE;
100 pub const PyBUF_CONTIG_RO: c_int = PyBUF_ND;
101
102 pub const PyBUF_STRIDED: c_int = PyBUF_STRIDES | PyBUF_WRITABLE;
103 pub const PyBUF_STRIDED_RO: c_int = PyBUF_STRIDES;
104
105 pub const PyBUF_RECORDS: c_int = PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT;
106 pub const PyBUF_RECORDS_RO: c_int = PyBUF_STRIDES | PyBUF_FORMAT;
107
108 pub const PyBUF_FULL: c_int = PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT;
109 pub const PyBUF_FULL_RO: c_int = PyBUF_INDIRECT | PyBUF_FORMAT;
110
111 pub const PyBUF_READ: c_int = 0x100;
112 pub const PyBUF_WRITE: c_int = 0x200;
113}
114
115#[cfg(not(Py_3_11))]
116pub use self::bufferinfo::*;
117
118#[repr(C)]
119#[derive(Copy, Clone)]
120pub struct PyNumberMethods {
121 pub nb_add: Option<object::binaryfunc>,
122 pub nb_subtract: Option<object::binaryfunc>,
123 pub nb_multiply: Option<object::binaryfunc>,
124 pub nb_remainder: Option<object::binaryfunc>,
125 pub nb_divmod: Option<object::binaryfunc>,
126 pub nb_power: Option<object::ternaryfunc>,
127 pub nb_negative: Option<object::unaryfunc>,
128 pub nb_positive: Option<object::unaryfunc>,
129 pub nb_absolute: Option<object::unaryfunc>,
130 pub nb_bool: Option<object::inquiry>,
131 pub nb_invert: Option<object::unaryfunc>,
132 pub nb_lshift: Option<object::binaryfunc>,
133 pub nb_rshift: Option<object::binaryfunc>,
134 pub nb_and: Option<object::binaryfunc>,
135 pub nb_xor: Option<object::binaryfunc>,
136 pub nb_or: Option<object::binaryfunc>,
137 pub nb_int: Option<object::unaryfunc>,
138 pub nb_reserved: *mut c_void,
139 pub nb_float: Option<object::unaryfunc>,
140 pub nb_inplace_add: Option<object::binaryfunc>,
141 pub nb_inplace_subtract: Option<object::binaryfunc>,
142 pub nb_inplace_multiply: Option<object::binaryfunc>,
143 pub nb_inplace_remainder: Option<object::binaryfunc>,
144 pub nb_inplace_power: Option<object::ternaryfunc>,
145 pub nb_inplace_lshift: Option<object::binaryfunc>,
146 pub nb_inplace_rshift: Option<object::binaryfunc>,
147 pub nb_inplace_and: Option<object::binaryfunc>,
148 pub nb_inplace_xor: Option<object::binaryfunc>,
149 pub nb_inplace_or: Option<object::binaryfunc>,
150 pub nb_floor_divide: Option<object::binaryfunc>,
151 pub nb_true_divide: Option<object::binaryfunc>,
152 pub nb_inplace_floor_divide: Option<object::binaryfunc>,
153 pub nb_inplace_true_divide: Option<object::binaryfunc>,
154 pub nb_index: Option<object::unaryfunc>,
155 pub nb_matrix_multiply: Option<object::binaryfunc>,
156 pub nb_inplace_matrix_multiply: Option<object::binaryfunc>,
157}
158
159#[repr(C)]
160#[derive(Clone)]
161pub struct PySequenceMethods {
162 pub sq_length: Option<object::lenfunc>,
163 pub sq_concat: Option<object::binaryfunc>,
164 pub sq_repeat: Option<object::ssizeargfunc>,
165 pub sq_item: Option<object::ssizeargfunc>,
166 pub was_sq_slice: *mut c_void,
167 pub sq_ass_item: Option<object::ssizeobjargproc>,
168 pub was_sq_ass_slice: *mut c_void,
169 pub sq_contains: Option<object::objobjproc>,
170 pub sq_inplace_concat: Option<object::binaryfunc>,
171 pub sq_inplace_repeat: Option<object::ssizeargfunc>,
172}
173
174#[repr(C)]
175#[derive(Clone, Default)]
176pub struct PyMappingMethods {
177 pub mp_length: Option<object::lenfunc>,
178 pub mp_subscript: Option<object::binaryfunc>,
179 pub mp_ass_subscript: Option<object::objobjargproc>,
180}
181
182#[cfg(Py_3_10)]
183pub type sendfunc = unsafe extern "C" fn(
184 iter: *mut PyObject,
185 value: *mut PyObject,
186 result: *mut *mut PyObject,
187) -> object::PySendResult;
188
189#[repr(C)]
190#[derive(Clone, Default)]
191pub struct PyAsyncMethods {
192 pub am_await: Option<object::unaryfunc>,
193 pub am_aiter: Option<object::unaryfunc>,
194 pub am_anext: Option<object::unaryfunc>,
195 #[cfg(Py_3_10)]
196 pub am_send: Option<sendfunc>,
197}
198
199#[repr(C)]
200#[derive(Clone, Default)]
201pub struct PyBufferProcs {
202 pub bf_getbuffer: Option<crate::getbufferproc>,
203 pub bf_releasebuffer: Option<crate::releasebufferproc>,
204}
205
206pub type printfunc =
207 unsafe extern "C" fn(arg1: *mut PyObject, arg2: *mut ::libc::FILE, arg3: c_int) -> c_int;
208
209#[repr(C)]
210#[derive(Debug)]
211pub struct PyTypeObject {
212 pub ob_base: object::PyVarObject,
213 pub tp_name: *const c_char,
214 pub tp_basicsize: Py_ssize_t,
215 pub tp_itemsize: Py_ssize_t,
216 pub tp_dealloc: Option<object::destructor>,
217 pub tp_vectorcall_offset: Py_ssize_t,
218 pub tp_getattr: Option<object::getattrfunc>,
219 pub tp_setattr: Option<object::setattrfunc>,
220 pub tp_as_async: *mut PyAsyncMethods,
221 pub tp_repr: Option<object::reprfunc>,
222 pub tp_as_number: *mut PyNumberMethods,
223 pub tp_as_sequence: *mut PySequenceMethods,
224 pub tp_as_mapping: *mut PyMappingMethods,
225 pub tp_hash: Option<object::hashfunc>,
226 pub tp_call: Option<object::ternaryfunc>,
227 pub tp_str: Option<object::reprfunc>,
228 pub tp_getattro: Option<object::getattrofunc>,
229 pub tp_setattro: Option<object::setattrofunc>,
230 pub tp_as_buffer: *mut PyBufferProcs,
231 #[cfg(not(Py_GIL_DISABLED))]
232 pub tp_flags: std::ffi::c_ulong,
233 #[cfg(Py_GIL_DISABLED)]
234 pub tp_flags: crate::impl_::AtomicCULong,
235 pub tp_doc: *const c_char,
236 pub tp_traverse: Option<object::traverseproc>,
237 pub tp_clear: Option<object::inquiry>,
238 pub tp_richcompare: Option<object::richcmpfunc>,
239 pub tp_weaklistoffset: Py_ssize_t,
240 pub tp_iter: Option<object::getiterfunc>,
241 pub tp_iternext: Option<object::iternextfunc>,
242 pub tp_methods: *mut PyMethodDef,
243 pub tp_members: *mut PyMemberDef,
244 pub tp_getset: *mut PyGetSetDef,
245 pub tp_base: *mut PyTypeObject,
246 pub tp_dict: *mut object::PyObject,
247 pub tp_descr_get: Option<object::descrgetfunc>,
248 pub tp_descr_set: Option<object::descrsetfunc>,
249 pub tp_dictoffset: Py_ssize_t,
250 pub tp_init: Option<object::initproc>,
251 pub tp_alloc: Option<object::allocfunc>,
252 pub tp_new: Option<object::newfunc>,
253 pub tp_free: Option<object::freefunc>,
254 pub tp_is_gc: Option<object::inquiry>,
255 pub tp_bases: *mut object::PyObject,
256 pub tp_mro: *mut object::PyObject,
257 pub tp_cache: *mut object::PyObject,
258 pub tp_subclasses: *mut object::PyObject,
259 pub tp_weaklist: *mut object::PyObject,
260 pub tp_del: Option<object::destructor>,
261 pub tp_version_tag: c_uint,
262 pub tp_finalize: Option<object::destructor>,
263 pub tp_vectorcall: Option<vectorcallfunc>,
264 #[cfg(Py_3_12)]
265 pub tp_watched: c_char,
266 #[cfg(not(any(PyPy, Py_3_9)))]
267 pub tp_print: Option<printfunc>,
268 #[cfg(py_sys_config = "COUNT_ALLOCS")]
269 pub tp_allocs: Py_ssize_t,
270 #[cfg(py_sys_config = "COUNT_ALLOCS")]
271 pub tp_frees: Py_ssize_t,
272 #[cfg(py_sys_config = "COUNT_ALLOCS")]
273 pub tp_maxalloc: Py_ssize_t,
274 #[cfg(py_sys_config = "COUNT_ALLOCS")]
275 pub tp_prev: *mut PyTypeObject,
276 #[cfg(py_sys_config = "COUNT_ALLOCS")]
277 pub tp_next: *mut PyTypeObject,
278 #[cfg(Py_3_13)]
279 pub tp_versions_used: u16,
280}
281
282#[cfg(Py_3_11)]
283#[repr(C)]
284#[derive(Clone)]
285struct _specialization_cache {
286 getitem: *mut PyObject,
287 #[cfg(Py_3_12)]
288 getitem_version: u32,
289 #[cfg(Py_3_13)]
290 init: *mut PyObject,
291}
292
293#[repr(C)]
294pub struct PyHeapTypeObject {
295 pub ht_type: PyTypeObject,
296 pub as_async: PyAsyncMethods,
297 pub as_number: PyNumberMethods,
298 pub as_mapping: PyMappingMethods,
299 pub as_sequence: PySequenceMethods,
300 pub as_buffer: PyBufferProcs,
301 pub ht_name: *mut object::PyObject,
302 pub ht_slots: *mut object::PyObject,
303 pub ht_qualname: *mut object::PyObject,
304 #[cfg(not(PyPy))]
305 pub ht_cached_keys: *mut c_void,
306 #[cfg(Py_3_9)]
307 pub ht_module: *mut object::PyObject,
308 #[cfg(all(Py_3_11, not(PyPy)))]
309 _ht_tpname: *mut c_char,
310 #[cfg(Py_3_14)]
311 pub ht_token: *mut c_void,
312 #[cfg(all(Py_3_11, not(PyPy)))]
313 _spec_cache: _specialization_cache,
314 #[cfg(all(Py_GIL_DISABLED, Py_3_14))]
315 pub unique_id: Py_ssize_t,
316}
317
318impl Default for PyHeapTypeObject {
319 #[inline]
320 fn default() -> Self {
321 unsafe { mem::zeroed() }
322 }
323}
324
325#[inline]
326#[cfg(not(Py_3_11))]
327pub unsafe fn PyHeapType_GET_MEMBERS(etype: *mut PyHeapTypeObject) -> *mut PyMemberDef {
328 let py_type = object::Py_TYPE(etype as *mut object::PyObject);
329 let ptr = etype.offset((*py_type).tp_basicsize);
330 ptr as *mut PyMemberDef
331}
332
333extern_libpython! {
338 #[cfg(Py_3_12)]
339 pub fn PyType_GetDict(o: *mut PyTypeObject) -> *mut PyObject;
340
341 #[cfg_attr(PyPy, link_name = "PyPyObject_Print")]
342 pub fn PyObject_Print(o: *mut PyObject, fp: *mut ::libc::FILE, flags: c_int) -> c_int;
343
344 pub fn PyObject_CallFinalizer(arg1: *mut PyObject);
351 #[cfg_attr(PyPy, link_name = "PyPyObject_CallFinalizerFromDealloc")]
352 pub fn PyObject_CallFinalizerFromDealloc(arg1: *mut PyObject) -> c_int;
353
354 }
358
359#[cfg(Py_3_14)]
400extern_libpython! {
401 pub fn PyUnstable_Object_IsUniqueReferencedTemporary(obj: *mut PyObject) -> c_int;
404
405 pub fn PyUnstable_TryIncRef(obj: *mut PyObject) -> c_int;
408
409 pub fn PyUnstable_EnableTryIncRef(obj: *mut PyObject) -> c_void;
410
411 pub fn PyUnstable_Object_IsUniquelyReferenced(op: *mut PyObject) -> c_int;
412}
413
414#[cfg(Py_3_15)]
415extern_libpython! {
416 pub fn PyUnstable_SetImmortal(op: *mut PyObject) -> c_int;
417}