From a6250c64f562770cd7a06355055a64d74ff7edad Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 26 Jan 2021 12:51:45 -0800 Subject: [PATCH 1/2] Factoring out find_registered_python_instance() from type_caster_generic::cast. --- include/pybind11/cast.h | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 0caccdb25b..1c239b266f 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -207,6 +207,19 @@ PYBIND11_NOINLINE inline handle get_type_handle(const std::type_info &tp, bool t return handle(type_info ? ((PyObject *) type_info->type) : nullptr); } +// Searches all_type_info for a registered instance, i.e. moving up the inheritance hierarchy. +PYBIND11_NOINLINE inline handle find_registered_python_instance(void *src, + const detail::type_info *tinfo) { + auto it_instances = get_internals().registered_instances.equal_range(src); + for (auto it_i = it_instances.first; it_i != it_instances.second; ++it_i) { + for (auto instance_type : detail::all_type_info(Py_TYPE(it_i->second))) { + if (instance_type && same_type(*instance_type->cpptype, *tinfo->cpptype)) + return handle((PyObject *) it_i->second).inc_ref(); + } + } + return handle(); +} + struct value_and_holder { instance *inst = nullptr; size_t index = 0u; @@ -508,13 +521,9 @@ class type_caster_generic { if (src == nullptr) return none().release(); - auto it_instances = get_internals().registered_instances.equal_range(src); - for (auto it_i = it_instances.first; it_i != it_instances.second; ++it_i) { - for (auto instance_type : detail::all_type_info(Py_TYPE(it_i->second))) { - if (instance_type && same_type(*instance_type->cpptype, *tinfo->cpptype)) - return handle((PyObject *) it_i->second).inc_ref(); - } - } + handle registered_inst = find_registered_python_instance(src, tinfo); + if (registered_inst) + return registered_inst; auto inst = reinterpret_steal(make_new_instance(tinfo->type)); auto wrapper = reinterpret_cast(inst.ptr()); From 5bc3dd72f66ae2e891fbaf92a71c4a3c4b7e48ce Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 26 Jan 2021 20:42:00 -0800 Subject: [PATCH 2/2] Addressing review comments. --- include/pybind11/cast.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 1c239b266f..4f9f5d7f78 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -207,7 +207,7 @@ PYBIND11_NOINLINE inline handle get_type_handle(const std::type_info &tp, bool t return handle(type_info ? ((PyObject *) type_info->type) : nullptr); } -// Searches all_type_info for a registered instance, i.e. moving up the inheritance hierarchy. +// Searches the inheritance graph for a registered Python instance, using all_type_info(). PYBIND11_NOINLINE inline handle find_registered_python_instance(void *src, const detail::type_info *tinfo) { auto it_instances = get_internals().registered_instances.equal_range(src); @@ -521,8 +521,7 @@ class type_caster_generic { if (src == nullptr) return none().release(); - handle registered_inst = find_registered_python_instance(src, tinfo); - if (registered_inst) + if (handle registered_inst = find_registered_python_instance(src, tinfo)) return registered_inst; auto inst = reinterpret_steal(make_new_instance(tinfo->type));