@@ -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 *);
@@ -302,6 +324,9 @@ struct npy_api {
302
324
API_PyArray_View = 137 ,
303
325
API_PyArray_DescrConverter = 174 ,
304
326
API_PyArray_EquivTypes = 182 ,
327
+ #ifndef PYBIND11_COMPILE_WITH_NUMPY2_SUPPORT
328
+ API_PyArray_GetArrayParamsFromObject = 278 ,
329
+ #endif
305
330
API_PyArray_SetBaseObject = 282
306
331
};
307
332
@@ -336,6 +361,9 @@ struct npy_api {
336
361
DECL_NPY_API (PyArray_View);
337
362
DECL_NPY_API (PyArray_DescrConverter);
338
363
DECL_NPY_API (PyArray_EquivTypes);
364
+ #ifndef PYBIND11_COMPILE_WITH_NUMPY2_SUPPORT
365
+ DECL_NPY_API (PyArray_GetArrayParamsFromObject);
366
+ #endif
339
367
DECL_NPY_API (PyArray_SetBaseObject);
340
368
341
369
#undef DECL_NPY_API
@@ -644,14 +672,21 @@ class dtype : public object {
644
672
}
645
673
646
674
// / Size of the data type in bytes.
675
+ #ifndef PYBIND11_COMPILE_WITH_NUMPY2_SUPPORT
676
+ ssize_t itemsize () const { return detail::array_descriptor_proxy (m_ptr)->elsize ; }
677
+ #else
647
678
ssize_t itemsize () const {
648
679
if (detail::npy_api::get ().PyArray_RUNTIME_VERSION_ < 0x12 ) {
649
680
return detail::array_descriptor1_proxy (m_ptr)->elsize ;
650
681
}
651
682
return detail::array_descriptor2_proxy (m_ptr)->elsize ;
652
683
}
684
+ #endif
653
685
654
686
// / Returns true for structured data types.
687
+ #ifndef PYBIND11_COMPILE_WITH_NUMPY2_SUPPORT
688
+ bool has_fields () const { return detail::array_descriptor_proxy (m_ptr)->names != nullptr ; }
689
+ #else
655
690
bool has_fields () const {
656
691
if (detail::npy_api::get ().PyArray_RUNTIME_VERSION_ < 0x12 ) {
657
692
return detail::array_descriptor1_proxy (m_ptr)->names != nullptr ;
@@ -661,6 +696,7 @@ class dtype : public object {
661
696
}
662
697
return detail::array_descriptor2_proxy (m_ptr)->names != nullptr ;
663
698
}
699
+ #endif
664
700
665
701
// / Single-character code for dtype's kind.
666
702
// / For example, floating point types are 'f' and integral types are 'i'.
@@ -686,21 +722,29 @@ class dtype : public object {
686
722
// / Single character for byteorder
687
723
char byteorder () const { return detail::array_descriptor_proxy (m_ptr)->byteorder ; }
688
724
689
- // / Alignment of the data type
725
+ // / Alignment of the data type
726
+ #ifndef PYBIND11_COMPILE_WITH_NUMPY2_SUPPORT
727
+ int alignment () const { return detail::array_descriptor_proxy (m_ptr)->alignment ; }
728
+ #else
690
729
ssize_t alignment () const {
691
730
if (detail::npy_api::get ().PyArray_RUNTIME_VERSION_ < 0x12 ) {
692
731
return detail::array_descriptor1_proxy (m_ptr)->alignment ;
693
732
}
694
733
return detail::array_descriptor2_proxy (m_ptr)->alignment ;
695
734
}
735
+ #endif
696
736
697
- // / Flags for the array descriptor
737
+ // / Flags for the array descriptor
738
+ #ifndef PYBIND11_COMPILE_WITH_NUMPY2_SUPPORT
739
+ char flags () const { return detail::array_descriptor_proxy (m_ptr)->flags ; }
740
+ #else
698
741
std::uint64_t flags () const {
699
742
if (detail::npy_api::get ().PyArray_RUNTIME_VERSION_ < 0x12 ) {
700
743
return (unsigned char ) detail::array_descriptor1_proxy (m_ptr)->flags ;
701
744
}
702
745
return detail::array_descriptor2_proxy (m_ptr)->flags ;
703
746
}
747
+ #endif
704
748
705
749
private:
706
750
static object &_dtype_from_pep3118 () {
0 commit comments