gh-101162: Forbid using issubclass() with GenericAlias as the 1st arg (GH-103369)

This commit is contained in:
Nikita Sobolev 2023-08-11 22:12:11 +03:00 committed by GitHub
parent 666b68e8f2
commit d93b4ac2ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 20 additions and 1 deletions

View File

@ -4091,6 +4091,22 @@ class GenericTests(BaseTestCase):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
C[()] C[()]
def test_generic_subclass_checks(self):
for typ in [list[int], List[int],
tuple[int, str], Tuple[int, str],
typing.Callable[..., None],
collections.abc.Callable[..., None]]:
with self.subTest(typ=typ):
self.assertRaises(TypeError, issubclass, typ, object)
self.assertRaises(TypeError, issubclass, typ, type)
self.assertRaises(TypeError, issubclass, typ, typ)
self.assertRaises(TypeError, issubclass, object, typ)
# isinstance is fine:
self.assertTrue(isinstance(typ, object))
# but, not when the right arg is also a generic:
self.assertRaises(TypeError, isinstance, typ, typ)
def test_init(self): def test_init(self):
T = TypeVar('T') T = TypeVar('T')
S = TypeVar('S') S = TypeVar('S')

View File

@ -0,0 +1,2 @@
Forbid using :func:`builtins.issubclass` with :class:`types.GenericAlias` as
the first argument.

View File

@ -2812,7 +2812,7 @@ object_issubclass(PyThreadState *tstate, PyObject *derived, PyObject *cls)
return -1; return -1;
} }
/* Probably never reached anymore. */ /* Can be reached when infinite recursion happens. */
return recursive_issubclass(derived, cls); return recursive_issubclass(derived, cls);
} }

View File

@ -626,6 +626,7 @@ ga_vectorcall(PyObject *self, PyObject *const *args,
static const char* const attr_exceptions[] = { static const char* const attr_exceptions[] = {
"__class__", "__class__",
"__bases__",
"__origin__", "__origin__",
"__args__", "__args__",
"__unpacked__", "__unpacked__",