@@ -53,17 +53,6 @@ struct handle_type_name<array> {
53
53
template <typename type, typename SFINAE = void >
54
54
struct npy_format_descriptor ;
55
55
56
- struct PyArrayDescr_Proxy {
57
- PyObject_HEAD
58
- PyObject *typeobj;
59
- char kind;
60
- char type;
61
- char byteorder;
62
- char _former_flags;
63
- int type_num;
64
- /* Additional fields are NumPy version specific. */
65
- };
66
-
67
56
/* NumPy 1 proxy (always includes legacy fields) */
68
57
struct PyArrayDescr1_Proxy {
69
58
PyObject_HEAD
@@ -80,6 +69,22 @@ struct PyArrayDescr1_Proxy {
80
69
PyObject *names;
81
70
};
82
71
72
+ #ifdef PYBIND11_COMPILE_WITH_NUMPY2_SUPPORT
73
+ struct PyArrayDescr_Proxy {
74
+ PyObject_HEAD
75
+ PyObject *typeobj;
76
+ char kind;
77
+ char type;
78
+ char byteorder;
79
+ char _former_flags;
80
+ int type_num;
81
+ /* Additional fields are NumPy version specific. */
82
+ };
83
+ #else
84
+ /* NumPy 1.x only, we can expose all fields */
85
+ typedef PyArrayDescr1_Proxy PyArrayDescr_Proxy;
86
+ #endif
87
+
83
88
/* NumPy 2 proxy, including legacy fields */
84
89
struct PyArrayDescr2_Proxy {
85
90
PyObject_HEAD
@@ -164,6 +169,13 @@ PYBIND11_NOINLINE module_ import_numpy_core_submodule(const char *submodule_name
164
169
object numpy_version = numpy_lib.attr (" NumpyVersion" )(version_string);
165
170
int major_version = numpy_version.attr (" major" ).cast <int >();
166
171
172
+ #ifndef PYBIND11_COMPILE_WITH_NUMPY2_SUPPORT
173
+ if (major_version >= 2 ) {
174
+ throw std::runtime_error (" module compiled without NumPy 2 support. Please modify the "
175
+ " `pybind11/numpy.h` include to `pybind11/numpy2.h` and recompile "
176
+ " (this remains NumPy 1.x compatible but has minor changes)." );
177
+ }
178
+ #endif
167
179
/* `numpy.core` was renamed to `numpy._core` in NumPy 2.0 as it officially
168
180
became a private module. */
169
181
std::string numpy_core_path = major_version >= 2 ? " numpy._core" : " numpy.core" ;
@@ -276,6 +288,16 @@ struct npy_api {
276
288
PyObject *(*PyArray_FromAny_)(PyObject *, PyObject *, int , int , int , PyObject *);
277
289
int (*PyArray_DescrConverter_)(PyObject *, PyObject **);
278
290
bool (*PyArray_EquivTypes_)(PyObject *, PyObject *);
291
+ #ifndef PYBIND11_COMPILE_WITH_NUMPY2_SUPPORT
292
+ int (*PyArray_GetArrayParamsFromObject_)(PyObject *,
293
+ PyObject *,
294
+ unsigned char ,
295
+ PyObject **,
296
+ int *,
297
+ Py_intptr_t *,
298
+ PyObject **,
299
+ PyObject *);
300
+ #endif
279
301
PyObject *(*PyArray_Squeeze_)(PyObject *);
280
302
// Unused. Not removed because that affects ABI of the class.
281
303
int (*PyArray_SetBaseObject_)(PyObject *, PyObject *);
@@ -301,7 +323,9 @@ struct npy_api {
301
323
API_PyArray_Squeeze = 136 ,
302
324
API_PyArray_View = 137 ,
303
325
API_PyArray_DescrConverter = 174 ,
326
+ #ifndef PYBIND11_COMPILE_WITH_NUMPY2_SUPPORT
304
327
API_PyArray_EquivTypes = 182 ,
328
+ #endif
305
329
API_PyArray_SetBaseObject = 282
306
330
};
307
331
@@ -644,12 +668,16 @@ class dtype : public object {
644
668
}
645
669
646
670
// / Size of the data type in bytes.
671
+ #ifdef PYBIND11_COMPILE_WITH_NUMPY2_SUPPORT
672
+ int itemsize () const { detail::array_descriptor_proxy (m_ptr)->elsize ; }
673
+ #else
647
674
ssize_t itemsize () const {
648
675
if (detail::npy_api::get ().PyArray_RUNTIME_VERSION_ < 0x12 ) {
649
676
return detail::array_descriptor1_proxy (m_ptr)->elsize ;
650
677
}
651
678
return detail::array_descriptor2_proxy (m_ptr)->elsize ;
652
679
}
680
+ #endif
653
681
654
682
// / Returns true for structured data types.
655
683
bool has_fields () const {
@@ -686,24 +714,31 @@ class dtype : public object {
686
714
// / Single character for byteorder
687
715
char byteorder () const { return detail::array_descriptor_proxy (m_ptr)->byteorder ; }
688
716
689
- // / Alignment of the data type
717
+ // / Alignment of the data type
718
+ #ifdef PYBIND11_COMPILE_WITH_NUMPY2_SUPPORT
719
+ int alignment () const { detail::array_descriptor2_proxy (m_ptr)->alignment ; }
720
+ #else
690
721
ssize_t alignment () const {
691
722
if (detail::npy_api::get ().PyArray_RUNTIME_VERSION_ < 0x12 ) {
692
- return detail::array_descriptor1_proxy (m_ptr)->alignment ;
723
+ return detail::array_descriptor2_proxy (m_ptr)->alignment ;
693
724
}
694
- return detail::array_descriptor2_proxy (m_ptr)->alignment ;
725
+ return detail::array_descriptor1_proxy (m_ptr)->alignment ;
695
726
}
727
+ #endif
696
728
697
- // / Flags for the array descriptor
729
+ // / Flags for the array descriptor
730
+ #ifdef PYBIND11_COMPILE_WITH_NUMPY2_SUPPORT
731
+ char flags () const {detail::array_descriptor_proxy (m_ptr)->flags }
732
+ #else
698
733
std::uint64_t flags () const {
699
734
if (detail::npy_api::get ().PyArray_RUNTIME_VERSION_ < 0x12 ) {
700
735
return (unsigned char ) detail::array_descriptor1_proxy (m_ptr)->flags ;
701
736
}
702
737
return detail::array_descriptor2_proxy (m_ptr)->flags ;
703
738
}
739
+ #endif
704
740
705
- private:
706
- static object &_dtype_from_pep3118 () {
741
+ private : static object &_dtype_from_pep3118 () {
707
742
PYBIND11_CONSTINIT static gil_safe_call_once_and_store<object> storage;
708
743
return storage
709
744
.call_once_and_store_result ([]() {
0 commit comments