11from __future__ import annotations
22
3+ import sys
4+ import typing
35from collections import abc
46from collections .abc import Collection , Mapping
57from typing import (
1416 _SpecialForm , # pyright: ignore[reportPrivateUsage]
1517)
1618
19+ import typing_extensions
1720from typing_extensions import Annotated , NotRequired , Required , get_args , get_origin
1821from typing_extensions import Literal as ExtensionsLiteral
1922
@@ -204,6 +207,19 @@ def is_variadic_tuple(self) -> bool:
204207 """
205208 return self .is_tuple and len (self .args ) == 2 and self .args [1 ] == ... # pyright: ignore
206209
210+ if sys .version_info < (3 , 12 ):
211+
212+ @property
213+ def is_type_alias (self ) -> bool :
214+ """Whether the annotation is a new-style `type Type = ...` alias or not."""
215+ return _is_typing_extensins_type_alias (self )
216+ else :
217+
218+ @property
219+ def is_type_alias (self ) -> bool :
220+ """Whether the annotation is a new-style `type Type = ...` alias or not."""
221+ return isinstance (self .annotation , typing .TypeAliasType ) or _is_typing_extensins_type_alias (self )
222+
207223 @property
208224 def safe_generic_origin (self ) -> Any :
209225 """A type, safe to be used as a generic type across all supported Python versions.
@@ -260,6 +276,7 @@ def is_subclass_of(self, typ: Any | tuple[Any, ...], /) -> bool:
260276 return isinstance (self .fallback_origin , type ) and issubclass (self .fallback_origin , typ )
261277
262278 def strip_optional (self ) -> TypeView [Any ]:
279+ """Remove the "Optional" component of an `Optional[T]` or `Union[T, None]` type."""
263280 if not self .is_optional :
264281 return self
265282
@@ -269,3 +286,21 @@ def strip_optional(self) -> TypeView[Any]:
269286 args = tuple (a for a in self .args if a is not NoneType )
270287 non_optional = Union [args ] # type: ignore[valid-type]
271288 return TypeView (non_optional )
289+
290+ def strip_type_alias (self ) -> TypeView [Any ]:
291+ """Remove the type alias from a `type Type = T` type alias.
292+
293+ Examples:
294+ >>> type Foo = int
295+ >>> TypeAlias(Foo).strip_type_alias()
296+ TypeView(int)
297+ """
298+ if not self .is_type_alias :
299+ return self
300+ return TypeView (self .annotation .__value__ )
301+
302+
303+ def _is_typing_extensins_type_alias (type_view : TypeView [Any ]) -> bool :
304+ if hasattr (typing_extensions , "TypeAliasType" ):
305+ return isinstance (type_view .annotation , typing_extensions .TypeAliasType )
306+ return False
0 commit comments