Skip to content

Commit 7903850

Browse files
committed
Merge branch 'master' into sh_merge_master
2 parents eba3d61 + b7c3300 commit 7903850

File tree

6 files changed

+32
-108
lines changed

6 files changed

+32
-108
lines changed

include/pybind11/detail/internals.h

Lines changed: 30 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,9 @@
4444
# endif
4545
#endif
4646

47-
// This requirement is mainly to reduce the support burden (see PR #4570).
48-
static_assert(PY_VERSION_HEX < 0x030C0000 || PYBIND11_INTERNALS_VERSION >= 5,
49-
"pybind11 ABI version 5 is the minimum for Python 3.12+");
50-
static_assert(PYBIND11_INTERNALS_VERSION >= 4,
51-
"pybind11 ABI version 4 is the minimum for all platforms.");
47+
#if PYBIND11_INTERNALS_VERSION < 6
48+
# error "PYBIND11_INTERNALS_VERSION 6 is the minimum for all platforms for pybind11v3."
49+
#endif
5250

5351
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
5452

@@ -67,49 +65,37 @@ inline PyObject *make_object_base_type(PyTypeObject *metaclass);
6765
// Thread Specific Storage (TSS) API.
6866
// Avoid unnecessary allocation of `Py_tss_t`, since we cannot use
6967
// `Py_LIMITED_API` anyway.
70-
#if PYBIND11_INTERNALS_VERSION > 4
71-
# define PYBIND11_TLS_KEY_REF Py_tss_t &
72-
# if defined(__clang__)
73-
# define PYBIND11_TLS_KEY_INIT(var) \
74-
_Pragma("clang diagnostic push") /**/ \
75-
_Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"") /**/ \
76-
Py_tss_t var \
77-
= Py_tss_NEEDS_INIT; \
78-
_Pragma("clang diagnostic pop")
79-
# elif defined(__GNUC__) && !defined(__INTEL_COMPILER)
80-
# define PYBIND11_TLS_KEY_INIT(var) \
81-
_Pragma("GCC diagnostic push") /**/ \
82-
_Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") /**/ \
83-
Py_tss_t var \
84-
= Py_tss_NEEDS_INIT; \
85-
_Pragma("GCC diagnostic pop")
86-
# else
87-
# define PYBIND11_TLS_KEY_INIT(var) Py_tss_t var = Py_tss_NEEDS_INIT;
88-
# endif
89-
# define PYBIND11_TLS_KEY_CREATE(var) (PyThread_tss_create(&(var)) == 0)
90-
# define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get(&(key))
91-
# define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set(&(key), (value))
92-
# define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set(&(key), nullptr)
93-
# define PYBIND11_TLS_FREE(key) PyThread_tss_delete(&(key))
68+
#define PYBIND11_TLS_KEY_REF Py_tss_t &
69+
#if defined(__clang__)
70+
# define PYBIND11_TLS_KEY_INIT(var) \
71+
_Pragma("clang diagnostic push") /**/ \
72+
_Pragma("clang diagnostic ignored \"-Wmissing-field-initializers\"") /**/ \
73+
Py_tss_t var \
74+
= Py_tss_NEEDS_INIT; \
75+
_Pragma("clang diagnostic pop")
76+
#elif defined(__GNUC__) && !defined(__INTEL_COMPILER)
77+
# define PYBIND11_TLS_KEY_INIT(var) \
78+
_Pragma("GCC diagnostic push") /**/ \
79+
_Pragma("GCC diagnostic ignored \"-Wmissing-field-initializers\"") /**/ \
80+
Py_tss_t var \
81+
= Py_tss_NEEDS_INIT; \
82+
_Pragma("GCC diagnostic pop")
9483
#else
95-
# define PYBIND11_TLS_KEY_REF Py_tss_t *
96-
# define PYBIND11_TLS_KEY_INIT(var) Py_tss_t *var = nullptr;
97-
# define PYBIND11_TLS_KEY_CREATE(var) \
98-
(((var) = PyThread_tss_alloc()) != nullptr && (PyThread_tss_create((var)) == 0))
99-
# define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get((key))
100-
# define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set((key), (value))
101-
# define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set((key), nullptr)
102-
# define PYBIND11_TLS_FREE(key) PyThread_tss_free(key)
84+
# define PYBIND11_TLS_KEY_INIT(var) Py_tss_t var = Py_tss_NEEDS_INIT;
10385
#endif
86+
#define PYBIND11_TLS_KEY_CREATE(var) (PyThread_tss_create(&(var)) == 0)
87+
#define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get(&(key))
88+
#define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set(&(key), (value))
89+
#define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set(&(key), nullptr)
90+
#define PYBIND11_TLS_FREE(key) PyThread_tss_delete(&(key))
10491

10592
// Python loads modules by default with dlopen with the RTLD_LOCAL flag; under libc++ and possibly
10693
// other STLs, this means `typeid(A)` from one module won't equal `typeid(A)` from another module
10794
// even when `A` is the same, non-hidden-visibility type (e.g. from a common include). Under
10895
// libstdc++, this doesn't happen: equality and the type_index hash are based on the type name,
10996
// which works. If not under a known-good stl, provide our own name-based hash and equality
11097
// functions that use the type name.
111-
#if (PYBIND11_INTERNALS_VERSION <= 4 && defined(__GLIBCXX__)) \
112-
|| (PYBIND11_INTERNALS_VERSION >= 5 && !defined(_LIBCPP_VERSION))
98+
#if !defined(_LIBCPP_VERSION)
11399
inline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; }
114100
using type_hash = std::hash<std::type_index>;
115101
using type_equal_to = std::equal_to<std::type_index>;
@@ -197,35 +183,26 @@ struct internals {
197183
std::forward_list<ExceptionTranslator> registered_exception_translators;
198184
std::unordered_map<std::string, void *> shared_data; // Custom data to be shared across
199185
// extensions
200-
#if PYBIND11_INTERNALS_VERSION == 4
201-
std::vector<PyObject *> unused_loader_patient_stack_remove_at_v5;
202-
#endif
203-
std::forward_list<std::string> static_strings; // Stores the std::strings backing
204-
// detail::c_str()
186+
std::forward_list<std::string> static_strings; // Stores the std::strings backing
187+
// detail::c_str()
205188
PyTypeObject *static_property_type;
206189
PyTypeObject *default_metaclass;
207190
PyObject *instance_base;
208191
// Unused if PYBIND11_SIMPLE_GIL_MANAGEMENT is defined:
209192
PYBIND11_TLS_KEY_INIT(tstate)
210-
#if PYBIND11_INTERNALS_VERSION > 4
211193
PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)
212-
#endif // PYBIND11_INTERNALS_VERSION > 4
213194
// Unused if PYBIND11_SIMPLE_GIL_MANAGEMENT is defined:
214195
PyInterpreterState *istate = nullptr;
215196

216-
#if PYBIND11_INTERNALS_VERSION > 4
217197
// Note that we have to use a std::string to allocate memory to ensure a unique address
218198
// We want unique addresses since we use pointer equality to compare function records
219199
std::string function_record_capsule_name = internals_function_record_capsule_name;
220-
#endif
221200

222201
internals() = default;
223202
internals(const internals &other) = delete;
224203
internals &operator=(const internals &other) = delete;
225204
~internals() {
226-
#if PYBIND11_INTERNALS_VERSION > 4
227205
PYBIND11_TLS_FREE(loader_life_support_tls_key);
228-
#endif // PYBIND11_INTERNALS_VERSION > 4
229206

230207
// This destructor is called *after* Py_Finalize() in finalize_interpreter().
231208
// That *SHOULD BE* fine. The following details what happens when PyThread_tss_free is
@@ -414,7 +391,7 @@ inline void translate_local_exception(std::exception_ptr p) {
414391

415392
inline object get_python_state_dict() {
416393
object state_dict;
417-
#if PYBIND11_INTERNALS_VERSION <= 4 || defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)
394+
#if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)
418395
state_dict = reinterpret_borrow<object>(PyEval_GetBuiltins());
419396
#else
420397
# if PY_VERSION_HEX < 0x03090000
@@ -512,13 +489,12 @@ PYBIND11_NOINLINE internals &get_internals() {
512489
}
513490
PYBIND11_TLS_REPLACE_VALUE(internals_ptr->tstate, tstate);
514491

515-
#if PYBIND11_INTERNALS_VERSION > 4
516492
// NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
517493
if (!PYBIND11_TLS_KEY_CREATE(internals_ptr->loader_life_support_tls_key)) {
518494
pybind11_fail("get_internals: could not successfully initialize the "
519495
"loader_life_support TSS key!");
520496
}
521-
#endif
497+
522498
internals_ptr->istate = tstate->interp;
523499
state_dict[PYBIND11_INTERNALS_ID] = capsule(reinterpret_cast<void *>(internals_pp));
524500
internals_ptr->registered_exception_translators.push_front(&translate_exception);
@@ -548,40 +524,6 @@ PYBIND11_NOINLINE internals &get_internals() {
548524
struct local_internals {
549525
type_map<type_info *> registered_types_cpp;
550526
std::forward_list<ExceptionTranslator> registered_exception_translators;
551-
#if PYBIND11_INTERNALS_VERSION == 4
552-
553-
// For ABI compatibility, we can't store the loader_life_support TLS key in
554-
// the `internals` struct directly. Instead, we store it in `shared_data` and
555-
// cache a copy in `local_internals`. If we allocated a separate TLS key for
556-
// each instance of `local_internals`, we could end up allocating hundreds of
557-
// TLS keys if hundreds of different pybind11 modules are loaded (which is a
558-
// plausible number).
559-
PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)
560-
561-
// Holds the shared TLS key for the loader_life_support stack.
562-
struct shared_loader_life_support_data {
563-
PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)
564-
shared_loader_life_support_data() {
565-
// NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
566-
if (!PYBIND11_TLS_KEY_CREATE(loader_life_support_tls_key)) {
567-
pybind11_fail("local_internals: could not successfully initialize the "
568-
"loader_life_support TLS key!");
569-
}
570-
}
571-
// We can't help but leak the TLS key, because Python never unloads extension modules.
572-
};
573-
574-
local_internals() {
575-
auto &internals = get_internals();
576-
// Get or create the `loader_life_support_stack_key`.
577-
auto &ptr = internals.shared_data["_life_support"];
578-
if (!ptr) {
579-
ptr = new shared_loader_life_support_data;
580-
}
581-
loader_life_support_tls_key
582-
= static_cast<shared_loader_life_support_data *>(ptr)->loader_life_support_tls_key;
583-
}
584-
#endif // PYBIND11_INTERNALS_VERSION == 4
585527
};
586528

587529
/// Works like `get_internals`, but for things which are locally registered.
@@ -688,7 +630,7 @@ const char *c_str(Args &&...args) {
688630

689631
inline const char *get_function_record_capsule_name() {
690632
// On GraalPy, pointer equality of the names is currently not guaranteed
691-
#if PYBIND11_INTERNALS_VERSION > 4 && !defined(GRAALVM_PYTHON)
633+
#if !defined(GRAALVM_PYTHON)
692634
return get_internals().function_record_capsule_name.c_str();
693635
#else
694636
return nullptr;

include/pybind11/detail/type_caster_base.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,7 @@ class loader_life_support {
4747

4848
// Store stack pointer in thread-local storage.
4949
static PYBIND11_TLS_KEY_REF get_stack_tls_key() {
50-
#if PYBIND11_INTERNALS_VERSION == 4
51-
return get_local_internals().loader_life_support_tls_key;
52-
#else
5350
return get_internals().loader_life_support_tls_key;
54-
#endif
5551
}
5652
static loader_life_support *get_stack_top() {
5753
return static_cast<loader_life_support *>(PYBIND11_TLS_GET_VALUE(get_stack_tls_key()));

tests/test_callbacks.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -269,12 +269,7 @@ TEST_SUBMODULE(callbacks, m) {
269269
rec_capsule.set_name(rec_capsule_name);
270270
m.add_object("custom_function", PyCFunction_New(custom_def, rec_capsule.ptr()));
271271

272-
// This test requires a new ABI version to pass
273-
#if PYBIND11_INTERNALS_VERSION > 4 && !defined(GRAALVM_PYTHON)
274272
// rec_capsule with nullptr name
275273
py::capsule rec_capsule2(std::malloc(1), [](void *data) { std::free(data); });
276274
m.add_object("custom_function2", PyCFunction_New(custom_def, rec_capsule2.ptr()));
277-
#else
278-
m.add_object("custom_function2", py::none());
279-
#endif
280275
}

tests/test_callbacks.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,7 @@ def test_custom_func():
217217
assert m.roundtrip(m.custom_function)(4) == 36
218218

219219

220-
@pytest.mark.skipif(
221-
m.custom_function2 is None, reason="Current PYBIND11_INTERNALS_VERSION too low"
222-
)
220+
@pytest.mark.skipif("env.GRAALPY", reason="TODO debug segfault")
223221
def test_custom_func2():
224222
assert m.custom_function2(3) == 27
225223
assert m.roundtrip(m.custom_function2)(3) == 27

tests/test_unnamed_namespace_a.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ TEST_SUBMODULE(unnamed_namespace_a, m) {
1010
} else {
1111
m.attr("unnamed_namespace_a_any_struct") = py::none();
1212
}
13-
m.attr("PYBIND11_INTERNALS_VERSION") = PYBIND11_INTERNALS_VERSION;
1413
m.attr("defined_WIN32_or__WIN32") =
1514
#if defined(WIN32) || defined(_WIN32)
1615
true;

tests/test_unnamed_namespace_a.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,7 @@
55
from pybind11_tests import unnamed_namespace_a as m
66
from pybind11_tests import unnamed_namespace_b as mb
77

8-
XFAIL_CONDITION = (
9-
"(m.PYBIND11_INTERNALS_VERSION <= 4 and (m.defined___clang__ or not m.defined___GLIBCXX__))"
10-
" or "
11-
"(m.PYBIND11_INTERNALS_VERSION >= 5 and not m.defined_WIN32_or__WIN32"
12-
" and "
13-
"(m.defined___clang__ or m.defined__LIBCPP_VERSION))"
14-
)
8+
XFAIL_CONDITION = "not m.defined_WIN32_or__WIN32 and (m.defined___clang__ or m.defined__LIBCPP_VERSION)"
159
XFAIL_REASON = "Known issues: https://github.com/pybind/pybind11/pull/4319"
1610

1711

0 commit comments

Comments
 (0)