@@ -309,11 +309,17 @@ struct internals {
309309 internals &operator =(const internals &other) = delete ;
310310 internals &operator =(internals &&other) = delete ;
311311 ~internals () {
312- Py_XDECREF (static_property_type);
313- static_property_type = nullptr ;
314-
315- Py_XDECREF (default_metaclass);
316- default_metaclass = nullptr ;
312+ // Normally this destructor runs during interpreter finalization and it may DECREF things.
313+ // In odd finalization scenarios it might end up running after the interpreter has
314+ // completely shut down, In that case, we should not decref these objects because pymalloc
315+ // is gone.
316+ if (Py_IsInitialized ()) {
317+ Py_XDECREF (static_property_type);
318+ static_property_type = nullptr ;
319+
320+ Py_XDECREF (default_metaclass);
321+ default_metaclass = nullptr ;
322+ }
317323 }
318324};
319325
@@ -333,8 +339,14 @@ struct local_internals {
333339 PyTypeObject *function_record_py_type = nullptr ;
334340
335341 ~local_internals () {
336- Py_XDECREF (function_record_py_type);
337- function_record_py_type = nullptr ;
342+ // Normally this destructor runs during interpreter finalization and it may DECREF things.
343+ // In odd finalization scenarios it might end up running after the interpreter has
344+ // completely shut down, In that case, we should not decref these objects because pymalloc
345+ // is gone.
346+ if (Py_IsInitialized ()) {
347+ Py_XDECREF (function_record_py_type);
348+ function_record_py_type = nullptr ;
349+ }
338350 }
339351};
340352
@@ -717,8 +729,9 @@ class internals_pp_manager {
717729 pp->reset ();
718730 }
719731 // Because the unique_ptr is still pointed to by the pp_manager in this and possibly other
720- // modules, we cannot free the unique_ptr itself until after the interpreter has shut down.
721- // If this interpreter was not created/owned by pybind11 then this unique_ptr is leaked.
732+ // modules, we cannot delete the unique_ptr itself until after the interpreter has shut
733+ // down. If this interpreter was not created/owned by pybind11 then the unique_ptr itself
734+ // (but not its contents) is leaked.
722735 }
723736
724737 std::unique_ptr<InternalsType> *get_or_create_pp_in_state_dict () {
0 commit comments