netgen-mesher 6.2.2505.post48.dev0__cp313-cp313-win_amd64.whl → 6.2.2506.post48.dev0__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. netgen/__init__.pyi +3 -3
  2. netgen/cmake/NetgenConfig.cmake +9 -8
  3. netgen/config/__init__.pyi +7 -7
  4. netgen/config/config.py +6 -6
  5. netgen/config/config.pyi +7 -7
  6. netgen/include/core/archive.hpp +18 -3
  7. netgen/include/core/array.hpp +20 -4
  8. netgen/include/core/autodiff.hpp +9 -11
  9. netgen/include/core/autodiffdiff.hpp +0 -2
  10. netgen/include/core/bitarray.hpp +1 -1
  11. netgen/include/core/flags.hpp +1 -1
  12. netgen/include/core/hashtable.hpp +1 -1
  13. netgen/include/core/memtracer.hpp +7 -7
  14. netgen/include/core/ngcore.hpp +5 -0
  15. netgen/include/core/ngcore_api.hpp +11 -0
  16. netgen/include/core/register_archive.hpp +8 -0
  17. netgen/include/core/simd_arm64.hpp +100 -5
  18. netgen/include/core/simd_generic.hpp +187 -6
  19. netgen/include/core/simd_math.hpp +3 -2
  20. netgen/include/core/statushandler.hpp +37 -0
  21. netgen/include/core/table.hpp +2 -2
  22. netgen/include/core/taskmanager.hpp +34 -1
  23. netgen/include/include/netgen_version.hpp +3 -3
  24. netgen/include/meshing/basegeom.hpp +1 -4
  25. netgen/include/meshing/global.hpp +0 -17
  26. netgen/include/meshing/hpref_tet.hpp +41 -0
  27. netgen/include/meshing/hprefinement.hpp +2 -0
  28. netgen/include/meshing/meshtype.hpp +1 -0
  29. netgen/include/meshing/msghandler.hpp +9 -6
  30. netgen/include/meshing/topology.hpp +2 -2
  31. netgen/include/nginterface.h +3 -2
  32. netgen/include/occ/occ_utils.hpp +26 -0
  33. netgen/include/occ/occgeom.hpp +8 -0
  34. netgen/include/pybind11/attr.h +40 -8
  35. netgen/include/pybind11/buffer_info.h +14 -14
  36. netgen/include/pybind11/cast.h +553 -29
  37. netgen/include/pybind11/chrono.h +4 -1
  38. netgen/include/pybind11/conduit/README.txt +15 -0
  39. netgen/include/pybind11/conduit/pybind11_conduit_v1.h +116 -0
  40. netgen/include/pybind11/conduit/pybind11_platform_abi_id.h +87 -0
  41. netgen/include/pybind11/conduit/wrap_include_python_h.h +72 -0
  42. netgen/include/pybind11/critical_section.h +56 -0
  43. netgen/include/pybind11/detail/class.h +172 -97
  44. netgen/include/pybind11/detail/common.h +270 -189
  45. netgen/include/pybind11/detail/cpp_conduit.h +75 -0
  46. netgen/include/pybind11/detail/descr.h +55 -0
  47. netgen/include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h +39 -0
  48. netgen/include/pybind11/detail/exception_translation.h +71 -0
  49. netgen/include/pybind11/detail/function_record_pyobject.h +191 -0
  50. netgen/include/pybind11/detail/init.h +113 -9
  51. netgen/include/pybind11/detail/internals.h +479 -344
  52. netgen/include/pybind11/detail/native_enum_data.h +209 -0
  53. netgen/include/pybind11/detail/pybind11_namespace_macros.h +82 -0
  54. netgen/include/pybind11/detail/struct_smart_holder.h +378 -0
  55. netgen/include/pybind11/detail/type_caster_base.h +506 -133
  56. netgen/include/pybind11/detail/using_smart_holder.h +22 -0
  57. netgen/include/pybind11/detail/value_and_holder.h +90 -0
  58. netgen/include/pybind11/eigen/matrix.h +19 -10
  59. netgen/include/pybind11/eigen/tensor.h +15 -11
  60. netgen/include/pybind11/embed.h +50 -46
  61. netgen/include/pybind11/eval.h +11 -6
  62. netgen/include/pybind11/functional.h +58 -49
  63. netgen/include/pybind11/gil.h +34 -82
  64. netgen/include/pybind11/gil_safe_call_once.h +12 -1
  65. netgen/include/pybind11/gil_simple.h +37 -0
  66. netgen/include/pybind11/native_enum.h +67 -0
  67. netgen/include/pybind11/numpy.h +272 -93
  68. netgen/include/pybind11/pybind11.h +947 -265
  69. netgen/include/pybind11/pytypes.h +127 -21
  70. netgen/include/pybind11/stl/filesystem.h +23 -25
  71. netgen/include/pybind11/stl.h +277 -59
  72. netgen/include/pybind11/stl_bind.h +42 -7
  73. netgen/include/pybind11/subinterpreter.h +299 -0
  74. netgen/include/pybind11/trampoline_self_life_support.h +65 -0
  75. netgen/include/pybind11/typing.h +177 -4
  76. netgen/include/pybind11/warnings.h +75 -0
  77. netgen/lib/libnggui.lib +0 -0
  78. netgen/lib/ngcore.lib +0 -0
  79. netgen/lib/nglib.lib +0 -0
  80. netgen/libnggui.dll +0 -0
  81. netgen/libngguipy.pyd +0 -0
  82. netgen/libngpy/_NgOCC.pyi +220 -141
  83. netgen/libngpy/_csg.pyi +26 -26
  84. netgen/libngpy/_geom2d.pyi +34 -25
  85. netgen/libngpy/_meshing.pyi +262 -111
  86. netgen/libngpy/_stl.pyi +3 -4
  87. netgen/libngpy.pyd +0 -0
  88. netgen/ngcore.dll +0 -0
  89. netgen/nglib.dll +0 -0
  90. netgen/read_gmsh.py +41 -0
  91. netgen/togl.dll +0 -0
  92. netgen/version.py +1 -1
  93. netgen/webgui.py +38 -2
  94. {netgen_mesher-6.2.2505.post48.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/METADATA +2 -1
  95. {netgen_mesher-6.2.2505.post48.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/RECORD +144 -124
  96. pyngcore/pyngcore.cp313-win_amd64.pyd +0 -0
  97. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/boundarycondition.geo +0 -0
  98. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/boxcyl.geo +0 -0
  99. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/circle_on_cube.geo +0 -0
  100. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cone.geo +0 -0
  101. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cube.geo +0 -0
  102. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubeandring.geo +0 -0
  103. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubeandspheres.geo +0 -0
  104. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubemcyl.geo +0 -0
  105. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubemsphere.geo +0 -0
  106. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cylinder.geo +0 -0
  107. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cylsphere.geo +0 -0
  108. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/doc/ng4.pdf +0 -0
  109. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ellipsoid.geo +0 -0
  110. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ellipticcyl.geo +0 -0
  111. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/extrusion.geo +0 -0
  112. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/fichera.geo +0 -0
  113. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/frame.step +0 -0
  114. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/hinge.stl +0 -0
  115. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/lshape3d.geo +0 -0
  116. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/manyholes.geo +0 -0
  117. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/manyholes2.geo +0 -0
  118. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/matrix.geo +0 -0
  119. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ortho.geo +0 -0
  120. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/part1.stl +0 -0
  121. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/period.geo +0 -0
  122. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/py_tutorials/exportNeutral.py +0 -0
  123. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/py_tutorials/mesh.py +0 -0
  124. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/py_tutorials/shaft.geo +0 -0
  125. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/revolution.geo +0 -0
  126. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/screw.step +0 -0
  127. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sculpture.geo +0 -0
  128. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/shaft.geo +0 -0
  129. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/shell.geo +0 -0
  130. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sphere.geo +0 -0
  131. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sphereincube.geo +0 -0
  132. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/square.in2d +0 -0
  133. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/squarecircle.in2d +0 -0
  134. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/squarehole.in2d +0 -0
  135. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/torus.geo +0 -0
  136. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/trafo.geo +0 -0
  137. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twobricks.geo +0 -0
  138. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twocubes.geo +0 -0
  139. {netgen_mesher-6.2.2505.post48.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twocyl.geo +0 -0
  140. {netgen_mesher-6.2.2505.post48.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/AUTHORS +0 -0
  141. {netgen_mesher-6.2.2505.post48.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/LICENSE +0 -0
  142. {netgen_mesher-6.2.2505.post48.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/WHEEL +0 -0
  143. {netgen_mesher-6.2.2505.post48.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/entry_points.txt +0 -0
  144. {netgen_mesher-6.2.2505.post48.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/top_level.txt +0 -0
@@ -29,8 +29,8 @@
29
29
  #include <utility>
30
30
  #include <vector>
31
31
 
32
- #if defined(PYBIND11_NUMPY_1_ONLY) && !defined(PYBIND11_INTERNAL_NUMPY_1_ONLY_DETECTED)
33
- # error PYBIND11_NUMPY_1_ONLY must be defined before any pybind11 header is included.
32
+ #if defined(PYBIND11_NUMPY_1_ONLY)
33
+ # error "PYBIND11_NUMPY_1_ONLY is no longer supported (see PR #5595)."
34
34
  #endif
35
35
 
36
36
  /* This will be true on all flat address space platforms and allows us to reduce the
@@ -49,6 +49,9 @@ PYBIND11_WARNING_DISABLE_MSVC(4127)
49
49
  class dtype; // Forward declaration
50
50
  class array; // Forward declaration
51
51
 
52
+ template <typename>
53
+ struct numpy_scalar; // Forward declaration
54
+
52
55
  PYBIND11_NAMESPACE_BEGIN(detail)
53
56
 
54
57
  template <>
@@ -80,7 +83,6 @@ struct PyArrayDescr1_Proxy {
80
83
  PyObject *names;
81
84
  };
82
85
 
83
- #ifndef PYBIND11_NUMPY_1_ONLY
84
86
  struct PyArrayDescr_Proxy {
85
87
  PyObject_HEAD
86
88
  PyObject *typeobj;
@@ -91,10 +93,6 @@ struct PyArrayDescr_Proxy {
91
93
  int type_num;
92
94
  /* Additional fields are NumPy version specific. */
93
95
  };
94
- #else
95
- /* NumPy 1.x only, we can expose all fields */
96
- using PyArrayDescr_Proxy = PyArrayDescr1_Proxy;
97
- #endif
98
96
 
99
97
  /* NumPy 2 proxy, including legacy fields */
100
98
  struct PyArrayDescr2_Proxy {
@@ -175,19 +173,10 @@ inline numpy_internals &get_numpy_internals() {
175
173
  PYBIND11_NOINLINE module_ import_numpy_core_submodule(const char *submodule_name) {
176
174
  module_ numpy = module_::import("numpy");
177
175
  str version_string = numpy.attr("__version__");
178
-
179
176
  module_ numpy_lib = module_::import("numpy.lib");
180
177
  object numpy_version = numpy_lib.attr("NumpyVersion")(version_string);
181
178
  int major_version = numpy_version.attr("major").cast<int>();
182
179
 
183
- #ifdef PYBIND11_NUMPY_1_ONLY
184
- if (major_version >= 2) {
185
- throw std::runtime_error(
186
- "This extension was built with PYBIND11_NUMPY_1_ONLY defined, "
187
- "but NumPy 2 is used in this process. For NumPy2 compatibility, "
188
- "this extension needs to be rebuilt without the PYBIND11_NUMPY_1_ONLY define.");
189
- }
190
- #endif
191
180
  /* `numpy.core` was renamed to `numpy._core` in NumPy 2.0 as it officially
192
181
  became a private module. */
193
182
  std::string numpy_core_path = major_version >= 2 ? "numpy._core" : "numpy.core";
@@ -212,6 +201,7 @@ constexpr int platform_lookup(int I, Ints... Is) {
212
201
  }
213
202
 
214
203
  struct npy_api {
204
+ // If you change this code, please review `normalized_dtype_num` below.
215
205
  enum constants {
216
206
  NPY_ARRAY_C_CONTIGUOUS_ = 0x0001,
217
207
  NPY_ARRAY_F_CONTIGUOUS_ = 0x0002,
@@ -258,6 +248,21 @@ struct npy_api {
258
248
  NPY_UINT64_
259
249
  = platform_lookup<std::uint64_t, unsigned long, unsigned long long, unsigned int>(
260
250
  NPY_ULONG_, NPY_ULONGLONG_, NPY_UINT_),
251
+ NPY_FLOAT32_ = platform_lookup<float, double, float, long double>(
252
+ NPY_DOUBLE_, NPY_FLOAT_, NPY_LONGDOUBLE_),
253
+ NPY_FLOAT64_ = platform_lookup<double, double, float, long double>(
254
+ NPY_DOUBLE_, NPY_FLOAT_, NPY_LONGDOUBLE_),
255
+ NPY_COMPLEX64_
256
+ = platform_lookup<std::complex<float>,
257
+ std::complex<double>,
258
+ std::complex<float>,
259
+ std::complex<long double>>(NPY_DOUBLE_, NPY_FLOAT_, NPY_LONGDOUBLE_),
260
+ NPY_COMPLEX128_
261
+ = platform_lookup<std::complex<double>,
262
+ std::complex<double>,
263
+ std::complex<float>,
264
+ std::complex<long double>>(NPY_DOUBLE_, NPY_FLOAT_, NPY_LONGDOUBLE_),
265
+ NPY_CHAR_ = std::is_signed<char>::value ? NPY_BYTE_ : NPY_UBYTE_,
261
266
  };
262
267
 
263
268
  unsigned int PyArray_RUNTIME_VERSION_;
@@ -281,6 +286,7 @@ struct npy_api {
281
286
 
282
287
  unsigned int (*PyArray_GetNDArrayCFeatureVersion_)();
283
288
  PyObject *(*PyArray_DescrFromType_)(int);
289
+ PyObject *(*PyArray_TypeObjectFromType_)(int);
284
290
  PyObject *(*PyArray_NewFromDescr_)(PyTypeObject *,
285
291
  PyObject *,
286
292
  int,
@@ -297,19 +303,11 @@ struct npy_api {
297
303
  PyTypeObject *PyVoidArrType_Type_;
298
304
  PyTypeObject *PyArrayDescr_Type_;
299
305
  PyObject *(*PyArray_DescrFromScalar_)(PyObject *);
306
+ PyObject *(*PyArray_Scalar_)(void *, PyObject *, PyObject *);
307
+ void (*PyArray_ScalarAsCtype_)(PyObject *, void *);
300
308
  PyObject *(*PyArray_FromAny_)(PyObject *, PyObject *, int, int, int, PyObject *);
301
309
  int (*PyArray_DescrConverter_)(PyObject *, PyObject **);
302
310
  bool (*PyArray_EquivTypes_)(PyObject *, PyObject *);
303
- #ifdef PYBIND11_NUMPY_1_ONLY
304
- int (*PyArray_GetArrayParamsFromObject_)(PyObject *,
305
- PyObject *,
306
- unsigned char,
307
- PyObject **,
308
- int *,
309
- Py_intptr_t *,
310
- PyObject **,
311
- PyObject *);
312
- #endif
313
311
  PyObject *(*PyArray_Squeeze_)(PyObject *);
314
312
  // Unused. Not removed because that affects ABI of the class.
315
313
  int (*PyArray_SetBaseObject_)(PyObject *, PyObject *);
@@ -324,7 +322,10 @@ private:
324
322
  API_PyArrayDescr_Type = 3,
325
323
  API_PyVoidArrType_Type = 39,
326
324
  API_PyArray_DescrFromType = 45,
325
+ API_PyArray_TypeObjectFromType = 46,
327
326
  API_PyArray_DescrFromScalar = 57,
327
+ API_PyArray_Scalar = 60,
328
+ API_PyArray_ScalarAsCtype = 62,
328
329
  API_PyArray_FromAny = 69,
329
330
  API_PyArray_Resize = 80,
330
331
  // CopyInto was slot 82 and 50 was effectively an alias. NumPy 2 removed 82.
@@ -337,9 +338,6 @@ private:
337
338
  API_PyArray_View = 137,
338
339
  API_PyArray_DescrConverter = 174,
339
340
  API_PyArray_EquivTypes = 182,
340
- #ifdef PYBIND11_NUMPY_1_ONLY
341
- API_PyArray_GetArrayParamsFromObject = 278,
342
- #endif
343
341
  API_PyArray_SetBaseObject = 282
344
342
  };
345
343
 
@@ -362,7 +360,10 @@ private:
362
360
  DECL_NPY_API(PyVoidArrType_Type);
363
361
  DECL_NPY_API(PyArrayDescr_Type);
364
362
  DECL_NPY_API(PyArray_DescrFromType);
363
+ DECL_NPY_API(PyArray_TypeObjectFromType);
365
364
  DECL_NPY_API(PyArray_DescrFromScalar);
365
+ DECL_NPY_API(PyArray_Scalar);
366
+ DECL_NPY_API(PyArray_ScalarAsCtype);
366
367
  DECL_NPY_API(PyArray_FromAny);
367
368
  DECL_NPY_API(PyArray_Resize);
368
369
  DECL_NPY_API(PyArray_CopyInto);
@@ -374,9 +375,6 @@ private:
374
375
  DECL_NPY_API(PyArray_View);
375
376
  DECL_NPY_API(PyArray_DescrConverter);
376
377
  DECL_NPY_API(PyArray_EquivTypes);
377
- #ifdef PYBIND11_NUMPY_1_ONLY
378
- DECL_NPY_API(PyArray_GetArrayParamsFromObject);
379
- #endif
380
378
  DECL_NPY_API(PyArray_SetBaseObject);
381
379
 
382
380
  #undef DECL_NPY_API
@@ -384,6 +382,151 @@ private:
384
382
  }
385
383
  };
386
384
 
385
+ template <typename T>
386
+ struct is_complex : std::false_type {};
387
+ template <typename T>
388
+ struct is_complex<std::complex<T>> : std::true_type {};
389
+
390
+ template <typename T, typename = void>
391
+ struct npy_format_descriptor_name;
392
+
393
+ template <typename T>
394
+ struct npy_format_descriptor_name<T, enable_if_t<std::is_integral<T>::value>> {
395
+ static constexpr auto name = const_name<std::is_same<T, bool>::value>(
396
+ const_name("numpy.bool"),
397
+ const_name<std::is_signed<T>::value>("numpy.int", "numpy.uint")
398
+ + const_name<sizeof(T) * 8>());
399
+ };
400
+
401
+ template <typename T>
402
+ struct npy_format_descriptor_name<T, enable_if_t<std::is_floating_point<T>::value>> {
403
+ static constexpr auto name = const_name < std::is_same<T, float>::value
404
+ || std::is_same<T, const float>::value
405
+ || std::is_same<T, double>::value
406
+ || std::is_same<T, const double>::value
407
+ > (const_name("numpy.float") + const_name<sizeof(T) * 8>(),
408
+ const_name("numpy.longdouble"));
409
+ };
410
+
411
+ template <typename T>
412
+ struct npy_format_descriptor_name<T, enable_if_t<is_complex<T>::value>> {
413
+ static constexpr auto name = const_name < std::is_same<typename T::value_type, float>::value
414
+ || std::is_same<typename T::value_type, const float>::value
415
+ || std::is_same<typename T::value_type, double>::value
416
+ || std::is_same<typename T::value_type, const double>::value
417
+ > (const_name("numpy.complex")
418
+ + const_name<sizeof(typename T::value_type) * 16>(),
419
+ const_name("numpy.longcomplex"));
420
+ };
421
+
422
+ template <typename T>
423
+ struct numpy_scalar_info {};
424
+
425
+ #define PYBIND11_NUMPY_SCALAR_IMPL(ctype_, typenum_) \
426
+ template <> \
427
+ struct numpy_scalar_info<ctype_> { \
428
+ static constexpr auto name = npy_format_descriptor_name<ctype_>::name; \
429
+ static constexpr int typenum = npy_api::typenum_##_; \
430
+ }
431
+
432
+ // boolean type
433
+ PYBIND11_NUMPY_SCALAR_IMPL(bool, NPY_BOOL);
434
+
435
+ // character types
436
+ PYBIND11_NUMPY_SCALAR_IMPL(char, NPY_CHAR);
437
+ PYBIND11_NUMPY_SCALAR_IMPL(signed char, NPY_BYTE);
438
+ PYBIND11_NUMPY_SCALAR_IMPL(unsigned char, NPY_UBYTE);
439
+
440
+ // signed integer types
441
+ PYBIND11_NUMPY_SCALAR_IMPL(std::int16_t, NPY_INT16);
442
+ PYBIND11_NUMPY_SCALAR_IMPL(std::int32_t, NPY_INT32);
443
+ PYBIND11_NUMPY_SCALAR_IMPL(std::int64_t, NPY_INT64);
444
+
445
+ // unsigned integer types
446
+ PYBIND11_NUMPY_SCALAR_IMPL(std::uint16_t, NPY_UINT16);
447
+ PYBIND11_NUMPY_SCALAR_IMPL(std::uint32_t, NPY_UINT32);
448
+ PYBIND11_NUMPY_SCALAR_IMPL(std::uint64_t, NPY_UINT64);
449
+
450
+ // floating point types
451
+ PYBIND11_NUMPY_SCALAR_IMPL(float, NPY_FLOAT);
452
+ PYBIND11_NUMPY_SCALAR_IMPL(double, NPY_DOUBLE);
453
+ PYBIND11_NUMPY_SCALAR_IMPL(long double, NPY_LONGDOUBLE);
454
+
455
+ // complex types
456
+ PYBIND11_NUMPY_SCALAR_IMPL(std::complex<float>, NPY_CFLOAT);
457
+ PYBIND11_NUMPY_SCALAR_IMPL(std::complex<double>, NPY_CDOUBLE);
458
+ PYBIND11_NUMPY_SCALAR_IMPL(std::complex<long double>, NPY_CLONGDOUBLE);
459
+
460
+ #undef PYBIND11_NUMPY_SCALAR_IMPL
461
+
462
+ // This table normalizes typenums by mapping NPY_INT_, NPY_LONG, ... to NPY_INT32_, NPY_INT64, ...
463
+ // This is needed to correctly handle situations where multiple typenums map to the same type,
464
+ // e.g. NPY_LONG_ may be equivalent to NPY_INT_ or NPY_LONGLONG_ despite having a different
465
+ // typenum. The normalized typenum should always match the values used in npy_format_descriptor.
466
+ // If you change this code, please review `enum constants` above.
467
+ static constexpr int normalized_dtype_num[npy_api::NPY_VOID_ + 1] = {
468
+ // NPY_BOOL_ =>
469
+ npy_api::NPY_BOOL_,
470
+ // NPY_BYTE_ =>
471
+ npy_api::NPY_BYTE_,
472
+ // NPY_UBYTE_ =>
473
+ npy_api::NPY_UBYTE_,
474
+ // NPY_SHORT_ =>
475
+ npy_api::NPY_INT16_,
476
+ // NPY_USHORT_ =>
477
+ npy_api::NPY_UINT16_,
478
+ // NPY_INT_ =>
479
+ sizeof(int) == sizeof(std::int16_t) ? npy_api::NPY_INT16_
480
+ : sizeof(int) == sizeof(std::int32_t) ? npy_api::NPY_INT32_
481
+ : sizeof(int) == sizeof(std::int64_t) ? npy_api::NPY_INT64_
482
+ : npy_api::NPY_INT_,
483
+ // NPY_UINT_ =>
484
+ sizeof(unsigned int) == sizeof(std::uint16_t) ? npy_api::NPY_UINT16_
485
+ : sizeof(unsigned int) == sizeof(std::uint32_t) ? npy_api::NPY_UINT32_
486
+ : sizeof(unsigned int) == sizeof(std::uint64_t) ? npy_api::NPY_UINT64_
487
+ : npy_api::NPY_UINT_,
488
+ // NPY_LONG_ =>
489
+ sizeof(long) == sizeof(std::int16_t) ? npy_api::NPY_INT16_
490
+ : sizeof(long) == sizeof(std::int32_t) ? npy_api::NPY_INT32_
491
+ : sizeof(long) == sizeof(std::int64_t) ? npy_api::NPY_INT64_
492
+ : npy_api::NPY_LONG_,
493
+ // NPY_ULONG_ =>
494
+ sizeof(unsigned long) == sizeof(std::uint16_t) ? npy_api::NPY_UINT16_
495
+ : sizeof(unsigned long) == sizeof(std::uint32_t) ? npy_api::NPY_UINT32_
496
+ : sizeof(unsigned long) == sizeof(std::uint64_t) ? npy_api::NPY_UINT64_
497
+ : npy_api::NPY_ULONG_,
498
+ // NPY_LONGLONG_ =>
499
+ sizeof(long long) == sizeof(std::int16_t) ? npy_api::NPY_INT16_
500
+ : sizeof(long long) == sizeof(std::int32_t) ? npy_api::NPY_INT32_
501
+ : sizeof(long long) == sizeof(std::int64_t) ? npy_api::NPY_INT64_
502
+ : npy_api::NPY_LONGLONG_,
503
+ // NPY_ULONGLONG_ =>
504
+ sizeof(unsigned long long) == sizeof(std::uint16_t) ? npy_api::NPY_UINT16_
505
+ : sizeof(unsigned long long) == sizeof(std::uint32_t) ? npy_api::NPY_UINT32_
506
+ : sizeof(unsigned long long) == sizeof(std::uint64_t) ? npy_api::NPY_UINT64_
507
+ : npy_api::NPY_ULONGLONG_,
508
+ // NPY_FLOAT_ =>
509
+ npy_api::NPY_FLOAT_,
510
+ // NPY_DOUBLE_ =>
511
+ npy_api::NPY_DOUBLE_,
512
+ // NPY_LONGDOUBLE_ =>
513
+ npy_api::NPY_LONGDOUBLE_,
514
+ // NPY_CFLOAT_ =>
515
+ npy_api::NPY_CFLOAT_,
516
+ // NPY_CDOUBLE_ =>
517
+ npy_api::NPY_CDOUBLE_,
518
+ // NPY_CLONGDOUBLE_ =>
519
+ npy_api::NPY_CLONGDOUBLE_,
520
+ // NPY_OBJECT_ =>
521
+ npy_api::NPY_OBJECT_,
522
+ // NPY_STRING_ =>
523
+ npy_api::NPY_STRING_,
524
+ // NPY_UNICODE_ =>
525
+ npy_api::NPY_UNICODE_,
526
+ // NPY_VOID_ =>
527
+ npy_api::NPY_VOID_,
528
+ };
529
+
387
530
  inline PyArray_Proxy *array_proxy(void *ptr) { return reinterpret_cast<PyArray_Proxy *>(ptr); }
388
531
 
389
532
  inline const PyArray_Proxy *array_proxy(const void *ptr) {
@@ -414,10 +557,6 @@ template <typename T>
414
557
  struct is_std_array : std::false_type {};
415
558
  template <typename T, size_t N>
416
559
  struct is_std_array<std::array<T, N>> : std::true_type {};
417
- template <typename T>
418
- struct is_complex : std::false_type {};
419
- template <typename T>
420
- struct is_complex<std::complex<T>> : std::true_type {};
421
560
 
422
561
  template <typename T>
423
562
  struct array_info_scalar {
@@ -631,8 +770,65 @@ template <typename T, ssize_t Dim>
631
770
  struct type_caster<unchecked_mutable_reference<T, Dim>>
632
771
  : type_caster<unchecked_reference<T, Dim>> {};
633
772
 
773
+ template <typename T>
774
+ struct type_caster<numpy_scalar<T>> {
775
+ using value_type = T;
776
+ using type_info = numpy_scalar_info<T>;
777
+
778
+ PYBIND11_TYPE_CASTER(numpy_scalar<T>, type_info::name);
779
+
780
+ static handle &target_type() {
781
+ static handle tp = npy_api::get().PyArray_TypeObjectFromType_(type_info::typenum);
782
+ return tp;
783
+ }
784
+
785
+ static handle &target_dtype() {
786
+ static handle tp = npy_api::get().PyArray_DescrFromType_(type_info::typenum);
787
+ return tp;
788
+ }
789
+
790
+ bool load(handle src, bool) {
791
+ if (isinstance(src, target_type())) {
792
+ npy_api::get().PyArray_ScalarAsCtype_(src.ptr(), &value.value);
793
+ return true;
794
+ }
795
+ return false;
796
+ }
797
+
798
+ static handle cast(numpy_scalar<T> src, return_value_policy, handle) {
799
+ return npy_api::get().PyArray_Scalar_(&src.value, target_dtype().ptr(), nullptr);
800
+ }
801
+ };
802
+
634
803
  PYBIND11_NAMESPACE_END(detail)
635
804
 
805
+ template <typename T>
806
+ struct numpy_scalar {
807
+ using value_type = T;
808
+
809
+ value_type value;
810
+
811
+ numpy_scalar() = default;
812
+ explicit numpy_scalar(value_type value) : value(value) {}
813
+
814
+ explicit operator value_type() const { return value; }
815
+ numpy_scalar &operator=(value_type value) {
816
+ this->value = value;
817
+ return *this;
818
+ }
819
+
820
+ friend bool operator==(const numpy_scalar &a, const numpy_scalar &b) {
821
+ return a.value == b.value;
822
+ }
823
+
824
+ friend bool operator!=(const numpy_scalar &a, const numpy_scalar &b) { return !(a == b); }
825
+ };
826
+
827
+ template <typename T>
828
+ numpy_scalar<T> make_scalar(T value) {
829
+ return numpy_scalar<T>(value);
830
+ }
831
+
636
832
  class dtype : public object {
637
833
  public:
638
834
  PYBIND11_OBJECT_DEFAULT(dtype, object, detail::npy_api::get().PyArrayDescr_Check_)
@@ -684,22 +880,22 @@ public:
684
880
  return detail::npy_format_descriptor<typename std::remove_cv<T>::type>::dtype();
685
881
  }
686
882
 
883
+ /// Return the type number associated with a C++ type.
884
+ /// This is the constexpr equivalent of `dtype::of<T>().num()`.
885
+ template <typename T>
886
+ static constexpr int num_of() {
887
+ return detail::npy_format_descriptor<typename std::remove_cv<T>::type>::value;
888
+ }
889
+
687
890
  /// Size of the data type in bytes.
688
- #ifdef PYBIND11_NUMPY_1_ONLY
689
- ssize_t itemsize() const { return detail::array_descriptor_proxy(m_ptr)->elsize; }
690
- #else
691
891
  ssize_t itemsize() const {
692
892
  if (detail::npy_api::get().PyArray_RUNTIME_VERSION_ < 0x12) {
693
893
  return detail::array_descriptor1_proxy(m_ptr)->elsize;
694
894
  }
695
895
  return detail::array_descriptor2_proxy(m_ptr)->elsize;
696
896
  }
697
- #endif
698
897
 
699
898
  /// Returns true for structured data types.
700
- #ifdef PYBIND11_NUMPY_1_ONLY
701
- bool has_fields() const { return detail::array_descriptor_proxy(m_ptr)->names != nullptr; }
702
- #else
703
899
  bool has_fields() const {
704
900
  if (detail::npy_api::get().PyArray_RUNTIME_VERSION_ < 0x12) {
705
901
  return detail::array_descriptor1_proxy(m_ptr)->names != nullptr;
@@ -710,7 +906,6 @@ public:
710
906
  }
711
907
  return proxy->names != nullptr;
712
908
  }
713
- #endif
714
909
 
715
910
  /// Single-character code for dtype's kind.
716
911
  /// For example, floating point types are 'f' and integral types are 'i'.
@@ -725,7 +920,9 @@ public:
725
920
  return detail::array_descriptor_proxy(m_ptr)->type;
726
921
  }
727
922
 
728
- /// type number of dtype.
923
+ /// Type number of dtype. Note that different values may be returned for equivalent types,
924
+ /// e.g. even though ``long`` may be equivalent to ``int`` or ``long long``, they still have
925
+ /// different type numbers. Consider using `normalized_num` to avoid this.
729
926
  int num() const {
730
927
  // Note: The signature, `dtype::num` follows the naming of NumPy's public
731
928
  // Python API (i.e., ``dtype.num``), rather than its internal
@@ -733,32 +930,35 @@ public:
733
930
  return detail::array_descriptor_proxy(m_ptr)->type_num;
734
931
  }
735
932
 
933
+ /// Type number of dtype, normalized to match the return value of `num_of` for equivalent
934
+ /// types. This function can be used to write switch statements that correctly handle
935
+ /// equivalent types with different type numbers.
936
+ int normalized_num() const {
937
+ int value = num();
938
+ if (value >= 0 && value <= detail::npy_api::NPY_VOID_) {
939
+ return detail::normalized_dtype_num[value];
940
+ }
941
+ return value;
942
+ }
943
+
736
944
  /// Single character for byteorder
737
945
  char byteorder() const { return detail::array_descriptor_proxy(m_ptr)->byteorder; }
738
946
 
739
- /// Alignment of the data type
740
- #ifdef PYBIND11_NUMPY_1_ONLY
741
- int alignment() const { return detail::array_descriptor_proxy(m_ptr)->alignment; }
742
- #else
947
+ /// Alignment of the data type
743
948
  ssize_t alignment() const {
744
949
  if (detail::npy_api::get().PyArray_RUNTIME_VERSION_ < 0x12) {
745
950
  return detail::array_descriptor1_proxy(m_ptr)->alignment;
746
951
  }
747
952
  return detail::array_descriptor2_proxy(m_ptr)->alignment;
748
953
  }
749
- #endif
750
954
 
751
- /// Flags for the array descriptor
752
- #ifdef PYBIND11_NUMPY_1_ONLY
753
- char flags() const { return detail::array_descriptor_proxy(m_ptr)->flags; }
754
- #else
955
+ /// Flags for the array descriptor
755
956
  std::uint64_t flags() const {
756
957
  if (detail::npy_api::get().PyArray_RUNTIME_VERSION_ < 0x12) {
757
958
  return (unsigned char) detail::array_descriptor1_proxy(m_ptr)->flags;
758
959
  }
759
960
  return detail::array_descriptor2_proxy(m_ptr)->flags;
760
961
  }
761
- #endif
762
962
 
763
963
  private:
764
964
  static object &_dtype_from_pep3118() {
@@ -901,7 +1101,11 @@ public:
901
1101
 
902
1102
  template <typename T>
903
1103
  array(ShapeContainer shape, StridesContainer strides, const T *ptr, handle base = handle())
904
- : array(pybind11::dtype::of<T>(), std::move(shape), std::move(strides), ptr, base) {}
1104
+ : array(pybind11::dtype::of<T>(),
1105
+ std::move(shape),
1106
+ std::move(strides),
1107
+ reinterpret_cast<const void *>(ptr),
1108
+ base) {}
905
1109
 
906
1110
  template <typename T>
907
1111
  array(ShapeContainer shape, const T *ptr, handle base = handle())
@@ -1362,38 +1566,6 @@ struct compare_buffer_info<T, detail::enable_if_t<detail::is_pod_struct<T>::valu
1362
1566
  }
1363
1567
  };
1364
1568
 
1365
- template <typename T, typename = void>
1366
- struct npy_format_descriptor_name;
1367
-
1368
- template <typename T>
1369
- struct npy_format_descriptor_name<T, enable_if_t<std::is_integral<T>::value>> {
1370
- static constexpr auto name = const_name<std::is_same<T, bool>::value>(
1371
- const_name("bool"),
1372
- const_name<std::is_signed<T>::value>("numpy.int", "numpy.uint")
1373
- + const_name<sizeof(T) * 8>());
1374
- };
1375
-
1376
- template <typename T>
1377
- struct npy_format_descriptor_name<T, enable_if_t<std::is_floating_point<T>::value>> {
1378
- static constexpr auto name = const_name < std::is_same<T, float>::value
1379
- || std::is_same<T, const float>::value
1380
- || std::is_same<T, double>::value
1381
- || std::is_same<T, const double>::value
1382
- > (const_name("numpy.float") + const_name<sizeof(T) * 8>(),
1383
- const_name("numpy.longdouble"));
1384
- };
1385
-
1386
- template <typename T>
1387
- struct npy_format_descriptor_name<T, enable_if_t<is_complex<T>::value>> {
1388
- static constexpr auto name = const_name < std::is_same<typename T::value_type, float>::value
1389
- || std::is_same<typename T::value_type, const float>::value
1390
- || std::is_same<typename T::value_type, double>::value
1391
- || std::is_same<typename T::value_type, const double>::value
1392
- > (const_name("numpy.complex")
1393
- + const_name<sizeof(typename T::value_type) * 16>(),
1394
- const_name("numpy.longcomplex"));
1395
- };
1396
-
1397
1569
  template <typename T>
1398
1570
  struct npy_format_descriptor<
1399
1571
  T,
@@ -1424,8 +1596,12 @@ public:
1424
1596
  };
1425
1597
 
1426
1598
  template <typename T>
1427
- struct npy_format_descriptor<T, enable_if_t<is_same_ignoring_cvref<T, PyObject *>::value>> {
1428
- static constexpr auto name = const_name("object");
1599
+ struct npy_format_descriptor<
1600
+ T,
1601
+ enable_if_t<is_same_ignoring_cvref<T, PyObject *>::value
1602
+ || ((std::is_same<T, handle>::value || std::is_same<T, object>::value)
1603
+ && sizeof(T) == sizeof(PyObject *))>> {
1604
+ static constexpr auto name = const_name("numpy.object_");
1429
1605
 
1430
1606
  static constexpr int value = npy_api::NPY_OBJECT_;
1431
1607
 
@@ -1553,7 +1729,9 @@ PYBIND11_NOINLINE void register_structured_dtype(any_container<field_descriptor>
1553
1729
 
1554
1730
  auto tindex = std::type_index(tinfo);
1555
1731
  numpy_internals.registered_dtypes[tindex] = {dtype_ptr, std::move(format_str)};
1556
- get_internals().direct_conversions[tindex].push_back(direct_converter);
1732
+ with_internals([tindex, &direct_converter](internals &internals) {
1733
+ internals.direct_conversions[tindex].push_back(direct_converter);
1734
+ });
1557
1735
  }
1558
1736
 
1559
1737
  template <typename T, typename SFINAE>
@@ -1984,7 +2162,7 @@ private:
1984
2162
  // Pointers to values the function was called with; the vectorized ones set here will start
1985
2163
  // out as array_t<T> pointers, but they will be changed them to T pointers before we make
1986
2164
  // call the wrapped function. Non-vectorized pointers are left as-is.
1987
- std::array<void *, N> params{{&args...}};
2165
+ std::array<void *, N> params{{reinterpret_cast<void *>(&args)...}};
1988
2166
 
1989
2167
  // The array of `buffer_info`s of vectorized arguments:
1990
2168
  std::array<buffer_info, NVectorized> buffers{
@@ -2084,7 +2262,8 @@ vectorize_helper<Func, Return, Args...> vectorize_extractor(const Func &f, Retur
2084
2262
  template <typename T, int Flags>
2085
2263
  struct handle_type_name<array_t<T, Flags>> {
2086
2264
  static constexpr auto name
2087
- = const_name("numpy.ndarray[") + npy_format_descriptor<T>::name + const_name("]");
2265
+ = io_name("typing.Annotated[numpy.typing.ArrayLike, ", "numpy.typing.NDArray[")
2266
+ + npy_format_descriptor<T>::name + const_name("]");
2088
2267
  };
2089
2268
 
2090
2269
  PYBIND11_NAMESPACE_END(detail)