netgen-mesher 6.2.2504.post11.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 (153) hide show
  1. netgen/__init__.pyi +3 -3
  2. netgen/cmake/NetgenConfig.cmake +10 -9
  3. netgen/config/__init__.pyi +8 -8
  4. netgen/config/config.py +7 -7
  5. netgen/config/config.pyi +8 -8
  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/paje_trace.hpp +9 -8
  17. netgen/include/core/profiler.hpp +5 -5
  18. netgen/include/core/register_archive.hpp +8 -0
  19. netgen/include/core/simd.hpp +69 -1
  20. netgen/include/core/simd_arm64.hpp +205 -1
  21. netgen/include/core/simd_avx.hpp +72 -4
  22. netgen/include/core/simd_avx512.hpp +9 -0
  23. netgen/include/core/simd_generic.hpp +274 -8
  24. netgen/include/core/simd_math.hpp +178 -0
  25. netgen/include/core/simd_sse.hpp +11 -1
  26. netgen/include/core/statushandler.hpp +37 -0
  27. netgen/include/core/table.hpp +3 -2
  28. netgen/include/core/taskmanager.hpp +34 -1
  29. netgen/include/core/utils.hpp +3 -8
  30. netgen/include/include/netgen_version.hpp +4 -4
  31. netgen/include/meshing/basegeom.hpp +1 -4
  32. netgen/include/meshing/global.hpp +0 -17
  33. netgen/include/meshing/hpref_tet.hpp +41 -0
  34. netgen/include/meshing/hprefinement.hpp +2 -0
  35. netgen/include/meshing/meshtype.hpp +2 -1
  36. netgen/include/meshing/msghandler.hpp +9 -6
  37. netgen/include/meshing/topology.hpp +2 -2
  38. netgen/include/nginterface.h +3 -2
  39. netgen/include/occ/occ_utils.hpp +26 -0
  40. netgen/include/occ/occgeom.hpp +8 -0
  41. netgen/include/pybind11/attr.h +40 -8
  42. netgen/include/pybind11/buffer_info.h +14 -14
  43. netgen/include/pybind11/cast.h +553 -29
  44. netgen/include/pybind11/chrono.h +4 -1
  45. netgen/include/pybind11/conduit/README.txt +15 -0
  46. netgen/include/pybind11/conduit/pybind11_conduit_v1.h +116 -0
  47. netgen/include/pybind11/conduit/pybind11_platform_abi_id.h +87 -0
  48. netgen/include/pybind11/conduit/wrap_include_python_h.h +72 -0
  49. netgen/include/pybind11/critical_section.h +56 -0
  50. netgen/include/pybind11/detail/class.h +172 -97
  51. netgen/include/pybind11/detail/common.h +270 -189
  52. netgen/include/pybind11/detail/cpp_conduit.h +75 -0
  53. netgen/include/pybind11/detail/descr.h +55 -0
  54. netgen/include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h +39 -0
  55. netgen/include/pybind11/detail/exception_translation.h +71 -0
  56. netgen/include/pybind11/detail/function_record_pyobject.h +191 -0
  57. netgen/include/pybind11/detail/init.h +113 -9
  58. netgen/include/pybind11/detail/internals.h +479 -344
  59. netgen/include/pybind11/detail/native_enum_data.h +209 -0
  60. netgen/include/pybind11/detail/pybind11_namespace_macros.h +82 -0
  61. netgen/include/pybind11/detail/struct_smart_holder.h +378 -0
  62. netgen/include/pybind11/detail/type_caster_base.h +506 -133
  63. netgen/include/pybind11/detail/using_smart_holder.h +22 -0
  64. netgen/include/pybind11/detail/value_and_holder.h +90 -0
  65. netgen/include/pybind11/eigen/matrix.h +19 -10
  66. netgen/include/pybind11/eigen/tensor.h +15 -11
  67. netgen/include/pybind11/embed.h +50 -46
  68. netgen/include/pybind11/eval.h +11 -6
  69. netgen/include/pybind11/functional.h +58 -49
  70. netgen/include/pybind11/gil.h +34 -82
  71. netgen/include/pybind11/gil_safe_call_once.h +12 -1
  72. netgen/include/pybind11/gil_simple.h +37 -0
  73. netgen/include/pybind11/native_enum.h +67 -0
  74. netgen/include/pybind11/numpy.h +272 -93
  75. netgen/include/pybind11/pybind11.h +947 -265
  76. netgen/include/pybind11/pytypes.h +127 -21
  77. netgen/include/pybind11/stl/filesystem.h +23 -25
  78. netgen/include/pybind11/stl.h +277 -59
  79. netgen/include/pybind11/stl_bind.h +42 -7
  80. netgen/include/pybind11/subinterpreter.h +299 -0
  81. netgen/include/pybind11/trampoline_self_life_support.h +65 -0
  82. netgen/include/pybind11/typing.h +177 -4
  83. netgen/include/pybind11/warnings.h +75 -0
  84. netgen/include/visualization/mvdraw.hpp +48 -12
  85. netgen/include/visualization/vssolution.hpp +3 -1
  86. netgen/lib/libnggui.lib +0 -0
  87. netgen/lib/ngcore.lib +0 -0
  88. netgen/lib/nglib.lib +0 -0
  89. netgen/libnggui.dll +0 -0
  90. netgen/libngguipy.pyd +0 -0
  91. netgen/libngpy/_NgOCC.pyi +224 -139
  92. netgen/libngpy/_csg.pyi +26 -26
  93. netgen/libngpy/_geom2d.pyi +34 -25
  94. netgen/libngpy/_meshing.pyi +262 -111
  95. netgen/libngpy/_stl.pyi +3 -4
  96. netgen/libngpy.pyd +0 -0
  97. netgen/ngcore.dll +0 -0
  98. netgen/nglib.dll +0 -0
  99. netgen/read_gmsh.py +41 -0
  100. netgen/togl.dll +0 -0
  101. netgen/version.py +1 -1
  102. netgen/webgui.py +38 -2
  103. {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/METADATA +2 -1
  104. {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/RECORD +153 -132
  105. pyngcore/pyngcore.cp313-win_amd64.pyd +0 -0
  106. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/boundarycondition.geo +0 -0
  107. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/boxcyl.geo +0 -0
  108. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/circle_on_cube.geo +0 -0
  109. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cone.geo +0 -0
  110. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cube.geo +0 -0
  111. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubeandring.geo +0 -0
  112. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubeandspheres.geo +0 -0
  113. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubemcyl.geo +0 -0
  114. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubemsphere.geo +0 -0
  115. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cylinder.geo +0 -0
  116. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cylsphere.geo +0 -0
  117. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/doc/ng4.pdf +0 -0
  118. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ellipsoid.geo +0 -0
  119. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ellipticcyl.geo +0 -0
  120. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/extrusion.geo +0 -0
  121. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/fichera.geo +0 -0
  122. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/frame.step +0 -0
  123. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/hinge.stl +0 -0
  124. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/lshape3d.geo +0 -0
  125. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/manyholes.geo +0 -0
  126. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/manyholes2.geo +0 -0
  127. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/matrix.geo +0 -0
  128. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ortho.geo +0 -0
  129. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/part1.stl +0 -0
  130. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/period.geo +0 -0
  131. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/py_tutorials/exportNeutral.py +0 -0
  132. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/py_tutorials/mesh.py +0 -0
  133. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/py_tutorials/shaft.geo +0 -0
  134. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/revolution.geo +0 -0
  135. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/screw.step +0 -0
  136. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sculpture.geo +0 -0
  137. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/shaft.geo +0 -0
  138. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/shell.geo +0 -0
  139. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sphere.geo +0 -0
  140. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sphereincube.geo +0 -0
  141. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/square.in2d +0 -0
  142. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/squarecircle.in2d +0 -0
  143. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/squarehole.in2d +0 -0
  144. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/torus.geo +0 -0
  145. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/trafo.geo +0 -0
  146. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twobricks.geo +0 -0
  147. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twocubes.geo +0 -0
  148. {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twocyl.geo +0 -0
  149. {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/AUTHORS +0 -0
  150. {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/LICENSE +0 -0
  151. {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/WHEEL +0 -0
  152. {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/entry_points.txt +0 -0
  153. {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/top_level.txt +0 -0
@@ -9,15 +9,20 @@
9
9
 
10
10
  #pragma once
11
11
 
12
- #include "common.h"
13
-
14
- #if defined(WITH_THREAD) && defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
15
- # include "../gil.h"
16
- #endif
12
+ #include <pybind11/conduit/pybind11_platform_abi_id.h>
13
+ #include <pybind11/gil_simple.h>
14
+ #include <pybind11/pytypes.h>
15
+ #include <pybind11/trampoline_self_life_support.h>
17
16
 
18
- #include "../pytypes.h"
17
+ #include "common.h"
18
+ #include "struct_smart_holder.h"
19
19
 
20
+ #include <atomic>
21
+ #include <cstdint>
20
22
  #include <exception>
23
+ #include <limits>
24
+ #include <mutex>
25
+ #include <thread>
21
26
 
22
27
  /// Tracks the `internals` and `type_info` ABI version independent of the main library version.
23
28
  ///
@@ -34,94 +39,109 @@
34
39
  /// further ABI-incompatible changes may be made before the ABI is officially
35
40
  /// changed to the new version.
36
41
  #ifndef PYBIND11_INTERNALS_VERSION
37
- # if PY_VERSION_HEX >= 0x030C0000 || defined(_MSC_VER)
38
- // Version bump for Python 3.12+, before first 3.12 beta release.
39
- // Version bump for MSVC piggy-backed on PR #4779. See comments there.
40
- # define PYBIND11_INTERNALS_VERSION 5
41
- # else
42
- # define PYBIND11_INTERNALS_VERSION 4
43
- # endif
42
+ # define PYBIND11_INTERNALS_VERSION 11
44
43
  #endif
45
44
 
46
- // This requirement is mainly to reduce the support burden (see PR #4570).
47
- static_assert(PY_VERSION_HEX < 0x030C0000 || PYBIND11_INTERNALS_VERSION >= 5,
48
- "pybind11 ABI version 5 is the minimum for Python 3.12+");
45
+ #if PYBIND11_INTERNALS_VERSION < 11
46
+ # error "PYBIND11_INTERNALS_VERSION 11 is the minimum for all platforms for pybind11v3."
47
+ #endif
49
48
 
50
49
  PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
51
50
 
52
51
  using ExceptionTranslator = void (*)(std::exception_ptr);
53
52
 
53
+ // The old Python Thread Local Storage (TLS) API is deprecated in Python 3.7 in favor of the new
54
+ // Thread Specific Storage (TSS) API.
55
+ // Avoid unnecessary allocation of `Py_tss_t`, since we cannot use
56
+ // `Py_LIMITED_API` anyway.
57
+ #define PYBIND11_TLS_KEY_REF Py_tss_t &
58
+ #if defined(__clang__)
59
+ # define PYBIND11_TLS_KEY_INIT(var) \
60
+ _Pragma("clang diagnostic push") /**/ \
61
+ _Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"") /**/ \
62
+ Py_tss_t var \
63
+ = Py_tss_NEEDS_INIT; \
64
+ _Pragma("clang diagnostic pop")
65
+ #elif defined(__GNUC__) && !defined(__INTEL_COMPILER)
66
+ # define PYBIND11_TLS_KEY_INIT(var) \
67
+ _Pragma("GCC diagnostic push") /**/ \
68
+ _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") /**/ \
69
+ Py_tss_t var \
70
+ = Py_tss_NEEDS_INIT; \
71
+ _Pragma("GCC diagnostic pop")
72
+ #else
73
+ # define PYBIND11_TLS_KEY_INIT(var) Py_tss_t var = Py_tss_NEEDS_INIT;
74
+ #endif
75
+ #define PYBIND11_TLS_KEY_CREATE(var) (PyThread_tss_create(&(var)) == 0)
76
+ #define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get(&(key))
77
+ #define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set(&(key), (value))
78
+ #define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set(&(key), nullptr)
79
+ #define PYBIND11_TLS_FREE(key) PyThread_tss_delete(&(key))
80
+
81
+ /// A smart-pointer-like wrapper around a thread-specific value. get/set of the pointer applies to
82
+ /// the current thread only.
83
+ template <typename T>
84
+ class thread_specific_storage {
85
+ public:
86
+ thread_specific_storage() {
87
+ // NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
88
+ if (!PYBIND11_TLS_KEY_CREATE(key_)) {
89
+ pybind11_fail(
90
+ "thread_specific_storage constructor: could not initialize the TSS key!");
91
+ }
92
+ }
93
+
94
+ ~thread_specific_storage() {
95
+ // This destructor is often called *after* Py_Finalize(). That *SHOULD BE* fine on most
96
+ // platforms. The following details what happens when PyThread_tss_free is called in
97
+ // CPython. PYBIND11_TLS_FREE is PyThread_tss_free on python 3.7+. On older python, it does
98
+ // nothing. PyThread_tss_free calls PyThread_tss_delete and PyMem_RawFree.
99
+ // PyThread_tss_delete just calls TlsFree (on Windows) or pthread_key_delete (on *NIX).
100
+ // Neither of those have anything to do with CPython internals. PyMem_RawFree *requires*
101
+ // that the `key` be allocated with the CPython allocator (as it is by
102
+ // PyThread_tss_create).
103
+ // However, in GraalPy (as of v24.2 or older), TSS is implemented by Java and this call
104
+ // requires a living Python interpreter.
105
+ #ifdef GRAALVM_PYTHON
106
+ if (!Py_IsInitialized() || _Py_IsFinalizing()) {
107
+ return;
108
+ }
109
+ #endif
110
+ PYBIND11_TLS_FREE(key_);
111
+ }
112
+
113
+ thread_specific_storage(thread_specific_storage const &) = delete;
114
+ thread_specific_storage(thread_specific_storage &&) = delete;
115
+ thread_specific_storage &operator=(thread_specific_storage const &) = delete;
116
+ thread_specific_storage &operator=(thread_specific_storage &&) = delete;
117
+
118
+ T *get() const { return reinterpret_cast<T *>(PYBIND11_TLS_GET_VALUE(key_)); }
119
+
120
+ T &operator*() const { return *get(); }
121
+ explicit operator T *() const { return get(); }
122
+ explicit operator bool() const { return get() != nullptr; }
123
+
124
+ void set(T *val) { PYBIND11_TLS_REPLACE_VALUE(key_, reinterpret_cast<void *>(val)); }
125
+ void reset(T *p = nullptr) { set(p); }
126
+ thread_specific_storage &operator=(T *pval) {
127
+ set(pval);
128
+ return *this;
129
+ }
130
+
131
+ private:
132
+ PYBIND11_TLS_KEY_INIT(mutable key_)
133
+ };
134
+
54
135
  PYBIND11_NAMESPACE_BEGIN(detail)
55
136
 
56
- constexpr const char *internals_function_record_capsule_name = "pybind11_function_record_capsule";
137
+ // This does NOT actually exist as a module.
138
+ #define PYBIND11_DUMMY_MODULE_NAME "pybind11_builtins"
57
139
 
58
140
  // Forward declarations
59
141
  inline PyTypeObject *make_static_property_type();
60
142
  inline PyTypeObject *make_default_metaclass();
61
143
  inline PyObject *make_object_base_type(PyTypeObject *metaclass);
62
-
63
- // The old Python Thread Local Storage (TLS) API is deprecated in Python 3.7 in favor of the new
64
- // Thread Specific Storage (TSS) API.
65
- #if PY_VERSION_HEX >= 0x03070000
66
- // Avoid unnecessary allocation of `Py_tss_t`, since we cannot use
67
- // `Py_LIMITED_API` anyway.
68
- # if PYBIND11_INTERNALS_VERSION > 4
69
- # define PYBIND11_TLS_KEY_REF Py_tss_t &
70
- # if defined(__clang__)
71
- # define PYBIND11_TLS_KEY_INIT(var) \
72
- _Pragma("clang diagnostic push") /**/ \
73
- _Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"") /**/ \
74
- Py_tss_t var \
75
- = Py_tss_NEEDS_INIT; \
76
- _Pragma("clang diagnostic pop")
77
- # elif defined(__GNUC__) && !defined(__INTEL_COMPILER)
78
- # define PYBIND11_TLS_KEY_INIT(var) \
79
- _Pragma("GCC diagnostic push") /**/ \
80
- _Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") /**/ \
81
- Py_tss_t var \
82
- = Py_tss_NEEDS_INIT; \
83
- _Pragma("GCC diagnostic pop")
84
- # else
85
- # define PYBIND11_TLS_KEY_INIT(var) Py_tss_t var = Py_tss_NEEDS_INIT;
86
- # endif
87
- # define PYBIND11_TLS_KEY_CREATE(var) (PyThread_tss_create(&(var)) == 0)
88
- # define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get(&(key))
89
- # define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set(&(key), (value))
90
- # define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set(&(key), nullptr)
91
- # define PYBIND11_TLS_FREE(key) PyThread_tss_delete(&(key))
92
- # else
93
- # define PYBIND11_TLS_KEY_REF Py_tss_t *
94
- # define PYBIND11_TLS_KEY_INIT(var) Py_tss_t *var = nullptr;
95
- # define PYBIND11_TLS_KEY_CREATE(var) \
96
- (((var) = PyThread_tss_alloc()) != nullptr && (PyThread_tss_create((var)) == 0))
97
- # define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get((key))
98
- # define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set((key), (value))
99
- # define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set((key), nullptr)
100
- # define PYBIND11_TLS_FREE(key) PyThread_tss_free(key)
101
- # endif
102
- #else
103
- // Usually an int but a long on Cygwin64 with Python 3.x
104
- # define PYBIND11_TLS_KEY_REF decltype(PyThread_create_key())
105
- # define PYBIND11_TLS_KEY_INIT(var) PYBIND11_TLS_KEY_REF var = 0;
106
- # define PYBIND11_TLS_KEY_CREATE(var) (((var) = PyThread_create_key()) != -1)
107
- # define PYBIND11_TLS_GET_VALUE(key) PyThread_get_key_value((key))
108
- # if defined(PYPY_VERSION)
109
- // On CPython < 3.4 and on PyPy, `PyThread_set_key_value` strangely does not set
110
- // the value if it has already been set. Instead, it must first be deleted and
111
- // then set again.
112
- inline void tls_replace_value(PYBIND11_TLS_KEY_REF key, void *value) {
113
- PyThread_delete_key_value(key);
114
- PyThread_set_key_value(key, value);
115
- }
116
- # define PYBIND11_TLS_DELETE_VALUE(key) PyThread_delete_key_value(key)
117
- # define PYBIND11_TLS_REPLACE_VALUE(key, value) \
118
- ::pybind11::detail::tls_replace_value((key), (value))
119
- # else
120
- # define PYBIND11_TLS_DELETE_VALUE(key) PyThread_set_key_value((key), nullptr)
121
- # define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_set_key_value((key), (value))
122
- # endif
123
- # define PYBIND11_TLS_FREE(key) (void) key
124
- #endif
144
+ inline void translate_exception(std::exception_ptr p);
125
145
 
126
146
  // Python loads modules by default with dlopen with the RTLD_LOCAL flag; under libc++ and possibly
127
147
  // other STLs, this means `typeid(A)` from one module won't equal `typeid(A)` from another module
@@ -129,8 +149,7 @@ inline void tls_replace_value(PYBIND11_TLS_KEY_REF key, void *value) {
129
149
  // libstdc++, this doesn't happen: equality and the type_index hash are based on the type name,
130
150
  // which works. If not under a known-good stl, provide our own name-based hash and equality
131
151
  // functions that use the type name.
132
- #if (PYBIND11_INTERNALS_VERSION <= 4 && defined(__GLIBCXX__)) \
133
- || (PYBIND11_INTERNALS_VERSION >= 5 && !defined(_LIBCPP_VERSION))
152
+ #if !defined(_LIBCPP_VERSION)
134
153
  inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; }
135
154
  using type_hash = std::hash<std::type_index>;
136
155
  using type_equal_to = std::equal_to<std::type_index>;
@@ -168,15 +187,65 @@ struct override_hash {
168
187
  }
169
188
  };
170
189
 
190
+ using instance_map = std::unordered_multimap<const void *, instance *>;
191
+
192
+ #ifdef Py_GIL_DISABLED
193
+ // Wrapper around PyMutex to provide BasicLockable semantics
194
+ class pymutex {
195
+ PyMutex mutex;
196
+
197
+ public:
198
+ pymutex() : mutex({}) {}
199
+ void lock() { PyMutex_Lock(&mutex); }
200
+ void unlock() { PyMutex_Unlock(&mutex); }
201
+ };
202
+
203
+ // Instance map shards are used to reduce mutex contention in free-threaded Python.
204
+ struct instance_map_shard {
205
+ instance_map registered_instances;
206
+ pymutex mutex;
207
+ // alignas(64) would be better, but causes compile errors in macOS before 10.14 (see #5200)
208
+ char padding[64 - (sizeof(instance_map) + sizeof(pymutex)) % 64];
209
+ };
210
+
211
+ static_assert(sizeof(instance_map_shard) % 64 == 0,
212
+ "instance_map_shard size is not a multiple of 64 bytes");
213
+
214
+ inline uint64_t round_up_to_next_pow2(uint64_t x) {
215
+ // Round-up to the next power of two.
216
+ // See https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
217
+ x--;
218
+ x |= (x >> 1);
219
+ x |= (x >> 2);
220
+ x |= (x >> 4);
221
+ x |= (x >> 8);
222
+ x |= (x >> 16);
223
+ x |= (x >> 32);
224
+ x++;
225
+ return x;
226
+ }
227
+ #endif
228
+
229
+ class loader_life_support;
230
+
171
231
  /// Internal data structure used to track registered instances and types.
172
232
  /// Whenever binary incompatible changes are made to this structure,
173
233
  /// `PYBIND11_INTERNALS_VERSION` must be incremented.
174
234
  struct internals {
235
+ #ifdef Py_GIL_DISABLED
236
+ pymutex mutex;
237
+ pymutex exception_translator_mutex;
238
+ #endif
175
239
  // std::type_index -> pybind11's type information
176
240
  type_map<type_info *> registered_types_cpp;
177
241
  // PyTypeObject* -> base type_info(s)
178
242
  std::unordered_map<PyTypeObject *, std::vector<type_info *>> registered_types_py;
179
- std::unordered_multimap<const void *, instance *> registered_instances; // void * -> instance*
243
+ #ifdef Py_GIL_DISABLED
244
+ std::unique_ptr<instance_map_shard[]> instance_shards; // void * -> instance*
245
+ size_t instance_shards_mask = 0;
246
+ #else
247
+ instance_map registered_instances; // void * -> instance*
248
+ #endif
180
249
  std::unordered_set<std::pair<const PyObject *, const char *>, override_hash>
181
250
  inactive_override_cache;
182
251
  type_map<std::vector<bool (*)(PyObject *, void *&)>> direct_conversions;
@@ -184,47 +253,65 @@ struct internals {
184
253
  std::forward_list<ExceptionTranslator> registered_exception_translators;
185
254
  std::unordered_map<std::string, void *> shared_data; // Custom data to be shared across
186
255
  // extensions
187
- #if PYBIND11_INTERNALS_VERSION == 4
188
- std::vector<PyObject *> unused_loader_patient_stack_remove_at_v5;
189
- #endif
190
- std::forward_list<std::string> static_strings; // Stores the std::strings backing
191
- // detail::c_str()
192
- PyTypeObject *static_property_type;
193
- PyTypeObject *default_metaclass;
194
- PyObject *instance_base;
195
- #if defined(WITH_THREAD)
256
+ std::forward_list<std::string> static_strings; // Stores the std::strings backing
257
+ // detail::c_str()
258
+ PyTypeObject *static_property_type = nullptr;
259
+ PyTypeObject *default_metaclass = nullptr;
260
+ PyObject *instance_base = nullptr;
196
261
  // Unused if PYBIND11_SIMPLE_GIL_MANAGEMENT is defined:
197
- PYBIND11_TLS_KEY_INIT(tstate)
198
- # if PYBIND11_INTERNALS_VERSION > 4
199
- PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)
200
- # endif // PYBIND11_INTERNALS_VERSION > 4
262
+ thread_specific_storage<PyThreadState> tstate;
263
+ thread_specific_storage<loader_life_support> loader_life_support_tls;
201
264
  // Unused if PYBIND11_SIMPLE_GIL_MANAGEMENT is defined:
202
265
  PyInterpreterState *istate = nullptr;
203
266
 
204
- # if PYBIND11_INTERNALS_VERSION > 4
205
- // Note that we have to use a std::string to allocate memory to ensure a unique address
206
- // We want unique addresses since we use pointer equality to compare function records
207
- std::string function_record_capsule_name = internals_function_record_capsule_name;
208
- # endif
209
-
210
- internals() = default;
267
+ type_map<PyObject *> native_enum_type_map;
268
+
269
+ internals()
270
+ : static_property_type(make_static_property_type()),
271
+ default_metaclass(make_default_metaclass()) {
272
+ PyThreadState *cur_tstate = PyThreadState_Get();
273
+ tstate = cur_tstate;
274
+
275
+ istate = cur_tstate->interp;
276
+ registered_exception_translators.push_front(&translate_exception);
277
+ #ifdef Py_GIL_DISABLED
278
+ // Scale proportional to the number of cores. 2x is a heuristic to reduce contention.
279
+ // Make sure the number isn't unreasonable by limiting it to 16 bits (65K)
280
+ auto num_shards = static_cast<std::uint16_t>(
281
+ std::min<std::size_t>(round_up_to_next_pow2(2 * std::thread::hardware_concurrency()),
282
+ std::numeric_limits<std::uint16_t>::max()));
283
+ if (num_shards == 0) {
284
+ num_shards = 1;
285
+ }
286
+ instance_shards.reset(new instance_map_shard[num_shards]);
287
+ instance_shards_mask = num_shards - 1;
288
+ #endif
289
+ }
211
290
  internals(const internals &other) = delete;
291
+ internals(internals &&other) = delete;
212
292
  internals &operator=(const internals &other) = delete;
213
- ~internals() {
214
- # if PYBIND11_INTERNALS_VERSION > 4
215
- PYBIND11_TLS_FREE(loader_life_support_tls_key);
216
- # endif // PYBIND11_INTERNALS_VERSION > 4
217
-
218
- // This destructor is called *after* Py_Finalize() in finalize_interpreter().
219
- // That *SHOULD BE* fine. The following details what happens when PyThread_tss_free is
220
- // called. PYBIND11_TLS_FREE is PyThread_tss_free on python 3.7+. On older python, it does
221
- // nothing. PyThread_tss_free calls PyThread_tss_delete and PyMem_RawFree.
222
- // PyThread_tss_delete just calls TlsFree (on Windows) or pthread_key_delete (on *NIX).
223
- // Neither of those have anything to do with CPython internals. PyMem_RawFree *requires*
224
- // that the `tstate` be allocated with the CPython allocator.
225
- PYBIND11_TLS_FREE(tstate);
226
- }
227
- #endif
293
+ internals &operator=(internals &&other) = delete;
294
+ ~internals() = default;
295
+ };
296
+
297
+ // the internals struct (above) is shared between all the modules. local_internals are only
298
+ // for a single module. Any changes made to internals may require an update to
299
+ // PYBIND11_INTERNALS_VERSION, breaking backwards compatibility. local_internals is, by design,
300
+ // restricted to a single module. Whether a module has local internals or not should not
301
+ // impact any other modules, because the only things accessing the local internals is the
302
+ // module that contains them.
303
+ struct local_internals {
304
+ type_map<type_info *> registered_types_cpp;
305
+ std::forward_list<ExceptionTranslator> registered_exception_translators;
306
+ PyTypeObject *function_record_py_type = nullptr;
307
+ };
308
+
309
+ enum class holder_enum_t : uint8_t {
310
+ undefined,
311
+ std_unique_ptr, // Default, lacking interop with std::shared_ptr.
312
+ std_shared_ptr, // Lacking interop with std::unique_ptr.
313
+ smart_holder, // Full std::unique_ptr / std::shared_ptr interop.
314
+ custom_holder,
228
315
  };
229
316
 
230
317
  /// Additional type information which does not fit into the PyTypeObject.
@@ -236,12 +323,19 @@ struct type_info {
236
323
  void *(*operator_new)(size_t);
237
324
  void (*init_instance)(instance *, const void *);
238
325
  void (*dealloc)(value_and_holder &v_h);
326
+
327
+ // Cross-DSO-safe function pointers, to sidestep cross-DSO RTTI issues
328
+ // on platforms like macOS (see PR #5728 for details):
329
+ memory::get_guarded_delete_fn get_memory_guarded_delete = memory::get_guarded_delete;
330
+ get_trampoline_self_life_support_fn get_trampoline_self_life_support = nullptr;
331
+
239
332
  std::vector<PyObject *(*) (PyObject *, PyTypeObject *)> implicit_conversions;
240
333
  std::vector<std::pair<const std::type_info *, void *(*) (void *)>> implicit_casts;
241
334
  std::vector<bool (*)(PyObject *, void *&)> *direct_conversions;
242
335
  buffer_info *(*get_buffer)(PyObject *, void *) = nullptr;
243
336
  void *get_buffer_data = nullptr;
244
337
  void *(*module_local_load)(PyObject *, const type_info *) = nullptr;
338
+ holder_enum_t holder_enum_v = holder_enum_t::undefined;
245
339
  /* A simple type never occurs as a (direct or indirect) parent
246
340
  * of a class that makes use of multiple inheritance.
247
341
  * A type can be simple even if it has non-simple ancestors as long as it has no descendants.
@@ -249,89 +343,34 @@ struct type_info {
249
343
  bool simple_type : 1;
250
344
  /* True if there is no multiple inheritance in this type's inheritance tree */
251
345
  bool simple_ancestors : 1;
252
- /* for base vs derived holder_type checks */
253
- bool default_holder : 1;
254
346
  /* true if this is a type registered with py::module_local */
255
347
  bool module_local : 1;
256
348
  };
257
349
 
258
- /// On MSVC, debug and release builds are not ABI-compatible!
259
- #if defined(_MSC_VER) && defined(_DEBUG)
260
- # define PYBIND11_BUILD_TYPE "_debug"
261
- #else
262
- # define PYBIND11_BUILD_TYPE ""
263
- #endif
264
-
265
- /// Let's assume that different compilers are ABI-incompatible.
266
- /// A user can manually set this string if they know their
267
- /// compiler is compatible.
268
- #ifndef PYBIND11_COMPILER_TYPE
269
- # if defined(_MSC_VER)
270
- # define PYBIND11_COMPILER_TYPE "_msvc"
271
- # elif defined(__INTEL_COMPILER)
272
- # define PYBIND11_COMPILER_TYPE "_icc"
273
- # elif defined(__clang__)
274
- # define PYBIND11_COMPILER_TYPE "_clang"
275
- # elif defined(__PGI)
276
- # define PYBIND11_COMPILER_TYPE "_pgi"
277
- # elif defined(__MINGW32__)
278
- # define PYBIND11_COMPILER_TYPE "_mingw"
279
- # elif defined(__CYGWIN__)
280
- # define PYBIND11_COMPILER_TYPE "_gcc_cygwin"
281
- # elif defined(__GNUC__)
282
- # define PYBIND11_COMPILER_TYPE "_gcc"
283
- # else
284
- # define PYBIND11_COMPILER_TYPE "_unknown"
285
- # endif
286
- #endif
287
-
288
- /// Also standard libs
289
- #ifndef PYBIND11_STDLIB
290
- # if defined(_LIBCPP_VERSION)
291
- # define PYBIND11_STDLIB "_libcpp"
292
- # elif defined(__GLIBCXX__) || defined(__GLIBCPP__)
293
- # define PYBIND11_STDLIB "_libstdcpp"
294
- # else
295
- # define PYBIND11_STDLIB ""
296
- # endif
297
- #endif
298
-
299
- /// On Linux/OSX, changes in __GXX_ABI_VERSION__ indicate ABI incompatibility.
300
- #ifndef PYBIND11_BUILD_ABI
301
- # if defined(__GXX_ABI_VERSION)
302
- # define PYBIND11_BUILD_ABI "_cxxabi" PYBIND11_TOSTRING(__GXX_ABI_VERSION)
303
- # else
304
- # define PYBIND11_BUILD_ABI ""
305
- # endif
306
- #endif
307
-
308
- #ifndef PYBIND11_INTERNALS_KIND
309
- # if defined(WITH_THREAD)
310
- # define PYBIND11_INTERNALS_KIND ""
311
- # else
312
- # define PYBIND11_INTERNALS_KIND "_without_thread"
313
- # endif
314
- #endif
315
-
316
350
  #define PYBIND11_INTERNALS_ID \
317
351
  "__pybind11_internals_v" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) \
318
- PYBIND11_INTERNALS_KIND PYBIND11_COMPILER_TYPE PYBIND11_STDLIB PYBIND11_BUILD_ABI \
319
- PYBIND11_BUILD_TYPE "__"
352
+ PYBIND11_COMPILER_TYPE_LEADING_UNDERSCORE PYBIND11_PLATFORM_ABI_ID "__"
320
353
 
321
354
  #define PYBIND11_MODULE_LOCAL_ID \
322
355
  "__pybind11_module_local_v" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) \
323
- PYBIND11_INTERNALS_KIND PYBIND11_COMPILER_TYPE PYBIND11_STDLIB PYBIND11_BUILD_ABI \
324
- PYBIND11_BUILD_TYPE "__"
325
-
326
- /// Each module locally stores a pointer to the `internals` data. The data
327
- /// itself is shared among modules with the same `PYBIND11_INTERNALS_ID`.
328
- inline internals **&get_internals_pp() {
329
- static internals **internals_pp = nullptr;
330
- return internals_pp;
356
+ PYBIND11_COMPILER_TYPE_LEADING_UNDERSCORE PYBIND11_PLATFORM_ABI_ID "__"
357
+
358
+ inline PyThreadState *get_thread_state_unchecked() {
359
+ #if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)
360
+ return PyThreadState_GET();
361
+ #elif PY_VERSION_HEX < 0x030D0000
362
+ return _PyThreadState_UncheckedGet();
363
+ #else
364
+ return PyThreadState_GetUnchecked();
365
+ #endif
331
366
  }
332
367
 
333
- // forward decl
334
- inline void translate_exception(std::exception_ptr);
368
+ /// We use this counter to figure out if there are or have been multiple subinterpreters active at
369
+ /// any point. This must never decrease while any interpreter may be running in any thread!
370
+ inline std::atomic<int> &get_num_interpreters_seen() {
371
+ static std::atomic<int> counter(0);
372
+ return counter;
373
+ }
335
374
 
336
375
  template <class T,
337
376
  enable_if_t<std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>
@@ -439,7 +478,7 @@ inline void translate_local_exception(std::exception_ptr p) {
439
478
 
440
479
  inline object get_python_state_dict() {
441
480
  object state_dict;
442
- #if PYBIND11_INTERNALS_VERSION <= 4 || PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)
481
+ #if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)
443
482
  state_dict = reinterpret_borrow<object>(PyEval_GetBuiltins());
444
483
  #else
445
484
  # if PY_VERSION_HEX < 0x03090000
@@ -458,145 +497,252 @@ inline object get_python_state_dict() {
458
497
  return state_dict;
459
498
  }
460
499
 
461
- inline object get_internals_obj_from_state_dict(handle state_dict) {
462
- return reinterpret_borrow<object>(dict_getitemstring(state_dict.ptr(), PYBIND11_INTERNALS_ID));
463
- }
464
-
465
- inline internals **get_internals_pp_from_capsule(handle obj) {
466
- void *raw_ptr = PyCapsule_GetPointer(obj.ptr(), /*name=*/nullptr);
467
- if (raw_ptr == nullptr) {
468
- raise_from(PyExc_SystemError, "pybind11::detail::get_internals_pp_from_capsule() FAILED");
469
- throw error_already_set();
500
+ template <typename InternalsType>
501
+ class internals_pp_manager {
502
+ public:
503
+ using on_fetch_function = void(InternalsType *);
504
+ internals_pp_manager(char const *id, on_fetch_function *on_fetch)
505
+ : holder_id_(id), on_fetch_(on_fetch) {}
506
+
507
+ /// Get the current pointer-to-pointer, allocating it if it does not already exist. May
508
+ /// acquire the GIL. Will never return nullptr.
509
+ std::unique_ptr<InternalsType> *get_pp() {
510
+ #ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
511
+ if (get_num_interpreters_seen() > 1) {
512
+ // Whenever the interpreter changes on the current thread we need to invalidate the
513
+ // internals_pp so that it can be pulled from the interpreter's state dict. That is
514
+ // slow, so we use the current PyThreadState to check if it is necessary.
515
+ auto *tstate = get_thread_state_unchecked();
516
+ if (!tstate || tstate->interp != last_istate_.get()) {
517
+ gil_scoped_acquire_simple gil;
518
+ if (!tstate) {
519
+ tstate = get_thread_state_unchecked();
520
+ }
521
+ last_istate_ = tstate->interp;
522
+ internals_tls_p_ = get_or_create_pp_in_state_dict();
523
+ }
524
+ return internals_tls_p_.get();
525
+ }
526
+ #endif
527
+ if (!internals_singleton_pp_) {
528
+ gil_scoped_acquire_simple gil;
529
+ internals_singleton_pp_ = get_or_create_pp_in_state_dict();
530
+ }
531
+ return internals_singleton_pp_;
470
532
  }
471
- return static_cast<internals **>(raw_ptr);
472
- }
473
533
 
474
- /// Return a reference to the current `internals` data
475
- PYBIND11_NOINLINE internals &get_internals() {
476
- auto **&internals_pp = get_internals_pp();
477
- if (internals_pp && *internals_pp) {
478
- return **internals_pp;
534
+ /// Drop all the references we're currently holding.
535
+ void unref() {
536
+ #ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
537
+ if (get_num_interpreters_seen() > 1) {
538
+ last_istate_.reset();
539
+ internals_tls_p_.reset();
540
+ return;
541
+ }
542
+ #endif
543
+ internals_singleton_pp_ = nullptr;
479
544
  }
480
545
 
481
- #if defined(WITH_THREAD)
482
- # if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
483
- gil_scoped_acquire gil;
484
- # else
485
- // Ensure that the GIL is held since we will need to make Python calls.
486
- // Cannot use py::gil_scoped_acquire here since that constructor calls get_internals.
487
- struct gil_scoped_acquire_local {
488
- gil_scoped_acquire_local() : state(PyGILState_Ensure()) {}
489
- gil_scoped_acquire_local(const gil_scoped_acquire_local &) = delete;
490
- gil_scoped_acquire_local &operator=(const gil_scoped_acquire_local &) = delete;
491
- ~gil_scoped_acquire_local() { PyGILState_Release(state); }
492
- const PyGILState_STATE state;
493
- } gil;
494
- # endif
546
+ void destroy() {
547
+ #ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
548
+ if (get_num_interpreters_seen() > 1) {
549
+ auto *tstate = get_thread_state_unchecked();
550
+ // this could be called without an active interpreter, just use what was cached
551
+ if (!tstate || tstate->interp == last_istate_.get()) {
552
+ auto tpp = internals_tls_p_.get();
553
+ if (tpp) {
554
+ delete tpp;
555
+ }
556
+ }
557
+ unref();
558
+ return;
559
+ }
495
560
  #endif
496
- error_scope err_scope;
497
-
498
- dict state_dict = get_python_state_dict();
499
- if (object internals_obj = get_internals_obj_from_state_dict(state_dict)) {
500
- internals_pp = get_internals_pp_from_capsule(internals_obj);
561
+ delete internals_singleton_pp_;
562
+ unref();
501
563
  }
502
- if (internals_pp && *internals_pp) {
503
- // We loaded the internals through `state_dict`, which means that our `error_already_set`
504
- // and `builtin_exception` may be different local classes than the ones set up in the
505
- // initial exception translator, below, so add another for our local exception classes.
506
- //
507
- // libstdc++ doesn't require this (types there are identified only by name)
508
- // libc++ with CPython doesn't require this (types are explicitly exported)
509
- // libc++ with PyPy still need it, awaiting further investigation
510
- #if !defined(__GLIBCXX__)
511
- (*internals_pp)->registered_exception_translators.push_front(&translate_local_exception);
512
- #endif
513
- } else {
514
- if (!internals_pp) {
515
- internals_pp = new internals *();
516
- }
517
- auto *&internals_ptr = *internals_pp;
518
- internals_ptr = new internals();
519
- #if defined(WITH_THREAD)
520
564
 
521
- PyThreadState *tstate = PyThreadState_Get();
522
- // NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
523
- if (!PYBIND11_TLS_KEY_CREATE(internals_ptr->tstate)) {
524
- pybind11_fail("get_internals: could not successfully initialize the tstate TSS key!");
565
+ private:
566
+ std::unique_ptr<InternalsType> *get_or_create_pp_in_state_dict() {
567
+ error_scope err_scope;
568
+ dict state_dict = get_python_state_dict();
569
+ auto internals_obj
570
+ = reinterpret_steal<object>(dict_getitemstringref(state_dict.ptr(), holder_id_));
571
+ std::unique_ptr<InternalsType> *pp = nullptr;
572
+ if (internals_obj) {
573
+ void *raw_ptr = PyCapsule_GetPointer(internals_obj.ptr(), /*name=*/nullptr);
574
+ if (!raw_ptr) {
575
+ raise_from(PyExc_SystemError,
576
+ "pybind11::detail::internals_pp_manager::get_pp_from_dict() FAILED");
577
+ throw error_already_set();
578
+ }
579
+ pp = reinterpret_cast<std::unique_ptr<InternalsType> *>(raw_ptr);
580
+ if (on_fetch_ && pp) {
581
+ on_fetch_(pp->get());
582
+ }
583
+ } else {
584
+ pp = new std::unique_ptr<InternalsType>;
585
+ // NOLINTNEXTLINE(bugprone-casting-through-void)
586
+ state_dict[holder_id_] = capsule(reinterpret_cast<void *>(pp));
525
587
  }
526
- PYBIND11_TLS_REPLACE_VALUE(internals_ptr->tstate, tstate);
588
+ return pp;
589
+ }
527
590
 
528
- # if PYBIND11_INTERNALS_VERSION > 4
529
- // NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
530
- if (!PYBIND11_TLS_KEY_CREATE(internals_ptr->loader_life_support_tls_key)) {
531
- pybind11_fail("get_internals: could not successfully initialize the "
532
- "loader_life_support TSS key!");
533
- }
534
- # endif
535
- internals_ptr->istate = tstate->interp;
591
+ char const *holder_id_ = nullptr;
592
+ on_fetch_function *on_fetch_ = nullptr;
593
+ #ifdef PYBIND11_HAS_SUBINTERPRETER_SUPPORT
594
+ thread_specific_storage<PyInterpreterState> last_istate_;
595
+ thread_specific_storage<std::unique_ptr<InternalsType>> internals_tls_p_;
536
596
  #endif
537
- state_dict[PYBIND11_INTERNALS_ID] = capsule(internals_pp);
538
- internals_ptr->registered_exception_translators.push_front(&translate_exception);
539
- internals_ptr->static_property_type = make_static_property_type();
540
- internals_ptr->default_metaclass = make_default_metaclass();
541
- internals_ptr->instance_base = make_object_base_type(internals_ptr->default_metaclass);
542
- }
543
- return **internals_pp;
544
- }
597
+ std::unique_ptr<InternalsType> *internals_singleton_pp_;
598
+ };
545
599
 
546
- // the internals struct (above) is shared between all the modules. local_internals are only
547
- // for a single module. Any changes made to internals may require an update to
548
- // PYBIND11_INTERNALS_VERSION, breaking backwards compatibility. local_internals is, by design,
549
- // restricted to a single module. Whether a module has local internals or not should not
550
- // impact any other modules, because the only things accessing the local internals is the
551
- // module that contains them.
552
- struct local_internals {
553
- type_map<type_info *> registered_types_cpp;
554
- std::forward_list<ExceptionTranslator> registered_exception_translators;
555
- #if defined(WITH_THREAD) && PYBIND11_INTERNALS_VERSION == 4
556
-
557
- // For ABI compatibility, we can't store the loader_life_support TLS key in
558
- // the `internals` struct directly. Instead, we store it in `shared_data` and
559
- // cache a copy in `local_internals`. If we allocated a separate TLS key for
560
- // each instance of `local_internals`, we could end up allocating hundreds of
561
- // TLS keys if hundreds of different pybind11 modules are loaded (which is a
562
- // plausible number).
563
- PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)
564
-
565
- // Holds the shared TLS key for the loader_life_support stack.
566
- struct shared_loader_life_support_data {
567
- PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)
568
- shared_loader_life_support_data() {
569
- // NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
570
- if (!PYBIND11_TLS_KEY_CREATE(loader_life_support_tls_key)) {
571
- pybind11_fail("local_internals: could not successfully initialize the "
572
- "loader_life_support TLS key!");
600
+ // If We loaded the internals through `state_dict`, our `error_already_set`
601
+ // and `builtin_exception` may be different local classes than the ones set up in the
602
+ // initial exception translator, below, so add another for our local exception classes.
603
+ //
604
+ // libstdc++ doesn't require this (types there are identified only by name)
605
+ // libc++ with CPython doesn't require this (types are explicitly exported)
606
+ // libc++ with PyPy still need it, awaiting further investigation
607
+ #if !defined(__GLIBCXX__)
608
+ inline void check_internals_local_exception_translator(internals *internals_ptr) {
609
+ if (internals_ptr) {
610
+ for (auto et : internals_ptr->registered_exception_translators) {
611
+ if (et == &translate_local_exception) {
612
+ return;
573
613
  }
574
614
  }
575
- // We can't help but leak the TLS key, because Python never unloads extension modules.
576
- };
615
+ internals_ptr->registered_exception_translators.push_front(&translate_local_exception);
616
+ }
617
+ }
618
+ #endif
577
619
 
578
- local_internals() {
579
- auto &internals = get_internals();
580
- // Get or create the `loader_life_support_stack_key`.
581
- auto &ptr = internals.shared_data["_life_support"];
582
- if (!ptr) {
583
- ptr = new shared_loader_life_support_data;
620
+ inline internals_pp_manager<internals> &get_internals_pp_manager() {
621
+ #if defined(__GLIBCXX__)
622
+ # define ON_FETCH_FN nullptr
623
+ #else
624
+ # define ON_FETCH_FN &check_internals_local_exception_translator
625
+ #endif
626
+ static internals_pp_manager<internals> internals_pp_manager(PYBIND11_INTERNALS_ID,
627
+ ON_FETCH_FN);
628
+ #undef ON_FETCH_FN
629
+ return internals_pp_manager;
630
+ }
631
+
632
+ /// Return a reference to the current `internals` data
633
+ PYBIND11_NOINLINE internals &get_internals() {
634
+ auto &ppmgr = get_internals_pp_manager();
635
+ auto &internals_ptr = *ppmgr.get_pp();
636
+ if (!internals_ptr) {
637
+ // Slow path, something needs fetched from the state dict or created
638
+ gil_scoped_acquire_simple gil;
639
+ error_scope err_scope;
640
+ internals_ptr.reset(new internals());
641
+
642
+ if (!internals_ptr->instance_base) {
643
+ // This calls get_internals, so cannot be called from within the internals constructor
644
+ // called above because internals_ptr must be set before get_internals is called again
645
+ internals_ptr->instance_base = make_object_base_type(internals_ptr->default_metaclass);
584
646
  }
585
- loader_life_support_tls_key
586
- = static_cast<shared_loader_life_support_data *>(ptr)->loader_life_support_tls_key;
587
647
  }
588
- #endif // defined(WITH_THREAD) && PYBIND11_INTERNALS_VERSION == 4
589
- };
648
+ return *internals_ptr;
649
+ }
650
+
651
+ inline internals_pp_manager<local_internals> &get_local_internals_pp_manager() {
652
+ // Use the address of this static itself as part of the key, so that the value is uniquely tied
653
+ // to where the module is loaded in memory
654
+ static const std::string this_module_idstr
655
+ = PYBIND11_MODULE_LOCAL_ID
656
+ + std::to_string(reinterpret_cast<uintptr_t>(&this_module_idstr));
657
+ static internals_pp_manager<local_internals> local_internals_pp_manager(
658
+ this_module_idstr.c_str(), nullptr);
659
+ return local_internals_pp_manager;
660
+ }
590
661
 
591
662
  /// Works like `get_internals`, but for things which are locally registered.
592
663
  inline local_internals &get_local_internals() {
593
- // Current static can be created in the interpreter finalization routine. If the later will be
594
- // destroyed in another static variable destructor, creation of this static there will cause
595
- // static deinitialization fiasco. In order to avoid it we avoid destruction of the
596
- // local_internals static. One can read more about the problem and current solution here:
597
- // https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables
598
- static auto *locals = new local_internals();
599
- return *locals;
664
+ auto &ppmgr = get_local_internals_pp_manager();
665
+ auto &internals_ptr = *ppmgr.get_pp();
666
+ if (!internals_ptr) {
667
+ internals_ptr.reset(new local_internals());
668
+ }
669
+ return *internals_ptr;
670
+ }
671
+
672
+ #ifdef Py_GIL_DISABLED
673
+ # define PYBIND11_LOCK_INTERNALS(internals) std::unique_lock<pymutex> lock((internals).mutex)
674
+ #else
675
+ # define PYBIND11_LOCK_INTERNALS(internals)
676
+ #endif
677
+
678
+ template <typename F>
679
+ inline auto with_internals(const F &cb) -> decltype(cb(get_internals())) {
680
+ auto &internals = get_internals();
681
+ PYBIND11_LOCK_INTERNALS(internals);
682
+ return cb(internals);
683
+ }
684
+
685
+ template <typename F>
686
+ inline auto with_exception_translators(const F &cb)
687
+ -> decltype(cb(get_internals().registered_exception_translators,
688
+ get_local_internals().registered_exception_translators)) {
689
+ auto &internals = get_internals();
690
+ #ifdef Py_GIL_DISABLED
691
+ std::unique_lock<pymutex> lock((internals).exception_translator_mutex);
692
+ #endif
693
+ auto &local_internals = get_local_internals();
694
+ return cb(internals.registered_exception_translators,
695
+ local_internals.registered_exception_translators);
696
+ }
697
+
698
+ inline std::uint64_t mix64(std::uint64_t z) {
699
+ // David Stafford's variant 13 of the MurmurHash3 finalizer popularized
700
+ // by the SplitMix PRNG.
701
+ // https://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html
702
+ z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
703
+ z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
704
+ return z ^ (z >> 31);
705
+ }
706
+
707
+ template <typename F>
708
+ inline auto with_instance_map(const void *ptr, const F &cb)
709
+ -> decltype(cb(std::declval<instance_map &>())) {
710
+ auto &internals = get_internals();
711
+
712
+ #ifdef Py_GIL_DISABLED
713
+ // Hash address to compute shard, but ignore low bits. We'd like allocations
714
+ // from the same thread/core to map to the same shard and allocations from
715
+ // other threads/cores to map to other shards. Using the high bits is a good
716
+ // heuristic because memory allocators often have a per-thread
717
+ // arena/superblock/segment from which smaller allocations are served.
718
+ auto addr = reinterpret_cast<std::uintptr_t>(ptr);
719
+ auto hash = mix64(static_cast<std::uint64_t>(addr >> 20));
720
+ auto idx = static_cast<size_t>(hash & internals.instance_shards_mask);
721
+
722
+ auto &shard = internals.instance_shards[idx];
723
+ std::unique_lock<pymutex> lock(shard.mutex);
724
+ return cb(shard.registered_instances);
725
+ #else
726
+ (void) ptr;
727
+ return cb(internals.registered_instances);
728
+ #endif
729
+ }
730
+
731
+ // Returns the number of registered instances for testing purposes. The result may not be
732
+ // consistent if other threads are registering or unregistering instances concurrently.
733
+ inline size_t num_registered_instances() {
734
+ auto &internals = get_internals();
735
+ #ifdef Py_GIL_DISABLED
736
+ size_t count = 0;
737
+ for (size_t i = 0; i <= internals.instance_shards_mask; ++i) {
738
+ auto &shard = internals.instance_shards[i];
739
+ std::unique_lock<pymutex> lock(shard.mutex);
740
+ count += shard.registered_instances.size();
741
+ }
742
+ return count;
743
+ #else
744
+ return internals.registered_instances.size();
745
+ #endif
600
746
  }
601
747
 
602
748
  /// Constructs a std::string with the given arguments, stores it in `internals`, and returns its
@@ -605,45 +751,33 @@ inline local_internals &get_local_internals() {
605
751
  /// suitable for c-style strings needed by Python internals (such as PyTypeObject's tp_name).
606
752
  template <typename... Args>
607
753
  const char *c_str(Args &&...args) {
608
- auto &strings = get_internals().static_strings;
754
+ // GCC 4.8 doesn't like parameter unpack within lambda capture, so use
755
+ // PYBIND11_LOCK_INTERNALS.
756
+ auto &internals = get_internals();
757
+ PYBIND11_LOCK_INTERNALS(internals);
758
+ auto &strings = internals.static_strings;
609
759
  strings.emplace_front(std::forward<Args>(args)...);
610
760
  return strings.front().c_str();
611
761
  }
612
762
 
613
- inline const char *get_function_record_capsule_name() {
614
- #if PYBIND11_INTERNALS_VERSION > 4
615
- return get_internals().function_record_capsule_name.c_str();
616
- #else
617
- return nullptr;
618
- #endif
619
- }
620
-
621
- // Determine whether or not the following capsule contains a pybind11 function record.
622
- // Note that we use `internals` to make sure that only ABI compatible records are touched.
623
- //
624
- // This check is currently used in two places:
625
- // - An important optimization in functional.h to avoid overhead in C++ -> Python -> C++
626
- // - The sibling feature of cpp_function to allow overloads
627
- inline bool is_function_record_capsule(const capsule &cap) {
628
- // Pointer equality as we rely on internals() to ensure unique pointers
629
- return cap.name() == get_function_record_capsule_name();
630
- }
631
-
632
763
  PYBIND11_NAMESPACE_END(detail)
633
764
 
634
765
  /// Returns a named pointer that is shared among all extension modules (using the same
635
766
  /// pybind11 version) running in the current interpreter. Names starting with underscores
636
767
  /// are reserved for internal usage. Returns `nullptr` if no matching entry was found.
637
768
  PYBIND11_NOINLINE void *get_shared_data(const std::string &name) {
638
- auto &internals = detail::get_internals();
639
- auto it = internals.shared_data.find(name);
640
- return it != internals.shared_data.end() ? it->second : nullptr;
769
+ return detail::with_internals([&](detail::internals &internals) {
770
+ auto it = internals.shared_data.find(name);
771
+ return it != internals.shared_data.end() ? it->second : nullptr;
772
+ });
641
773
  }
642
774
 
643
775
  /// Set the shared data that can be later recovered by `get_shared_data()`.
644
776
  PYBIND11_NOINLINE void *set_shared_data(const std::string &name, void *data) {
645
- detail::get_internals().shared_data[name] = data;
646
- return data;
777
+ return detail::with_internals([&](detail::internals &internals) {
778
+ internals.shared_data[name] = data;
779
+ return data;
780
+ });
647
781
  }
648
782
 
649
783
  /// Returns a typed reference to a shared data entry (by using `get_shared_data()`) if
@@ -651,14 +785,15 @@ PYBIND11_NOINLINE void *set_shared_data(const std::string &name, void *data) {
651
785
  /// added to the shared data under the given name and a reference to it is returned.
652
786
  template <typename T>
653
787
  T &get_or_create_shared_data(const std::string &name) {
654
- auto &internals = detail::get_internals();
655
- auto it = internals.shared_data.find(name);
656
- T *ptr = (T *) (it != internals.shared_data.end() ? it->second : nullptr);
657
- if (!ptr) {
658
- ptr = new T();
659
- internals.shared_data[name] = ptr;
660
- }
661
- return *ptr;
788
+ return *detail::with_internals([&](detail::internals &internals) {
789
+ auto it = internals.shared_data.find(name);
790
+ T *ptr = (T *) (it != internals.shared_data.end() ? it->second : nullptr);
791
+ if (!ptr) {
792
+ ptr = new T();
793
+ internals.shared_data[name] = ptr;
794
+ }
795
+ return ptr;
796
+ });
662
797
  }
663
798
 
664
799
  PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)