1+ import abc
12import contextlib
23import collections
34import pickle
1415from typing import Generic
1516from typing import cast
1617from typing import get_type_hints
18+ from typing import is_compatible
1719from typing import no_type_check , no_type_check_decorator
1820from typing import NamedTuple
1921from 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 [Manager , 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
836838class 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
13381452class OtherABCTests (TestCase ):
0 commit comments