From aed215c4d49532a1b162ea11cd96f77bd3540fed Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Sat, 22 Feb 2025 11:12:12 -0800 Subject: [PATCH] [smart_holder] Remove obsolete `detail::type_info::default_holder` member. (#5541) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * git merge --squash purge_internals_versions_4_5 * Remove PYBIND11_HAS_INTERNALS_WITH_SMART_HOLDER_SUPPORT, set PYBIND11_INTERNALS_VERSION 7 * Remove all uses of PYBIND11_SMART_HOLDER_ENABLED under include/pybind11 * Remove obsolete PYBIND11_ACTUALLY_USING_SMART_HOLDER_AS_DEFAULT macro. * Remove PYBIND11_SMART_HOLDER_ENABLED in ubench/holder_comparison.cpp * Remove all uses of PYBIND11_SMART_HOLDER_ENABLED under tests/ * Remove `#define PYBIND11_SMART_HOLDER_ENABLED` * Remove all uses of PYBIND11_SMART_HOLDER_TYPE_CASTERS under tests/ * Remove all uses of PYBIND11_TYPE_CASTER_BASE_HOLDER under tests/ * Add missing `#include ` Example error message (🐍 3.11 • ubuntu-latest • x64, GNU 13.3.0): ``` include/pybind11/detail/value_and_holder.h:56:52: error: ‘uint8_t’ is not a member of ‘std’; did you mean ‘wint_t’? 56 | inst->nonsimple.status[index] &= (std::uint8_t) ~instance::status_holder_constructed; | ^~~~~~~ ``` * Remove type_info::default_holder member. DOES NOT BUILD * Remove some obsolete default_holder code and #ifdef out uses of typeinfo->default_holder. BUILDS BUT 2 TESTS ARE FAILING. * Replace `default_holder` with `holder_enum_v == holder_enum_t::std_unique_ptr` Intentionally not changing error messages, because this would result in a significantly bigger change. * Change PYBIND11_INTERNALS_VERSION to 106: It will be changed to 7 in a follow-on PR that actually changes the internals. * Change PYBIND11_INTERNALS_VERSION to 7 (because this PR actually changes the internals). --- include/pybind11/attr.h | 16 ++++++++-------- include/pybind11/cast.h | 10 ++++++++-- include/pybind11/detail/internals.h | 12 ++++-------- include/pybind11/pybind11.h | 4 ---- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h index 726711935..ef2ca1709 100644 --- a/include/pybind11/attr.h +++ b/include/pybind11/attr.h @@ -276,8 +276,7 @@ struct function_record { struct type_record { PYBIND11_NOINLINE type_record() : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false), - default_holder(true), module_local(false), is_final(false), - release_gil_before_calling_cpp_dtor(false) {} + module_local(false), is_final(false), release_gil_before_calling_cpp_dtor(false) {} /// Handle to the parent scope handle scope; @@ -327,9 +326,6 @@ struct type_record { /// Does the class implement the buffer protocol? bool buffer_protocol : 1; - /// Is the default (unique_ptr) holder type used? - bool default_holder : 1; - /// Is the class definition local to the module shared object? bool module_local : 1; @@ -350,13 +346,17 @@ struct type_record { + "\" referenced unknown base type \"" + tname + "\""); } - if (default_holder != base_info->default_holder) { + // SMART_HOLDER_BAKEIN_FOLLOW_ON: Refine holder compatibility checks. + bool this_has_unique_ptr_holder = (holder_enum_v == holder_enum_t::std_unique_ptr); + bool base_has_unique_ptr_holder + = (base_info->holder_enum_v == holder_enum_t::std_unique_ptr); + if (this_has_unique_ptr_holder != base_has_unique_ptr_holder) { std::string tname(base.name()); detail::clean_type_id(tname); pybind11_fail("generic_type: type \"" + std::string(name) + "\" " - + (default_holder ? "does not have" : "has") + + (this_has_unique_ptr_holder ? "does not have" : "has") + " a non-default holder type while its base \"" + tname + "\" " - + (base_info->default_holder ? "does not" : "does")); + + (base_has_unique_ptr_holder ? "does not" : "does")); } bases.append((PyObject *) base_info->type); diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 09c262afa..13a589f17 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -790,7 +790,10 @@ public: protected: friend class type_caster_generic; void check_holder_compat() { - if (typeinfo->default_holder) { + // SMART_HOLDER_BAKEIN_FOLLOW_ON: Refine holder compatibility checks. + bool inst_has_unique_ptr_holder + = (typeinfo->holder_enum_v == holder_enum_t::std_unique_ptr); + if (inst_has_unique_ptr_holder) { throw cast_error("Unable to load a custom holder type from a default-holder instance"); } } @@ -908,7 +911,10 @@ public: protected: friend class type_caster_generic; void check_holder_compat() { - if (typeinfo->default_holder) { + // SMART_HOLDER_BAKEIN_FOLLOW_ON: Refine holder compatibility checks. + bool inst_has_unique_ptr_holder + = (typeinfo->holder_enum_v == holder_enum_t::std_unique_ptr); + if (inst_has_unique_ptr_holder) { throw cast_error("Unable to load a custom holder type from a default-holder instance"); } } diff --git a/include/pybind11/detail/internals.h b/include/pybind11/detail/internals.h index d8b7f693e..234524f91 100644 --- a/include/pybind11/detail/internals.h +++ b/include/pybind11/detail/internals.h @@ -37,11 +37,11 @@ /// further ABI-incompatible changes may be made before the ABI is officially /// changed to the new version. #ifndef PYBIND11_INTERNALS_VERSION -# define PYBIND11_INTERNALS_VERSION 106 +# define PYBIND11_INTERNALS_VERSION 7 #endif -#if PYBIND11_INTERNALS_VERSION < 106 -# error "PYBIND11_INTERNALS_VERSION 106 is the minimum (SPECIAL SITUATION)." +#if PYBIND11_INTERNALS_VERSION < 7 +# error "PYBIND11_INTERNALS_VERSION 7 is the minimum for all platforms for pybind11v3." #endif PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) @@ -234,6 +234,7 @@ struct type_info { buffer_info *(*get_buffer)(PyObject *, void *) = nullptr; void *get_buffer_data = nullptr; void *(*module_local_load)(PyObject *, const type_info *) = nullptr; + holder_enum_t holder_enum_v = holder_enum_t::undefined; /* A simple type never occurs as a (direct or indirect) parent * of a class that makes use of multiple inheritance. * A type can be simple even if it has non-simple ancestors as long as it has no descendants. @@ -241,13 +242,8 @@ struct type_info { bool simple_type : 1; /* True if there is no multiple inheritance in this type's inheritance tree */ bool simple_ancestors : 1; - /* for base vs derived holder_type checks */ - // SMART_HOLDER_BAKEIN_FOLLOW_ON: Remove default_holder member here and - // produce better error messages in the places where it is currently used. - bool default_holder : 1; /* true if this is a type registered with py::module_local */ bool module_local : 1; - holder_enum_t holder_enum_v = holder_enum_t::undefined; }; #define PYBIND11_INTERNALS_ID \ diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index b4fdccfce..5564f040e 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -1446,7 +1446,6 @@ protected: tinfo->dealloc = rec.dealloc; tinfo->simple_type = true; tinfo->simple_ancestors = true; - tinfo->default_holder = rec.default_holder; tinfo->module_local = rec.module_local; tinfo->holder_enum_v = rec.holder_enum_v; @@ -1903,9 +1902,6 @@ public: record.holder_size = sizeof(holder_type); record.init_instance = init_instance; - // A more fitting name would be uses_unique_ptr_holder. - record.default_holder = detail::is_instantiation::value; - if (detail::is_instantiation::value) { record.holder_enum_v = detail::holder_enum_t::std_unique_ptr; } else if (detail::is_instantiation::value) {