diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 648300eef..eff40a849 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -555,8 +555,8 @@ protected: auto self_value_and_holder = value_and_holder(); if (overloads->is_constructor) { - if (!PyObject_TypeCheck(parent.ptr(), (PyTypeObject *) overloads->scope.ptr())) { - PyErr_SetString(PyExc_TypeError, "__init__(self, ...) called with invalid `self` argument"); + if (!parent || !PyObject_TypeCheck(parent.ptr(), (PyTypeObject *) overloads->scope.ptr())) { + PyErr_SetString(PyExc_TypeError, "__init__(self, ...) called with invalid or missing `self` argument"); return nullptr; } diff --git a/tests/test_factory_constructors.py b/tests/test_factory_constructors.py index ffcce6fd4..8c6ca173a 100644 --- a/tests/test_factory_constructors.py +++ b/tests/test_factory_constructors.py @@ -486,7 +486,9 @@ def test_invalid_self(): # Same as above, but for a class with an alias: class BrokenTF6(m.TestFactory6): def __init__(self, bad): - if bad == 1: + if bad == 0: + m.TestFactory6.__init__() + elif bad == 1: a = m.TestFactory2(tag.pointer, 1) m.TestFactory6.__init__(a, tag.base, 1) elif bad == 2: @@ -506,13 +508,13 @@ def test_invalid_self(): BrokenTF1(arg) assert ( str(excinfo.value) - == "__init__(self, ...) called with invalid `self` argument" + == "__init__(self, ...) called with invalid or missing `self` argument" ) - for arg in (1, 2, 3, 4): + for arg in (0, 1, 2, 3, 4): with pytest.raises(TypeError) as excinfo: BrokenTF6(arg) assert ( str(excinfo.value) - == "__init__(self, ...) called with invalid `self` argument" + == "__init__(self, ...) called with invalid or missing `self` argument" )