From 3f5b48e20c4670d27739533e313551e91f91e208 Mon Sep 17 00:00:00 2001 From: Sorin Sbarnea Date: Wed, 30 Dec 2020 09:47:33 +0000 Subject: [PATCH] Assure MatchError takes a rule instance Replace use of class with an instance of a Rule for MatchErrors, as this will allows us to process rules that produce various different error messages (aka meta-rules). Prepares-For: #955 --- lib/ansiblelint/errors.py | 6 +++--- lib/ansiblelint/rules/__init__.py | 5 +++-- lib/ansiblelint/runner.py | 2 +- lib/ansiblelint/utils.py | 4 ++-- test/TestMatchError.py | 4 ++-- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/ansiblelint/errors.py b/lib/ansiblelint/errors.py index 68434fe72b..0d5bd53102 100644 --- a/lib/ansiblelint/errors.py +++ b/lib/ansiblelint/errors.py @@ -1,7 +1,7 @@ """Exceptions and error representations.""" import functools import os -from typing import Any, Optional, Type +from typing import Any, Optional from ansiblelint._internal.rules import BaseRule, RuntimeErrorRule from ansiblelint.file_utils import normpath @@ -29,13 +29,13 @@ def __init__( linenumber: int = 0, details: str = "", filename: Optional[str] = None, - rule: Type[BaseRule] = RuntimeErrorRule, + rule: BaseRule = RuntimeErrorRule(), tag: Optional[str] = None # optional fine-graded tag ) -> None: """Initialize a MatchError instance.""" super().__init__(message) - if rule is RuntimeErrorRule and not message: + if rule.__class__ is RuntimeErrorRule and not message: raise TypeError( f'{self.__class__.__name__}() missing a ' "required argument: one of 'message' or 'rule'", diff --git a/lib/ansiblelint/rules/__init__.py b/lib/ansiblelint/rules/__init__.py index dd386c4572..7c45399baf 100644 --- a/lib/ansiblelint/rules/__init__.py +++ b/lib/ansiblelint/rules/__init__.py @@ -1,4 +1,5 @@ """All internal ansible-lint rules.""" +import copy import glob import importlib.util import logging @@ -42,7 +43,7 @@ def create_matcherror( linenumber=linenumber, details=details, filename=filename, - rule=self.__class__ + rule=copy.copy(self) ) if tag: match.tag = tag @@ -250,7 +251,7 @@ def run(self, playbookfile, tags=set(), skip_list=frozenset()) -> List: return [MatchError( message=str(error), filename=playbookfile['path'], - rule=LoadingFailureRule)] + rule=LoadingFailureRule())] for rule in self.rules: if not tags or not set(rule.tags).union([rule.id]).isdisjoint(tags): diff --git a/lib/ansiblelint/runner.py b/lib/ansiblelint/runner.py index 1e42b31f4a..3264aefc49 100644 --- a/lib/ansiblelint/runner.py +++ b/lib/ansiblelint/runner.py @@ -119,6 +119,6 @@ def _emit_matches(self, files: List) -> Generator[MatchError, None, None]: self.playbooks.add((child['path'], child['type'])) files.append(child) except MatchError as e: - e.rule = LoadingFailureRule + e.rule = LoadingFailureRule() yield e visited.add(arg) diff --git a/lib/ansiblelint/utils.py b/lib/ansiblelint/utils.py index 3907922869..47c0fb5cc3 100644 --- a/lib/ansiblelint/utils.py +++ b/lib/ansiblelint/utils.py @@ -273,7 +273,7 @@ def _taskshandlers_children(basedir, k, v, parent_type: FileType) -> List: if v is None: raise MatchError( message="A malformed block was encountered while loading a block.", - rule=RuntimeErrorRule) + rule=RuntimeErrorRule()) for th in v: # ignore empty tasks, `-` @@ -458,7 +458,7 @@ def normalize_task_v2(task: dict) -> dict: # noqa: C901 action, arguments, result['delegate_to'] = mod_arg_parser.parse() except AnsibleParserError as e: raise MatchError( - rule=AnsibleParserErrorRule, + rule=AnsibleParserErrorRule(), message=e.message, filename=task.get(FILENAME_KEY, "Unknown"), linenumber=task.get(LINE_NUMBER_KEY, 0), diff --git a/test/TestMatchError.py b/test/TestMatchError.py index f17d8656a7..ef61183319 100644 --- a/test/TestMatchError.py +++ b/test/TestMatchError.py @@ -76,9 +76,9 @@ def test_matcherror_invalid(): # filenames takes priority in sorting (MatchError("a", filename="b"), MatchError("a", filename="a")), # rule id 501 > rule id 101 - (MatchError(rule=BecomeUserWithoutBecomeRule), MatchError(rule=AlwaysRunRule)), + (MatchError(rule=BecomeUserWithoutBecomeRule()), MatchError(rule=AlwaysRunRule())), # rule id "200" > rule id 101 - (MatchError(rule=AnsibleLintRuleWithStringId), MatchError(rule=AlwaysRunRule)), + (MatchError(rule=AnsibleLintRuleWithStringId()), MatchError(rule=AlwaysRunRule())), # details are taken into account (MatchError("a", details="foo"), MatchError("a", details="bar")), ))