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 [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 ])
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 ):
@@ -1176,14 +1192,17 @@ def test_bytestring(self):
1176
1192
1177
1193
def test_list (self ):
1178
1194
assert issubclass (list , typing .List )
1195
+ assert is_compatible (list , typing .List )
1179
1196
1180
1197
def test_set (self ):
1181
1198
assert issubclass (set , typing .Set )
1182
1199
assert not issubclass (frozenset , typing .Set )
1200
+ assert not is_compatible (frozenset , typing .Set )
1183
1201
1184
1202
def test_frozenset (self ):
1185
- assert issubclass (frozenset , typing .FrozenSet )
1203
+ assert is_compatible (frozenset , typing .FrozenSet )
1186
1204
assert not issubclass (set , typing .FrozenSet )
1205
+ assert not is_compatible (set , typing .FrozenSet )
1187
1206
1188
1207
def test_dict (self ):
1189
1208
assert issubclass (dict , typing .Dict )
@@ -1204,9 +1223,11 @@ class MyList(typing.List[int]):
1204
1223
a = MyList ()
1205
1224
assert isinstance (a , MyList )
1206
1225
assert isinstance (a , typing .Sequence )
1226
+ assert isinstance (a , collections .Sequence )
1207
1227
1208
1228
assert issubclass (MyList , list )
1209
- assert not issubclass (list , MyList )
1229
+ assert is_compatible (MyList , list )
1230
+ assert not is_compatible (list , MyList )
1210
1231
1211
1232
def test_no_dict_instantiation (self ):
1212
1233
with self .assertRaises (TypeError ):
@@ -1224,9 +1245,11 @@ class MyDict(typing.Dict[str, int]):
1224
1245
d = MyDict ()
1225
1246
assert isinstance (d , MyDict )
1226
1247
assert isinstance (d , typing .MutableMapping )
1248
+ assert isinstance (d , collections .MutableMapping )
1227
1249
1228
1250
assert issubclass (MyDict , dict )
1229
- assert not issubclass (dict , MyDict )
1251
+ assert is_compatible (MyDict , dict )
1252
+ assert not is_compatible (dict , MyDict )
1230
1253
1231
1254
def test_no_defaultdict_instantiation (self ):
1232
1255
with self .assertRaises (TypeError ):
@@ -1245,7 +1268,7 @@ class MyDefDict(typing.DefaultDict[str, int]):
1245
1268
assert isinstance (dd , MyDefDict )
1246
1269
1247
1270
assert issubclass (MyDefDict , collections .defaultdict )
1248
- assert not issubclass (collections .defaultdict , MyDefDict )
1271
+ assert not is_compatible (collections .defaultdict , MyDefDict )
1249
1272
1250
1273
def test_no_set_instantiation (self ):
1251
1274
with self .assertRaises (TypeError ):
@@ -1292,10 +1315,11 @@ def foo():
1292
1315
yield 42
1293
1316
g = foo ()
1294
1317
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 ])
1299
1323
1300
1324
def test_no_generator_instantiation (self ):
1301
1325
with self .assertRaises (TypeError ):
@@ -1314,25 +1338,115 @@ class MMA(typing.MutableMapping):
1314
1338
MMA ()
1315
1339
1316
1340
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 ): ...
1319
1346
1320
1347
assert len (MMC ()) == 0
1348
+ assert callable (MMC .update )
1349
+ assert isinstance (MMC (), typing .Mapping )
1321
1350
1322
1351
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 ): ...
1325
1357
1326
1358
assert len (MMB ()) == 0
1327
1359
assert len (MMB [str , str ]()) == 0
1328
1360
assert len (MMB [KT , VT ]()) == 0
1361
+ assert isinstance (MMB [KT , VT ](), typing .Mapping )
1362
+ assert isinstance (MMB [KT , VT ](), collections .Mapping )
1329
1363
1330
1364
assert not issubclass (dict , MMA )
1331
1365
assert not issubclass (dict , MMB )
1366
+ assert not is_compatible (dict , MMA )
1367
+ assert not is_compatible (dict , MMB )
1332
1368
1333
1369
assert issubclass (MMA , typing .Mapping )
1334
1370
assert issubclass (MMB , typing .Mapping )
1335
1371
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 )
1336
1450
1337
1451
1338
1452
class OtherABCTests (TestCase ):
0 commit comments