30
30
except ImportError :
31
31
ExtensionsTypedDictMeta = None
32
32
33
- __all__ = [
34
- "ExtensionsTypedDict" ,
35
- "is_py37" ,
36
- "is_py38" ,
37
- "is_py39_plus" ,
38
- "is_py310_plus" ,
39
- "is_py311_plus" ,
40
- "is_typeddict" ,
41
- "TypedDict" ,
42
- ]
43
-
44
- version_info = sys .version_info [0 :3 ]
45
- is_py37 = version_info [:2 ] == (3 , 7 )
46
- is_py38 = version_info [:2 ] == (3 , 8 )
47
- is_py39_plus = version_info [:2 ] >= (3 , 9 )
48
- is_py310_plus = version_info [:2 ] >= (3 , 10 )
49
- is_py311_plus = version_info [:2 ] >= (3 , 11 )
50
-
51
- if is_py37 :
33
+ if sys .version_info >= (3 , 8 ):
34
+ from typing import Final , Protocol , get_args , get_origin
35
+
36
+ else :
52
37
53
38
def get_args (cl ):
54
39
return cl .__args__
@@ -58,10 +43,7 @@ def get_origin(cl):
58
43
59
44
from typing_extensions import Final , Protocol
60
45
61
- else :
62
- from typing import Final , Protocol , get_args , get_origin
63
-
64
- if is_py311_plus :
46
+ if sys .version_info >= (3 , 11 ):
65
47
ExceptionGroup = ExceptionGroup
66
48
else :
67
49
from exceptiongroup import ExceptionGroup as ExceptionGroup # noqa: PLC0414
@@ -157,144 +139,7 @@ def get_final_base(type) -> Optional[type]:
157
139
OriginAbstractSet = AbcSet
158
140
OriginMutableSet = AbcMutableSet
159
141
160
- if is_py37 or is_py38 :
161
- Set = TypingSet
162
- AbstractSet = TypingAbstractSet
163
- MutableSet = TypingMutableSet
164
-
165
- Sequence = TypingSequence
166
- MutableSequence = TypingMutableSequence
167
- MutableMapping = TypingMutableMapping
168
- Mapping = TypingMapping
169
- FrozenSetSubscriptable = FrozenSet
170
- TupleSubscriptable = Tuple
171
-
172
- from collections import Counter as ColCounter
173
- from typing import Counter , Union , _GenericAlias
174
-
175
- from typing_extensions import Annotated , NotRequired , Required
176
- from typing_extensions import get_origin as te_get_origin
177
-
178
- if is_py38 :
179
- from typing import TypedDict , _TypedDictMeta
180
- else :
181
- _TypedDictMeta = None
182
- TypedDict = ExtensionsTypedDict
183
-
184
- def is_annotated (type ) -> bool :
185
- return te_get_origin (type ) is Annotated
186
-
187
- def is_tuple (type ):
188
- return type in (Tuple , tuple ) or (
189
- type .__class__ is _GenericAlias and issubclass (type .__origin__ , Tuple )
190
- )
191
-
192
- def is_union_type (obj ):
193
- return (
194
- obj is Union or isinstance (obj , _GenericAlias ) and obj .__origin__ is Union
195
- )
196
-
197
- def get_newtype_base (typ : Any ) -> Optional [type ]:
198
- supertype = getattr (typ , "__supertype__" , None )
199
- if (
200
- supertype is not None
201
- and getattr (typ , "__qualname__" , "" ) == "NewType.<locals>.new_type"
202
- and typ .__module__ in ("typing" , "typing_extensions" )
203
- ):
204
- return supertype
205
- return None
206
-
207
- def is_sequence (type : Any ) -> bool :
208
- return type in (List , list , Tuple , tuple ) or (
209
- type .__class__ is _GenericAlias
210
- and (
211
- type .__origin__ not in (Union , Tuple , tuple )
212
- and issubclass (type .__origin__ , TypingSequence )
213
- )
214
- or (type .__origin__ in (Tuple , tuple ) and type .__args__ [1 ] is ...)
215
- )
216
-
217
- def is_deque (type : Any ) -> bool :
218
- return (
219
- type in (deque , Deque )
220
- or (type .__class__ is _GenericAlias and issubclass (type .__origin__ , deque ))
221
- or type .__origin__ is deque
222
- )
223
-
224
- def is_mutable_set (type ):
225
- return type is set or (
226
- type .__class__ is _GenericAlias and issubclass (type .__origin__ , MutableSet )
227
- )
228
-
229
- def is_frozenset (type ):
230
- return type is frozenset or (
231
- type .__class__ is _GenericAlias and issubclass (type .__origin__ , FrozenSet )
232
- )
233
-
234
- def is_mapping (type ):
235
- return type in (TypingMapping , dict ) or (
236
- type .__class__ is _GenericAlias
237
- and issubclass (type .__origin__ , TypingMapping )
238
- )
239
-
240
- bare_generic_args = {
241
- List .__args__ ,
242
- TypingSequence .__args__ ,
243
- TypingMapping .__args__ ,
244
- Dict .__args__ ,
245
- TypingMutableSequence .__args__ ,
246
- Tuple .__args__ ,
247
- None , # non-parametrized containers do not have `__args__ attribute in py3.7-8
248
- }
249
-
250
- def is_bare (type ):
251
- return getattr (type , "__args__" , None ) in bare_generic_args
252
-
253
- def is_counter (type ):
254
- return (
255
- type in (Counter , ColCounter )
256
- or getattr (type , "__origin__" , None ) is ColCounter
257
- )
258
-
259
- if is_py38 :
260
- from typing import Literal
261
-
262
- def is_literal (type ) -> bool :
263
- return type .__class__ is _GenericAlias and type .__origin__ is Literal
264
-
265
- else :
266
- # No literals in 3.7.
267
- def is_literal (_ ) -> bool :
268
- return False
269
-
270
- def is_generic (obj ):
271
- return isinstance (obj , _GenericAlias )
272
-
273
- def copy_with (type , args ):
274
- """Replace a generic type's arguments."""
275
- return type .copy_with (args )
276
-
277
- def is_typeddict (cls ) -> bool :
278
- return (
279
- cls .__class__ is _TypedDictMeta
280
- or (is_generic (cls ) and (cls .__origin__ .__class__ is _TypedDictMeta ))
281
- or (
282
- ExtensionsTypedDictMeta is not None
283
- and cls .__class__ is ExtensionsTypedDictMeta
284
- or (
285
- is_generic (cls )
286
- and (cls .__origin__ .__class__ is ExtensionsTypedDictMeta )
287
- )
288
- )
289
- )
290
-
291
- def get_notrequired_base (type ) -> "Union[Any, Literal[NOTHING]]" :
292
- if get_origin (type ) in (NotRequired , Required ):
293
- return get_args (type )[0 ]
294
- return NOTHING
295
-
296
- else :
297
- # 3.9+
142
+ if sys .version_info >= (3 , 9 ):
298
143
from collections import Counter
299
144
from collections .abc import Mapping as AbcMapping
300
145
from collections .abc import MutableMapping as AbcMutableMapping
@@ -348,7 +193,7 @@ def is_tuple(type):
348
193
or (getattr (type , "__origin__" , None ) is tuple )
349
194
)
350
195
351
- if is_py310_plus :
196
+ if sys . version_info >= ( 3 , 10 ) :
352
197
353
198
def is_union_type (obj ):
354
199
from types import UnionType
@@ -364,7 +209,7 @@ def get_newtype_base(typ: Any) -> Optional[type]:
364
209
return typ .__supertype__
365
210
return None
366
211
367
- if is_py311_plus :
212
+ if sys . version_info >= ( 3 , 11 ) :
368
213
from typing import NotRequired , Required
369
214
else :
370
215
from typing_extensions import NotRequired , Required
@@ -500,6 +345,142 @@ def copy_with(type, args):
500
345
return Annotated [args ]
501
346
return type .__origin__ [args ]
502
347
348
+ else :
349
+ Set = TypingSet
350
+ AbstractSet = TypingAbstractSet
351
+ MutableSet = TypingMutableSet
352
+
353
+ Sequence = TypingSequence
354
+ MutableSequence = TypingMutableSequence
355
+ MutableMapping = TypingMutableMapping
356
+ Mapping = TypingMapping
357
+ FrozenSetSubscriptable = FrozenSet
358
+ TupleSubscriptable = Tuple
359
+
360
+ from collections import Counter as ColCounter
361
+ from typing import Counter , Union , _GenericAlias
362
+
363
+ from typing_extensions import Annotated , NotRequired , Required
364
+ from typing_extensions import get_origin as te_get_origin
365
+
366
+ if sys .version_info >= (3 , 8 ):
367
+ from typing import TypedDict , _TypedDictMeta
368
+ else :
369
+ _TypedDictMeta = None
370
+ TypedDict = ExtensionsTypedDict
371
+
372
+ def is_annotated (type ) -> bool :
373
+ return te_get_origin (type ) is Annotated
374
+
375
+ def is_tuple (type ):
376
+ return type in (Tuple , tuple ) or (
377
+ type .__class__ is _GenericAlias and issubclass (type .__origin__ , Tuple )
378
+ )
379
+
380
+ def is_union_type (obj ):
381
+ return (
382
+ obj is Union or isinstance (obj , _GenericAlias ) and obj .__origin__ is Union
383
+ )
384
+
385
+ def get_newtype_base (typ : Any ) -> Optional [type ]:
386
+ supertype = getattr (typ , "__supertype__" , None )
387
+ if (
388
+ supertype is not None
389
+ and getattr (typ , "__qualname__" , "" ) == "NewType.<locals>.new_type"
390
+ and typ .__module__ in ("typing" , "typing_extensions" )
391
+ ):
392
+ return supertype
393
+ return None
394
+
395
+ def is_sequence (type : Any ) -> bool :
396
+ return type in (List , list , Tuple , tuple ) or (
397
+ type .__class__ is _GenericAlias
398
+ and (
399
+ type .__origin__ not in (Union , Tuple , tuple )
400
+ and issubclass (type .__origin__ , TypingSequence )
401
+ )
402
+ or (type .__origin__ in (Tuple , tuple ) and type .__args__ [1 ] is ...)
403
+ )
404
+
405
+ def is_deque (type : Any ) -> bool :
406
+ return (
407
+ type in (deque , Deque )
408
+ or (type .__class__ is _GenericAlias and issubclass (type .__origin__ , deque ))
409
+ or type .__origin__ is deque
410
+ )
411
+
412
+ def is_mutable_set (type ):
413
+ return type is set or (
414
+ type .__class__ is _GenericAlias and issubclass (type .__origin__ , MutableSet )
415
+ )
416
+
417
+ def is_frozenset (type ):
418
+ return type is frozenset or (
419
+ type .__class__ is _GenericAlias and issubclass (type .__origin__ , FrozenSet )
420
+ )
421
+
422
+ def is_mapping (type ):
423
+ return type in (TypingMapping , dict ) or (
424
+ type .__class__ is _GenericAlias
425
+ and issubclass (type .__origin__ , TypingMapping )
426
+ )
427
+
428
+ bare_generic_args = {
429
+ List .__args__ ,
430
+ TypingSequence .__args__ ,
431
+ TypingMapping .__args__ ,
432
+ Dict .__args__ ,
433
+ TypingMutableSequence .__args__ ,
434
+ Tuple .__args__ ,
435
+ None , # non-parametrized containers do not have `__args__ attribute in py3.7-8
436
+ }
437
+
438
+ def is_bare (type ):
439
+ return getattr (type , "__args__" , None ) in bare_generic_args
440
+
441
+ def is_counter (type ):
442
+ return (
443
+ type in (Counter , ColCounter )
444
+ or getattr (type , "__origin__" , None ) is ColCounter
445
+ )
446
+
447
+ if sys .version_info >= (3 , 8 ):
448
+ from typing import Literal
449
+
450
+ def is_literal (type ) -> bool :
451
+ return type .__class__ is _GenericAlias and type .__origin__ is Literal
452
+
453
+ else :
454
+ # No literals in 3.7.
455
+ def is_literal (_ ) -> bool :
456
+ return False
457
+
458
+ def is_generic (obj ):
459
+ return isinstance (obj , _GenericAlias )
460
+
461
+ def copy_with (type , args ):
462
+ """Replace a generic type's arguments."""
463
+ return type .copy_with (args )
464
+
465
+ def is_typeddict (cls ) -> bool :
466
+ return (
467
+ cls .__class__ is _TypedDictMeta
468
+ or (is_generic (cls ) and (cls .__origin__ .__class__ is _TypedDictMeta ))
469
+ or (
470
+ ExtensionsTypedDictMeta is not None
471
+ and cls .__class__ is ExtensionsTypedDictMeta
472
+ or (
473
+ is_generic (cls )
474
+ and (cls .__origin__ .__class__ is ExtensionsTypedDictMeta )
475
+ )
476
+ )
477
+ )
478
+
479
+ def get_notrequired_base (type ) -> "Union[Any, Literal[NOTHING]]" :
480
+ if get_origin (type ) in (NotRequired , Required ):
481
+ return get_args (type )[0 ]
482
+ return NOTHING
483
+
503
484
504
485
def is_generic_attrs (type ):
505
486
return is_generic (type ) and has (type .__origin__ )
0 commit comments