Skip to content

Commit

Permalink
minor improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
Aran-Fey committed Mar 30, 2024
1 parent 4943609 commit e0e2996
Show file tree
Hide file tree
Showing 13 changed files with 88 additions and 66 deletions.
2 changes: 1 addition & 1 deletion introspection/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
New and improved introspection functions
"""

__version__ = "1.7.12"
__version__ = "1.7.13"

from .parameter import *
from .signature_ import *
Expand Down
27 changes: 26 additions & 1 deletion introspection/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,11 +336,29 @@ def add_method_to_class(
setattr(cls, method_name, method)


@overload
def wrap_method(
method: Callable[..., Any],
cls: type,
method: Callable[..., object],
name: Optional[str] = None,
method_type: Union[None, Type[staticmethod], Type[classmethod]] = auto, # type: ignore
) -> None: ...


@overload # Deprecated signature
def wrap_method(
method: Callable[..., object],
cls: type,
name: Optional[str] = None,
method_type: Union[None, Type[staticmethod], Type[classmethod]] = auto, # type: ignore
) -> None: ...


def wrap_method( # type: ignore[wtf]
cls: Union[type, Callable[..., object]],
method: Union[type, Callable[..., object]],
name: Optional[str] = None,
method_type: Union[None, Type[staticmethod], Type[classmethod]] = auto, # type: ignore
) -> None:
r"""
Adds ``method`` to ``cls``\ 's namespace under the given ``name``, wrapping the existing method
Expand Down Expand Up @@ -443,12 +461,19 @@ def __new__(original_new, cls, *args, **kwargs):
Child(5) # works!
.. versionadded:: 1.3
.. versionchanged:: 1.7.13
Swapped the first two parameters. Passing the function as the first argument is still
possible, but deprecated.
:param method: The method to add to the class
:param cls: The class to which to add the method
:param name: The name under which the method is registered in the class namespace
:param method_type: One of :class:`staticmethod`, :class:`classmethod`, or ``None`` (or omitted)
"""
# Deprecated call signature: Swap the first two arguments
if not isinstance(cls, type):
cls, method = method, cls

if not isinstance(cls, type):
raise InvalidArgumentType("cls", cls, type)

Expand Down
2 changes: 1 addition & 1 deletion introspection/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ def __str__(self) -> str:

class CannotResolveForwardref(Error, ValueError):
forward_ref: ForwardReference
context: ForwardRefContext
context: Optional[ForwardRefContext]

def __str__(self) -> str:
return f"Cannot resolve forward reference {self.forward_ref!r} in context {self.context!r}"
Expand Down
6 changes: 5 additions & 1 deletion introspection/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing_extensions import Self

from ._utils import PARAM_EMPTY
from .types import ForwardRefContext

__all__ = ["Parameter"]

Expand All @@ -20,7 +21,7 @@ class Parameter(inspect.Parameter):
This class adds a new special value for the ``default`` attribute: :attr:`Parameter.missing`.
"""

__slots__ = ()
__slots__ = ("forward_ref_context",)

#: A special class-level marker that can be used to specify
#: that the parameter is optional, but doesn't have a (known)
Expand All @@ -46,6 +47,7 @@ def __init__(
kind: inspect._ParameterKind = inspect.Parameter.POSITIONAL_OR_KEYWORD,
default: Any = PARAM_EMPTY,
annotation: Any = PARAM_EMPTY,
forward_ref_context: Optional[ForwardRefContext] = None,
):
"""
:param name: The parameter's name
Expand All @@ -61,6 +63,8 @@ def __init__(

super().__init__(name, kind, default=default, annotation=annotation)

self.forward_ref_context = forward_ref_context

@classmethod
def from_parameter(cls, parameter: inspect.Parameter) -> Self:
"""
Expand Down
10 changes: 5 additions & 5 deletions introspection/signature_.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from .misc import unwrap, static_mro, static_vars, extract_functions
from ._utils import SIG_EMPTY
from .errors import *
from .types import P, TypeAnnotation
from .types import P, TypeAnnotation, ForwardRefContext

__all__ = ["Signature"]

Expand All @@ -39,13 +39,13 @@ class Signature(inspect.Signature):
__slots__ = ("forward_ref_context",)

parameters: types.MappingProxyType[str, Parameter] # type: ignore
forward_ref_context: Optional[str]
forward_ref_context: Optional[ForwardRefContext]

def __init__(
self,
parameters: Union[Iterable[Parameter], Mapping[str, Parameter], None] = None,
return_annotation: Any = SIG_EMPTY,
forward_ref_context: Optional[str] = None,
forward_ref_context: Optional[ForwardRefContext] = None,
validate_parameters: bool = True,
):
"""
Expand Down Expand Up @@ -144,7 +144,7 @@ def from_callable(
callable_ = cast(Callable[P, Any], _find_constructor_function(callable_))

ignore_first_parameter = False

if inspect.ismethod(callable_):
callable_ = callable_.__func__ # type: ignore
ignore_first_parameter = True
Expand All @@ -153,7 +153,7 @@ def from_callable(
callable_ = unwrap(callable_, lambda func: hasattr(func, "__signature__")) # type: ignore

if not callable(callable_):
raise InvalidArgumentType("callable_", callable_, typing.Callable)
raise InvalidArgumentType("callable_", callable_, typing.Callable) # type: ignore

try:
sig = inspect.signature(callable_, follow_wrapped=False)
Expand Down
11 changes: 4 additions & 7 deletions introspection/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
ForwardReference = typing.Union[str, typing.ForwardRef]
TypeAnnotation = typing.Union[Type_, ForwardReference]
ForwardRefContext = typing.Union[
None, type, types.FunctionType, types.ModuleType, str, typing.Mapping[str, object]
type, types.FunctionType, types.ModuleType, str, typing.Mapping[str, object]
]


Expand All @@ -58,14 +58,11 @@


class Slot(typing.Protocol[T]): # type: ignore[variance]
def __get__(self, instance: T, owner: typing.Optional[typing.Type[T]]) -> object:
...
def __get__(self, instance: T, owner: typing.Optional[typing.Type[T]]) -> object: ...

def __set__(self, instance: T, value: object) -> None:
...
def __set__(self, instance: T, value: object) -> None: ...

def __delete__(self, instance: T) -> None:
...
def __delete__(self, instance: T) -> None: ...


class ObjectWithQualname(typing.Protocol):
Expand Down
6 changes: 4 additions & 2 deletions introspection/typing/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def resolve_names_in_all_typing_modules(

@dataclasses.dataclass
class TypeCheckingConfig:
forward_ref_context: ForwardRefContext
forward_ref_context: typing.Optional[ForwardRefContext]
treat_name_errors_as_imports: bool

def resolve_at_least_1_level_of_forward_refs(self, annotation: TypeAnnotation) -> Type_:
Expand All @@ -48,7 +48,9 @@ def resolve_at_least_1_level_of_forward_refs(self, annotation: TypeAnnotation) -


def resolve_at_least_1_level_of_forward_refs(
annotation: TypeAnnotation, context: ForwardRefContext, treat_name_errors_as_imports: bool
annotation: TypeAnnotation,
context: typing.Optional[ForwardRefContext],
treat_name_errors_as_imports: bool,
) -> Type_:
# Given a forward reference as input, this function resolves the outermost type, but may leave
# subtypes unevaluated. If the input isn't a forward reference, it is returned as-is.
Expand Down
6 changes: 3 additions & 3 deletions introspection/typing/instance_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
)
from .subtype_check import _is_subtype
from .type_compat import to_python
from ..errors import CannotResolveForwardref
from ..parameter import Parameter
from ..signature_ import Signature
from .._utils import eval_or_discard
Expand All @@ -35,7 +34,7 @@ def is_instance(
obj: object,
type_: Union[Type[T], TypeAnnotation],
*,
forward_ref_context: ForwardRefContext = None,
forward_ref_context: Optional[ForwardRefContext] = None,
treat_name_errors_as_imports: bool = False,
) -> typing_extensions.TypeGuard[T]:
"""
Expand Down Expand Up @@ -180,7 +179,8 @@ def _test_callable_subtypes(
) -> bool:
signature = Signature.from_callable(obj)
new_config = TypeCheckingConfig(
signature.forward_ref_context, config.treat_name_errors_as_imports
signature.forward_ref_context, # type: ignore[wtf]
config.treat_name_errors_as_imports,
)

if signature.return_annotation is not Signature.empty:
Expand Down
21 changes: 9 additions & 12 deletions introspection/typing/introspection.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,15 @@ def _resolve_dotted_name(name: str) -> object:


@overload
def _resolve_dotted_names(names: Dict[str, T]) -> Dict[object, T]:
...
def _resolve_dotted_names(names: Dict[str, T]) -> Dict[object, T]: ...


@overload
def _resolve_dotted_names(names: Tuple[str, ...]) -> Tuple[object, ...]:
...
def _resolve_dotted_names(names: Tuple[str, ...]) -> Tuple[object, ...]: ...


@overload
def _resolve_dotted_names(names: Iterable[str]) -> Iterable[object]:
...
def _resolve_dotted_names(names: Iterable[str]) -> Iterable[object]: ...


def _resolve_dotted_names(
Expand Down Expand Up @@ -294,7 +291,7 @@ def _get_type_parameters(type_):
if isinstance(type_, types.UnionType):
return type_.__parameters__ # type: ignore

if safe_is_subclass(type_, Generic):
if safe_is_subclass(type_, Generic): # type: ignore[wtf]
# Classes that inherit from Generic directly (like
# ``class Protocol(Generic):``) and Generic itself don't
# have __orig_bases__, while classes that have type
Expand Down Expand Up @@ -421,7 +418,7 @@ def _get_name(cls):
if sys.version_info >= (3, 9):

def _is_generic_base_class(cls):
if safe_is_subclass(cls, Generic):
if safe_is_subclass(cls, Generic): # type: ignore[wtf]
return bool(cls.__parameters__) # type: ignore

return False
Expand Down Expand Up @@ -818,7 +815,7 @@ def get_generic_base_class(type_: Type_) -> Type_:
if len(args) == 1:
base = Optional

return base
return base # type: ignore[wtf]


def get_type_arguments(type_: Type_) -> Tuple[object, ...]:
Expand Down Expand Up @@ -1070,7 +1067,7 @@ class MySequence(Sequence):
arg = args[i]
except IndexError:
if assume_any:
return Any
return Any # type: ignore

raise TypeVarNotSet(type_var, base_type, type_) # type: ignore

Expand Down Expand Up @@ -1150,11 +1147,11 @@ def get_parent_types(type_: Type_) -> Tuple[Type_, ...]:
try:
orig_bases = type_.__orig_bases__ # type: ignore
except AttributeError:
return type_.__bases__
return type_.__bases__ # type: ignore[wtf]

parent_types = []

for base, orig_base in zip(type_.__bases__, orig_bases):
for base, orig_base in zip(type_.__bases__, orig_bases): # type: ignore[wtf]
# Non-generic types show up as-is in both tuples
if base is orig_base:
parent_types.append(base)
Expand Down
12 changes: 6 additions & 6 deletions introspection/typing/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def is_forward_ref(
@overload
def resolve_forward_refs(
annotation: TypeAnnotation,
context: ForwardRefContext = None,
context: Optional[ForwardRefContext] = None,
*,
mode: Literal["eval", "getattr", "ast"] = "eval",
strict: bool = True,
Expand All @@ -64,7 +64,7 @@ def resolve_forward_refs(

def resolve_forward_refs( # type: ignore
annotation: TypeAnnotation,
context: ForwardRefContext = None,
context: Optional[ForwardRefContext] = None,
eval_: Optional[bool] = None,
strict: bool = True,
*,
Expand Down Expand Up @@ -458,7 +458,7 @@ def process_nested(prefix: str, elems: Iterable[TypeAnnotation]):
if base in (typing.Callable, collections.abc.Callable):
param_types, return_type = subtypes

prefix = recurse(base)
prefix = recurse(base) # type: ignore[wtf]
return_str = recurse(return_type) # type: ignore

if isinstance(param_types, list):
Expand All @@ -471,18 +471,18 @@ def process_nested(prefix: str, elems: Iterable[TypeAnnotation]):

if base in LITERAL_TYPES:
literals = ", ".join(repr(value) for value in subtypes)
prefix = recurse(base)
prefix = recurse(base) # type: ignore[wtf]
return f"{prefix}[{literals}]"

if base is typing_extensions.Annotated:
sub_type, *annotations = subtypes
sub_strs = [recurse(sub_type)] # type: ignore
sub_strs.extend(repr(ann) for ann in annotations)

prefix = recurse(base)
prefix = recurse(base) # type: ignore[wtf]
return f'{prefix}[{", ".join(sub_strs)}]'

prefix = recurse(base)
prefix = recurse(base) # type: ignore[wtf]
return process_nested(prefix, subtypes) # type: ignore

if isinstance(annotation, (typing.TypeVar, typing_extensions.ParamSpec)):
Expand Down
Loading

0 comments on commit e0e2996

Please sign in to comment.