Skip to content

Commit 51978a8

Browse files
committed
Clean up code for cleaning up type internals
1 parent 35ce747 commit 51978a8

File tree

1 file changed

+29
-21
lines changed

1 file changed

+29
-21
lines changed

include/pybind11/pybind11.h

+29-21
Original file line numberDiff line numberDiff line change
@@ -1021,6 +1021,30 @@ inline dict globals() {
10211021
}
10221022

10231023
PYBIND11_NAMESPACE_BEGIN(detail)
1024+
/// Cleanup the type-info for a pybind11-registered type.
1025+
PYBIND11_NOINLINE inline void cleanup_type_info(detail::type_info *tinfo) {
1026+
auto &internals = get_internals();
1027+
auto tindex = std::type_index(*tinfo->cpptype);
1028+
internals.direct_conversions.erase(tindex);
1029+
1030+
if (tinfo->module_local)
1031+
registered_local_types_cpp().erase(tindex);
1032+
else
1033+
internals.registered_types_cpp.erase(tindex);
1034+
internals.registered_types_py.erase(tinfo->type);
1035+
1036+
// Actually just `std::erase_if`, but that's only available in C++20
1037+
auto &cache = internals.inactive_override_cache;
1038+
for (auto it = cache.begin(), last = cache.end(); it != last; ) {
1039+
if (it->first == (PyObject *) tinfo->type)
1040+
it = cache.erase(it);
1041+
else
1042+
++it;
1043+
}
1044+
1045+
delete tinfo;
1046+
}
1047+
10241048
/// Generic support for creating new Python heap types
10251049
class generic_type : public object {
10261050
template <typename...> friend class class_;
@@ -1037,11 +1061,10 @@ class generic_type : public object {
10371061
"\" is already registered!");
10381062

10391063
m_ptr = make_new_python_type(rec);
1040-
auto type = (PyTypeObject *) m_ptr;
10411064

10421065
/* Register supplemental type information in C++ dict */
10431066
auto *tinfo = new detail::type_info();
1044-
tinfo->type = type;
1067+
tinfo->type = (PyTypeObject *) m_ptr;
10451068
tinfo->cpptype = rec.type;
10461069
tinfo->type_size = rec.type_size;
10471070
tinfo->type_align = rec.type_align;
@@ -1056,31 +1079,16 @@ class generic_type : public object {
10561079

10571080
auto &internals = get_internals();
10581081
auto tindex = std::type_index(*rec.type);
1059-
auto module_local = rec.module_local;
10601082
tinfo->direct_conversions = &internals.direct_conversions[tindex];
1061-
if (module_local)
1083+
if (rec.module_local)
10621084
registered_local_types_cpp()[tindex] = tinfo;
10631085
else
10641086
internals.registered_types_cpp[tindex] = tinfo;
1065-
internals.registered_types_py[type] = { tinfo };
1087+
internals.registered_types_py[(PyTypeObject *) m_ptr] = { tinfo };
10661088

10671089
// Clean up our internals after the Python type object gets garbage collected
1068-
weakref(m_ptr, cpp_function([type, tindex, module_local](handle wr) {
1069-
auto &internals = get_internals();
1070-
internals.direct_conversions.erase(tindex);
1071-
if (module_local)
1072-
registered_local_types_cpp().erase(tindex);
1073-
else
1074-
internals.registered_types_cpp.erase(tindex);
1075-
internals.registered_types_py.erase(type);
1076-
// Actually just `std::erase_if`, but that's only available in C++20
1077-
auto &cache = internals.inactive_override_cache;
1078-
for (auto it = cache.begin(), last = cache.end(); it != last; ) {
1079-
if (it->first == (PyObject *) type)
1080-
it = cache.erase(it);
1081-
else
1082-
++it;
1083-
}
1090+
weakref(m_ptr, cpp_function([tinfo](handle wr) {
1091+
cleanup_type_info(tinfo);
10841092
wr.dec_ref();
10851093
})).release();
10861094

0 commit comments

Comments
 (0)