1#![allow(
12 non_camel_case_types,
13 missing_docs,
14 missing_debug_implementations,
15 clippy::too_many_arguments,
16 clippy::missing_safety_doc
17)]
18
19use std::ffi::{c_uint, c_void};
20use std::mem::forget;
21use std::ptr::NonNull;
22
23use pyo3::{
24 ffi::PyTypeObject,
25 sync::PyOnceLock,
26 types::{PyAnyMethods, PyCapsule, PyCapsuleMethods, PyModule},
27 PyResult, Python,
28};
29
30static API_VERSION: PyOnceLock<c_uint> = PyOnceLock::new();
31
32fn get_numpy_api<'py>(
33 py: Python<'py>,
34 module: &str,
35 capsule: &str,
36) -> PyResult<NonNull<*const c_void>> {
37 let module = PyModule::import(py, module)?;
38 let capsule = module.getattr(capsule)?.cast_into::<PyCapsule>()?;
39
40 let api = capsule.pointer_checked(None)?;
41
42 forget(capsule);
45
46 Ok(api.cast())
47}
48
49pub fn is_numpy_2<'py>(py: Python<'py>) -> bool {
51 let api_version = *API_VERSION.get_or_init(py, || unsafe {
52 PY_ARRAY_API.PyArray_GetNDArrayCFeatureVersion(py)
53 });
54 api_version >= NPY_2_0_API_VERSION
55}
56
57macro_rules! impl_api {
59 [$offset: expr; $fname: ident ($($arg: ident: $t: ty),* $(,)?) $(-> $ret: ty)?] => {
61 impl_api![$offset; pub $fname($($arg : $t), *) $(-> $ret)*];
62 };
63 [$offset: expr; $vis:vis $fname: ident ($($arg: ident: $t: ty),* $(,)?) $(-> $ret: ty)?] => {
64 #[allow(non_snake_case)]
65 $vis unsafe fn $fname<'py>(&self, py: Python<'py>, $($arg : $t), *) $(-> $ret)* {
66 let f: extern "C" fn ($($arg : $t), *) $(-> $ret)* = self.get(py, $offset).cast().read();
67 f($($arg), *)
68 }
69 }
70}
71
72macro_rules! impl_array_type {
74 ($(($api:ident [ $offset:expr ] , $tname:ident)),* $(,)?) => {
75 #[allow(non_camel_case_types)]
77 pub enum NpyTypes { $($tname),* }
78
79 pub unsafe fn get_type_object<'py>(py: Python<'py>, ty: NpyTypes) -> *mut PyTypeObject {
81 match ty {
82 $( NpyTypes::$tname => $api.get(py, $offset).read() as _ ),*
83 }
84 }
85 }
86}
87
88#[cfg(all(Py_LIMITED_API, Py_GIL_DISABLED))]
92macro_rules! opaque_struct {
93 ($(#[$attrs:meta])* $pub:vis $name:ident) => {
94 $(#[$attrs])*
95 #[repr(C)]
96 $pub struct $name {
97 _data: (),
98 _marker: core::marker::PhantomData<(*mut u8, core::marker::PhantomPinned)>,
99 }
100 };
101}
102
103impl_array_type! {
104 (PY_ARRAY_API[2], PyArray_Type),
107 (PY_ARRAY_API[3], PyArrayDescr_Type),
108 (PY_ARRAY_API[5], PyArrayIter_Type),
110 (PY_ARRAY_API[6], PyArrayMultiIter_Type),
111 (PY_ARRAY_API[8], PyBoolArrType_Type),
113 (PY_ARRAY_API[10], PyGenericArrType_Type),
115 (PY_ARRAY_API[11], PyNumberArrType_Type),
116 (PY_ARRAY_API[12], PyIntegerArrType_Type),
117 (PY_ARRAY_API[13], PySignedIntegerArrType_Type),
118 (PY_ARRAY_API[14], PyUnsignedIntegerArrType_Type),
119 (PY_ARRAY_API[15], PyInexactArrType_Type),
120 (PY_ARRAY_API[16], PyFloatingArrType_Type),
121 (PY_ARRAY_API[17], PyComplexFloatingArrType_Type),
122 (PY_ARRAY_API[18], PyFlexibleArrType_Type),
123 (PY_ARRAY_API[19], PyCharacterArrType_Type),
124 (PY_ARRAY_API[20], PyByteArrType_Type),
125 (PY_ARRAY_API[21], PyShortArrType_Type),
126 (PY_ARRAY_API[22], PyIntArrType_Type),
127 (PY_ARRAY_API[23], PyLongArrType_Type),
128 (PY_ARRAY_API[24], PyLongLongArrType_Type),
129 (PY_ARRAY_API[25], PyUByteArrType_Type),
130 (PY_ARRAY_API[26], PyUShortArrType_Type),
131 (PY_ARRAY_API[27], PyUIntArrType_Type),
132 (PY_ARRAY_API[28], PyULongArrType_Type),
133 (PY_ARRAY_API[29], PyULongLongArrType_Type),
134 (PY_ARRAY_API[30], PyFloatArrType_Type),
135 (PY_ARRAY_API[31], PyDoubleArrType_Type),
136 (PY_ARRAY_API[32], PyLongDoubleArrType_Type),
137 (PY_ARRAY_API[33], PyCFloatArrType_Type),
138 (PY_ARRAY_API[34], PyCDoubleArrType_Type),
139 (PY_ARRAY_API[35], PyCLongDoubleArrType_Type),
140 (PY_ARRAY_API[36], PyObjectArrType_Type),
141 (PY_ARRAY_API[37], PyStringArrType_Type),
142 (PY_ARRAY_API[38], PyUnicodeArrType_Type),
143 (PY_ARRAY_API[39], PyVoidArrType_Type),
144 (PY_ARRAY_API[214], PyTimeIntegerArrType_Type),
145 (PY_ARRAY_API[215], PyDatetimeArrType_Type),
146 (PY_ARRAY_API[216], PyTimedeltaArrType_Type),
147 (PY_ARRAY_API[217], PyHalfArrType_Type),
148 (PY_ARRAY_API[218], NpyIter_Type),
149 (PY_UFUNC_API[0], PyUFunc_Type),
151}
152
153pub mod array;
154pub mod flags;
155mod npy_common;
156mod numpyconfig;
157pub mod objects;
158pub mod random;
159pub mod types;
160pub mod ufunc;
161
162pub use self::array::*;
163pub use self::flags::*;
164pub use self::npy_common::*;
165pub use self::numpyconfig::*;
166pub use self::objects::*;
167pub use self::random::*;
168pub use self::types::*;
169pub use self::ufunc::*;