https://github.com/python/cpython/commit/c45f4f3ebe34529a8db3a7918e8dd2e9f7ce8e86
commit: c45f4f3ebe34529a8db3a7918e8dd2e9f7ce8e86
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2025-06-27T14:35:55+03:00
summary:
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(...).
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2025-06-26-15-25-51.gh-issue-78465.MbDN8X.rst
M Lib/test/support/__init__.py
M Lib/test/test_sys.py
M Lib/test/test_types.py
M Objects/typeobject.c
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 51c0ce11e8269d..fd39d3f7c95368 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -2333,6 +2333,7 @@ def check_disallow_instantiation(testcase, tp, *args,
**kwds):
qualname = f"{name}"
msg = f"cannot create '{re.escape(qualname)}' instances"
testcase.assertRaisesRegex(TypeError, msg, tp, *args, **kwds)
+ testcase.assertRaisesRegex(TypeError, msg, tp.__new__, tp, *args, **kwds)
def get_recursion_depth():
"""Get the recursion depth of the caller function.
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index 27524d86355b9c..486bf10a0b5647 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -869,12 +869,7 @@ def test_sys_flags(self):
def assert_raise_on_new_sys_type(self, sys_attr):
# Users are intentionally prevented from creating new instances of
# sys.flags, sys.version_info, and sys.getwindowsversion.
- arg = sys_attr
- attr_type = type(sys_attr)
- with self.assertRaises(TypeError):
- attr_type(arg)
- with self.assertRaises(TypeError):
- attr_type.__new__(attr_type, arg)
+ support.check_disallow_instantiation(self, type(sys_attr), sys_attr)
def test_sys_flags_no_instantiation(self):
self.assert_raise_on_new_sys_type(sys.flags)
diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py
index 02592ea5eb21a1..fc26e71ffcb67b 100644
--- a/Lib/test/test_types.py
+++ b/Lib/test/test_types.py
@@ -2,7 +2,7 @@
from test.support import (
run_with_locale, cpython_only, no_rerun,
- MISSING_C_DOCSTRINGS, EqualToForwardRef,
+ MISSING_C_DOCSTRINGS, EqualToForwardRef, check_disallow_instantiation,
)
from test.support.script_helper import assert_python_ok
from test.support.import_helper import import_fresh_module
@@ -1148,8 +1148,7 @@ def test_or_type_operator_reference_cycle(self):
msg='Check for union reference leak.')
def test_instantiation(self):
- with self.assertRaises(TypeError):
- types.UnionType()
+ check_disallow_instantiation(self, types.UnionType)
self.assertIs(int, types.UnionType[int])
self.assertIs(int, types.UnionType[int, int])
self.assertEqual(int | str, types.UnionType[int, str])
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2025-06-26-15-25-51.gh-issue-78465.MbDN8X.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-26-15-25-51.gh-issue-78465.MbDN8X.rst
new file mode 100644
index 00000000000000..99734d63c5d87e
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-26-15-25-51.gh-issue-78465.MbDN8X.rst
@@ -0,0 +1,2 @@
+Fix error message for ``cls.__new__(cls, ...)`` where ``cls`` is not
+instantiable builtin or extension type (with ``tp_new`` set to ``NULL``).
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index b9d549610693c1..6e7471cb5941a7 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -10020,6 +10020,11 @@ tp_new_wrapper(PyObject *self, PyObject *args,
PyObject *kwds)
/* If staticbase is NULL now, it is a really weird type.
In the spirit of backwards compatibility (?), just shut up. */
if (staticbase && staticbase->tp_new != type->tp_new) {
+ if (staticbase->tp_new == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "cannot create '%s' instances", subtype->tp_name);
+ return NULL;
+ }
PyErr_Format(PyExc_TypeError,
"%s.__new__(%s) is not safe, use %s.__new__()",
type->tp_name,
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]