Failed Conditions
Pull Request — master (#2076)
by Abdeali
02:11
created

coalib/results/Result.py (61 issues)

1
import uuid
2
from os.path import relpath
3
4
from coalib.misc.Decorators import (
5
    enforce_signature, generate_ordering, generate_repr, get_public_members)
6
from coalib.results.RESULT_SEVERITY import RESULT_SEVERITY
7
from coalib.results.SourceRange import SourceRange
8
9
10
# Omit additional info, debug message and diffs for brevity
11
@generate_repr(("id", hex),
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable hex does not seem to be defined.
Loading history...
12
               "origin",
13
               "affected_code",
14
               ("severity", RESULT_SEVERITY.reverse.get),
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable RESULT_SEVERITY does not seem to be defined.
Loading history...
15
               "message")
16
@generate_ordering("affected_code",
17
                   "severity",
18
                   "origin",
19
                   "message",
20
                   "additional_info",
21
                   "debug_msg",
22
                   "diffs")
23
class Result:
24
    """
25
    A result is anything that has an origin and a message.
26
27
    Optionally it might affect a file.
28
    """
29
30
    @enforce_signature
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable enforce_signature does not seem to be defined.
Loading history...
31
    def __init__(self,
32
                 origin,
33
                 message: str,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable str does not seem to be defined.
Loading history...
34
                 affected_code: (tuple, list)=(),
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable list does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable tuple does not seem to be defined.
Loading history...
35
                 severity: int=RESULT_SEVERITY.NORMAL,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable RESULT_SEVERITY does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable int does not seem to be defined.
Loading history...
36
                 additional_info: str="",
37
                 debug_msg="",
38
                 diffs: (dict, None)=None):
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable dict does not seem to be defined.
Loading history...
39
        """
40
        :param origin:          Class name or class of the creator of this
41
                                object.
42
        :param message:         Message to show with this result.
43
        :param affected_code:   A tuple of SourceRange objects pointing to
44
                                related positions in the source code.
45
        :param severity:        Severity of this result.
46
        :param additional_info: A long description holding additional
47
                                information about the issue and/or how to fix
48
                                it. You can use this like a manual entry for a
49
                                category of issues.
50
        :param debug_msg:       A message which may help the user find out why
51
                                this result was yielded.
52
        :param diffs:           A dictionary with filenames as key and a
53
                                sequence of ``Diff`` objects associated with
54
                                them as values.
55
        """
56
        origin = origin or ""
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable origin does not seem to be defined.
Loading history...
57
        if not isinstance(origin, str):
58
            origin = origin.__class__.__name__
59
        if severity not in RESULT_SEVERITY.reverse:
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable severity does not seem to be defined.
Loading history...
60
            raise ValueError("severity is no valid RESULT_SEVERITY")
61
62
        self.origin = origin
63
        self.message = message
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable message does not seem to be defined.
Loading history...
64
        self.debug_msg = debug_msg
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable debug_msg does not seem to be defined.
Loading history...
65
        self.additional_info = additional_info
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable additional_info does not seem to be defined.
Loading history...
66
        # Sorting is important for tuple comparison
67
        self.affected_code = tuple(sorted(affected_code))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable affected_code does not seem to be defined.
Loading history...
68
        self.severity = severity
69
        self.diffs = diffs
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable diffs does not seem to be defined.
Loading history...
70
        self.id = uuid.uuid4().int
71
72
    @classmethod
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable classmethod does not seem to be defined.
Loading history...
73
    @enforce_signature
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable enforce_signature does not seem to be defined.
Loading history...
74
    def from_values(cls,
75
                    origin,
76
                    message: str,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable str does not seem to be defined.
Loading history...
77
                    file: str,
78
                    line: (int, None)=None,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable int does not seem to be defined.
Loading history...
79
                    column: (int, None)=None,
80
                    end_line: (int, None)=None,
81
                    end_column: (int, None)=None,
82
                    severity: int=RESULT_SEVERITY.NORMAL,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable RESULT_SEVERITY does not seem to be defined.
Loading history...
83
                    additional_info: str="",
84
                    debug_msg="",
85
                    diffs: (dict, None)=None):
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable dict does not seem to be defined.
Loading history...
86
        """
87
        Creates a result with only one SourceRange with the given start and end
88
        locations.
89
90
        :param origin:          Class name or class of the creator of this
91
                                object.
92
        :param message:         A message to explain the result.
93
        :param file:            The related file.
94
        :param line:            The first related line in the file.
95
                                (First line is 1)
96
        :param column:          The column indicating the first character.
97
                                (First character is 1)
98
        :param end_line:        The last related line in the file.
99
        :param end_column:      The column indicating the last character.
100
        :param severity:        A RESULT_SEVERITY object.
101
        :param debug_msg:       Another message for debugging purposes.
102
        :param additional_info: A long description holding additional
103
                                information about the issue and/or how to fix
104
                                it. You can use this like a manual entry for a
105
                                category of issues.
106
        :param diffs:           A dictionary with filenames as key and a
107
                                sequence of ``Diff`` objects associated with
108
                                them as values.
109
        """
110
        range = SourceRange.from_values(file,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable file does not seem to be defined.
Loading history...
111
                                        line,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable line does not seem to be defined.
Loading history...
112
                                        column,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable column does not seem to be defined.
Loading history...
113
                                        end_line,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable end_line does not seem to be defined.
Loading history...
114
                                        end_column)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable end_column does not seem to be defined.
Loading history...
115
116
        return cls(origin=origin,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable origin does not seem to be defined.
Loading history...
117
                   message=message,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable message does not seem to be defined.
Loading history...
118
                   affected_code=(range,),
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable range does not seem to be defined.
Loading history...
119
                   severity=severity,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable severity does not seem to be defined.
Loading history...
120
                   additional_info=additional_info,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable additional_info does not seem to be defined.
Loading history...
121
                   debug_msg=debug_msg,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable debug_msg does not seem to be defined.
Loading history...
122
                   diffs=diffs)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable diffs does not seem to be defined.
Loading history...
123
124
    def to_string_dict(self):
125
        """
126
        Makes a dictionary which has all keys and values as strings and
127
        contains all the data that the base Result has.
128
129
        FIXME: diffs are not serialized ATM.
130
        FIXME: Only the first SourceRange of affected_code is serialized. If
131
        there are more, this data is currently missing.
132
133
        :return: Dictionary with keys and values as string.
134
        """
135
        retval = {}
136
137
        members = ["id",
138
                   "additional_info",
139
                   "debug_msg",
140
                   "message",
141
                   "origin"]
142
143
        for member in members:
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable members does not seem to be defined.
Loading history...
144
            value = getattr(self, member)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable member does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable self does not seem to be defined.
Loading history...
145
            retval[member] = "" if value == None else str(value)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable value does not seem to be defined.
Loading history...
146
147
        retval["severity"] = str(RESULT_SEVERITY.reverse.get(
148
            self.severity, ""))
149
        if len(self.affected_code) > 0:
150
            retval["file"] = self.affected_code[0].file
151
            line = self.affected_code[0].start.line
152
            retval["line_nr"] = "" if line is None else str(line)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable line does not seem to be defined.
Loading history...
153
        else:
154
            retval["file"], retval["line_nr"] = "", ""
155
156
        return retval
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable retval does not seem to be defined.
Loading history...
157
158
    @enforce_signature
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable enforce_signature does not seem to be defined.
Loading history...
159
    def apply(self, file_dict: dict):
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable dict does not seem to be defined.
Loading history...
160
        """
161
        Applies all contained diffs to the given file_dict. This operation will
162
        be done in-place.
163
164
        :param file_dict: A dictionary containing all files with filename as
165
                          key and all lines a value. Will be modified.
166
        """
167
        for filename in self.diffs:
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable self does not seem to be defined.
Loading history...
168
            file_dict[filename] = self.diffs[filename].modified
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable filename does not seem to be defined.
Loading history...
169
170
    def __add__(self, other):
171
        """
172
        Joins those patches to one patch.
173
174
        :param other: The other patch.
175
        """
176
        assert isinstance(self.diffs, dict)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable dict does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable self does not seem to be defined.
Loading history...
177
        assert isinstance(other.diffs, dict)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable other does not seem to be defined.
Loading history...
178
179
        for filename in other.diffs:
180
            if filename in self.diffs:
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable filename does not seem to be defined.
Loading history...
181
                self.diffs[filename] += other.diffs[filename]
182
            else:
183
                self.diffs[filename] = other.diffs[filename]
184
185
        return self
186
187
    def overlaps(self, ranges):
188
        """
189
        Determines if the result overlaps with source ranges provided.
190
191
        :param ranges: A list SourceRange objects to check for overlap.
192
        :return:       True if the ranges overlap with the result.
193
        """
194
        if isinstance(ranges, SourceRange):
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable SourceRange does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable ranges does not seem to be defined.
Loading history...
195
            ranges = [ranges]
196
197
        for range in ranges:
198
            for self_range in self.affected_code:
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable self does not seem to be defined.
Loading history...
199
                if range.overlaps(self_range):
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable self_range does not seem to be defined.
Loading history...
200
                    return True
201
202
        return False
203
204
    def location_repr(self):
205
        """
206
        Retrieves a string, that briefly represents
207
        the affected code of the result.
208
209
        :return: A string containing all of the affected files
210
                 seperated by a comma.
211
        """
212
213
        if not self.affected_code:
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable self does not seem to be defined.
Loading history...
214
            return "the whole project"
215
216
        # Set important to exclude duplicate file names
217
        range_paths = set(sourcerange.file
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable sourcerange does not seem to be defined.
Loading history...
218
                          for sourcerange in self.affected_code)
219
220
        return ', '.join(repr(relpath(range_path))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable range_path does not seem to be defined.
Loading history...
221
                         for range_path in sorted(range_paths))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable range_paths does not seem to be defined.
Loading history...
222
223
    def __json__(self, use_relpath=False):
224
        _dict = get_public_members(self)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable self does not seem to be defined.
Loading history...
225
        if use_relpath and _dict['diffs']:
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable use_relpath does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable _dict does not seem to be defined.
Loading history...
226
            _dict['diffs'] = {relpath(file): diff
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable diff does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable file does not seem to be defined.
Loading history...
227
                              for file, diff in _dict['diffs'].items()}
228
        return _dict
229