https://github.com/python/cpython/commit/3576e1a9545dee13c9dab3ef154b34f95acf4025
commit: 3576e1a9545dee13c9dab3ef154b34f95acf4025
branch: 3.13
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2025-06-27T12:07:22Z
summary:

[3.13] gh-78465: Fix error message for cls.__new__(cls, ...) where cls is not 
instantiable (GH-135981) (GH-136031)

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)

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 Objects/typeobject.c

diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index c2b407159a57ec..8bed02a158989a 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -2269,6 +2269,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 72d51361e0b4d1..6b37094ed5fc32 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -894,12 +894,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/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 2b63c1bbfab337..2dface4b758224 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -9087,6 +9087,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]

Reply via email to