diff --git a/salt/state.py b/salt/state.py index 25004b6ee1c..d5956981eed 100644 --- a/salt/state.py +++ b/salt/state.py @@ -483,24 +483,20 @@ class Compiler: else: fun = 0 if "." in state: + # This should not happen usually since `pad_funcs` + # is run on rendered templates fun += 1 for arg in body[state]: if isinstance(arg, str): - if "." in state: + fun += 1 + if " " in arg.strip(): errors.append( - "Argument not formed as a dictionary in state " - f"'{name}' in SLS '{body['__sls__']}': '{arg}'" + f'The function "{arg}" in state ' + f'"{name}" in SLS "{body["__sls__"]}" has ' + "whitespace, a function with whitespace is " + "not supported, perhaps this is an argument" + ' that is missing a ":"' ) - else: - fun += 1 - if " " in arg.strip(): - errors.append( - f'The function "{arg}" in state ' - f'"{name}" in SLS "{body["__sls__"]}" has ' - "whitespace, a function with whitespace is " - "not supported, perhaps this is an argument" - ' that is missing a ":"' - ) elif isinstance(arg, dict): # The arg is a dict, if the arg is require or # watch, it must be a list. @@ -595,17 +591,22 @@ class Compiler: if state == "require" or state == "watch": continue errors.append( - "No function declared in state '{}' in SLS '{}'".format( - state, body["__sls__"] - ) + f"No function declared in state '{name}' in SLS " + f"'{body['__sls__']}'" ) elif fun > 1: + funs = ( + [state.split(".", maxsplit=1)[1]] + if "." in state + else [] + ) + funs.extend( + arg for arg in body[state] if isinstance(arg, str) + ) errors.append( - f"Too many functions declared in state '{state}' in " - f"SLS '{body['__sls__']}'. Please choose one of the following: " - + ", ".join( - arg for arg in body[state] if isinstance(arg, str) - ) + f"Too many functions declared in state '{name}' in " + f"SLS '{body['__sls__']}'. Please choose one of " + "the following: " + ", ".join(funs) ) return errors @@ -1513,24 +1514,20 @@ class State: else: fun = 0 if "." in state: + # This should not happen usually since `_handle_state_decls` + # is run on rendered templates fun += 1 for arg in body[state]: if isinstance(arg, str): - if "." in state: + fun += 1 + if " " in arg.strip(): errors.append( - "Argument not formed as a dictionary in state " - f"'{name}' in SLS '{body['__sls__']}': '{arg}'" + f'The function "{arg}" in state ' + f'"{name}" in SLS "{body["__sls__"]}" has ' + "whitespace, a function with whitespace is " + "not supported, perhaps this is an argument" + ' that is missing a ":"' ) - else: - fun += 1 - if " " in arg.strip(): - errors.append( - f'The function "{arg}" in state ' - f'"{name}" in SLS "{body["__sls__"]}" has ' - "whitespace, a function with whitespace is " - "not supported, perhaps this is an argument" - ' that is missing a ":"' - ) elif isinstance(arg, dict): # The arg is a dict, if the arg is require or @@ -1624,17 +1621,16 @@ class State: if state == "require" or state == "watch": continue errors.append( - "No function declared in state '{}' in SLS '{}'".format( - state, body["__sls__"] - ) + f"No function declared in state '{name}' in SLS " + f"'{body['__sls__']}'" ) elif fun > 1: + funs = [state.split(".", maxsplit=1)[1]] if "." in state else [] + funs.extend(arg for arg in body[state] if isinstance(arg, str)) errors.append( - f"Too many functions declared in state '{state}' in " - f"SLS '{body['__sls__']}'. Please choose one of the following: " - + ", ".join( - arg for arg in body[state] if isinstance(arg, str) - ) + f"Too many functions declared in state '{name}' in " + f"SLS '{body['__sls__']}'. Please choose one of " + "the following: " + ", ".join(funs) ) return errors diff --git a/tests/pytests/unit/state/test_reactor_compiler.py b/tests/pytests/unit/state/test_reactor_compiler.py index 36c914232b8..d0f03fbfdb7 100644 --- a/tests/pytests/unit/state/test_reactor_compiler.py +++ b/tests/pytests/unit/state/test_reactor_compiler.py @@ -416,7 +416,7 @@ def test_compiler_verify_high_short_sls(minion_opts, tmp_path, high, exp): }, [ "The require statement in state 'add_test_2' in SLS '/srv/reactor/start.sls' needs to be formed as a list", - "Argument not formed as a dictionary in state 'add_test_2' in SLS '/srv/reactor/start.sls': 'cmd.run'", + "Too many functions declared in state 'add_test_2' in SLS '/srv/reactor/start.sls'. Please choose one of the following: cmd.run, cmd.run", ], ), ( diff --git a/tests/pytests/unit/state/test_state_compiler.py b/tests/pytests/unit/state/test_state_compiler.py index 79d3a7e8013..e03d4caee5a 100644 --- a/tests/pytests/unit/state/test_state_compiler.py +++ b/tests/pytests/unit/state/test_state_compiler.py @@ -1107,11 +1107,11 @@ def test_verify_onlyif_cmd_opts_exclude(minion_opts): ( ( {"/some/file": {"file.managed": ["source:salt://bla"]}}, - "Argument not formed as a dictionary", + "Too many functions declared in state '/some/file' in SLS 'sls'. Please choose one of the following: managed, source:salt://bla", ), ( {"/some/file": {"file": ["managed", "source:salt://bla"]}}, - "Please choose one of the following: managed, source:salt", + "Too many functions declared in state '/some/file' in SLS 'sls'. Please choose one of the following: managed, source:salt://bla", ), ), )