diff --git a/include/pybind11/detail/init.h b/include/pybind11/detail/init.h index 35b95bcfa..3ef78c117 100644 --- a/include/pybind11/detail/init.h +++ b/include/pybind11/detail/init.h @@ -132,6 +132,7 @@ void construct(value_and_holder &v_h, Alias *alias_ptr, bool) { template void construct(value_and_holder &v_h, Holder holder, bool need_alias) { auto *ptr = holder_helper>::get(holder); + no_nullptr(ptr); // If we need an alias, check that the held pointer is actually an alias instance if (Class::has_alias && need_alias && !is_alias(ptr)) throw type_error("pybind11::init(): construction failed: returned holder-wrapped instance " diff --git a/tests/test_factory_constructors.cpp b/tests/test_factory_constructors.cpp index 5cfbfdc3f..61cf33d16 100644 --- a/tests/test_factory_constructors.cpp +++ b/tests/test_factory_constructors.cpp @@ -154,6 +154,8 @@ TEST_SUBMODULE(factory_constructors, m) { MAKE_TAG_TYPE(TF4); MAKE_TAG_TYPE(TF5); MAKE_TAG_TYPE(null_ptr); + MAKE_TAG_TYPE(null_unique_ptr); + MAKE_TAG_TYPE(null_shared_ptr); MAKE_TAG_TYPE(base); MAKE_TAG_TYPE(invalid_base); MAKE_TAG_TYPE(alias); @@ -194,6 +196,8 @@ TEST_SUBMODULE(factory_constructors, m) { // Returns nullptr: .def(py::init([](null_ptr_tag) { return (TestFactory3 *) nullptr; })) + .def(py::init([](null_unique_ptr_tag) { return std::unique_ptr(); })) + .def(py::init([](null_shared_ptr_tag) { return std::shared_ptr(); })) .def_readwrite("value", &TestFactory3::value) ; diff --git a/tests/test_factory_constructors.py b/tests/test_factory_constructors.py index 8465c59e3..6c4bed165 100644 --- a/tests/test_factory_constructors.py +++ b/tests/test_factory_constructors.py @@ -41,9 +41,12 @@ def test_init_factory_basic(): z3 = m.TestFactory3("bye") assert z3.value == "bye" - with pytest.raises(TypeError) as excinfo: - m.TestFactory3(tag.null_ptr) - assert str(excinfo.value) == "pybind11::init(): factory function returned nullptr" + for null_ptr_kind in [tag.null_ptr, + tag.null_unique_ptr, + tag.null_shared_ptr]: + with pytest.raises(TypeError) as excinfo: + m.TestFactory3(null_ptr_kind) + assert str(excinfo.value) == "pybind11::init(): factory function returned nullptr" assert [i.alive() for i in cstats] == [3, 3, 3] assert ConstructorStats.detail_reg_inst() == n_inst + 9