https://github.com/python/cpython/commit/f160f16373f9ea3f636bc5cd6fb4be7e150bb27f
commit: f160f16373f9ea3f636bc5cd6fb4be7e150bb27f
branch: main
author: Santhosh .I 🦇 <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-07-14T21:49:03+05:30
summary:
gh-151912: Fix segfault in `type()` with NULL `tp_new` metaclasses (#151916)
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2026-06-22-14-48-22.gh-issue-151912.YcxfnU.rst
M Lib/test/test_descr.py
M Objects/typeobject.c
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py
index 8a8e70214e27ae9..ba504119d294fd3 100644
--- a/Lib/test/test_descr.py
+++ b/Lib/test/test_descr.py
@@ -815,6 +815,15 @@ class X(C, int()):
class X(int(), C):
pass
+ @unittest.skipIf(_testcapi is None, 'need the _testcapi module')
+ def test_type_with_null_new_metaclass(self):
+ metaclass = _testcapi.HeapCTypeMetaclassNullNew
+ base = _testcapi.pytype_fromspec_meta(metaclass)
+
+ # Exercise type_new's metaclass selection path, not a direct call.
+ with self.assertRaisesRegex(TypeError, r"cannot create '.*'
instances"):
+ type("Derived", (base,), {})
+
def test_module_subclasses(self):
# Testing Python subclass of module...
log = []
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-22-14-48-22.gh-issue-151912.YcxfnU.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-22-14-48-22.gh-issue-151912.YcxfnU.rst
new file mode 100644
index 000000000000000..07b73949b438a33
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-22-14-48-22.gh-issue-151912.YcxfnU.rst
@@ -0,0 +1 @@
+Fixed a crash in ``type()`` when selecting a metaclass whose ``tp_new`` slot
is ``NULL``. Such metaclasses are now rejected with ``TypeError`` instead of
causing a NULL pointer dereference.
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index b77f3e3bce54551..ffa20ccaf3dfb87 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -5031,6 +5031,13 @@ type_new_get_bases(type_new_ctx *ctx, PyObject **type)
if (winner != ctx->metatype) {
if (winner->tp_new != type_new) {
+ /* Check if tp_new is NULL (cannot instantiate this type) */
+ if (winner->tp_new == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "cannot create '%.400s' instances",
+ winner->tp_name);
+ return -1;
+ }
/* Pass it to the winner */
*type = winner->tp_new(winner, ctx->args, ctx->kwds);
if (*type == NULL) {
_______________________________________________
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]