diff --git a/src/ansiblelint/_prerun.py b/src/ansiblelint/_prerun.py index df19533a59..135d2fd350 100644 --- a/src/ansiblelint/_prerun.py +++ b/src/ansiblelint/_prerun.py @@ -25,7 +25,7 @@ from ansiblelint.loaders import yaml_from_file -def check_ansible_presence(exit_on_error=False) -> Tuple[str, str]: +def check_ansible_presence(exit_on_error: bool = False) -> Tuple[str, str]: """Assures we stop execution if Ansible is missing or outdated. Returne found version and an optional exception if something wrong diff --git a/src/ansiblelint/cli.py b/src/ansiblelint/cli.py index 47bc97f0a0..19555b4a8b 100644 --- a/src/ansiblelint/cli.py +++ b/src/ansiblelint/cli.py @@ -6,7 +6,7 @@ import sys from argparse import Namespace from pathlib import Path -from typing import Any, Dict, List, Optional +from typing import Any, Dict, List, Optional, Sequence, Union import yaml @@ -42,7 +42,9 @@ def abspath(path: str, base_dir: str) -> str: return os.path.normpath(path) -def expand_to_normalized_paths(config: dict, base_dir: str = None) -> None: +def expand_to_normalized_paths( + config: Dict[str, Any], base_dir: Optional[str] = None +) -> None: # config can be None (-c /dev/null) if not config: return @@ -112,12 +114,21 @@ def get_config_path(config_file: str = '.ansible-lint') -> Optional[str]: class AbspathArgAction(argparse.Action): - def __call__(self, parser, namespace, values, option_string=None): + def __call__( + self, + parser: argparse.ArgumentParser, + namespace: Namespace, + values: Union[str, Sequence[Any], None], + option_string: Optional[str] = None, + ) -> None: if isinstance(values, (str, Path)): values = [values] - normalized_values = [Path(expand_path_vars(path)).resolve() for path in values] - previous_values = getattr(namespace, self.dest, []) - setattr(namespace, self.dest, previous_values + normalized_values) + if values: + normalized_values = [ + Path(expand_path_vars(str(path))).resolve() for path in values + ] + previous_values = getattr(namespace, self.dest, []) + setattr(namespace, self.dest, previous_values + normalized_values) def get_cli_parser() -> argparse.ArgumentParser: @@ -278,7 +289,7 @@ def get_cli_parser() -> argparse.ArgumentParser: return parser -def merge_config(file_config, cli_config: Namespace) -> Namespace: +def merge_config(file_config: Dict[Any, Any], cli_config: Namespace) -> Namespace: bools = ( 'display_relative_path', 'parseable', @@ -358,7 +369,7 @@ def get_config(arguments: List[str]) -> Namespace: return config -def print_help(file=sys.stdout): +def print_help(file: Any = sys.stdout) -> None: get_cli_parser().print_help(file=file) diff --git a/src/ansiblelint/file_utils.py b/src/ansiblelint/file_utils.py index b740258904..8edde0d193 100644 --- a/src/ansiblelint/file_utils.py +++ b/src/ansiblelint/file_utils.py @@ -67,7 +67,7 @@ def expand_paths_vars(paths: List[str]) -> List[str]: return paths -def kind_from_path(path: Path): +def kind_from_path(path: Path) -> str: """Determine the file kind based on its name.""" # pathlib.Path.match patterns are very limited, they do not support *a*.yml # glob.glob supports **/foo.yml but not multiple extensions @@ -82,7 +82,7 @@ def kind_from_path(path: Path): | wcmatch.pathlib.DOTGLOB ), ): - return k + return str(k) if path.is_dir(): return "role" @@ -146,18 +146,18 @@ def __init__( else: self.dir = str(self.path.parent.resolve()) - def __getitem__(self, item): + def __getitem__(self, key: Any) -> Any: """Provide compatibility subscriptable support.""" - if item == 'path': + if key == 'path': return str(self.path) - if item == 'type': + if key == 'type': return str(self.kind) raise NotImplementedError() - def get(self, item, default=None): + def get(self, key: Any, default: Any = None) -> Any: """Provide compatibility subscriptable support.""" try: - return self.__getitem__(item) + return self.__getitem__(key) except NotImplementedError: return default diff --git a/src/ansiblelint/logger.py b/src/ansiblelint/logger.py index 568c0dc0ec..18b36f4f6c 100644 --- a/src/ansiblelint/logger.py +++ b/src/ansiblelint/logger.py @@ -2,13 +2,13 @@ import logging import time from contextlib import contextmanager -from typing import Any +from typing import Any, Iterator _logger = logging.getLogger(__name__) @contextmanager -def timed_info(msg: Any, *args: Any): +def timed_info(msg: Any, *args: Any) -> Iterator[None]: """Context manager for logging slow operations, mentions duration.""" start = time.time() try: diff --git a/src/ansiblelint/skip_utils.py b/src/ansiblelint/skip_utils.py index 030e3e77ea..8010b71f1e 100644 --- a/src/ansiblelint/skip_utils.py +++ b/src/ansiblelint/skip_utils.py @@ -43,7 +43,7 @@ # ansible.parsing.yaml.objects.AnsibleSequence -def get_rule_skips_from_line(line: str) -> List: +def get_rule_skips_from_line(line: str) -> List[str]: """Return list of rule ids skipped via comment on the line of yaml.""" _before_noqa, _noqa_marker, noqa_text = line.partition("# noqa") noqa_text = noqa_text.lstrip(" :") @@ -52,7 +52,7 @@ def get_rule_skips_from_line(line: str) -> List: def append_skipped_rules( pyyaml_data: "AnsibleBaseYAMLObject", lintable: Lintable -) -> Sequence: +) -> Sequence[Any]: """Append 'skipped_rules' to individual tasks or single metadata block. For a file, uses 2nd parser (ruamel.yaml) to pull comments out of @@ -87,7 +87,9 @@ def load_data(file_text: str) -> Any: return yaml.load(file_text) -def _append_skipped_rules(pyyaml_data: Sequence[Any], lintable: Lintable) -> Sequence: +def _append_skipped_rules( + pyyaml_data: Sequence[Any], lintable: Lintable +) -> Sequence[Any]: # parse file text using 2nd parser library ruamel_data = load_data(lintable.content) @@ -132,7 +134,7 @@ def _append_skipped_rules(pyyaml_data: Sequence[Any], lintable: Lintable) -> Seq return pyyaml_data -def _get_task_blocks_from_playbook(playbook: Sequence) -> List: +def _get_task_blocks_from_playbook(playbook: Sequence[Any]) -> List[Any]: """Return parts of playbook that contains tasks, and nested tasks. :param playbook: playbook yaml from yaml parser. @@ -151,7 +153,7 @@ def _get_task_blocks_from_playbook(playbook: Sequence) -> List: return task_blocks -def _get_tasks_from_blocks(task_blocks: Sequence) -> Generator: +def _get_tasks_from_blocks(task_blocks: Sequence[Any]) -> Generator[Any, None, None]: """Get list of tasks from list made of tasks and nested tasks.""" NESTED_TASK_KEYS = [ 'block', @@ -171,7 +173,7 @@ def get_nested_tasks(task: Any) -> Generator[Any, None, None]: yield task -def _get_rule_skips_from_yaml(yaml_input: Sequence) -> Sequence: +def _get_rule_skips_from_yaml(yaml_input: Sequence[Any]) -> Sequence[Any]: """Traverse yaml for comments with rule skips and return list of rules.""" yaml_comment_obj_strs = [] diff --git a/src/ansiblelint/utils.py b/src/ansiblelint/utils.py index 0e34ba798b..badbabab8f 100644 --- a/src/ansiblelint/utils.py +++ b/src/ansiblelint/utils.py @@ -76,7 +76,7 @@ _logger = logging.getLogger(__name__) -def parse_yaml_from_file(filepath: str) -> dict: +def parse_yaml_from_file(filepath: str) -> Any: dl = DataLoader() if hasattr(dl, 'set_vault_password'): dl.set_vault_password(DEFAULT_VAULT_PASSWORD) @@ -86,7 +86,7 @@ def parse_yaml_from_file(filepath: str) -> dict: def path_dwim(basedir: str, given: str) -> str: dl = DataLoader() dl.set_basedir(basedir) - return dl.path_dwim(given) + return str(dl.path_dwim(given)) def ansible_template(basedir: str, varname: Any, templatevars, **kwargs) -> Any: