8000 Insert extras as bases, remove GenericMeta.__subclasscheck__ · python/typing@0ec4dd2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0ec4dd2

Browse files
committed
Insert extras as bases, remove GenericMeta.__subclasscheck__
1 parent 2ef2a50 commit 0ec4dd2

File tree

2 files changed

+247
-89
lines changed

2 files changed

+247
-89
lines changed

src/test_typing.py

Lines changed: 163 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import abc
12
import contextlib
23
import collections
34
import pickle
@@ -14,6 +15,7 @@
1415
from typing import Generic
1516
from typing import cast
1617
from typing import get_type_hints
18+
from typing import is_compatible
1719
from typing import no_type_check, no_type_check_decorator
1820
from typing import NamedTuple
1921
from typing import IO, TextIO, BinaryIO
@@ -81,15 +83,15 @@ def test_cannot_subscript(self):
8183
def test_any_is_subclass(self):
8284
# Any should be considered a subclass of everything.
8385
assert issubclass(Any, Any)
84-
assert issubclass(Any, typing.List)
85-
assert issubclass(Any, typing.List[int])
86-
assert issubclass(Any, typing.List[T])
87-
assert issubclass(Any, typing.Mapping)
88-
assert issubclass(Any, typing.Mapping[str, int])
89-
assert issubclass(Any, typing.Mapping[KT, VT])
90-
assert issubclass(Any, Generic)
91-
assert issubclass(Any, Generic[T])
92-
assert issubclass(Any, Generic[KT, VT])
86+
assert is_compatible(Any, typing.List)
87+
assert is_compatible(Any, typing.List[int])
88+
assert is_compatible(Any, typing.List[T])
89+
assert is_compatible(Any, typing.Mapping)
90+
assert is_compatible(Any, typing.Mapping[str, int])
91+
assert is_compatible(Any, typing.Mapping[KT, VT])
92+
assert is_compatible(Any, Generic)
93+
assert is_compatible(Any, Generic[T])
94+
assert is_compatible(Any, Generic[KT, VT])
9395
assert issubclass(Any, AnyStr)
9496
assert issubclass(Any, Union)
9597
assert issubclass(Any, Union[int, str])
@@ -794,13 +796,13 @@ class VarianceTests(TestCase):
794796
def test_invariance(self):
795797
# Because of invariance, List[subclass of X] is not a subclass
796798
# of List[X], and ditto for MutableSequence.
797-
assert not issubclass(typing.List[Manager], typing.List[Employee])
798-
assert not issubclass(typing.MutableSequence[Manager],
799-
typing.MutableSequence[Employee])
799+
assert not is_compatible(typing.List[Manager], typing.List[Employee])
800+
assert not is_compatible(typing.MutableSequence[Manager],
801+
typing.MutableSequence[Employee])
800802
# It's still reflexive.
801-
assert issubclass(typing.List[Employee], typing.List[Employee])
802-
assert issubclass(typing.MutableSequence[Employee],
803-
typing.MutableSequence[Employee])
803+
assert is_compatible(typing.List[Employee], typing.List[Employee])
804+
assert is_compatible(typing.MutableSequence[Employee],
805+
typing.MutableSequence[Employee])
804806

805807
def test_covariance_tuple(self):
806808
# Check covariace for Tuple (which are really special cases).
@@ -817,20 +819,20 @@ def test_covariance_tuple(self):
817819
def test_covariance_sequence(self):
818820
# Check covariance for Sequence (which is just a generic class
819821
# for this purpose, but using a covariant type variable).
820-
assert issubclass(typing.Sequence[Manager], typing.Sequence[Employee])
821-
assert not issubclass(typing.Sequence[Employee],
822-
typing.Sequence[Manager])
822+
assert is_compatible(typing.Sequence[Manager], typing.Sequence[Employee])
823+
assert not is_compatible(typing.Sequence[Employee],
824+
typing.Sequence[Manager])
823825

824826
def test_covariance_mapping(self):
825827
# Ditto for Mapping (covariant in the value, invariant in the key).
826-
assert issubclass(typing.Mapping[Employee, Manager],
827-
typing.Mapping[Employee, Employee])
828-
assert not issubclass(typing.Mapping[Manager, Employee],
829-
typing.Mapping[Employee, Employee])
830-
assert not issubclass(typing.Mapping[Employee, Manager],
831-
typing.Mapping[Manager, Manager])
832-
assert not issubclass(typing.Mapping[Manager, Employee],
833-
typing.Mapping[Manager, Manager])
828+
assert is_compatible(typing.Mapping[Employee, Manager],
829+
typing.Mapping[Employee, Employee])
830+
assert not is_compatible(typing.Mapping[Manage F438 r, Employee],
831+
typing.Mapping[Employee, Employee])
832+
assert not is_compatible(typing.Mapping[Employee, Manager],
833+
typing.Mapping[Manager, Manager])
834+
assert not is_compatible(typing.Mapping[Manager, Employee],
835+
typing.Mapping[Manager, Manager])
834836

835837

836838
class CastTests(TestCase):
@@ -1089,17 +1091,28 @@ def test_iterable(self):
10891091
# path and could fail. So call this a few times.
10901092
assert isinstance([], typing.Iterable)
10911093
assert isinstance([], typing.Iterable)
1092-
assert isinstance([], typing.Iterable[int])
1094+
assert not isinstance([], typing.Iterable[int])
10931095
assert not isinstance(42, typing.Iterable)
10941096
# Just in case, also test issubclass() a few times.
10951097
assert issubclass(list, typing.Iterable)
10961098
assert issubclass(list, typing.Iterable)
1099+
assert is_compatible(list, typing.Iterable)
1100+
assert not issubclass(list, typing.Iterable[int])
1101+
assert is_compatible(list, typing.Iterable[int])
1102+
assert not is_compatible(int, typing.Iterable[int])
1103+
assert issubclass(tuple, typing.Sequence)
1104+
assert is_compatible(tuple, typing.Sequence)
1105+
assert not issubclass(tuple, typing.Sequence[int])
1106+
assert is_compatible(tuple, typing.Sequence[int])
10971107

10981108
def test_iterator(self):
10991109
it = iter([])
11001110
assert isinstance(it, typing.Iterator)
1101-
assert isinstance(it, typing.Iterator[int])
1111+
assert not isinstance(it, typing.Iterator[int])
11021112
assert not isinstance(42, typing.Iterator)
1113+
assert is_compatible(type(it), typing.Iterator)
1114+
assert is_compatible(type(it), typing.Iterator[int])
1115+
assert not is_compatible(int, typing.Iterator[int])
11031116

11041117
@skipUnless(PY35, 'Python 3.5 required')
11051118
def test_awaitable(self):
@@ -1110,13 +1123,16 @@ def test_awaitable(self):
11101123
globals(), ns)
11111124
foo = ns['foo']
11121125
g = foo()
1113-
assert issubclass(type(g), typing.Awaitable[int])
11141126
assert isinstance(g, typing.Awaitable)
11151127
assert not isinstance(foo, typing.Awaitable)
1116-
assert issubclass(typing.Awaitable[Manager],
1117-
typing.Awaitable[Employee])
1118-
assert not issubclass(typing.Awaitable[Employee],
1119-
typing.Awaitable[Manager])
1128+
assert is_compatible(type(g), typing.Awaitable[int])
1129+
assert not is_compatible(type(foo), typing.Awaitable[int])
1130+
assert not issubclass(typing.Awaitable[Manager],
1131+
typing.Awaitable[Employee])
1132+
assert is_compatible(typing.Awaitable[Manager],
1133+
typing.Awaitable[Employee])
1134+
assert not is_compatible(typing.Awaitable[Employee],
1135+
typing.Awaitable[Manager])
11201136
g.send(None) # Run foo() till completion, to avoid warning.
11211137

11221138
@skipUnless(PY35, 'Python 3.5 required')
@@ -1125,17 +1141,17 @@ def test_async_iterable(self):
11251141
it = AsyncIteratorWrapper(base_it)
11261142
assert isinstance(it, typing.AsyncIterable)
11271143
assert isinstance(it, typing.AsyncIterable)
1128-
assert issubclass(typing.AsyncIterable[Manager],
1129-
typing.AsyncIterable[Employee])
1144+
assert is_compatible(typing.AsyncIterable[Manager],
1145+
typing.AsyncIterable[Employee])
11301146
assert not isinstance(42, typing.AsyncIterable)
11311147

11321148
@skipUnless(PY35, 'Python 3.5 required')
11331149
def test_async_iterator(self):
11341150
base_it = range(10) # type: Iterator[int]
11351151
it = AsyncIteratorWrapper(base_it)
11361152
assert isinstance(it, typing.AsyncIterator)
1137-
assert issubclass(typing.AsyncIterator[Manager],
1138-
typing.AsyncIterator[Employee])
1153+
assert is_compatible(typing.AsyncIterator[Manager],
1154+
typing.AsyncIterator[Employee])
11391155
assert not isinstance(42, typing.AsyncIterator)
11401156

11411157
def test_sized(self):
@@ -1176,14 +1192,17 @@ def test_bytestring(self):
11761192

11771193
def test_list(self):
11781194
assert issubclass(list, typing.List)
1195+
assert is_compatible(list, typing.List)
11791196

11801197
def test_set(self):
11811198
assert issubclass(set, typing.Set)
11821199
assert not issubclass(frozenset, typing.Set)
1200+
assert not is_compatible(frozenset, typing.Set)
11831201

11841202
def test_frozenset(self):
1185-
assert issubclass(frozenset, typing.FrozenSet)
1203+
assert is_compatible(frozenset, typing.FrozenSet)
11861204
assert not issubclass(set, typing.FrozenSet)
1205+
assert not is_compatible(set, typing.FrozenSet)
11871206

11881207
def test_dict(self):
11891208
assert issubclass(dict, typing.Dict)
@@ -1204,9 +1223,11 @@ class MyList(typing.List[int]):
12041223
a = MyList()
12051224
assert isinstance(a, MyList)
12061225
assert isinstance(a, typing.Sequence)
1226+
assert isinstance(a, collections.Sequence)
12071227

12081228
assert issubclass(MyList, list)
1209-
assert not issubclass(list, MyList)
1229+
assert is_compatible(MyList, list)
1230+
assert not is_compatible(list, MyList)
12101231

12111232
def test_no_dict_instantiation(self):
12121233
with self.assertRaises(TypeError):
@@ -1224,9 +1245,11 @@ class MyDict(typing.Dict[str, int]):
12241245
d = MyDict()
12251246
assert isinstance(d, MyDict)
12261247
assert isinstance(d, typing.MutableMapping)
1248+
assert isinstance(d, collections.MutableMapping)
12271249

12281250
assert issubclass(MyDict, dict)
1229-
assert not issubclass(dict, MyDict)
1251+
assert is_compatible(MyDict, dict)
1252+
assert not is_compatible(dict, MyDict)
12301253

12311254
def test_no_defaultdict_instantiation(self):
12321255
with self.assertRaises(TypeError):
@@ -1245,7 +1268,7 @@ class MyDefDict(typing.DefaultDict[str, int]):
12451268
assert isinstance(dd, MyDefDict)
12461269

12471270
assert issubclass(MyDefDict, collections.defaultdict)
1248-
assert not issubclass(collections.defaultdict, MyDefDict)
1271+
assert not is_compatible(collections.defaultdict, MyDefDict)
12491272

12501273
def test_no_set_instantiation(self):
12511274
with self.assertRaises(TypeError):
@@ -1292,10 +1315,11 @@ def foo():
12921315
yield 42
12931316
g = foo()
12941317
assert issubclass(type(g), typing.Generator)
1295-
assert issubclass(typing.Generator[Manager, Employee, Manager],
1296-
typing.Generator[Employee, Manager, Employee])
1297-
assert not issubclass(typing.Generator[Manager, Manager, Manager],
1298-
typing.Generator[Employee, Employee, Employee])
1318+
assert not issubclass(int, typing.Generator)
1319+
assert is_compatible(typing.Generator[Manager, Employee, Manager],
1320+
typing.Generator[Employee, Manager, Employee])
1321+
assert not is_compatible(typing.Generator[Manager, Manager, Manager],
1322+
typing.Generator[Employee, Employee, Employee])
12991323

13001324
def test_no_generator_instantiation(self):
13011325
with self.assertRaises(TypeError):
@@ -1314,25 +1338,115 @@ class MMA(typing.MutableMapping):
13141338
MMA()
13151339

13161340
class MMC(MMA):
1317-
def __len__(self):
1318-
return 0
1341+
def __iter__(self): ...
1342+
def __len__(self): return 0
1343+
def __getitem__(self, name): ...
1344+
def __setitem__(self, name, value): ...
1345+
def __delitem__(self, name): ...
13191346

13201347
assert len(MMC()) == 0
1348+
assert callable(MMC.update)
1349+
assert isinstance(MMC(), typing.Mapping)
13211350

13221351
class MMB(typing.MutableMapping[KT, VT]):
1323-
def __len__(self):
1324-
return 0
1352+
def __iter__(self): ...
1353+
def __len__(self): return 0
1354+
def __getitem__(self, name): ...
1355+
def __setitem__(self, name, value): ...
1356+
def __delitem__(self, name): ...
13251357

13261358
assert len(MMB()) == 0
13271359
assert len(MMB[str, str]()) == 0
13281360
assert len(MMB[KT, VT]()) == 0
1361+
assert isinstance(MMB[KT, VT](), typing.Mapping)
1362+
assert isinstance(MMB[KT, VT](), collections.Mapping)
13291363

13301364
assert not issubclass(dict, MMA)
13311365
assert not issubclass(dict, MMB)
1366+
assert not is_compatible(dict, MMA)
1367+
assert not is_compatible(dict, MMB)
13321368

13331369
assert issubclass(MMA, typing.Mapping)
13341370
assert issubclass(MMB, typing.Mapping)
13351371
assert issubclass(MMC, typing.Mapping)
1372+
assert issubclass(MMA, collections.Mapping)
1373+
assert issubclass(MMB, collections.Mapping)
1374+
assert issubclass(MMC, collections.Mapping)
1375+
assert is_compatible(MMC, typing.Mapping)
1376+
assert is_compatible(MMC, collections.Mapping)
1377+
1378+
assert issubclass(MMB[str, str], typing.Mapping)
1379+
assert is_compatible(MMB[str, str], typing.Mapping)
1380+
1381+
assert issubclass(MMC, MMA)
1382+
assert is_compatible(MMC, MMA)
1383+
1384+
assert not issubclass(MMA, typing.Mapping[str, str])
1385+
assert not issubclass(MMB, typing.Mapping[str, str])
1386+
1387+
class I(typing.Iterable): ...
1388+
assert not issubclass(list, I)
1389+
1390+
class G(typing.Generator[int, int, int]): ...
1391+
def g(): yield 0
1392+
assert issubclass(G, typing.Generator)
1393+
assert issubclass(G, typing.Iterable)
1394+
if hasattr(collections, 'Generator'):
1395+
assert issubclass(G, collections.Generator)
1396+
assert issubclass(G, collections.Iterable)
1397+
assert not issubclass(type(g), G)
1398+
1399+
def test_subclassing_subclasshook(self):
1400+
1401+
class Base:
1402+
@classmethod
1403+
def __subclasshook__(cls, other):
1404+
if other.__name__ == 'Foo':
1405+
return True
1406+
else:
1407+
return False
1408+
1409+
class C(Base, typing.Iterable): ...
1410+
class Foo: ...
1411+
1412+
assert issubclass(Foo, C)
1413+
1414+
def test_subclassing_register(self):
1415+
1416+
class A(typing.Container): ...
1417+
class B(A): ...
1418+
1419+
class C: ...
1420+
A.register(C)
1421+
assert is_compatible(C, A)
1422+
assert not is_compatible(C, B)
1423+
1424+
class D: ...
1425+
B.register(D)
1426+
assert is_compatible(D, A)
1427+
assert is_compatible(D, B)
1428+
1429+
class M(): ...
1430+
collections.MutableMapping.register(M)
1431+
assert issubclass(M, typing.Mapping)
1432+
1433+
def test_collections_as_base(self):
1434+
1435+
class M(collections.Mapping): ...
1436+
assert issubclass(M, typing.Mapping)
1437+
assert issubclass(M, typing.Iterable)
1438+
1439+
class S(collections.MutableSequence): ...
1440+
assert issubclass(S, typing.MutableSequence)
1441+
assert issubclass(S, typing.Iterable)
1442+
1443+
class I(collections.Iterable): ...
1444+
assert issubclass(I, typing.Iterable)
1445+
1446+
class A(collections.Mapping, metaclass=abc.ABCMeta): ...
1447+
class B: ...
1448+
A.register(B)
1449+
assert issubclass(B, typing.Mapping)
13361450

13371451

13381452
class OtherABCTests(TestCase):

0 commit comments

Comments
 (0)
0