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.
- netgen/__init__.pyi +3 -3
- netgen/cmake/NetgenConfig.cmake +10 -9
- netgen/config/__init__.pyi +8 -8
- netgen/config/config.py +7 -7
- netgen/config/config.pyi +8 -8
- netgen/include/core/archive.hpp +18 -3
- netgen/include/core/array.hpp +20 -4
- netgen/include/core/autodiff.hpp +9 -11
- netgen/include/core/autodiffdiff.hpp +0 -2
- netgen/include/core/bitarray.hpp +1 -1
- netgen/include/core/flags.hpp +1 -1
- netgen/include/core/hashtable.hpp +1 -1
- netgen/include/core/memtracer.hpp +7 -7
- netgen/include/core/ngcore.hpp +5 -0
- netgen/include/core/ngcore_api.hpp +11 -0
- netgen/include/core/paje_trace.hpp +9 -8
- netgen/include/core/profiler.hpp +5 -5
- netgen/include/core/register_archive.hpp +8 -0
- netgen/include/core/simd.hpp +69 -1
- netgen/include/core/simd_arm64.hpp +205 -1
- netgen/include/core/simd_avx.hpp +72 -4
- netgen/include/core/simd_avx512.hpp +9 -0
- netgen/include/core/simd_generic.hpp +274 -8
- netgen/include/core/simd_math.hpp +178 -0
- netgen/include/core/simd_sse.hpp +11 -1
- netgen/include/core/statushandler.hpp +37 -0
- netgen/include/core/table.hpp +3 -2
- netgen/include/core/taskmanager.hpp +34 -1
- netgen/include/core/utils.hpp +3 -8
- netgen/include/include/netgen_version.hpp +4 -4
- netgen/include/meshing/basegeom.hpp +1 -4
- netgen/include/meshing/global.hpp +0 -17
- netgen/include/meshing/hpref_tet.hpp +41 -0
- netgen/include/meshing/hprefinement.hpp +2 -0
- netgen/include/meshing/meshtype.hpp +2 -1
- netgen/include/meshing/msghandler.hpp +9 -6
- netgen/include/meshing/topology.hpp +2 -2
- netgen/include/nginterface.h +3 -2
- netgen/include/occ/occ_utils.hpp +26 -0
- netgen/include/occ/occgeom.hpp +8 -0
- netgen/include/pybind11/attr.h +40 -8
- netgen/include/pybind11/buffer_info.h +14 -14
- netgen/include/pybind11/cast.h +553 -29
- netgen/include/pybind11/chrono.h +4 -1
- netgen/include/pybind11/conduit/README.txt +15 -0
- netgen/include/pybind11/conduit/pybind11_conduit_v1.h +116 -0
- netgen/include/pybind11/conduit/pybind11_platform_abi_id.h +87 -0
- netgen/include/pybind11/conduit/wrap_include_python_h.h +72 -0
- netgen/include/pybind11/critical_section.h +56 -0
- netgen/include/pybind11/detail/class.h +172 -97
- netgen/include/pybind11/detail/common.h +270 -189
- netgen/include/pybind11/detail/cpp_conduit.h +75 -0
- netgen/include/pybind11/detail/descr.h +55 -0
- netgen/include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h +39 -0
- netgen/include/pybind11/detail/exception_translation.h +71 -0
- netgen/include/pybind11/detail/function_record_pyobject.h +191 -0
- netgen/include/pybind11/detail/init.h +113 -9
- netgen/include/pybind11/detail/internals.h +479 -344
- netgen/include/pybind11/detail/native_enum_data.h +209 -0
- netgen/include/pybind11/detail/pybind11_namespace_macros.h +82 -0
- netgen/include/pybind11/detail/struct_smart_holder.h +378 -0
- netgen/include/pybind11/detail/type_caster_base.h +506 -133
- netgen/include/pybind11/detail/using_smart_holder.h +22 -0
- netgen/include/pybind11/detail/value_and_holder.h +90 -0
- netgen/include/pybind11/eigen/matrix.h +19 -10
- netgen/include/pybind11/eigen/tensor.h +15 -11
- netgen/include/pybind11/embed.h +50 -46
- netgen/include/pybind11/eval.h +11 -6
- netgen/include/pybind11/functional.h +58 -49
- netgen/include/pybind11/gil.h +34 -82
- netgen/include/pybind11/gil_safe_call_once.h +12 -1
- netgen/include/pybind11/gil_simple.h +37 -0
- netgen/include/pybind11/native_enum.h +67 -0
- netgen/include/pybind11/numpy.h +272 -93
- netgen/include/pybind11/pybind11.h +947 -265
- netgen/include/pybind11/pytypes.h +127 -21
- netgen/include/pybind11/stl/filesystem.h +23 -25
- netgen/include/pybind11/stl.h +277 -59
- netgen/include/pybind11/stl_bind.h +42 -7
- netgen/include/pybind11/subinterpreter.h +299 -0
- netgen/include/pybind11/trampoline_self_life_support.h +65 -0
- netgen/include/pybind11/typing.h +177 -4
- netgen/include/pybind11/warnings.h +75 -0
- netgen/include/visualization/mvdraw.hpp +48 -12
- netgen/include/visualization/vssolution.hpp +3 -1
- netgen/lib/libnggui.lib +0 -0
- netgen/lib/ngcore.lib +0 -0
- netgen/lib/nglib.lib +0 -0
- netgen/libnggui.dll +0 -0
- netgen/libngguipy.pyd +0 -0
- netgen/libngpy/_NgOCC.pyi +224 -139
- netgen/libngpy/_csg.pyi +26 -26
- netgen/libngpy/_geom2d.pyi +34 -25
- netgen/libngpy/_meshing.pyi +262 -111
- netgen/libngpy/_stl.pyi +3 -4
- netgen/libngpy.pyd +0 -0
- netgen/ngcore.dll +0 -0
- netgen/nglib.dll +0 -0
- netgen/read_gmsh.py +41 -0
- netgen/togl.dll +0 -0
- netgen/version.py +1 -1
- netgen/webgui.py +38 -2
- {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/METADATA +2 -1
- {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/RECORD +153 -132
- pyngcore/pyngcore.cp313-win_amd64.pyd +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/boundarycondition.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/boxcyl.geo +0 -0
- {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
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cone.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cube.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubeandring.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubeandspheres.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubemcyl.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cubemsphere.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cylinder.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/cylsphere.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/doc/ng4.pdf +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ellipsoid.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ellipticcyl.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/extrusion.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/fichera.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/frame.step +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/hinge.stl +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/lshape3d.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/manyholes.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/manyholes2.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/matrix.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/ortho.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/part1.stl +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/period.geo +0 -0
- {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
- {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
- {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
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/revolution.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/screw.step +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sculpture.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/shaft.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/shell.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sphere.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/sphereincube.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/square.in2d +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/squarecircle.in2d +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/squarehole.in2d +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/torus.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/trafo.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twobricks.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twocubes.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.data → netgen_mesher-6.2.2506.post48.dev0.data}/data/share/netgen/twocyl.geo +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/AUTHORS +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/LICENSE +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/WHEEL +0 -0
- {netgen_mesher-6.2.2504.post11.dev0.dist-info → netgen_mesher-6.2.2506.post48.dev0.dist-info}/entry_points.txt +0 -0
- {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
|
|
13
|
-
|
|
14
|
-
#
|
|
15
|
-
#
|
|
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 "
|
|
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
|
-
#
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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
|
-
|
|
198
|
-
|
|
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
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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
|
-
|
|
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
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
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
|
-
|
|
334
|
-
|
|
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
|
|
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
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
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
|
-
///
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
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
|
-
|
|
482
|
-
#
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
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
|
-
|
|
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
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
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
|
-
|
|
588
|
+
return pp;
|
|
589
|
+
}
|
|
527
590
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
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
|
-
|
|
538
|
-
|
|
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
|
-
//
|
|
547
|
-
//
|
|
548
|
-
//
|
|
549
|
-
//
|
|
550
|
-
//
|
|
551
|
-
//
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
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
|
-
|
|
576
|
-
}
|
|
615
|
+
internals_ptr->registered_exception_translators.push_front(&translate_local_exception);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
#endif
|
|
577
619
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
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
|
-
|
|
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
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
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
|
-
|
|
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
|
-
|
|
639
|
-
|
|
640
|
-
|
|
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::
|
|
646
|
-
|
|
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
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
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)
|