1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
"""Exceptions and error representations."""
import functools
from ansiblelint.file_utils import normpath
@functools.total_ordering
class MatchError(ValueError):
"""Rule violation detected during linting.
It can be raised as Exception but also just added to the list of found
rules violations.
Note that line argument is not considered when building hash of an
instance.
"""
# IMPORTANT: any additional comparison protocol methods must return
# IMPORTANT: `NotImplemented` singleton to allow the check to use the
# IMPORTANT: other object's fallbacks.
# Ref: https://docs.python.org/3/reference/datamodel.html#object.__lt__
def __init__(
self,
message=None,
linenumber=0,
details: str = "",
filename=None,
rule=None) -> None:
"""Initialize a MatchError instance."""
super().__init__(message)
if not (message or rule):
raise TypeError(
f'{self.__class__.__name__}() missing a '
"required argument: one of 'message' or 'rule'",
)
self.message = message or getattr(rule, 'shortdesc', "")
self.linenumber = linenumber
self.details = details
self.filename = normpath(filename) if filename else None
self.rule = rule
self.ignored = False # If set it will be displayed but not counted as failure
def __repr__(self):
"""Return a MatchError instance representation."""
formatstr = u"[{0}] ({1}) matched {2}:{3} {4}"
# note that `rule.id` can be int, str or even missing, as users
# can defined their own custom rules.
_id = getattr(self.rule, "id", "000")
return formatstr.format(_id, self.message,
self.filename, self.linenumber, self.details)
@property
def _hash_key(self):
# line attr is knowingly excluded, as dict is not hashable
return (
self.filename,
self.linenumber,
str(getattr(self.rule, 'id', 0)),
self.message,
self.details,
)
def __lt__(self, other):
"""Return whether the current object is less than the other."""
if not isinstance(other, self.__class__):
return NotImplemented
return self._hash_key < other._hash_key
def __hash__(self):
"""Return a hash value of the MatchError instance."""
return hash(self._hash_key)
def __eq__(self, other):
"""Identify whether the other object represents the same rule match."""
if not isinstance(other, self.__class__):
return NotImplemented
return self.__hash__() == other.__hash__()
|