55import ast
66import builtins
77import contextlib
8+ import enum
89import inspect
910import re
1011import sys
1112import types
1213import typing
1314from collections .abc import Mapping
14- from enum import Enum
1515from functools import cached_property , partial , partialmethod , singledispatchmethod
1616from importlib import import_module
1717from inspect import Parameter , Signature
2525
2626if TYPE_CHECKING :
2727 from collections .abc import Callable , Sequence
28+ from enum import Enum
2829 from inspect import _ParameterKind
30+ from types import MethodType , ModuleType
2931 from typing import Final , Protocol , Union
3032
31- from typing_extensions import TypeGuard
33+ from typing_extensions import TypeAlias , TypeGuard
3234
3335 class _SupportsGet (Protocol ):
3436 def __get__ (self , __instance : Any , __owner : type | None = ...) -> Any : ... # NoQA: E704
@@ -41,20 +43,7 @@ class _SupportsDelete(Protocol):
4143 # instance is contravariant but we do not need that precision
4244 def __delete__ (self , __instance : Any ) -> None : ... # NoQA: E704
4345
44- class _GenericAliasLike (Protocol ):
45- # Minimalist interface for a generic alias in typing.py.
46-
47- # The ``__origin__`` is defined both on the base type for generics
48- # in typing.py *and* on the public ``types.GenericAlias`` type.
49- __origin__ : type
50-
51- # Note that special generic alias types (tuple and callables) do
52- # not directly define ``__args__``. At runtime, however, they are
53- # actually instances of ``typing._GenericAlias`` which does have
54- # an ``__args__`` field.
55- __args__ : tuple [Any , ...]
56-
57- _RoutineType = Union [
46+ _RoutineType : TypeAlias = Union [
5847 types .FunctionType ,
5948 types .LambdaType ,
6049 types .MethodType ,
@@ -64,6 +53,11 @@ class _GenericAliasLike(Protocol):
6453 types .MethodDescriptorType ,
6554 types .ClassMethodDescriptorType ,
6655 ]
56+ _SignatureType : TypeAlias = Union [
57+ Callable [..., Any ],
58+ staticmethod ,
59+ classmethod ,
60+ ]
6761
6862logger = logging .getLogger (__name__ )
6963
@@ -126,7 +120,7 @@ class methods and static methods.
126120
127121
128122def getall (obj : Any ) -> Sequence [str ] | None :
129- """Get the ``__all__`` attribute of an object as a sequence.
123+ """Get the ``__all__`` attribute of an object as sequence.
130124
131125 This returns ``None`` if the given ``obj.__all__`` does not exist and
132126 raises :exc:`ValueError` if ``obj.__all__`` is not a list or tuple of
@@ -222,12 +216,12 @@ def isNewType(obj: Any) -> bool:
222216
223217def isenumclass (x : Any ) -> TypeGuard [type [Enum ]]:
224218 """Check if the object is an :class:`enumeration class <enum.Enum>`."""
225- return isclass (x ) and issubclass (x , Enum )
219+ return isclass (x ) and issubclass (x , enum . Enum )
226220
227221
228222def isenumattribute (x : Any ) -> TypeGuard [Enum ]:
229223 """Check if the object is an enumeration attribute."""
230- return isinstance (x , Enum )
224+ return isinstance (x , enum . Enum )
231225
232226
233227def unpartial (obj : Any ) -> Any :
@@ -247,7 +241,11 @@ def ispartial(obj: Any) -> TypeGuard[partial | partialmethod]:
247241 return isinstance (obj , (partial , partialmethod ))
248242
249243
250- def isclassmethod (obj : Any , cls : Any = None , name : str | None = None ) -> bool :
244+ def isclassmethod (
245+ obj : Any ,
246+ cls : Any = None ,
247+ name : str | None = None ,
248+ ) -> TypeGuard [classmethod ]:
251249 """Check if the object is a :class:`classmethod`."""
252250 if isinstance (obj , classmethod ):
253251 return True
@@ -263,7 +261,11 @@ def isclassmethod(obj: Any, cls: Any = None, name: str | None = None) -> bool:
263261 return False
264262
265263
266- def isstaticmethod (obj : Any , cls : Any = None , name : str | None = None ) -> bool :
264+ def isstaticmethod (
265+ obj : Any ,
266+ cls : Any = None ,
267+ name : str | None = None ,
268+ ) -> TypeGuard [staticmethod ]:
267269 """Check if the object is a :class:`staticmethod`."""
268270 if isinstance (obj , staticmethod ):
269271 return True
@@ -289,7 +291,7 @@ def isabstractmethod(obj: Any) -> bool:
289291 return safe_getattr (obj , '__isabstractmethod__' , False ) is True
290292
291293
292- def isboundmethod (method : types . MethodType ) -> bool :
294+ def isboundmethod (method : MethodType ) -> bool :
293295 """Check if the method is a bound method."""
294296 return safe_getattr (method , '__self__' , None ) is not None
295297
@@ -379,7 +381,7 @@ def isroutine(obj: Any) -> TypeGuard[_RoutineType]:
379381 return inspect .isroutine (unpartial (obj ))
380382
381383
382- def iscoroutinefunction (obj : Any ) -> bool :
384+ def iscoroutinefunction (obj : Any ) -> TypeGuard [ Callable [..., types . CoroutineType ]] :
383385 """Check if the object is a :external+python:term:`coroutine` function."""
384386 obj = unwrap_all (obj , stop = _is_wrapped_coroutine )
385387 return inspect .iscoroutinefunction (obj )
@@ -399,7 +401,7 @@ def isproperty(obj: Any) -> TypeGuard[property | cached_property]:
399401 return isinstance (obj , (property , cached_property ))
400402
401403
402- def isgenericalias (obj : Any ) -> bool :
404+ def isgenericalias (obj : Any ) -> TypeGuard [ types . GenericAlias ] :
403405 """Check if the object is a generic alias."""
404406 return isinstance (obj , (types .GenericAlias , typing ._BaseGenericAlias )) # type: ignore[attr-defined]
405407
@@ -469,8 +471,8 @@ def object_description(obj: Any, *, _seen: frozenset[int] = frozenset()) -> str:
469471 return 'frozenset({%s})' % ', ' .join (
470472 object_description (x , _seen = seen ) for x in sorted_values
471473 )
472- elif isinstance (obj , Enum ):
473- if obj .__repr__ .__func__ is not Enum .__repr__ : # type: ignore[attr-defined]
474+ elif isinstance (obj , enum . Enum ):
475+ if obj .__repr__ .__func__ is not enum . Enum .__repr__ : # type: ignore[attr-defined]
474476 return repr (obj )
475477 return f'{ obj .__class__ .__name__ } .{ obj .name } '
476478 elif isinstance (obj , tuple ):
@@ -565,7 +567,7 @@ def __init__(self, modname: str, mapping: Mapping[str, str]) -> None:
565567 self .__modname = modname
566568 self .__mapping = mapping
567569
568- self .__module : types . ModuleType | None = None
570+ self .__module : ModuleType | None = None
569571
570572 def __getattr__ (self , name : str ) -> Any :
571573 fullname = '.' .join (filter (None , [self .__modname , name ]))
@@ -615,7 +617,7 @@ def __getitem__(self, key: str) -> Any:
615617 raise KeyError
616618
617619
618- def _should_unwrap (subject : Callable [..., Any ] ) -> bool :
620+ def _should_unwrap (subject : _SignatureType ) -> bool :
619621 """Check the function should be unwrapped on getting signature."""
620622 __globals__ = getglobals (subject )
621623 # contextmanger should be unwrapped
@@ -626,7 +628,7 @@ def _should_unwrap(subject: Callable[..., Any]) -> bool:
626628
627629
628630def signature (
629- subject : Callable [..., Any ] ,
631+ subject : _SignatureType ,
630632 bound_method : bool = False ,
631633 type_aliases : Mapping [str , str ] | None = None ,
632634) -> Signature :
@@ -639,12 +641,12 @@ def signature(
639641
640642 try :
641643 if _should_unwrap (subject ):
642- signature = inspect .signature (subject )
644+ signature = inspect .signature (subject ) # type: ignore[arg-type]
643645 else :
644- signature = inspect .signature (subject , follow_wrapped = True )
646+ signature = inspect .signature (subject , follow_wrapped = True ) # type: ignore[arg-type]
645647 except ValueError :
646648 # follow built-in wrappers up (ex. functools.lru_cache)
647- signature = inspect .signature (subject )
649+ signature = inspect .signature (subject ) # type: ignore[arg-type]
648650 parameters = list (signature .parameters .values ())
649651 return_annotation = signature .return_annotation
650652
0 commit comments