From a9e857b9be748627d827bbeeafce6bad8d134405 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Wed, 2 Feb 2022 17:03:09 +0300 Subject: [PATCH 1/3] bpo-46611: add coverage to instance and class checks in `typing.py` --- Lib/test/test_types.py | 42 +++++++++++++++++++++++++---------------- Lib/test/test_typing.py | 3 +++ 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index c54854eeb5ad22..be40446bb5e199 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -703,22 +703,32 @@ def test_hash(self): self.assertEqual(hash(int | str), hash(str | int)) self.assertEqual(hash(int | str), hash(typing.Union[int, str])) - def test_instancecheck(self): - x = int | str - self.assertIsInstance(1, x) - self.assertIsInstance(True, x) - self.assertIsInstance('a', x) - self.assertNotIsInstance(None, x) - self.assertTrue(issubclass(int, x)) - self.assertTrue(issubclass(bool, x)) - self.assertTrue(issubclass(str, x)) - self.assertFalse(issubclass(type(None), x)) - x = int | None - self.assertIsInstance(None, x) - self.assertTrue(issubclass(type(None), x)) - x = int | collections.abc.Mapping - self.assertIsInstance({}, x) - self.assertTrue(issubclass(dict, x)) + def test_instancecheck_and_subclasscheck(self): + for x in [int | str, typing.Union[int, str]]: + with self.subTest(x=x): + self.assertIsInstance(1, x) + self.assertIsInstance(True, x) + self.assertIsInstance('a', x) + self.assertNotIsInstance(None, x) + self.assertTrue(issubclass(int, x)) + self.assertTrue(issubclass(bool, x)) + self.assertTrue(issubclass(str, x)) + self.assertFalse(issubclass(type(None), x)) + + for x in [int | None, typing.Union[int, None]]: + with self.subTest(x=x): + self.assertIsInstance(None, x) + self.assertTrue(issubclass(type(None), x)) + + for x in [ + int | collections.abc.Mapping, + typing.Union[int, collections.abc.Mapping], + ]: + with self.subTest(x=x): + self.assertIsInstance({}, x) + self.assertNotIsInstance((), x) + self.assertTrue(issubclass(dict, x)) + self.assertFalse(issubclass(list, x)) def test_bad_instancecheck(self): class BadMeta(type): diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 85f74064458f2d..3873c0e70dde34 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -430,6 +430,8 @@ def test_tuple_subclass(self): class MyTuple(tuple): pass self.assertIsSubclass(MyTuple, Tuple) + self.assertIsSubclass(Tuple, Tuple) + self.assertIsSubclass(tuple, Tuple) def test_tuple_instance_type_error(self): with self.assertRaises(TypeError): @@ -457,6 +459,7 @@ def test_self_subclass(self): with self.assertRaises(TypeError): issubclass(types.FunctionType, Callable[[int], int]) self.assertIsSubclass(types.FunctionType, Callable) + self.assertIsSubclass(Callable, Callable) def test_eq_hash(self): Callable = self.Callable From d20ac7a794bb00fe384ee4af4abe641502866432 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Thu, 3 Feb 2022 10:17:07 +0300 Subject: [PATCH 2/3] Add more tests --- Lib/test/test_types.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index be40446bb5e199..3252d70ea7239e 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -730,6 +730,36 @@ def test_instancecheck_and_subclasscheck(self): self.assertTrue(issubclass(dict, x)) self.assertFalse(issubclass(list, x)) + def test_instancecheck_and_subclasscheck_order(self): + T = typing.TypeVar('T') + + will_resolve = [ + int | T, + typing.Union[int, T], + ] + for x in will_resolve: + with self.subTest(x=x): + self.assertIsInstance(1, x) + self.assertTrue(issubclass(int, x)) + + wont_resolve = [ + T | int, + typing.Union[T, int], + ] + for x in wont_resolve: + with self.subTest(x=x): + with self.assertRaises(TypeError): + issubclass(int, x) + with self.assertRaises(TypeError): + isinstance(1, x) + + for x in [*will_resolve, *wont_resolve]: + with self.subTest(x=x): + with self.assertRaises(TypeError): + issubclass(object, x) + with self.assertRaises(TypeError): + isinstance(object(), x) + def test_bad_instancecheck(self): class BadMeta(type): def __instancecheck__(cls, inst): From 96fa62e664ed5d3ce0470e5db0599b8f73c564bd Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sat, 5 Feb 2022 10:42:25 +0300 Subject: [PATCH 3/3] Address review, use `()` --- Lib/test/test_types.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 3252d70ea7239e..b8b1ce96f93c3a 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -704,7 +704,7 @@ def test_hash(self): self.assertEqual(hash(int | str), hash(typing.Union[int, str])) def test_instancecheck_and_subclasscheck(self): - for x in [int | str, typing.Union[int, str]]: + for x in (int | str, typing.Union[int, str]): with self.subTest(x=x): self.assertIsInstance(1, x) self.assertIsInstance(True, x) @@ -715,15 +715,15 @@ def test_instancecheck_and_subclasscheck(self): self.assertTrue(issubclass(str, x)) self.assertFalse(issubclass(type(None), x)) - for x in [int | None, typing.Union[int, None]]: + for x in (int | None, typing.Union[int, None]): with self.subTest(x=x): self.assertIsInstance(None, x) self.assertTrue(issubclass(type(None), x)) - for x in [ + for x in ( int | collections.abc.Mapping, typing.Union[int, collections.abc.Mapping], - ]: + ): with self.subTest(x=x): self.assertIsInstance({}, x) self.assertNotIsInstance((), x) @@ -733,19 +733,19 @@ def test_instancecheck_and_subclasscheck(self): def test_instancecheck_and_subclasscheck_order(self): T = typing.TypeVar('T') - will_resolve = [ + will_resolve = ( int | T, typing.Union[int, T], - ] + ) for x in will_resolve: with self.subTest(x=x): self.assertIsInstance(1, x) self.assertTrue(issubclass(int, x)) - wont_resolve = [ + wont_resolve = ( T | int, typing.Union[T, int], - ] + ) for x in wont_resolve: with self.subTest(x=x): with self.assertRaises(TypeError): @@ -753,7 +753,7 @@ def test_instancecheck_and_subclasscheck_order(self): with self.assertRaises(TypeError): isinstance(1, x) - for x in [*will_resolve, *wont_resolve]: + for x in (*will_resolve, *wont_resolve): with self.subTest(x=x): with self.assertRaises(TypeError): issubclass(object, x)