@@ -193,6 +193,44 @@ extern "C" inline PyObject *pybind11_meta_call(PyObject *type, PyObject *args, P
193
193
return self;
194
194
}
195
195
196
+ // / Cleanup the type-info for a pybind11-registered type.
197
+ extern " C" inline void pybind11_meta_dealloc (PyObject *obj) {
198
+ auto *type = (PyTypeObject *) obj;
199
+ auto &internals = get_internals ();
200
+
201
+ auto found_type = internals.registered_types_py .find (type);
202
+ if (found_type != internals.registered_types_py .end ()) {
203
+ auto &all_tinfo = found_type->second ;
204
+ for (auto *tinfo : all_tinfo) {
205
+ if (tinfo->type != type)
206
+ continue ;
207
+
208
+ auto tindex = std::type_index (*tinfo->cpptype );
209
+ internals.direct_conversions .erase (tindex);
210
+
211
+ if (tinfo->module_local )
212
+ registered_local_types_cpp ().erase (tindex);
213
+ else
214
+ internals.registered_types_cpp .erase (tindex);
215
+ internals.registered_types_py .erase (tinfo->type );
216
+
217
+ // Actually just `std::erase_if`, but that's only available in C++20
218
+ auto &cache = internals.inactive_override_cache ;
219
+ for (auto it = cache.begin (), last = cache.end (); it != last; ) {
220
+ if (it->first == (PyObject *) tinfo->type )
221
+ it = cache.erase (it);
222
+ else
223
+ ++it;
224
+ }
225
+
226
+ delete tinfo;
227
+ break ;
228
+ }
229
+ }
230
+
231
+ PyType_Type.tp_dealloc (obj);
232
+ }
233
+
196
234
/* * This metaclass is assigned by default to all pybind11 types and is required in order
197
235
for static properties to function correctly. Users may override this using `py::metaclass`.
198
236
Return value: New reference. */
@@ -225,6 +263,8 @@ inline PyTypeObject* make_default_metaclass() {
225
263
type->tp_getattro = pybind11_meta_getattro;
226
264
#endif
227
265
266
+ type->tp_dealloc = pybind11_meta_dealloc;
267
+
228
268
if (PyType_Ready (type) < 0 )
229
269
pybind11_fail (" make_default_metaclass(): failure in PyType_Ready()!" );
230
270
0 commit comments