Skip to content

Commit ff1b5c4

Browse files
authored
mention type name in "no constructor defined" message (#4481)
fixes #4470
1 parent 44c16ec commit ff1b5c4

File tree

3 files changed

+18
-10
lines changed

3 files changed

+18
-10
lines changed

newsfragments/4481.changed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Mention the type name in the exception message when trying to instantiate a class with no constructor defined.

pytests/tests/test_pyclasses.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,24 +65,26 @@ def test_new_classmethod():
6565
_ = AssertingSubClass(expected_type=str)
6666

6767

68-
class ClassWithoutConstructorPy:
68+
class ClassWithoutConstructor:
6969
def __new__(cls):
70-
raise TypeError("No constructor defined")
70+
raise TypeError("No constructor defined for ClassWithoutConstructor")
7171

7272

7373
@pytest.mark.parametrize(
74-
"cls", [pyclasses.ClassWithoutConstructor, ClassWithoutConstructorPy]
74+
"cls", [pyclasses.ClassWithoutConstructor, ClassWithoutConstructor]
7575
)
7676
def test_no_constructor_defined_propagates_cause(cls: Type):
7777
original_error = ValueError("Original message")
7878
with pytest.raises(Exception) as exc_info:
7979
try:
8080
raise original_error
8181
except Exception:
82-
cls() # should raise TypeError("No constructor defined")
82+
cls() # should raise TypeError("No constructor defined for ...")
8383

8484
assert exc_info.type is TypeError
85-
assert exc_info.value.args == ("No constructor defined",)
85+
assert exc_info.value.args == (
86+
"No constructor defined for ClassWithoutConstructor",
87+
)
8688
assert exc_info.value.__context__ is original_error
8789

8890

src/pyclass/create_type_object.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -524,14 +524,19 @@ fn bpo_45315_workaround(py: Python<'_>, class_name: CString) {
524524

525525
/// Default new implementation
526526
unsafe extern "C" fn no_constructor_defined(
527-
_subtype: *mut ffi::PyTypeObject,
527+
subtype: *mut ffi::PyTypeObject,
528528
_args: *mut ffi::PyObject,
529529
_kwds: *mut ffi::PyObject,
530530
) -> *mut ffi::PyObject {
531-
trampoline(|_| {
532-
Err(crate::exceptions::PyTypeError::new_err(
533-
"No constructor defined",
534-
))
531+
trampoline(|py| {
532+
let tpobj = PyType::from_borrowed_type_ptr(py, subtype);
533+
let name = tpobj
534+
.name()
535+
.map_or_else(|_| "<unknown>".into(), |name| name.to_string());
536+
Err(crate::exceptions::PyTypeError::new_err(format!(
537+
"No constructor defined for {}",
538+
name
539+
)))
535540
})
536541
}
537542

0 commit comments

Comments
 (0)