Skip to content

Commit c6be832

Browse files
committed
Implement GetArgs
1 parent 8a39bdd commit c6be832

4 files changed

Lines changed: 36 additions & 5 deletions

File tree

spec-draft.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ It's important that there be a clearly specified type language for the type-leve
6969
Special forms unfortunately require some special handling: the arguments list of a ``Callable`` will be packed in a tuple, and a ``...`` will become ``SpecialFormEllipsis``.
7070

7171

72-
* ``GetArgs[T, Base]`` - returns a tuple containing all of the type arguments of ``T`` when interpreted as ``Base``, or ``Never`` if it cannot be. (TODO: UNIMPLEMENTED)
72+
* ``GetArgs[T, Base]`` - returns a tuple containing all of the type arguments of ``T`` when interpreted as ``Base``, or ``Never`` if it cannot be.
7373
* ``FromUnion[T]`` - returns a tuple containing all of the union elements, or a 1-ary tuple containing T if it is not a union.
7474

7575

tests/test_type_eval.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
Attrs,
88
FromUnion,
99
GetArg,
10+
GetArgs,
1011
GetAttr,
1112
GetName,
1213
GetType,
@@ -178,6 +179,16 @@ def test_getarg_never():
178179
assert d is Never
179180

180181

182+
def test_eval_getargs():
183+
t = dict[int, str]
184+
args = eval_typing(GetArgs[t, dict])
185+
assert args == tuple[int, str]
186+
187+
t = dict
188+
args = eval_typing(GetArgs[t, dict])
189+
assert args == tuple[Any, Any]
190+
191+
181192
def test_eval_getarg_callable():
182193
# oh hmmmmmmm -- yeah maybe callable could be fully bespoke if we
183194
# disallowed putting Callable here...!

typemap/type_eval/_eval_operators.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
Capitalize,
1717
FromUnion,
1818
GetArg,
19+
GetArgs,
1920
GetAttr,
2021
IsSubSimilar,
2122
IsSubtype,
@@ -247,12 +248,11 @@ def _eval_GetAttr(lhs, prop, *, ctx):
247248
return typing.get_type_hints(lhs)[name]
248249

249250

250-
def _get_args(tp, base, ctx) -> typing.Any:
251+
def _get_raw_args(tp, base_head, ctx) -> typing.Any:
251252
# XXX: check against base!!
252253
evaled = _eval_types(tp, ctx)
253254

254255
tp_head = _typing_inspect.get_head(tp)
255-
base_head = _typing_inspect.get_head(base)
256256
if not tp_head or not base_head:
257257
return None
258258

@@ -271,6 +271,14 @@ def _get_args(tp, base, ctx) -> typing.Any:
271271
return None
272272

273273

274+
def _get_args(tp, base, ctx) -> typing.Any:
275+
base_head = _typing_inspect.get_head(base)
276+
args = _get_raw_args(tp, base, ctx)
277+
if args == ():
278+
args = _get_defaults(base_head)
279+
return args
280+
281+
274282
def _fix_type(tp):
275283
"""Fix up a type getting returned from GetArg
276284
@@ -383,8 +391,6 @@ def _get_defaults(base_head):
383391
def _eval_GetArg(tp, base, idx, *, ctx) -> typing.Any:
384392
base_head = _typing_inspect.get_head(base)
385393
args = _get_args(tp, base_head, ctx)
386-
if args == ():
387-
args = _get_defaults(base_head)
388394
if args is None:
389395
return typing.Never
390396

@@ -394,6 +400,16 @@ def _eval_GetArg(tp, base, idx, *, ctx) -> typing.Any:
394400
return typing.Never
395401

396402

403+
@type_eval.register_evaluator(GetArgs)
404+
@_lift_over_unions
405+
def _eval_GetArgs(tp, base, *, ctx) -> typing.Any:
406+
base_head = _typing_inspect.get_head(base)
407+
args = _get_args(tp, base_head, ctx)
408+
if args is None:
409+
return typing.Never
410+
return tuple[*args] # type: ignore[valid-type]
411+
412+
397413
@type_eval.register_evaluator(Length)
398414
@_lift_over_unions
399415
def _eval_Length(tp, *, ctx) -> typing.Any:

typemap/typing.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ class GetArg[Tp, Base, Idx: int]:
5252
pass
5353

5454

55+
class GetArgs[Tp, Base]:
56+
pass
57+
58+
5559
class Length[S: tuple]:
5660
pass
5761

0 commit comments

Comments
 (0)