Skip to content

Commit b172d84

Browse files
committed
Allow out-of-order kwonly args in signatures
1 parent 7e7bd2c commit b172d84

File tree

2 files changed

+27
-19
lines changed

2 files changed

+27
-19
lines changed

array_api_tests/meta/test_signatures.py

+7-10
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,13 @@ def stub(foo, /, bar=None, *, baz=None):
2929
Parameter("baz", Parameter.POSITIONAL_OR_KEYWORD),
3030
]
3131
),
32-
pytest.param(
33-
Signature(
34-
[
35-
Parameter("foo", Parameter.POSITIONAL_ONLY),
36-
Parameter("bar", Parameter.POSITIONAL_OR_KEYWORD),
37-
Parameter("qux", Parameter.KEYWORD_ONLY),
38-
Parameter("baz", Parameter.KEYWORD_ONLY),
39-
]
40-
),
41-
marks=pytest.mark.xfail(reason="out-of-order kwonly args not supported"),
32+
Signature(
33+
[
34+
Parameter("foo", Parameter.POSITIONAL_ONLY),
35+
Parameter("bar", Parameter.POSITIONAL_OR_KEYWORD),
36+
Parameter("qux", Parameter.KEYWORD_ONLY),
37+
Parameter("baz", Parameter.KEYWORD_ONLY),
38+
]
4239
),
4340
],
4441
)

array_api_tests/test_signatures.py

+20-9
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,15 @@ def squeeze(x, /, axis):
6060
def _test_inspectable_func(sig: Signature, stub_sig: Signature):
6161
params = list(sig.parameters.values())
6262
stub_params = list(stub_sig.parameters.values())
63+
64+
non_kwonly_stub_params = [
65+
p for p in stub_params if p.kind != Parameter.KEYWORD_ONLY
66+
]
67+
# sanity check
68+
assert non_kwonly_stub_params == stub_params[: len(non_kwonly_stub_params)]
6369
# We're not interested if the array module has additional arguments, so we
6470
# only iterate through the arguments listed in the spec.
65-
for i, stub_param in enumerate(stub_params):
71+
for i, stub_param in enumerate(non_kwonly_stub_params):
6672
assert (
6773
len(params) >= i + 1
6874
), f"Argument '{stub_param.name}' missing from signature"
@@ -74,19 +80,24 @@ def _test_inspectable_func(sig: Signature, stub_sig: Signature):
7480
param.name == stub_param.name
7581
), f"Expected argument '{param.name}' to be named '{stub_param.name}'"
7682

77-
f_stub_kind = kind_to_str[stub_param.kind]
7883
if stub_param.kind in [Parameter.POSITIONAL_OR_KEYWORD, *VAR_KINDS]:
84+
f_stub_kind = kind_to_str[stub_param.kind]
7985
assert param.kind == stub_param.kind, (
8086
f"{param.name} is a {kind_to_str[param.kind]}, "
8187
f"but should be a {f_stub_kind}"
8288
)
83-
else:
84-
# TODO: allow for kw-only args to be out-of-order
85-
assert param.kind in [stub_param.kind, Parameter.POSITIONAL_OR_KEYWORD,], (
86-
f"{param.name} is a {kind_to_str[param.kind]}, "
87-
f"but should be a {f_stub_kind} "
88-
f"(or at least a {kind_to_str[ParameterKind.POSITIONAL_OR_KEYWORD]})"
89-
)
89+
90+
kwonly_stub_params = stub_params[len(non_kwonly_stub_params) :]
91+
for stub_param in kwonly_stub_params:
92+
assert (
93+
stub_param.name in sig.parameters.keys()
94+
), f"Argument '{stub_param.name}' missing from signature"
95+
param = next(p for p in params if p.name == stub_param.name)
96+
assert param.kind in [stub_param.kind, Parameter.POSITIONAL_OR_KEYWORD,], (
97+
f"{param.name} is a {kind_to_str[param.kind]}, "
98+
f"but should be a {f_stub_kind} "
99+
f"(or at least a {kind_to_str[ParameterKind.POSITIONAL_OR_KEYWORD]})"
100+
)
90101

91102

92103
def get_dtypes_strategy(func_name: str) -> st.SearchStrategy[DataType]:

0 commit comments

Comments
 (0)