3939import ruamel .yaml .parser
4040import yaml
4141from ansible .errors import AnsibleError , AnsibleParserError
42+ from ansible .module_utils ._text import to_bytes
4243from ansible .module_utils .parsing .convert_bool import boolean
4344from ansible .parsing .dataloader import DataLoader
4445from ansible .parsing .mod_args import ModuleArgsParser
4546from ansible .parsing .plugin_docs import read_docstring
4647from ansible .parsing .splitter import split_args
48+ from ansible .parsing .vault import PromptVaultSecret
4749from ansible .parsing .yaml .constructor import AnsibleConstructor , AnsibleMapping
4850from ansible .parsing .yaml .loader import AnsibleLoader
4951from ansible .parsing .yaml .objects import AnsibleBaseYAMLObject , AnsibleSequence
5658from ansible .template import Templar
5759from ansible .utils .collection_loader import AnsibleCollectionConfig
5860from yaml .composer import Composer
61+ from yaml .parser import ParserError
5962from yaml .representer import RepresenterError
63+ from yaml .scanner import ScannerError
6064
6165from ansiblelint ._internal .rules import (
6266 AnsibleParserErrorRule ,
9599def parse_yaml_from_file (filepath : str ) -> AnsibleBaseYAMLObject :
96100 """Extract a decrypted YAML object from file."""
97101 dataloader = DataLoader ()
98- if hasattr (dataloader , "set_vault_password" ):
99- dataloader .set_vault_password (DEFAULT_VAULT_PASSWORD )
102+ if hasattr (dataloader , "set_vault_secrets" ):
103+ dataloader .set_vault_secrets (
104+ [("default" , PromptVaultSecret (_bytes = to_bytes (DEFAULT_VAULT_PASSWORD )))]
105+ )
106+
100107 return dataloader .load_from_file (filepath )
101108
102109
@@ -254,7 +261,11 @@ def set_collections_basedir(basedir: Path) -> None:
254261 """Set the playbook directory as playbook_paths for the collection loader."""
255262 # Ansible expects only absolute paths inside `playbook_paths` and will
256263 # produce weird errors if we use a relative one.
257- AnsibleCollectionConfig .playbook_paths = str (basedir .resolve ())
264+ # https://github.com/psf/black/issues/4519
265+ # fmt: off
266+ AnsibleCollectionConfig .playbook_paths = ( # pyright: ignore[reportAttributeAccessIssue]
267+ str (basedir .resolve ()))
268+ # fmt: on
258269
259270
260271def template (
@@ -911,7 +922,7 @@ def task_in_list(
911922 """Get action tasks from block structures."""
912923
913924 def each_entry (data : AnsibleBaseYAMLObject , position : str ) -> Iterator [Task ]:
914- if not data :
925+ if not data or not isinstance ( data , Iterable ) :
915926 return
916927 for entry_index , entry in enumerate (data ):
917928 if not entry :
@@ -951,29 +962,35 @@ def each_entry(data: AnsibleBaseYAMLObject, position: str) -> Iterator[Task]:
951962 yield from each_entry (data , position )
952963
953964
954- def add_action_type (actions : AnsibleBaseYAMLObject , action_type : str ) -> list [Any ]:
965+ def add_action_type (
966+ actions : AnsibleBaseYAMLObject , action_type : str
967+ ) -> AnsibleSequence :
955968 """Add action markers to task objects."""
956- results = []
957- for action in actions :
958- # ignore empty task
959- if not action :
960- continue
961- action ["__ansible_action_type__" ] = BLOCK_NAME_TO_ACTION_TYPE_MAP [action_type ]
962- results .append (action )
969+ results = AnsibleSequence ()
970+ if isinstance (actions , Iterable ):
971+ for action in actions :
972+ # ignore empty task
973+ if not action :
974+ continue
975+ action ["__ansible_action_type__" ] = BLOCK_NAME_TO_ACTION_TYPE_MAP [
976+ action_type
977+ ]
978+ results .append (action )
963979 return results
964980
965981
966982@cache
967983def parse_yaml_linenumbers (
968984 lintable : Lintable ,
969- ) -> AnsibleBaseYAMLObject :
985+ ) -> AnsibleBaseYAMLObject | None :
970986 """Parse yaml as ansible.utils.parse_yaml but with linenumbers.
971987
972988 The line numbers are stored in each node's LINE_NUMBER_KEY key.
973989 """
974- result = []
990+ result = AnsibleSequence ()
975991
976- def compose_node (parent : yaml .nodes .Node , index : int ) -> yaml .nodes .Node :
992+ # signature of Composer.compose_node
993+ def compose_node (parent : yaml .nodes .Node | None , index : int ) -> yaml .nodes .Node :
977994 # the line number where the previous token has ended (plus empty lines)
978995 line = loader .line
979996 node = Composer .compose_node (loader , parent , index )
@@ -983,14 +1000,15 @@ def compose_node(parent: yaml.nodes.Node, index: int) -> yaml.nodes.Node:
9831000 node .__line__ = line + 1 # type: ignore[attr-defined]
9841001 return node
9851002
1003+ # signature of AnsibleConstructor.construct_mapping
9861004 def construct_mapping (
987- node : AnsibleBaseYAMLObject ,
988- * ,
989- deep : bool = False ,
1005+ node : yaml .MappingNode ,
1006+ deep : bool = False , # noqa: FBT002
9901007 ) -> AnsibleMapping :
1008+ # pyright: ignore[reportArgumentType]
9911009 mapping = AnsibleConstructor .construct_mapping (loader , node , deep = deep )
992- if hasattr (node , "__line__" ):
993- mapping [LINE_NUMBER_KEY ] = node . __line__
1010+ if hasattr (node , LINE_NUMBER_KEY ):
1011+ mapping [LINE_NUMBER_KEY ] = getattr ( node , LINE_NUMBER_KEY )
9941012 else :
9951013 mapping [LINE_NUMBER_KEY ] = mapping ._line_number # noqa: SLF001
9961014 mapping [FILENAME_KEY ] = lintable .path
@@ -1001,7 +1019,9 @@ def construct_mapping(
10011019 if "vault_password" in inspect .getfullargspec (AnsibleLoader .__init__ ).args :
10021020 kwargs ["vault_password" ] = DEFAULT_VAULT_PASSWORD
10031021 loader = AnsibleLoader (lintable .content , ** kwargs )
1022+ # redefine Composer.compose_node
10041023 loader .compose_node = compose_node
1024+ # redefine AnsibleConstructor.construct_mapping
10051025 loader .construct_mapping = construct_mapping
10061026 # while Ansible only accepts single documents, we also need to load
10071027 # multi-documents, as we attempt to load any YAML file, not only
@@ -1012,8 +1032,8 @@ def construct_mapping(
10121032 break
10131033 result .append (data )
10141034 except (
1015- yaml . parser . ParserError ,
1016- yaml . scanner . ScannerError ,
1035+ ParserError ,
1036+ ScannerError ,
10171037 yaml .constructor .ConstructorError ,
10181038 ruamel .yaml .parser .ParserError ,
10191039 ) as exc :
0 commit comments