| | |
| |
|
| | import inspect |
| | import platform |
| | import sys |
| | import threading |
| |
|
| | from collections.abc import Mapping, Sequence |
| | from typing import _GenericAlias |
| |
|
| |
|
| | PYPY = platform.python_implementation() == "PyPy" |
| | PY_3_10_PLUS = sys.version_info[:2] >= (3, 10) |
| | PY_3_11_PLUS = sys.version_info[:2] >= (3, 11) |
| | PY_3_12_PLUS = sys.version_info[:2] >= (3, 12) |
| | PY_3_13_PLUS = sys.version_info[:2] >= (3, 13) |
| | PY_3_14_PLUS = sys.version_info[:2] >= (3, 14) |
| |
|
| |
|
| | if PY_3_14_PLUS: |
| | import annotationlib |
| |
|
| | |
| | |
| |
|
| | def _get_annotations(cls): |
| | return annotationlib.get_annotations( |
| | cls, format=annotationlib.Format.FORWARDREF |
| | ) |
| |
|
| | else: |
| |
|
| | def _get_annotations(cls): |
| | """ |
| | Get annotations for *cls*. |
| | """ |
| | return cls.__dict__.get("__annotations__", {}) |
| |
|
| |
|
| | class _AnnotationExtractor: |
| | """ |
| | Extract type annotations from a callable, returning None whenever there |
| | is none. |
| | """ |
| |
|
| | __slots__ = ["sig"] |
| |
|
| | def __init__(self, callable): |
| | try: |
| | self.sig = inspect.signature(callable) |
| | except (ValueError, TypeError): |
| | self.sig = None |
| |
|
| | def get_first_param_type(self): |
| | """ |
| | Return the type annotation of the first argument if it's not empty. |
| | """ |
| | if not self.sig: |
| | return None |
| |
|
| | params = list(self.sig.parameters.values()) |
| | if params and params[0].annotation is not inspect.Parameter.empty: |
| | return params[0].annotation |
| |
|
| | return None |
| |
|
| | def get_return_type(self): |
| | """ |
| | Return the return type if it's not empty. |
| | """ |
| | if ( |
| | self.sig |
| | and self.sig.return_annotation is not inspect.Signature.empty |
| | ): |
| | return self.sig.return_annotation |
| |
|
| | return None |
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | repr_context = threading.local() |
| |
|
| |
|
| | def get_generic_base(cl): |
| | """If this is a generic class (A[str]), return the generic base for it.""" |
| | if cl.__class__ is _GenericAlias: |
| | return cl.__origin__ |
| | return None |
| |
|