Skip to content

Commit 5ab036b

Browse files
authored
[smart_holder] Simplification: Enable smart_holder functionality unconditionally. (#5531)
* 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 <cstdint>` 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; | ^~~~~~~ ``` * Change PYBIND11_INTERNALS_VERSION to 106: It will be changed to 7 in a follow-on PR that actually changes the internals.
1 parent dc37cba commit 5ab036b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+35
-440
lines changed

.github/workflows/ci.yml

-14
Original file line numberDiff line numberDiff line change
@@ -102,20 +102,6 @@ jobs:
102102
python: '3.12'
103103
args: >
104104
-DCMAKE_CXX_FLAGS="/DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT /GR /EHsc"
105-
# Exercise PYBIND11_SMART_HOLDER_DISABLE
106-
# with recent (or ideally latest) released Python version.
107-
- runs-on: ubuntu-latest
108-
python: '3.12'
109-
args: >
110-
-DCMAKE_CXX_FLAGS="-DPYBIND11_SMART_HOLDER_DISABLE"
111-
- runs-on: macos-13
112-
python: '3.12'
113-
args: >
114-
-DCMAKE_CXX_FLAGS="-DPYBIND11_SMART_HOLDER_DISABLE"
115-
- runs-on: windows-2022
116-
python: '3.12'
117-
args: >
118-
-DCMAKE_CXX_FLAGS="/DPYBIND11_SMART_HOLDER_DISABLE /GR /EHsc"
119105
exclude:
120106
# The setup-python action currently doesn't have graalpy for windows
121107
- python: 'graalpy-24.1'

include/pybind11/attr.h

-2
Original file line numberDiff line numberDiff line change
@@ -339,9 +339,7 @@ struct type_record {
339339
/// Solves pybind/pybind11#1446
340340
bool release_gil_before_calling_cpp_dtor : 1;
341341

342-
#ifdef PYBIND11_HAS_INTERNALS_WITH_SMART_HOLDER_SUPPORT
343342
holder_enum_t holder_enum_v = holder_enum_t::undefined;
344-
#endif
345343

346344
PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *) ) {
347345
auto *base_info = detail::get_type_info(base, false);

include/pybind11/cast.h

+3-13
Original file line numberDiff line numberDiff line change
@@ -836,8 +836,6 @@ struct copyable_holder_caster : public type_caster_base<type> {
836836
holder_type holder;
837837
};
838838

839-
#ifdef PYBIND11_SMART_HOLDER_ENABLED
840-
841839
template <typename, typename SFINAE = void>
842840
struct copyable_holder_caster_shared_ptr_with_smart_holder_support_enabled : std::true_type {};
843841

@@ -928,13 +926,13 @@ struct copyable_holder_caster<
928926
return;
929927
}
930928
throw cast_error("Unable to cast from non-held to held instance (T& to Holder<T>) "
931-
# if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
929+
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
932930
"(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for "
933931
"type information)");
934-
# else
932+
#else
935933
"of type '"
936934
+ type_id<std::shared_ptr<type>>() + "''");
937-
# endif
935+
#endif
938936
}
939937

940938
template <typename T = std::shared_ptr<type>,
@@ -968,8 +966,6 @@ struct copyable_holder_caster<
968966
std::shared_ptr<type> shared_ptr_storage;
969967
};
970968

971-
#endif // PYBIND11_SMART_HOLDER_ENABLED
972-
973969
/// Specialize for the common std::shared_ptr, so users don't need to
974970
template <typename T>
975971
class type_caster<std::shared_ptr<T>> : public copyable_holder_caster<T, std::shared_ptr<T>> {};
@@ -990,8 +986,6 @@ struct move_only_holder_caster {
990986
static constexpr auto name = type_caster_base<type>::name;
991987
};
992988

993-
#ifdef PYBIND11_SMART_HOLDER_ENABLED
994-
995989
template <typename, typename SFINAE = void>
996990
struct move_only_holder_caster_unique_ptr_with_smart_holder_support_enabled : std::true_type {};
997991

@@ -1129,8 +1123,6 @@ struct move_only_holder_caster<
11291123
std::shared_ptr<std::unique_ptr<type, deleter>> unique_ptr_storage;
11301124
};
11311125

1132-
#endif // PYBIND11_SMART_HOLDER_ENABLED
1133-
11341126
template <typename type, typename deleter>
11351127
class type_caster<std::unique_ptr<type, deleter>>
11361128
: public move_only_holder_caster<type, std::unique_ptr<type, deleter>> {};
@@ -1169,10 +1161,8 @@ struct is_holder_type
11691161
template <typename base, typename deleter>
11701162
struct is_holder_type<base, std::unique_ptr<base, deleter>> : std::true_type {};
11711163

1172-
#ifdef PYBIND11_SMART_HOLDER_ENABLED
11731164
template <typename base>
11741165
struct is_holder_type<base, smart_holder> : std::true_type {};
1175-
#endif
11761166

11771167
#ifdef PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION // See PR #4888
11781168

include/pybind11/detail/common.h

-3
Original file line numberDiff line numberDiff line change
@@ -605,11 +605,8 @@ struct instance {
605605
bool simple_instance_registered : 1;
606606
/// If true, get_internals().patients has an entry for this object
607607
bool has_patients : 1;
608-
// Cannot use PYBIND11_INTERNALS_VERSION >= 106 here without refactoring.
609-
#if PYBIND11_VERSION_MAJOR >= 3
610608
/// If true, this Python object needs to be kept alive for the lifetime of the C++ value.
611609
bool is_alias : 1;
612-
#endif
613610

614611
/// Initializes all of the above type/values/holders data (but not the instance values
615612
/// themselves)

include/pybind11/detail/init.h

-4
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,6 @@ void construct(value_and_holder &v_h, Alias<Class> &&result, bool) {
198198
v_h.value_ptr() = new Alias<Class>(std::move(result));
199199
}
200200

201-
#ifdef PYBIND11_SMART_HOLDER_ENABLED
202-
203201
template <typename T, typename D>
204202
smart_holder init_smart_holder_from_unique_ptr(std::unique_ptr<T, D> &&unq_ptr,
205203
bool void_cast_raw_ptr) {
@@ -268,8 +266,6 @@ void construct(value_and_holder &v_h,
268266
v_h.type->init_instance(v_h.inst, &smhldr);
269267
}
270268

271-
#endif // PYBIND11_SMART_HOLDER_ENABLED
272-
273269
// Implementing class for py::init<...>()
274270
template <typename... Args>
275271
struct constructor {

include/pybind11/detail/internals.h

+3-20
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,11 @@
3737
/// further ABI-incompatible changes may be made before the ABI is officially
3838
/// changed to the new version.
3939
#ifndef PYBIND11_INTERNALS_VERSION
40-
# if PYBIND11_VERSION_MAJOR >= 3
41-
# define PYBIND11_INTERNALS_VERSION 106
42-
# else
43-
# define PYBIND11_INTERNALS_VERSION 6
44-
# endif
40+
# define PYBIND11_INTERNALS_VERSION 106
4541
#endif
4642

47-
#if PYBIND11_INTERNALS_VERSION < 6
48-
# error "PYBIND11_INTERNALS_VERSION 6 is the minimum for all platforms for pybind11v3."
43+
#if PYBIND11_INTERNALS_VERSION < 106
44+
# error "PYBIND11_INTERNALS_VERSION 106 is the minimum (SPECIAL SITUATION)."
4945
#endif
5046

5147
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
@@ -215,10 +211,6 @@ struct internals {
215211
}
216212
};
217213

218-
#if PYBIND11_INTERNALS_VERSION >= 106
219-
220-
# define PYBIND11_HAS_INTERNALS_WITH_SMART_HOLDER_SUPPORT
221-
222214
enum class holder_enum_t : uint8_t {
223215
undefined,
224216
std_unique_ptr, // Default, lacking interop with std::shared_ptr.
@@ -227,13 +219,6 @@ enum class holder_enum_t : uint8_t {
227219
custom_holder,
228220
};
229221

230-
#endif
231-
232-
#if defined(PYBIND11_HAS_INTERNALS_WITH_SMART_HOLDER_SUPPORT) \
233-
&& !defined(PYBIND11_SMART_HOLDER_DISABLE)
234-
# define PYBIND11_SMART_HOLDER_ENABLED
235-
#endif
236-
237222
/// Additional type information which does not fit into the PyTypeObject.
238223
/// Changes to this struct also require bumping `PYBIND11_INTERNALS_VERSION`.
239224
struct type_info {
@@ -262,9 +247,7 @@ struct type_info {
262247
bool default_holder : 1;
263248
/* true if this is a type registered with py::module_local */
264249
bool module_local : 1;
265-
#ifdef PYBIND11_HAS_INTERNALS_WITH_SMART_HOLDER_SUPPORT
266250
holder_enum_t holder_enum_v = holder_enum_t::undefined;
267-
#endif
268251
};
269252

270253
#define PYBIND11_INTERNALS_ID \

include/pybind11/detail/type_caster_base.h

-6
Original file line numberDiff line numberDiff line change
@@ -511,8 +511,6 @@ inline PyThreadState *get_thread_state_unchecked() {
511511
void keep_alive_impl(handle nurse, handle patient);
512512
inline PyObject *make_new_instance(PyTypeObject *type);
513513

514-
#ifdef PYBIND11_SMART_HOLDER_ENABLED
515-
516514
// PYBIND11:REMINDER: Needs refactoring of existing pybind11 code.
517515
inline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo);
518516

@@ -868,8 +866,6 @@ struct load_helper : value_and_holder_helper {
868866

869867
PYBIND11_NAMESPACE_END(smart_holder_type_caster_support)
870868

871-
#endif // PYBIND11_SMART_HOLDER_ENABLED
872-
873869
class type_caster_generic {
874870
public:
875871
PYBIND11_NOINLINE explicit type_caster_generic(const std::type_info &type_info)
@@ -974,7 +970,6 @@ class type_caster_generic {
974970

975971
// Base methods for generic caster; there are overridden in copyable_holder_caster
976972
void load_value(value_and_holder &&v_h) {
977-
#ifdef PYBIND11_SMART_HOLDER_ENABLED
978973
if (typeinfo->holder_enum_v == detail::holder_enum_t::smart_holder) {
979974
smart_holder_type_caster_support::value_and_holder_helper v_h_helper;
980975
v_h_helper.loaded_v_h = v_h;
@@ -984,7 +979,6 @@ class type_caster_generic {
984979
return;
985980
}
986981
}
987-
#endif
988982
auto *&vptr = v_h.value_ptr();
989983
// Lazy allocation for unallocated values:
990984
if (vptr == nullptr) {

include/pybind11/detail/using_smart_holder.h

+1-12
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,18 @@
55
#pragma once
66

77
#include "common.h"
8-
#include "internals.h"
8+
#include "struct_smart_holder.h"
99

1010
#include <type_traits>
1111

12-
#ifdef PYBIND11_SMART_HOLDER_ENABLED
13-
# include "struct_smart_holder.h"
14-
#endif
15-
1612
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
1713

18-
#ifdef PYBIND11_SMART_HOLDER_ENABLED
1914
using pybindit::memory::smart_holder;
20-
#endif
2115

2216
PYBIND11_NAMESPACE_BEGIN(detail)
2317

24-
#ifdef PYBIND11_SMART_HOLDER_ENABLED
2518
template <typename H>
2619
using is_smart_holder = std::is_same<H, smart_holder>;
27-
#else
28-
template <typename>
29-
struct is_smart_holder : std::false_type {};
30-
#endif
3120

3221
PYBIND11_NAMESPACE_END(detail)
3322
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

include/pybind11/detail/value_and_holder.h

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "common.h"
88

99
#include <cstddef>
10+
#include <cstdint>
1011
#include <typeinfo>
1112

1213
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

include/pybind11/pybind11.h

+1-18
Original file line numberDiff line numberDiff line change
@@ -1448,9 +1448,7 @@ class generic_type : public object {
14481448
tinfo->simple_ancestors = true;
14491449
tinfo->default_holder = rec.default_holder;
14501450
tinfo->module_local = rec.module_local;
1451-
#ifdef PYBIND11_HAS_INTERNALS_WITH_SMART_HOLDER_SUPPORT
14521451
tinfo->holder_enum_v = rec.holder_enum_v;
1453-
#endif
14541452

14551453
with_internals([&](internals &internals) {
14561454
auto tindex = std::type_index(*rec.type);
@@ -1665,8 +1663,6 @@ PYBIND11_NAMESPACE_END(detail)
16651663
template <typename T, typename D, typename SFINAE = void>
16661664
struct property_cpp_function : detail::property_cpp_function_classic<T, D> {};
16671665

1668-
#ifdef PYBIND11_SMART_HOLDER_ENABLED
1669-
16701666
PYBIND11_NAMESPACE_BEGIN(detail)
16711667

16721668
template <typename T, typename D, typename SFINAE = void>
@@ -1844,17 +1840,14 @@ struct property_cpp_function<
18441840
detail::both_t_and_d_use_type_caster_base<T, typename D::element_type>>::value>>
18451841
: detail::property_cpp_function_sh_unique_ptr_member<T, D> {};
18461842

1847-
#endif // PYBIND11_SMART_HOLDER_ENABLED
1848-
1849-
#if defined(PYBIND11_USE_SMART_HOLDER_AS_DEFAULT) && defined(PYBIND11_SMART_HOLDER_ENABLED)
1843+
#if defined(PYBIND11_USE_SMART_HOLDER_AS_DEFAULT)
18501844
// NOTE: THIS IS MEANT FOR STRESS-TESTING ONLY!
18511845
// As of PR #5257, for production use, there is no longer a strong reason to make
18521846
// smart_holder the default holder:
18531847
// Simply use `py::classh` (see below) instead of `py::class_` as needed.
18541848
// Running the pybind11 unit tests with smart_holder as the default holder is to ensure
18551849
// that `py::smart_holder` / `py::classh` is backward-compatible with all pre-existing
18561850
// functionality.
1857-
# define PYBIND11_ACTUALLY_USING_SMART_HOLDER_AS_DEFAULT
18581851
template <typename>
18591852
using default_holder_type = smart_holder;
18601853
#else
@@ -1913,7 +1906,6 @@ class class_ : public detail::generic_type {
19131906
// A more fitting name would be uses_unique_ptr_holder.
19141907
record.default_holder = detail::is_instantiation<std::unique_ptr, holder_type>::value;
19151908

1916-
#ifdef PYBIND11_SMART_HOLDER_ENABLED
19171909
if (detail::is_instantiation<std::unique_ptr, holder_type>::value) {
19181910
record.holder_enum_v = detail::holder_enum_t::std_unique_ptr;
19191911
} else if (detail::is_instantiation<std::shared_ptr, holder_type>::value) {
@@ -1923,7 +1915,6 @@ class class_ : public detail::generic_type {
19231915
} else {
19241916
record.holder_enum_v = detail::holder_enum_t::custom_holder;
19251917
}
1926-
#endif
19271918

19281919
set_operator_new<type>(&record);
19291920

@@ -2265,8 +2256,6 @@ class class_ : public detail::generic_type {
22652256
init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr<type>());
22662257
}
22672258

2268-
#ifdef PYBIND11_SMART_HOLDER_ENABLED
2269-
22702259
template <typename WrappedType>
22712260
static bool try_initialization_using_shared_from_this(holder_type *, WrappedType *, ...) {
22722261
return false;
@@ -2326,8 +2315,6 @@ class class_ : public detail::generic_type {
23262315
v_h.set_holder_constructed();
23272316
}
23282317

2329-
#endif // PYBIND11_SMART_HOLDER_ENABLED
2330-
23312318
// Deallocates an instance; via holder, if constructed; otherwise via operator delete.
23322319
// NOTE: The Python error indicator needs to cleared BEFORE this function is called.
23332320
// This is because we could be deallocating while cleaning up after a Python exception.
@@ -2393,8 +2380,6 @@ class class_ : public detail::generic_type {
23932380
}
23942381
};
23952382

2396-
#ifdef PYBIND11_SMART_HOLDER_ENABLED
2397-
23982383
// Supports easier switching between py::class_<T> and py::class_<T, py::smart_holder>:
23992384
// users can simply replace the `_` in `class_` with `h` or vice versa.
24002385
template <typename type_, typename... options>
@@ -2403,8 +2388,6 @@ class classh : public class_<type_, smart_holder, options...> {
24032388
using class_<type_, smart_holder, options...>::class_;
24042389
};
24052390

2406-
#endif
2407-
24082391
/// Binds an existing constructor taking arguments Args...
24092392
template <typename... Args>
24102393
detail::initimpl::constructor<Args...> init() {

include/pybind11/trampoline_self_life_support.h

+3-9
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,9 @@
44

55
#pragma once
66

7-
#include "detail/internals.h"
8-
9-
#ifdef PYBIND11_SMART_HOLDER_ENABLED
10-
11-
# include "detail/common.h"
12-
# include "detail/using_smart_holder.h"
13-
# include "detail/value_and_holder.h"
7+
#include "detail/common.h"
8+
#include "detail/using_smart_holder.h"
9+
#include "detail/value_and_holder.h"
1410

1511
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
1612

@@ -62,5 +58,3 @@ struct trampoline_self_life_support {
6258
};
6359

6460
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
65-
66-
#endif // PYBIND11_SMART_HOLDER_ENABLED

tests/test_class.cpp

+1-5
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,7 @@ TEST_SUBMODULE(class_, m) {
109109
struct ToBeHeldByUniquePtr {};
110110
py::class_<ToBeHeldByUniquePtr, std::unique_ptr<ToBeHeldByUniquePtr>>(m, "ToBeHeldByUniquePtr")
111111
.def(py::init<>());
112-
#ifdef PYBIND11_SMART_HOLDER_ENABLED
113112
m.def("pass_unique_ptr", [](std::unique_ptr<ToBeHeldByUniquePtr> &&) {});
114-
#else
115-
m.attr("pass_unique_ptr") = py::none();
116-
#endif
117113

118114
// test_inheritance
119115
class Pet {
@@ -636,7 +632,7 @@ CHECK_NOALIAS(8);
636632
CHECK_HOLDER(1, unique);
637633
CHECK_HOLDER(2, unique);
638634
CHECK_HOLDER(3, unique);
639-
#ifndef PYBIND11_ACTUALLY_USING_SMART_HOLDER_AS_DEFAULT
635+
#ifndef PYBIND11_USE_SMART_HOLDER_AS_DEFAULT
640636
CHECK_HOLDER(4, unique);
641637
CHECK_HOLDER(5, unique);
642638
#endif

tests/test_class.py

-2
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ def test_instance_new():
5151

5252
def test_pass_unique_ptr():
5353
obj = m.ToBeHeldByUniquePtr()
54-
if m.pass_unique_ptr is None:
55-
pytest.skip("smart_holder not available.")
5654
with pytest.raises(RuntimeError) as execinfo:
5755
m.pass_unique_ptr(obj)
5856
assert str(execinfo.value).startswith(

0 commit comments

Comments
 (0)