diff --git a/typing_extensions/README.rst b/typing_extensions/README.rst index eb998a953..885c4d2f7 100644 --- a/typing_extensions/README.rst +++ b/typing_extensions/README.rst @@ -44,6 +44,7 @@ All Python versions: - ``NewType`` - ``NoReturn`` - ``overload`` (note that older versions of ``typing`` only let you use ``overload`` in stubs) +- ``OrderedDict`` - ``Protocol`` (except on Python 3.5.0) - ``runtime`` (except on Python 3.5.0) - ``Text`` diff --git a/typing_extensions/src_py3/test_typing_extensions.py b/typing_extensions/src_py3/test_typing_extensions.py index 98d02a0b9..6d131b82b 100644 --- a/typing_extensions/src_py3/test_typing_extensions.py +++ b/typing_extensions/src_py3/test_typing_extensions.py @@ -610,6 +610,30 @@ class MyDefDict(typing_extensions.DefaultDict[str, int]): if TYPING_3_5_3: self.assertNotIsSubclass(collections.defaultdict, MyDefDict) + @skipUnless(CAN_INSTANTIATE_COLLECTIONS, "Behavior added in typing 3.6.1") + def test_ordereddict_instantiation(self): + self.assertIs( + type(typing_extensions.OrderedDict()), + collections.OrderedDict) + self.assertIs( + type(typing_extensions.OrderedDict[KT, VT]()), + collections.OrderedDict) + self.assertIs( + type(typing_extensions.OrderedDict[str, int]()), + collections.OrderedDict) + + def test_ordereddict_subclass(self): + + class MyOrdDict(typing_extensions.OrderedDict[str, int]): + pass + + od = MyOrdDict() + self.assertIsInstance(od, MyOrdDict) + + self.assertIsSubclass(MyOrdDict, collections.OrderedDict) + if TYPING_3_5_3: + self.assertNotIsSubclass(collections.OrderedDict, MyOrdDict) + def test_chainmap_instantiation(self): self.assertIs(type(typing_extensions.ChainMap()), collections.ChainMap) self.assertIs(type(typing_extensions.ChainMap[KT, VT]()), collections.ChainMap) diff --git a/typing_extensions/src_py3/typing_extensions.py b/typing_extensions/src_py3/typing_extensions.py index 97fa7dc3e..57b8d75e4 100644 --- a/typing_extensions/src_py3/typing_extensions.py +++ b/typing_extensions/src_py3/typing_extensions.py @@ -134,6 +134,7 @@ def _check_methods_in_mro(C, *methods): 'Counter', 'Deque', 'DefaultDict', + 'OrderedDict' 'TypedDict', # Structural checks, a.k.a. protocols. @@ -938,6 +939,34 @@ def __new__(cls, *args, **kwds): return _generic_new(collections.defaultdict, cls, *args, **kwds) +if hasattr(typing, 'OrderedDict'): + OrderedDict = typing.OrderedDict +elif (3, 7, 0) <= sys.version_info[:3] < (3, 7, 2): + OrderedDict = typing._alias(collections.OrderedDict, (KT, VT)) +elif _geqv_defined: + class OrderedDict(collections.OrderedDict, typing.MutableMapping[KT, VT], + metaclass=_ExtensionsGenericMeta, + extra=collections.OrderedDict): + + __slots__ = () + + def __new__(cls, *args, **kwds): + if _geqv(cls, OrderedDict): + return collections.OrderedDict(*args, **kwds) + return _generic_new(collections.OrderedDict, cls, *args, **kwds) +else: + class OrderedDict(collections.OrderedDict, typing.MutableMapping[KT, VT], + metaclass=_ExtensionsGenericMeta, + extra=collections.OrderedDict): + + __slots__ = () + + def __new__(cls, *args, **kwds): + if cls._gorg is OrderedDict: + return collections.OrderedDict(*args, **kwds) + return _generic_new(collections.OrderedDict, cls, *args, **kwds) + + if hasattr(typing, 'Counter'): Counter = typing.Counter elif (3, 5, 0) <= sys.version_info[:3] <= (3, 5, 1):