Skip to content

Commit af262d0

Browse files
committed
better solution
1 parent d93860a commit af262d0

File tree

1 file changed

+49
-84
lines changed

1 file changed

+49
-84
lines changed

src/typing_extensions.py

Lines changed: 49 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,55 @@ def __new__(cls, *args, **kwargs):
221221

222222
ClassVar = typing.ClassVar
223223

224+
# Vendored from cpython typing._SpecialFrom
225+
# Having a separate class means that instances will not be rejected by
226+
# typing._type_check.
227+
class _SpecialForm(typing._Final, _root=True):
228+
__slots__ = ('_name', '__doc__', '_getitem')
229+
230+
def __init__(self, getitem):
231+
self._getitem = getitem
232+
self._name = getitem.__name__
233+
self.__doc__ = getitem.__doc__
234+
235+
def __getattr__(self, item):
236+
if item in {'__name__', '__qualname__'}:
237+
return self._name
238+
239+
raise AttributeError(item)
224240

241+
def __mro_entries__(self, bases):
242+
raise TypeError(f"Cannot subclass {self!r}")
243+
244+
def __repr__(self):
245+
return f'typing_extensions.{self._name}'
246+
247+
def __reduce__(self):
248+
return self._name
249+
250+
def __call__(self, *args, **kwds):
251+
raise TypeError(f"Cannot instantiate {self!r}")
252+
253+
def __or__(self, other):
254+
return typing.Union[self, other]
255+
256+
def __ror__(self, other):
257+
return typing.Union[other, self]
258+
259+
def __instancecheck__(self, obj):
260+
raise TypeError(f"{self} cannot be used with isinstance()")
261+
262+
def __subclasscheck__(self, cls):
263+
raise TypeError(f"{self} cannot be used with issubclass()")
264+
265+
@typing._tp_cache
266+
def __getitem__(self, parameters):
267+
return self._getitem(self, parameters)
268+
269+
270+
# Note that inheriting from this class means that the object will be
271+
# rejected by typing._type_check, so do not use it if the special form
272+
# is arguably valid as a type by itself.
225273
class _ExtensionsSpecialForm(typing._SpecialForm, _root=True):
226274
def __repr__(self):
227275
return 'typing_extensions.' + self._name
@@ -1223,50 +1271,9 @@ def _create_typeddict(
12231271
td.__orig_bases__ = (TypedDict,)
12241272
return td
12251273

1226-
# Cannot inherit from typing._SpecialForm, because then typing._type_check
1227-
# would reject TypedDict as a type, and we need that to work for compatibility.
1228-
if hasattr(typing, "_NotIterable"):
1229-
_special_form_bases = (typing._Final, typing._NotIterable)
1230-
else:
1231-
_special_form_bases = (typing._Final,)
1232-
1233-
class _TypedDictSpecialForm(*_special_form_bases, _root=True):
1274+
class _TypedDictSpecialForm(_SpecialForm, _root=True):
12341275
__slots__ = ('_name', '__doc__', '_getitem')
12351276

1236-
def __init__(self, getitem):
1237-
self._getitem = getitem
1238-
self._name = getitem.__name__
1239-
self.__doc__ = getitem.__doc__
1240-
1241-
def __getattr__(self, item):
1242-
if item in {'__name__', '__qualname__'}:
1243-
return self._name
1244-
1245-
raise AttributeError(item)
1246-
1247-
def __repr__(self):
1248-
return 'typing_extensions.' + self._name
1249-
1250-
def __reduce__(self):
1251-
return self._name
1252-
1253-
if sys.version_info >= (3, 10):
1254-
def __or__(self, other):
1255-
return typing.Union[self, other]
1256-
1257-
def __ror__(self, other):
1258-
return typing.Union[other, self]
1259-
1260-
def __instancecheck__(self, obj):
1261-
raise TypeError(f"{self} cannot be used with isinstance()")
1262-
1263-
def __subclasscheck__(self, cls):
1264-
raise TypeError(f"{self} cannot be used with issubclass()")
1265-
1266-
@typing._tp_cache
1267-
def __getitem__(self, parameters):
1268-
return self._getitem(self, parameters)
1269-
12701277
def __call__(
12711278
self,
12721279
typename,
@@ -2244,48 +2251,6 @@ def cast[T](typ: TypeForm[T], value: Any) -> T: ...
22442251
return typing._GenericAlias(self, (item,))
22452252

22462253

2247-
# Vendored from cpython typing._SpecialFrom
2248-
class _SpecialForm(typing._Final, _root=True):
2249-
__slots__ = ('_name', '__doc__', '_getitem')
2250-
2251-
def __init__(self, getitem):
2252-
self._getitem = getitem
2253-
self._name = getitem.__name__
2254-
self.__doc__ = getitem.__doc__
2255-
2256-
def __getattr__(self, item):
2257-
if item in {'__name__', '__qualname__'}:
2258-
return self._name
2259-
2260-
raise AttributeError(item)
2261-
2262-
def __mro_entries__(self, bases):
2263-
raise TypeError(f"Cannot subclass {self!r}")
2264-
2265-
def __repr__(self):
2266-
return f'typing_extensions.{self._name}'
2267-
2268-
def __reduce__(self):
2269-
return self._name
2270-
2271-
def __call__(self, *args, **kwds):
2272-
raise TypeError(f"Cannot instantiate {self!r}")
2273-
2274-
def __or__(self, other):
2275-
return typing.Union[self, other]
2276-
2277-
def __ror__(self, other):
2278-
return typing.Union[other, self]
2279-
2280-
def __instancecheck__(self, obj):
2281-
raise TypeError(f"{self} cannot be used with isinstance()")
2282-
2283-
def __subclasscheck__(self, cls):
2284-
raise TypeError(f"{self} cannot be used with issubclass()")
2285-
2286-
@typing._tp_cache
2287-
def __getitem__(self, parameters):
2288-
return self._getitem(self, parameters)
22892254

22902255

22912256
if hasattr(typing, "LiteralString"): # 3.11+

0 commit comments

Comments
 (0)