From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Fri, 27 Jun 2025 12:01:48 +0000 (+0200) Subject: [3.14] gh-78465: Fix error message for cls.__new__(cls, ...) where cls is not instant... X-Git-Tag: v3.14.0b4~80 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1b218680b7c1bb4dfbbb1c750b8929d5e778577e;p=thirdparty%2FPython%2Fcpython.git [3.14] gh-78465: Fix error message for cls.__new__(cls, ...) where cls is not instantiable (GH-135981) (GH-136030) Previous error message suggested to use cls.__new__(), which obviously does not work. Now the error message is the same as for cls(...). (cherry picked from commit c45f4f3ebe34529a8db3a7918e8dd2e9f7ce8e86) Co-authored-by: Serhiy Storchaka --- diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 8afc9c28182b..ce18518bb8aa 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2334,6 +2334,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 ec9da33cf463..e2117b9588db 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -869,12 +869,7 @@ class SysModuleTest(unittest.TestCase): 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 02592ea5eb21..fc26e71ffcb6 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 @@ class UnionTests(unittest.TestCase): 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 000000000000..99734d63c5d8 --- /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 32bbaecf9a3d..455d32434c46 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -9717,6 +9717,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,