1
+ import abc
1
2
import contextlib
2
3
import collections
3
4
import pickle
14
15
from typing import Generic
15
16
from typing import cast
16
17
from typing import get_type_hints
18
+ from typing import is_compatible
17
19
from typing import no_type_check , no_type_check_decorator
18
20
from typing import NamedTuple
19
21
from typing import IO , TextIO , BinaryIO
@@ -81,15 +83,15 @@ def test_cannot_subscript(self):
81
83
def test_any_is_subclass (self ):
82
84
# Any should be considered a subclass of everything.
83
85
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 ])
93
95
assert issubclass (Any , AnyStr )
94
96
assert issubclass (Any , Union )
95
97
assert issubclass (Any , Union [int , str ])
@@ -794,13 +796,13 @@ class VarianceTests(TestCase):
794
796
def test_invariance (self ):
795
797
# Because of invariance, List[subclass of X] is not a subclass
796
798
# 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 ])
800
802
# 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 ])
804
806
805
807
def test_covariance_tuple (self ):
806
808
# Check covariace for Tuple (which are really special cases).
@@ -817,20 +819,20 @@ def test_covariance_tuple(self):
817
819
def test_covariance_sequence (self ):
818
820
# Check covariance for Sequence (which is just a generic class
819
821
# 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 ])
823
825
824
826
def test_covariance_mapping (self ):
825
827
# 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 ])
834
836
835
837
836
838
class CastTests (TestCase ):
@@ -1089,17 +1091,28 @@ def test_iterable(self):
1089
1091
# path and could fail. So call this a few times.
1090
1092
assert isinstance ([], typing .Iterable )
1091
1093
assert isinstance ([], typing .Iterable )
1092
- assert isinstance ([], typing .Iterable [int ])
1094
+ assert not isinstance ([], typing .Iterable [int ])
1093
1095
assert not isinstance (42 , typing .Iterable )
1094
1096
# Just in case, also test issubclass() a few times.
1095
1097
assert issubclass (list , typing .Iterable )
1096
1098
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 ])
1097
1107
1098
1108
def test_iterator (self ):
1099
1109
it = iter ([])
1100
1110
assert isinstance (it , typing .Iterator )
1101
- assert isinstance (it , typing .Iterator [int ])
1111
+ assert not isinstance (it , typing .Iterator [int ])
1102
1112
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 ])
1103
1116
1104
1117
@skipUnless (PY35 , 'Python 3.5 required' )
1105
1118
def test_awaitable (self ):
@@ -1110,13 +1123,16 @@ def test_awaitable(self):
1110
1123
globals (), ns )
1111
1124
foo = ns ['foo' ]
1112
1125
g = foo ()
1113
- assert issubclass (type (g ), typing .Awaitable [int ])
1114
1126
assert isinstance (g , typing .Awaitable )
1115
1127
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 ])
1120
1136
g .send (None ) # Run foo() till completion, to avoid warning.
1121
1137
1122
1138
@skipUnless (PY35 , 'Python 3.5 required' )
@@ -1125,17 +1141,17 @@ def test_async_iterable(self):
1125
1141
it = AsyncIteratorWrapper (base_it )
1126
1142
assert isinstance (it , typing .AsyncIterable )
1127
1143
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 ])
1130
1146
assert not isinstance (42 , typing .AsyncIterable )
1131
1147
1132
1148
@skipUnless (PY35 , 'Python 3.5 required' )
1133
1149
def test_async_iterator (self ):
1134
1150
base_it = range (10 ) # type: Iterator[int]
1135
1151
it = AsyncIteratorWrapper (base_it )
1136
1152
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 ])
1139
1155
assert not isinstance (42 , typing .AsyncIterator )
1140
1156
1141
1157
def test_sized (self ):
@@ -1175,18 +1191,19 @@ def test_bytestring(self):
1175
1191
assert isinstance (bytearray (b'' ), typing .ByteString )
1176
1192
1177
1193
def test_list (self ):
1178
- assert issubclass (list , typing .List )
1194
+ assert is_compatible (list , typing .List )
1195
+ assert not issubclass (list , typing .List )
1179
1196
1180
1197
def test_set (self ):
1181
- assert issubclass (set , typing .Set )
1182
- assert not issubclass (frozenset , typing .Set )
1198
+ assert is_compatible (set , typing .Set )
1199
+ assert not is_compatible (frozenset , typing .Set )
1183
1200
1184
1201
def test_frozenset (self ):
1185
- assert issubclass (frozenset , typing .FrozenSet )
1186
- assert not issubclass (set , typing .FrozenSet )
1202
+ assert is_compatible (frozenset , typing .FrozenSet )
1203
+ assert not is_compatible (set , typing .FrozenSet )
1187
1204
1188
1205
def test_dict (self ):
1189
- assert issubclass (dict , typing .Dict )
1206
+ assert is_compatible (dict , typing .Dict )
1190
1207
1191
1208
def test_no_list_instantiation (self ):
1192
1209
with self .assertRaises (TypeError ):
@@ -1204,9 +1221,11 @@ class MyList(typing.List[int]):
1204
1221
a = MyList ()
1205
1222
assert isinstance (a , MyList )
1206
1223
assert isinstance (a , typing .Sequence )
1224
+ assert isinstance (a , collections .Sequence )
1207
1225
1208
1226
assert issubclass (MyList , list )
1209
- assert not issubclass (list , MyList )
1227
+ assert is_compatible (MyList , list )
1228
+ assert not is_compatible (list , MyList )
1210
1229
1211
1230
def test_no_dict_instantiation (self ):
1212
1231
with self .assertRaises (TypeError ):
@@ -1224,9 +1243,11 @@ class MyDict(typing.Dict[str, int]):
1224
1243
d = MyDict ()
1225
1244
assert isinstance (d , MyDict )
1226
1245
assert isinstance (d , typing .MutableMapping )
1246
+ assert isinstance (d , collections .MutableMapping )
1227
1247
1228
1248
assert issubclass (MyDict , dict )
1229
- assert not issubclass (dict , MyDict )
1249
+ assert is_compatible (MyDict , dict )
1250
+ assert not is_compatible (dict , MyDict )
1230
1251
1231
1252
def test_no_defaultdict_instantiation (self ):
1232
1253
with self .assertRaises (TypeError ):
@@ -1245,7 +1266,7 @@ class MyDefDict(typing.DefaultDict[str, int]):
1245
1266
assert isinstance (dd , MyDefDict )
1246
1267
1247
1268
assert issubclass (MyDefDict , collections .defaultdict )
1248
- assert not issubclass (collections .defaultdict , MyDefDict )
1269
+ assert not is_compatible (collections .defaultdict , MyDefDict )
1249
1270
1250
1271
def test_no_set_instantiation (self ):
1251
1272
with self .assertRaises (TypeError ):
@@ -1292,10 +1313,11 @@ def foo():
1292
1313
yield 42
1293
1314
g = foo ()
1294
1315
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 ])
1316
+ assert not issubclass (int , typing .Generator )
1317
+ assert is_compatible (typing .Generator [Manager , Employee , Manager ],
1318
+ typing .Generator [Employee , Manager , Employee ])
1319
+ assert not is_compatible (typing .Generator [Manager , Manager , Manager ],
1320
+ typing .Generator [Employee , Employee , Employee ])
1299
1321
1300
1322
def test_no_generator_instantiation (self ):
1301
1323
with self .assertRaises (TypeError ):
@@ -1314,25 +1336,115 @@ class MMA(typing.MutableMapping):
1314
1336
MMA ()
1315
1337
1316
1338
class MMC (MMA ):
1317
- def __len__ (self ):
1318
- return 0
1339
+ def __iter__ (self ): ...
1340
+ def __len__ (self ): return 0
1341
+ def __getitem__ (self , name ): ...
1342
+ def __setitem__ (self , name , value ): ...
1343
+ def __delitem__ (self , name ): ...
1319
1344
1320
1345
assert len (MMC ()) == 0
1346
+ assert callable (MMC .update )
1347
+ assert isinstance (MMC (), typing .Mapping )
1321
1348
1322
1349
class MMB (typing .MutableMapping [KT , VT ]):
1323
- def __len__ (self ):
1324
- return 0
1350
+ def __iter__ (self ): ...
1351
+ def __len__ (self ): return 0
1352
+ def __getitem__ (self , name ): ...
1353
+ def __setitem__ (self , name , value ): ...
1354
+ def __delitem__ (self , name ): ...
1325
1355
1326
1356
assert len (MMB ()) == 0
1327
1357
assert len (MMB [str , str ]()) == 0
1328
1358
assert len (MMB [KT , VT ]()) == 0
1359
+ assert isinstance (MMB [KT , VT ](), typing .Mapping )
1360
+ assert isinstance (MMB [KT , VT ](), collections .Mapping )
1329
1361
1330
1362
assert not issubclass (dict , MMA )
1331
1363
assert not issubclass (dict , MMB )
1364
+ assert not is_compatible (dict , MMA )
1365
+ assert not is_compatible (dict , MMB )
1332
1366
1333
1367
assert issubclass (MMA , typing .Mapping )
1334
1368
assert issubclass (MMB , typing .Mapping )
1335
1369
assert issubclass (MMC , typing .Mapping )
1370
+ assert issubclass (MMA , collections .Mapping )
1371
+ assert issubclass (MMB , collections .Mapping )
1372
+ assert issubclass (MMC , collections .Mapping )
1373
+ assert is_compatible (MMC , typing .Mapping )
1374
+ assert is_compatible (MMC , collections .Mapping )
1375
+
1376
+ assert issubclass (MMB [str , str ], typing .Mapping )
1377
+ assert is_compatible (MMB [str , str ], typing .Mapping )
1378
+
1379
+ assert issubclass (MMC , MMA )
1380
+ assert is_compatible (MMC , MMA )
1381
+
1382
+ assert not issubclass (MMA , typing .Mapping [str , str ])
1383
+ assert not issubclass (MMB , typing .Mapping [str , str ])
1384
+
1385
+ class I (typing .Iterable ): ...
1386
+ assert not issubclass (list , I )
1387
+
1388
+ class G (typing .Generator [int , int , int ]): ...
1389
+ def g (): yield 0
1390
+ assert issubclass (G , typing .Generator )
1391
+ assert issubclass (G , typing .Iterable )
1392
+ if hasattr (collections , 'Generator' ):
1393
+ assert issubclass (G , collections .Generator )
1394
+ assert issubclass (G , collections .Iterable )
1395
+ assert not issubclass (type (g ), G )
1396
+
1397
+ def test_subclassing_subclasshook (self ):
1398
+
1399
+ class Base :
1400
+ @classmethod
1401
+ def __subclasshook__ (cls , other ):
1402
+ if other .__name__ == 'Foo' :
1403
+ return True
1404
+ else :
1405
+ return False
1406
+
1407
+ class C (Base , typing .Iterable ): ...
1408
+ class Foo : ...
1409
+
1410
+ assert issubclass (Foo , C )
1411
+
1412
+ def test_subclassing_register (self ):
1413
+
1414
+ class A (typing .Container ): ...
1415
+ class B (A ): ...
1416
+
1417
+ class C : ...
1418
+ A .register (C )
1419
+ assert is_compatible (C , A )
1420
+ assert not is_compatible (C , B )
1421
+
1422
+ class D : ...
1423
+ B .register (D )
1424
+ assert is_compatible (D , A )
1425
+ assert is_compatible (D , B )
1426
+
1427
+ class M (): ...
1428
+ collections .MutableMapping .register (M )
1429
+ assert issubclass (M , typing .Mapping )
1430
+
1431
+ def test_collections_as_base (self ):
1432
+
1433
+ class M (collections .Mapping ): ...
1434
+ assert issubclass (M , typing .Mapping )
1435
+ assert issubclass (M , typing .Iterable )
1436
+
1437
+ class S (collections .MutableSequence ): ...
1438
+ assert issubclass (S , typing .MutableSequence )
1439
+ assert issubclass (S , typing .Iterable )
1440
+
1441
+ class I (collections .Iterable ): ...
1442
+ assert issubclass (I , typing .Iterable )
1443
+
1444
+ class A (collections .Mapping , metaclass = abc .ABCMeta ): ...
1445
+ class B : ...
1446
+ A .register (B )
1447
+ assert issubclass (B , typing .Mapping )
1336
1448
1337
1449
1338
1450
class OtherABCTests (TestCase ):
0 commit comments