Skip to content

Commit 502bf24

Browse files
committed
fixup! Replace global map holders_seen with local holder_type in registered type_info
Having replaced the global map holders_seen, we can only check return values against already registered types. Hence, we need to replace the check at initialization time with a check at call time (when casting the return value).
1 parent e2aa4ec commit 502bf24

File tree

4 files changed

+7
-7
lines changed

4 files changed

+7
-7
lines changed

include/pybind11/cast.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,6 +1538,7 @@ struct copyable_holder_caster : public type_caster_base<type> {
15381538
explicit operator holder_type&() { return holder; }
15391539

15401540
static handle cast(const holder_type &src, return_value_policy, handle) {
1541+
check_for_holder_mismatch_impl<holder_type>();
15411542
const auto *ptr = holder_helper<holder_type>::get(src);
15421543
return type_caster_base<type>::cast_holder(ptr, &src);
15431544
}

include/pybind11/pybind11.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ class cpp_function : public function {
157157
static_assert(expected_num_args<Extra...>(sizeof...(Args), cast_in::has_args, cast_in::has_kwargs),
158158
"The number of argument annotations does not match the number of function arguments");
159159

160-
// Fail if we've previously seen a different holder around the held type
160+
// Fail if the type was previously registered with a different holder type
161161
detail::check_for_holder_mismatch<Return>();
162162

163163
/* Dispatch code which converts function arguments and performs the actual function call */
@@ -1225,9 +1225,6 @@ class class_ : public detail::generic_type {
12251225
none_of<std::is_same<multiple_inheritance, Extra>...>::value), // no multiple_inheritance attr
12261226
"Error: multiple inheritance bases must be specified via class_ template options");
12271227

1228-
// Fail if we've previously seen a different holder around the type
1229-
detail::check_for_holder_mismatch<holder_type>();
1230-
12311228
type_record record;
12321229
record.scope = scope;
12331230
record.name = name;

tests/test_smart_ptr.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,8 +378,7 @@ TEST_SUBMODULE(smart_ptr, m) {
378378
m.def("bad1", []() { return std::unique_ptr<HeldByShared>(new HeldByShared()); });
379379
});
380380
m.def("return_shared", []() { return std::make_shared<HeldByUnique>(); });
381-
m.def("register_mismatch_class", [](py::module m) {
382-
// Fails: `return_shared' already returned this via shared_ptr holder
381+
m.def("register_HeldByUnique", [](py::module m) {
383382
py::class_<HeldByUnique>(m, "HeldByUnique");
384383
});
385384
// Fails: MyObject5 was declared with huge_unique_ptr as holder instead of shared_ptr

tests/test_smart_ptr.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,11 @@ def test_holder_mismatch():
316316
m.register_mismatch_return(m)
317317
assert "Mismatched holders detected" in str(excinfo)
318318

319+
with pytest.raises(TypeError) as excinfo:
320+
m.return_shared() # calling a function returning an unregistered type
321+
m.register_HeldByUnique(m) # register the type
319322
with pytest.raises(RuntimeError) as excinfo:
320-
m.register_mismatch_class(m)
323+
m.return_shared() # calling a function returning a mismatching holder type
321324
assert "Mismatched holders detected" in str(excinfo)
322325

323326
with pytest.raises(RuntimeError) as excinfo:

0 commit comments

Comments
 (0)