@@ -277,6 +277,12 @@ struct type_info {
277
277
# endif
278
278
#endif
279
279
280
+ #if PY_VERSION_HEX < 0x03090000
281
+ # define PYBIND11_INTERPRETER_STATE_GET _PyInterpreterState_Get
282
+ #else
283
+ # define PYBIND11_INTERPRETER_STATE_GET PyInterpreterState_Get
284
+ #endif
285
+
280
286
#define PYBIND11_INTERNALS_ID \
281
287
" __pybind11_internals_v" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION) \
282
288
PYBIND11_INTERNALS_KIND PYBIND11_COMPILER_TYPE PYBIND11_STDLIB PYBIND11_BUILD_ABI \
@@ -403,7 +409,7 @@ inline void translate_local_exception(std::exception_ptr p) {
403
409
404
410
// / Return a reference to the current `internals` data
405
411
PYBIND11_NOINLINE internals &get_internals () {
406
- auto **&internals_pp = get_internals_pp ();
412
+ internals **&internals_pp = get_internals_pp ();
407
413
if (internals_pp && *internals_pp) {
408
414
return **internals_pp;
409
415
}
@@ -419,11 +425,24 @@ PYBIND11_NOINLINE internals &get_internals() {
419
425
} gil;
420
426
error_scope err_scope;
421
427
422
- PYBIND11_STR_TYPE id (PYBIND11_INTERNALS_ID);
423
- auto builtins = handle (PyEval_GetBuiltins ());
424
- if (builtins.contains (id) && isinstance<capsule>(builtins[id])) {
425
- internals_pp = static_cast <internals **>(capsule (builtins[id]));
428
+ const char *id_cstr = PYBIND11_INTERNALS_ID;
429
+ PYBIND11_STR_TYPE id (id_cstr);
430
+
431
+ dict state_dict
432
+ = reinterpret_borrow<dict>(PyInterpreterState_GetDict (PYBIND11_INTERPRETER_STATE_GET ()));
433
+ if (!state_dict)
434
+ pybind11_fail (" get_internals(): PyInterpreterState_GetDict() failed!" );
435
+
436
+ if (state_dict.contains (id_cstr)) {
437
+ object o = state_dict[id];
438
+ // May fail if 'capsule_obj' is not a capsule, or if it has a different
439
+ // name. We clear the error status below in that case
440
+ internals_pp = static_cast <internals **>(PyCapsule_GetPointer (o.ptr (), id_cstr));
441
+ if (!internals_pp)
442
+ PyErr_Clear ();
443
+ }
426
444
445
+ if (internals_pp) {
427
446
// We loaded builtins through python's builtins, which means that our `error_already_set`
428
447
// and `builtin_exception` may be different local classes than the ones set up in the
429
448
// initial exception translator, below, so add another for our local exception classes.
@@ -435,9 +454,7 @@ PYBIND11_NOINLINE internals &get_internals() {
435
454
(*internals_pp)->registered_exception_translators .push_front (&translate_local_exception);
436
455
#endif
437
456
} else {
438
- if (!internals_pp) {
439
- internals_pp = new internals *();
440
- }
457
+ internals_pp = new internals *();
441
458
auto *&internals_ptr = *internals_pp;
442
459
internals_ptr = new internals ();
443
460
#if defined(WITH_THREAD)
@@ -459,7 +476,7 @@ PYBIND11_NOINLINE internals &get_internals() {
459
476
# endif
460
477
internals_ptr->istate = tstate->interp ;
461
478
#endif
462
- builtins [id] = capsule (internals_pp);
479
+ state_dict [id] = capsule (internals_pp, id_cstr );
463
480
internals_ptr->registered_exception_translators .push_front (&translate_exception);
464
481
internals_ptr->static_property_type = make_static_property_type ();
465
482
internals_ptr->default_metaclass = make_default_metaclass ();
0 commit comments