Skip to content

Commit 11c0fcf

Browse files
committed
Incorporate speed improvements for typing
Incorporates change made by #439, which was recently merged.
1 parent eab214c commit 11c0fcf

File tree

1 file changed

+61
-33
lines changed

1 file changed

+61
-33
lines changed

typing_extensions/src_py3/typing_extensions.py

+61-33
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@
1111
def _generic_new(base_cls, cls, *args, **kwargs):
1212
return base_cls.__new__(cls, *args, **kwargs)
1313

14+
# See https://github.com/python/typing/pull/439
15+
if hasattr(typing, '_geqv'):
16+
from typing import _geqv
17+
_geqv_defined = True
18+
else:
19+
_geqv = None
20+
_geqv_defined = False
21+
1422
if sys.version_info[:2] >= (3, 6):
1523
import _collections_abc
1624
_check_methods_in_mro = _collections_abc._check_methods
@@ -122,29 +130,6 @@ def stop() -> NoReturn:
122130
T_contra = typing.TypeVar('T_contra', contravariant=True) # Ditto contravariant.
123131

124132

125-
def _gorg(a):
126-
"""Return the farthest origin of a generic class (internal helper)."""
127-
assert isinstance(a, typing.GenericMeta)
128-
while a.__origin__ is not None:
129-
a = a.__origin__
130-
return a
131-
132-
133-
def _geqv(a, b):
134-
"""Return whether two generic classes are equivalent (internal helper).
135-
136-
The intention is to consider generic class X and any of its
137-
parameterized forms (X[T], X[int], etc.) as equivalent.
138-
139-
However, X is not equivalent to a subclass of X.
140-
141-
The relation is reflexive, symmetric and transitive.
142-
"""
143-
assert isinstance(a, typing.GenericMeta) and isinstance(b, typing.GenericMeta)
144-
# Reduce each to its origin.
145-
return _gorg(a) is _gorg(b)
146-
147-
148133
if hasattr(typing, 'ClassVar'):
149134
ClassVar = typing.ClassVar
150135
elif hasattr(typing, '_FinalTypingBase'):
@@ -392,7 +377,7 @@ class AsyncIterator(AsyncIterable[T_co],
392377

393378
if hasattr(typing, 'Deque'):
394379
Deque = typing.Deque
395-
else:
380+
elif _geqv_defined:
396381
class Deque(collections.deque, typing.MutableSequence[T],
397382
extra=collections.deque):
398383
__slots__ = ()
@@ -401,6 +386,15 @@ def __new__(cls, *args, **kwds):
401386
if _geqv(cls, Deque):
402387
return collections.deque(*args, **kwds)
403388
return _generic_new(collections.deque, cls, *args, **kwds)
389+
else:
390+
class Deque(collections.deque, typing.MutableSequence[T],
391+
extra=collections.deque):
392+
__slots__ = ()
393+
394+
def __new__(cls, *args, **kwds):
395+
if cls._gorg is Deque:
396+
return collections.deque(*args, **kwds)
397+
return _generic_new(collections.deque, cls, *args, **kwds)
404398

405399

406400
if hasattr(typing, 'ContextManager'):
@@ -467,7 +461,7 @@ def __subclasshook__(cls, C):
467461

468462
if hasattr(typing, 'DefaultDict'):
469463
DefaultDict = typing.DefaultDict
470-
else:
464+
elif _geqv_defined:
471465
class DefaultDict(collections.defaultdict, typing.MutableMapping[KT, VT],
472466
extra=collections.defaultdict):
473467

@@ -477,11 +471,22 @@ def __new__(cls, *args, **kwds):
477471
if _geqv(cls, DefaultDict):
478472
return collections.defaultdict(*args, **kwds)
479473
return _generic_new(collections.defaultdict, cls, *args, **kwds)
474+
else:
475+
class DefaultDict(collections.defaultdict, typing.MutableMapping[KT, VT],
476+
extra=collections.defaultdict):
477+
478+
__slots__ = ()
479+
480+
def __new__(cls, *args, **kwds):
481+
if cls._gorg is DefaultDict:
482+
return collections.defaultdict(*args, **kwds)
483+
return _generic_new(collections.defaultdict, cls, *args, **kwds)
480484

481485

482486
if hasattr(typing, 'Counter'):
483487
Counter = typing.Counter
484488
elif (3, 5, 0) <= sys.version_info[:3] <= (3, 5, 1):
489+
assert _geqv_defined
485490
_TInt = typing.TypeVar('_TInt')
486491

487492
class CounterMeta(typing.GenericMeta):
@@ -501,7 +506,7 @@ def __new__(cls, *args, **kwds):
501506
return collections.Counter(*args, **kwds)
502507
return _generic_new(collections.Counter, cls, *args, **kwds)
503508

504-
else:
509+
elif _geqv_defined:
505510
class Counter(collections.Counter,
506511
typing.Dict[T, int],
507512
extra=collections.Counter):
@@ -513,21 +518,44 @@ def __new__(cls, *args, **kwds):
513518
return collections.Counter(*args, **kwds)
514519
return _generic_new(collections.Counter, cls, *args, **kwds)
515520

521+
else:
522+
class Counter(collections.Counter,
523+
typing.Dict[T, int],
524+
extra=collections.Counter):
525+
526+
__slots__ = ()
527+
528+
def __new__(cls, *args, **kwds):
529+
if cls._gorg is Counter:
530+
return collections.Counter(*args, **kwds)
531+
return _generic_new(collections.Counter, cls, *args, **kwds)
532+
516533

517534
if hasattr(typing, 'ChainMap'):
518535
ChainMap = typing.ChainMap
519536
__all__.append('ChainMap')
520537
elif hasattr(collections, 'ChainMap'):
521538
# ChainMap only exists in 3.3+
522-
class ChainMap(collections.ChainMap, typing.MutableMapping[KT, VT],
523-
extra=collections.ChainMap):
539+
if _geqv_defined:
540+
class ChainMap(collections.ChainMap, typing.MutableMapping[KT, VT],
541+
extra=collections.ChainMap):
524542

525-
__slots__ = ()
543+
__slots__ = ()
526544

527-
def __new__(cls, *args, **kwds):
528-
if _geqv(cls, ChainMap):
529-
return collections.ChainMap(*args, **kwds)
530-
return _generic_new(collections.ChainMap, cls, *args, **kwds)
545+
def __new__(cls, *args, **kwds):
546+
if _geqv(cls, ChainMap):
547+
return collections.ChainMap(*args, **kwds)
548+
return _generic_new(collections.ChainMap, cls, *args, **kwds)
549+
else:
550+
class ChainMap(collections.ChainMap, typing.MutableMapping[KT, VT],
551+
extra=collections.ChainMap):
552+
553+
__slots__ = ()
554+
555+
def __new__(cls, *args, **kwds):
556+
if cls._gorg is ChainMap:
557+
return collections.ChainMap(*args, **kwds)
558+
return _generic_new(collections.ChainMap, cls, *args, **kwds)
531559

532560
__all__.append('ChainMap')
533561

0 commit comments

Comments
 (0)