From 171947e68f2848b845b4b248dc0298c8a592d885 Mon Sep 17 00:00:00 2001 From: Fidget-Spinner <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 25 May 2021 23:55:19 +0800 Subject: [PATCH] Fix type_new crash --- Lib/test/test_builtin.py | 17 ++++++++++++++++- .../2021-05-25-23-55-02.bpo-44232.KEDM_e.rst | 2 ++ Objects/typeobject.c | 1 - 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2021-05-25-23-55-02.bpo-44232.KEDM_e.rst diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index bd8353d038b6fea..efe1fa0911eddb9 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -19,7 +19,7 @@ import types import unittest import warnings -from contextlib import ExitStack +from contextlib import ExitStack, suppress from functools import partial from inspect import CO_COROUTINE from itertools import product @@ -2343,6 +2343,21 @@ def test_namespace_order(self): C = type('C', (), od) self.assertEqual(list(C.__dict__.items())[:2], [('b', 2), ('a', 1)]) + def test_new_type_bad_tp_new(self): + # bpo-44232: Bad tp_new in bases tuple should just return NULL + # instead of causing an interpreter crash in debug mode. + class XBase(type): + def __new__(cls, name, bases, attrs, **kwargs): + attrs.pop('__module__') + return super().__new__(cls, name, bases, attrs, **kwargs) + + class X(metaclass=XBase): ... + + # The actual error here doesn't matter. As long as the interpreter + # doesn't crash. + with suppress(Exception): + type('A', (X,), {}) + def load_tests(loader, tests, pattern): from doctest import DocTestSuite diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-05-25-23-55-02.bpo-44232.KEDM_e.rst b/Misc/NEWS.d/next/Core and Builtins/2021-05-25-23-55-02.bpo-44232.KEDM_e.rst new file mode 100644 index 000000000000000..463c764cecad9e2 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-05-25-23-55-02.bpo-44232.KEDM_e.rst @@ -0,0 +1,2 @@ +Fixed a crash caused by bad metaclass bases being passed into :func:`type`. +This only affected debug builds of Python -- release builds are unaffected. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index af99ab79d14ade8..d8aff7ac07580a0 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3310,7 +3310,6 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) return NULL; } if (res == 1) { - assert(type != NULL); return type; } assert(ctx.base != NULL);