Skip to content

Commit c45f4f3

Browse files
gh-78465: Fix error message for cls.__new__(cls, ...) where cls is not instantiable (GH-135981)
Previous error message suggested to use cls.__new__(), which obviously does not work. Now the error message is the same as for cls(...).
1 parent f3aec60 commit c45f4f3

File tree

5 files changed

+11
-9
lines changed

5 files changed

+11
-9
lines changed

Lib/test/support/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,6 +2333,7 @@ def check_disallow_instantiation(testcase, tp, *args, **kwds):
23332333
qualname = f"{name}"
23342334
msg = f"cannot create '{re.escape(qualname)}' instances"
23352335
testcase.assertRaisesRegex(TypeError, msg, tp, *args, **kwds)
2336+
testcase.assertRaisesRegex(TypeError, msg, tp.__new__, tp, *args, **kwds)
23362337

23372338
def get_recursion_depth():
23382339
"""Get the recursion depth of the caller function.

Lib/test/test_sys.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -869,12 +869,7 @@ def test_sys_flags(self):
869869
def assert_raise_on_new_sys_type(self, sys_attr):
870870
# Users are intentionally prevented from creating new instances of
871871
# sys.flags, sys.version_info, and sys.getwindowsversion.
872-
arg = sys_attr
873-
attr_type = type(sys_attr)
874-
with self.assertRaises(TypeError):
875-
attr_type(arg)
876-
with self.assertRaises(TypeError):
877-
attr_type.__new__(attr_type, arg)
872+
support.check_disallow_instantiation(self, type(sys_attr), sys_attr)
878873

879874
def test_sys_flags_no_instantiation(self):
880875
self.assert_raise_on_new_sys_type(sys.flags)

Lib/test/test_types.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from test.support import (
44
run_with_locale, cpython_only, no_rerun,
5-
MISSING_C_DOCSTRINGS, EqualToForwardRef,
5+
MISSING_C_DOCSTRINGS, EqualToForwardRef, check_disallow_instantiation,
66
)
77
from test.support.script_helper import assert_python_ok
88
from test.support.import_helper import import_fresh_module
@@ -1148,8 +1148,7 @@ def test_or_type_operator_reference_cycle(self):
11481148
msg='Check for union reference leak.')
11491149

11501150
def test_instantiation(self):
1151-
with self.assertRaises(TypeError):
1152-
types.UnionType()
1151+
check_disallow_instantiation(self, types.UnionType)
11531152
self.assertIs(int, types.UnionType[int])
11541153
self.assertIs(int, types.UnionType[int, int])
11551154
self.assertEqual(int | str, types.UnionType[int, str])
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix error message for ``cls.__new__(cls, ...)`` where ``cls`` is not
2+
instantiable builtin or extension type (with ``tp_new`` set to ``NULL``).

Objects/typeobject.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10020,6 +10020,11 @@ tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds)
1002010020
/* If staticbase is NULL now, it is a really weird type.
1002110021
In the spirit of backwards compatibility (?), just shut up. */
1002210022
if (staticbase && staticbase->tp_new != type->tp_new) {
10023+
if (staticbase->tp_new == NULL) {
10024+
PyErr_Format(PyExc_TypeError,
10025+
"cannot create '%s' instances", subtype->tp_name);
10026+
return NULL;
10027+
}
1002310028
PyErr_Format(PyExc_TypeError,
1002410029
"%s.__new__(%s) is not safe, use %s.__new__()",
1002510030
type->tp_name,

0 commit comments

Comments
 (0)