aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wesseling <chris.wesseling@protonmail.com>2021-11-29 04:10:51 +0100
committerGitHub <noreply@github.com>2021-11-28 19:10:51 -0800
commit0c8e55f1631177d0965015e18f56518604b2f519 (patch)
tree5fdf2a495ce6efb37bf112db35e98fc726334e27
parent273fe266abe09373a4d379f21c8b78d208864d94 (diff)
downloadtyping-0c8e55f1631177d0965015e18f56518604b2f519.tar.gz
Vendor typing._SpecialForm to fool typing._type_check (#966)
Adds a local copy of _SpecialForm in our namespace, so typing._type_check won't raise TypeError. (#964) Co-authored-by: James Hilton-Balfe <50501825+Gobot1234@users.noreply.github.com>
-rw-r--r--typing_extensions/src/test_typing_extensions.py6
-rw-r--r--typing_extensions/src/typing_extensions.py62
2 files changed, 45 insertions, 23 deletions
diff --git a/typing_extensions/src/test_typing_extensions.py b/typing_extensions/src/test_typing_extensions.py
index 2fc5b3f..731f973 100644
--- a/typing_extensions/src/test_typing_extensions.py
+++ b/typing_extensions/src/test_typing_extensions.py
@@ -2199,6 +2199,12 @@ class SelfTests(BaseTestCase):
with self.assertRaises(TypeError):
issubclass(int, Self)
+ def test_alias(self):
+ TupleSelf = Tuple[Self, Self]
+ class Alias:
+ def return_tuple(self) -> TupleSelf:
+ return (self, self)
+
class AllTests(BaseTestCase):
def test_typing_extensions_includes_standard(self):
diff --git a/typing_extensions/src/typing_extensions.py b/typing_extensions/src/typing_extensions.py
index 15fec25..9f1c7aa 100644
--- a/typing_extensions/src/typing_extensions.py
+++ b/typing_extensions/src/typing_extensions.py
@@ -2048,40 +2048,55 @@ else:
TypeGuard = _TypeGuard(_root=True)
-
if hasattr(typing, "Self"):
Self = typing.Self
+elif sys.version_info[:2] >= (3, 7):
+ # Vendored from cpython typing._SpecialFrom
+ class _SpecialForm(typing._Final, _root=True):
+ __slots__ = ('_name', '__doc__', '_getitem')
+
+ def __init__(self, getitem):
+ self._getitem = getitem
+ self._name = getitem.__name__
+ self.__doc__ = getitem.__doc__
+
+ def __getattr__(self, item):
+ if item in {'__name__', '__qualname__'}:
+ return self._name
+
+ raise AttributeError(item)
+
+ def __mro_entries__(self, bases):
+ raise TypeError(f"Cannot subclass {self!r}")
-elif sys.version_info[:2] >= (3, 9):
- class _SelfForm(typing._SpecialForm, _root=True):
def __repr__(self):
- return 'typing_extensions.' + self._name
+ return f'typing_extensions.{self._name}'
- @_SelfForm
- def Self(self, params):
- """Used to spell the type of "self" in classes.
+ def __reduce__(self):
+ return self._name
- Example::
+ def __call__(self, *args, **kwds):
+ raise TypeError(f"Cannot instantiate {self!r}")
- from typing import Self
+ def __or__(self, other):
+ return typing.Union[self, other]
- class ReturnsSelf:
- def parse(self, data: bytes) -> Self:
- ...
- return self
+ def __ror__(self, other):
+ return typing.Union[other, self]
- """
+ def __instancecheck__(self, obj):
+ raise TypeError(f"{self} cannot be used with isinstance()")
- raise TypeError(f"{self} is not subscriptable")
+ def __subclasscheck__(self, cls):
+ raise TypeError(f"{self} cannot be used with issubclass()")
-elif sys.version_info[:2] >= (3, 7):
- class _SelfForm(typing._SpecialForm, _root=True):
- def __repr__(self):
- return 'typing_extensions.' + self._name
+ @typing._tp_cache
+ def __getitem__(self, parameters):
+ return self._getitem(self, parameters)
- Self = _SelfForm(
- "Self",
- doc="""Used to spell the type of "self" in classes.
+ @_SpecialForm
+ def Self(self, params):
+ """Used to spell the type of "self" in classes.
Example::
@@ -2093,7 +2108,8 @@ elif sys.version_info[:2] >= (3, 7):
return self
"""
- )
+
+ raise TypeError(f"{self} is not subscriptable")
else:
class _Self(typing._FinalTypingBase, _root=True):
"""Used to spell the type of "self" in classes.