10000 Vendor typing._SpecialForm to fool typing._type_check · python/typing@936ebbe · GitHub
[go: up one dir, main page]

Skip to content

Commit 936ebbe

Browse files
Chris WesselingChris Wesseling
Chris Wesseling
authored and
Chris Wesseling
committed
Vendor typing._SpecialForm to fool typing._type_check
Adds a local copy of _SpecialForm in our namespace, so typing._type_check won't raise TypeError. (#964)
1 parent caa9cdf commit 936ebbe

File tree

2 files changed

+49
-21
lines changed

2 files changed

+49
-21
lines changed

typing_extensions/src/test_typing_extensions.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2199,6 +2199,12 @@ def test_no_isinstance(self):
21992199
with self.assertRaises(TypeError):
22002200
issubclass(int, Self)
22012201

2202+
def test_alias(self):
2203+
TupleSelf = Tuple[Self, Self]
2204+
class Alias:
2205+
def return_tuple(self) -> TupleSelf:
2206+
return (self, self)
2207+
22022208
class AllTests(BaseTestCase):
22032209

22042210
def test_typing_extensions_includes_standard(self):

typing_extensions/src/typing_extensions.py

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2048,40 +2048,61 @@ def __eq__(self, other):
20482048

20492049
TypeGuard = _TypeGuard(_root=True)
20502050

2051+
if not hasattr(typing, "Self") and sys.version_info[:2] >= (3, 7):
2052+
# Vendored from cpython typing._SpecialFrom
2053+
class _SpecialForm(typing._Final, _root=True):
2054+
__slots__ = ('_name', '__doc__', '_getitem')
20512055

2052-
if hasattr(typing, "Self"):
2053-
Self = typing.Self
2056+
def __init__(self, getitem):
2057+
self._getitem = getitem
2058+
self._name = getitem.__name__
2059+
self.__doc__ = getitem.__doc__
2060+
2061+
def __getattr__(self, item):
2062+
if item in {'__name__', '__qualname__'}:
2063+
return self._name
2064+
2065+
raise AttributeError(item)
2066+
2067+
def __mro_entries__(self, bases):
2068+
raise TypeError(f"Cannot subclass {self!r}")
20542069

2055-
elif sys.version_info[:2] >= (3, 9):
2056-
class _SelfForm(typing._SpecialForm, _root=True):
20572070
def __repr__(self):
2058-
return 'typing_extensions.' + self._name
2071+
return 'typing.' + self._name
20592072

2060-
@_SelfForm
2061-
def Self(self, params):
2062-
"""Used to spell the type of "self" in classes.
2073+
def __reduce__(self):
2074+
return self._name
20632075

2064-
Example::
2076+
def __call__(self, *args, **kwds):
2077+
raise TypeError(f"Cannot instantiate {self!r}")
20652078

2066-
from typing import Self
2079+
def __or__(self, other):
2080+
return Union[self, other]
20672081

2068-
class ReturnsSelf:
2069-
def parse(self, data: bytes) -> Self:
2070-
...
2071-
return self
2082+
def __ror__(self, other):
2083+
return Union[other, self]
20722084

2073-
"""
2085+
def __instancecheck__(self, obj):
2086+
raise TypeError(f"{self} cannot be used with isinstance()")
20742087

2075-
raise TypeError(f"{self} is not subscriptable")
2088+
def __subclasscheck__(self, cls):
2089+
raise TypeError(f"{self} cannot be used with issubclass()")
2090+
2091+
@typing._tp_cache
2092+
def __getitem__(self, parameters):
2093+
return self._getitem(self, parameters)
2094+
2095+
if hasattr(typing, "Self"):
2096+
Self = typing.Self
20762097

20772098
elif sys.version_info[:2] >= (3, 7):
2078-
class _SelfForm(typing._SpecialForm, _root=True):
2099+
class _SelfForm(_SpecialForm, _root=True):
20792100
def __repr__(self):
20802101
return 'typing_extensions.' + self._name
20812102

2082-
Self = _SelfForm(
2083-
"Self",
2084-
doc="""Used to spell the type of "self" in classes.
2103+
@_SelfForm
2104+
def Self(self, params):
2105+
"""Used to spell the type of "self" in classes.
20852106
20862107
Example::
20872108
@@ -2093,7 +2114,8 @@ def parse(self, data: bytes) -> Self:
20932114
return self
20942115
20952116
"""
2096-
)
2117+
2118+
raise TypeError(f"{self} is not subscriptable")
20972119
else:
20982120
class _Self(typing._FinalTypingBase, _root=True):
20992121
"""Used to spell the type of "self" in classes.

0 commit comments

Comments
 (0)
0