Skip to content

Commit

Permalink
fix: pass globals through signature resolution (#75)
Browse files Browse the repository at this point in the history
* fix: fix sig resolution with mixed globals

* undo change
  • Loading branch information
tlambert03 authored Oct 10, 2023
1 parent 83ecfcb commit f9427c3
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
17 changes: 12 additions & 5 deletions src/in_n_out/_type_resolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def resolve_type_hints(

def resolve_single_type_hints(
*objs: Any,
globalns: dict | None = None,
localns: dict | None = None,
include_extras: bool = False,
) -> tuple[Any, ...]:
Expand All @@ -99,7 +100,9 @@ def resolve_single_type_hints(
"""
annotations = {str(n): v for n, v in enumerate(objs)}
mock_obj = type("_T", (), {"__annotations__": annotations})()
hints = resolve_type_hints(mock_obj, localns=localns, include_extras=include_extras)
hints = resolve_type_hints(
mock_obj, globalns=globalns, localns=localns, include_extras=include_extras
)
return tuple(hints[k] for k in annotations)


Expand Down Expand Up @@ -184,6 +187,7 @@ class method. This is done as follows:
) from err
hints = _resolve_params_one_by_one(
sig,
globalns=getattr(func, "__globals__", None),
localns=localns,
exclude_unresolved_mandatory=not raise_unresolved_required_args,
)
Expand All @@ -200,6 +204,7 @@ class method. This is done as follows:

def _resolve_params_one_by_one(
sig: Signature,
globalns: dict | None = None,
localns: dict | None = None,
exclude_unresolved_optionals: bool = False,
exclude_unresolved_mandatory: bool = False,
Expand All @@ -215,6 +220,8 @@ def _resolve_params_one_by_one(
----------
sig : Signature
:class:`inspect.Signature` object with unresolved type annotations.
globalns : Optional[dict]
Optional global namespace for name resolution, by default None
localns : Optional[dict]
Optional local namespace for name resolution, by default None
exclude_unresolved_optionals : bool
Expand All @@ -239,9 +246,9 @@ def _resolve_params_one_by_one(
if param.annotation is sig.empty:
continue # pragma: no cover
try:
hints[name] = resolve_single_type_hints(param.annotation, localns=localns)[
0
]
hints[name] = resolve_single_type_hints(
param.annotation, globalns=globalns, localns=localns
)[0]
except NameError as e:
if (
param.default is param.empty
Expand All @@ -257,7 +264,7 @@ def _resolve_params_one_by_one(
if sig.return_annotation is not sig.empty:
try:
hints["return"] = resolve_single_type_hints(
sig.return_annotation, localns=localns
sig.return_annotation, globalns=globalns, localns=localns
)[0]
except NameError:
if not exclude_unresolved_optionals:
Expand Down
18 changes: 18 additions & 0 deletions tests/test_type_resolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,21 @@ def func2(bar: "Bar", foo: "Foo"): # noqa

assert sig2.parameters["foo"].annotation == Foo
assert sig2.parameters["bar"].annotation == "Bar"


GlobalThing = int


def test_type_resolved_signature_mixed_global() -> None:
"""Test that we can resolve a mix of global annotations and missing forward refs."""

def myfun(a: "unknown", b: "GlobalThing"): # type: ignore # noqa
pass

_a = type_resolved_signature(
myfun,
raise_unresolved_optional_args=False,
raise_unresolved_required_args=False,
)
assert _a.parameters["a"].annotation == "unknown"
assert _a.parameters["b"].annotation == int

0 comments on commit f9427c3

Please sign in to comment.