Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions tests/test_call.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ def test_call_1():
ret = eval_call(func, a=1, b=2, c="aaa")
fmt = format_helper.format_class(ret)

# XXX: We want better than this for a name
assert fmt == textwrap.dedent("""\
class NewProtocol:
class func[...]:
a: int
b: int
c: int
Expand Down
21 changes: 16 additions & 5 deletions typemap/type_eval/_eval_call.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,17 @@


def eval_call(func: types.FunctionType, /, *args: Any, **kwargs: Any) -> Any:
with _eval_typing._ensure_context():
return _eval_call(func, *args, **kwargs)
with _eval_typing._ensure_context() as ctx:
return _eval_call(func, ctx, *args, **kwargs)


def _eval_call(func: types.FunctionType, /, *args: Any, **kwargs: Any) -> Any:
def _eval_call(
func: types.FunctionType,
ctx: _eval_typing.EvalContext,
/,
*args: Any,
**kwargs: Any,
) -> Any:
vars: dict[str, Any] = {}

params = func.__type_params__
Expand All @@ -39,6 +45,11 @@ def _eval_call(func: types.FunctionType, /, *args: Any, **kwargs: Any) -> Any:
ff = types.FunctionType(
af.__code__, af.__globals__, af.__name__, None, af_args
)
rr = ff(annotationlib.Format.VALUE)

return _eval_typing.eval_typing(rr["return"])
old_obj = ctx.current_alias
ctx.current_alias = func
try:
rr = ff(annotationlib.Format.VALUE)
return _eval_typing.eval_typing(rr["return"])
finally:
ctx.current_alias = old_obj
4 changes: 3 additions & 1 deletion typemap/type_eval/_eval_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
@dataclasses.dataclass
class EvalContext:
seen: dict[Any, Any]
current_alias: types.GenericAlias | None = None
# The typing.Any is really a types.FunctionType, but mypy gets
# confused and wants to treat it as a MethodType.
current_alias: types.GenericAlias | typing.Any | None = None


# `eval_types()` calls can be nested, context must be preserved
Expand Down
5 changes: 4 additions & 1 deletion typemap/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,10 @@ def __getitem__(cls, val: list[Property]):
# If the type evaluation context
ctx = type_eval._get_current_context()
if ctx.current_alias:
name = str(ctx.current_alias)
if isinstance(ctx.current_alias, types.GenericAlias):
name = str(ctx.current_alias)
else:
name = f"{ctx.current_alias.__name__}[...]"
module_name = ctx.current_alias.__module__

dct["__module__"] = module_name
Expand Down