Skip to content

Commit c0080a8

Browse files
committed
Adjust other consumers of get_function_argspec
1 parent e5e3c61 commit c0080a8

10 files changed

Lines changed: 53 additions & 35 deletions

File tree

salt/fileserver/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ def envs(self, back=None, sources=False):
504504
fstr = f"{fsb}.envs"
505505
kwargs = (
506506
{"ignore_cache": True}
507-
if "ignore_cache" in _argspec(self.servers[fstr]).args
507+
if "ignore_cache" in _argspec(self.servers[fstr]).namedargs
508508
and self.opts["__role"] == "minion"
509509
else {}
510510
)

salt/key.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
"""
55

66
import fnmatch
7-
import itertools
87
import logging
98
import os
109
import shutil
@@ -146,14 +145,8 @@ def _get_args_kwargs(self, fun, args=None):
146145
if args is None:
147146
args = []
148147
if argspec.args:
149-
# Iterate in reverse order to ensure we get the correct default
150-
# value for the positional argument.
151-
for arg, default in itertools.zip_longest(
152-
reversed(argspec.args), reversed(argspec.defaults or ())
153-
):
148+
for arg, default in argspec.argdefaults.items():
154149
args.append(self.opts.get(arg, default))
155-
# Reverse the args so that they are in the correct order
156-
args = args[::-1]
157150

158151
if argspec.keywords is None:
159152
kwargs = {}

salt/master.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2494,7 +2494,7 @@ def _prep_pub(self, minions, jid, clear_load, extra, missing):
24942494

24952495
# Check if 'minions' is included in returner's save_load arg_spec.
24962496
# This may be missing in custom returners, which we should warn about.
2497-
if "minions" not in arg_spec.args:
2497+
if "minions" not in arg_spec.namedargs:
24982498
log.critical(
24992499
"The specified returner used for the external job cache "
25002500
"'%s' does not have a 'minions' kwarg in the returner's "
@@ -2522,7 +2522,7 @@ def _prep_pub(self, minions, jid, clear_load, extra, missing):
25222522
# always write out to the master job caches
25232523
try:
25242524
fstr = "{}.save_load".format(self.opts["master_job_cache"])
2525-
self.mminion.returners[fstr](clear_load["jid"], clear_load, minions)
2525+
self.mminion.returners[fstr](clear_load["jid"], clear_load, minions=minions)
25262526
except KeyError:
25272527
log.critical(
25282528
"The specified returner used for the master job cache "

salt/modules/saltutil.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,7 +2009,7 @@ def runner(
20092009

20102010
if name in rclient.functions:
20112011
aspec = salt.utils.args.get_function_argspec(rclient.functions[name])
2012-
if "saltenv" in aspec.args:
2012+
if "saltenv" in aspec.namedargs:
20132013
kwarg["saltenv"] = saltenv
20142014

20152015
if name in ["state.orchestrate", "state.orch", "state.sls"]:
@@ -2095,7 +2095,7 @@ def wheel(name, *args, **kwargs):
20952095
try:
20962096
if name in wheel_client.functions:
20972097
aspec = salt.utils.args.get_function_argspec(wheel_client.functions[name])
2098-
if "saltenv" in aspec.args:
2098+
if "saltenv" in aspec.namedargs:
20992099
valid_kwargs["saltenv"] = saltenv
21002100

21012101
if jid:

salt/pillar/__init__.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,10 +1147,12 @@ def _external_pillar_data(self, pillar, val, key):
11471147
Builds actual pillar data structure and updates the ``pillar`` variable
11481148
"""
11491149
ext = None
1150-
args = salt.utils.args.get_function_argspec(self.ext_pillars[key]).args
1150+
valid_kwargs = salt.utils.args.get_function_argspec(
1151+
self.ext_pillars[key]
1152+
).namedargs
11511153

11521154
if isinstance(val, dict):
1153-
if ("extra_minion_data" in args) and self.extra_minion_data:
1155+
if ("extra_minion_data" in valid_kwargs) and self.extra_minion_data:
11541156
ext = self.ext_pillars[key](
11551157
self.minion_id,
11561158
pillar,
@@ -1160,7 +1162,7 @@ def _external_pillar_data(self, pillar, val, key):
11601162
else:
11611163
ext = self.ext_pillars[key](self.minion_id, pillar, **val)
11621164
elif isinstance(val, list):
1163-
if ("extra_minion_data" in args) and self.extra_minion_data:
1165+
if ("extra_minion_data" in valid_kwargs) and self.extra_minion_data:
11641166
ext = self.ext_pillars[key](
11651167
self.minion_id,
11661168
pillar,
@@ -1170,7 +1172,7 @@ def _external_pillar_data(self, pillar, val, key):
11701172
else:
11711173
ext = self.ext_pillars[key](self.minion_id, pillar, *val)
11721174
else:
1173-
if ("extra_minion_data" in args) and self.extra_minion_data:
1175+
if ("extra_minion_data" in valid_kwargs) and self.extra_minion_data:
11741176
ext = self.ext_pillars[key](
11751177
self.minion_id,
11761178
pillar,

salt/state.py

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,19 +1498,9 @@ def verify_data(self, data):
14981498
else:
14991499
# First verify that the parameters are met
15001500
aspec = salt.utils.args.get_function_argspec(self.states[full])
1501-
arglen = 0
1502-
deflen = 0
1503-
if isinstance(aspec.args, list):
1504-
arglen = len(aspec.args)
1505-
if isinstance(aspec.defaults, tuple):
1506-
deflen = len(aspec.defaults)
1507-
for ind in range(arglen - deflen):
1508-
if aspec.args[ind] not in data:
1509-
errors.append(
1510-
"Missing parameter {} for state {}".format(
1511-
aspec.args[ind], full
1512-
)
1513-
)
1501+
for req in aspec.allreq:
1502+
if req not in data:
1503+
errors.append(f"Missing parameter {req} for state {full}")
15141504
# If this chunk has a recursive require, then it will cause a
15151505
# recursive loop when executing, check for it
15161506
reqdec = ""

salt/states/service.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ def _get_systemd_only(func, kwargs):
103103

104104
ret = {}
105105
warnings = []
106-
valid_args = _argspec(func).args
106+
valid_kwargs = _argspec(func).namedargs
107107
for systemd_arg in SYSTEMD_ONLY:
108-
if systemd_arg in kwargs and systemd_arg in valid_args:
108+
if systemd_arg in kwargs and systemd_arg in valid_kwargs:
109109
if _get_systemd_only.HAS_SYSTEMD:
110110
ret[systemd_arg] = kwargs[systemd_arg]
111111
else:

salt/utils/args.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,24 @@ def kwonlyreq(self) -> tuple[str, ...]:
335335
kwdefaults = self.kwonlydefaults
336336
return tuple(kw for kw in self.kwonlyargs if kw not in kwdefaults)
337337

338+
@property
339+
def allreq(self) -> tuple[str, ...]:
340+
"""
341+
Tuple of parameters of any kind that require an argument.
342+
"""
343+
return tuple(list(self.argreq) + list(self.kwonlyreq))
344+
345+
@property
346+
def namedargs(self) -> tuple[str, ...]:
347+
"""
348+
Tuple of parameters that can be passed by name.
349+
The positional equivalent to this is just ``args``.
350+
"""
351+
return tuple(
352+
[arg for arg in self.args if arg not in self.posonlyargs]
353+
+ list(self.kwonlyargs)
354+
)
355+
338356

339357
def get_function_argspec(func, is_class_method=None) -> _ArgSpec:
340358
"""

tests/pytests/integration/states/test_arg_kinds.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,12 @@ def test_kwonly_defaults_required_kwonly_missing(salt_call_cli, salt_master):
9292
with salt_master.state_tree.base.temp_file("kwonly_defaults_miss.sls", contents):
9393
ret = salt_call_cli.run("state.apply", "kwonly_defaults_miss")
9494
assert ret.returncode != 0, ret
95-
assert any(
96-
"missing 1 required keyword-only" in stream
97-
for stream in (ret.stdout, ret.stderr)
95+
# Ensure state verification catches it, not salt.utils.args.format_call
96+
single_ret = ret.data[next(iter(ret.data))]
97+
assert single_ret["result"] is False
98+
assert (
99+
"Missing parameter c for state arg_kinds.kwonly_defaults"
100+
in single_ret["comment"]
98101
)
99102

100103

tests/pytests/unit/utils/test_args.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,20 @@ def test_get_function_argspec(fun, expected):
302302
"kwdefaults": {},
303303
"posonlydefaults": {},
304304
"alldefaults": {},
305+
"allreq": (),
306+
"namedargs": (),
305307
}
306308
expected = defaults | expected
309+
# Fill allreq/namedargs from expected data to avoid repetition
310+
if expected["argreq"] or expected["kwonlyreq"]:
311+
expected["allreq"] = expected["allreq"] or tuple(
312+
list(expected["argreq"]) + list(expected["kwonlyreq"])
313+
)
314+
if expected["args"] or expected["kwonlyargs"]:
315+
expected["namedargs"] = expected["namedargs"] or tuple(
316+
list(arg for arg in expected["args"] if arg not in expected["posonlyargs"])
317+
+ list(expected["kwonlyargs"])
318+
)
307319
spec = salt.utils.args.get_function_argspec(fun)
308320
for attr, exp in expected.items():
309321
assert getattr(spec, attr) == exp

0 commit comments

Comments
 (0)