From 4d10f703d79b72a9c7f88862c0b4a9abbfb04ee2 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 2 May 2022 08:29:49 +0300 Subject: [PATCH] gh-92114: Improve error message for types with __class_getitem__ = None (GH-92115) --- Lib/test/test_genericclass.py | 8 ++++++++ .../2022-05-01-16-40-07.gh-issue-92114.5xTlLt.rst | 2 ++ Objects/abstract.c | 3 ++- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-05-01-16-40-07.gh-issue-92114.5xTlLt.rst diff --git a/Lib/test/test_genericclass.py b/Lib/test/test_genericclass.py index 27420d4f2ba..d8bb37f69e1 100644 --- a/Lib/test/test_genericclass.py +++ b/Lib/test/test_genericclass.py @@ -220,6 +220,7 @@ class TestClassGetitem(unittest.TestCase): return None with self.assertRaises(TypeError): C_too_few[int] + class C_too_many: def __class_getitem__(cls, one, two): return None @@ -232,16 +233,23 @@ class TestClassGetitem(unittest.TestCase): return None with self.assertRaises(TypeError): C()[int] + class E: ... e = E() e.__class_getitem__ = lambda cls, item: 'This will not work' with self.assertRaises(TypeError): e[int] + class C_not_callable: __class_getitem__ = "Surprise!" with self.assertRaises(TypeError): C_not_callable[int] + class C_is_none(tuple): + __class_getitem__ = None + with self.assertRaisesRegex(TypeError, "C_is_none"): + C_is_none[int] + def test_class_getitem_metaclass(self): class Meta(type): def __class_getitem__(cls, item): diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-01-16-40-07.gh-issue-92114.5xTlLt.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-01-16-40-07.gh-issue-92114.5xTlLt.rst new file mode 100644 index 00000000000..a9992459530 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-05-01-16-40-07.gh-issue-92114.5xTlLt.rst @@ -0,0 +1,2 @@ +Improve error message when subscript a type with ``__class_getitem__`` set +to ``None``. diff --git a/Objects/abstract.c b/Objects/abstract.c index cfb0edcab0e..90347372356 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -185,11 +185,12 @@ PyObject_GetItem(PyObject *o, PyObject *key) if (_PyObject_LookupAttr(o, &_Py_ID(__class_getitem__), &meth) < 0) { return NULL; } - if (meth) { + if (meth && meth != Py_None) { result = PyObject_CallOneArg(meth, key); Py_DECREF(meth); return result; } + Py_XDECREF(meth); PyErr_Format(PyExc_TypeError, "type '%.200s' is not subscriptable", ((PyTypeObject *)o)->tp_name); return NULL;