prospector 1.14.0__py3-none-any.whl → 1.15.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- prospector/blender_combinations.yaml +989 -6
- prospector/postfilter.py +12 -2
- prospector/run.py +10 -3
- prospector/suppression.py +52 -16
- prospector/tools/base.py +10 -0
- prospector/tools/mypy/__init__.py +63 -14
- prospector/tools/pylint/__init__.py +8 -0
- prospector/tools/ruff/__init__.py +10 -1
- {prospector-1.14.0.dist-info → prospector-1.15.0.dist-info}/METADATA +1 -1
- {prospector-1.14.0.dist-info → prospector-1.15.0.dist-info}/RECORD +13 -13
- {prospector-1.14.0.dist-info → prospector-1.15.0.dist-info}/LICENSE +0 -0
- {prospector-1.14.0.dist-info → prospector-1.15.0.dist-info}/WHEEL +0 -0
- {prospector-1.14.0.dist-info → prospector-1.15.0.dist-info}/entry_points.txt +0 -0
prospector/postfilter.py
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
|
+
from typing import Optional
|
|
2
3
|
|
|
3
4
|
from prospector.message import Message
|
|
4
5
|
from prospector.suppression import get_suppressions
|
|
6
|
+
from prospector.tools.base import ToolBase
|
|
5
7
|
|
|
6
8
|
|
|
7
|
-
def filter_messages(
|
|
9
|
+
def filter_messages(
|
|
10
|
+
filepaths: list[Path],
|
|
11
|
+
messages: list[Message],
|
|
12
|
+
tools: Optional[dict[str, ToolBase]] = None,
|
|
13
|
+
blending: bool = False,
|
|
14
|
+
blend_combos: Optional[list[list[tuple[str, str]]]] = None,
|
|
15
|
+
) -> list[Message]:
|
|
8
16
|
"""
|
|
9
17
|
This method post-processes all messages output by all tools, in order to filter
|
|
10
18
|
out any based on the overall output.
|
|
@@ -23,7 +31,9 @@ def filter_messages(filepaths: list[Path], messages: list[Message]) -> list[Mess
|
|
|
23
31
|
This method uses the information about suppressed messages from pylint to
|
|
24
32
|
squash the unwanted redundant error from pyflakes and frosted.
|
|
25
33
|
"""
|
|
26
|
-
paths_to_ignore, lines_to_ignore, messages_to_ignore = get_suppressions(
|
|
34
|
+
paths_to_ignore, lines_to_ignore, messages_to_ignore = get_suppressions(
|
|
35
|
+
filepaths, messages, tools, blending, blend_combos
|
|
36
|
+
)
|
|
27
37
|
|
|
28
38
|
filtered = []
|
|
29
39
|
for message in messages:
|
prospector/run.py
CHANGED
|
@@ -16,6 +16,7 @@ from prospector.finder import FileFinder
|
|
|
16
16
|
from prospector.formatters import FORMATTERS, Formatter
|
|
17
17
|
from prospector.message import Location, Message
|
|
18
18
|
from prospector.tools import DEPRECATED_TOOL_NAMES
|
|
19
|
+
from prospector.tools.base import ToolBase
|
|
19
20
|
from prospector.tools.utils import CaptureOutput
|
|
20
21
|
|
|
21
22
|
|
|
@@ -25,7 +26,9 @@ class Prospector:
|
|
|
25
26
|
self.summary: Optional[dict[str, Any]] = None
|
|
26
27
|
self.messages = config.messages
|
|
27
28
|
|
|
28
|
-
def process_messages(
|
|
29
|
+
def process_messages(
|
|
30
|
+
self, found_files: FileFinder, messages: list[Message], tools: dict[str, tools.ToolBase]
|
|
31
|
+
) -> list[Message]:
|
|
29
32
|
if self.config.blending:
|
|
30
33
|
messages = blender.blend(messages)
|
|
31
34
|
|
|
@@ -37,7 +40,7 @@ class Prospector:
|
|
|
37
40
|
updated.append(msg)
|
|
38
41
|
messages = updated
|
|
39
42
|
|
|
40
|
-
return postfilter.filter_messages(found_files.python_modules, messages)
|
|
43
|
+
return postfilter.filter_messages(found_files.python_modules, messages, tools, self.config.blending)
|
|
41
44
|
|
|
42
45
|
def execute(self) -> None:
|
|
43
46
|
deprecated_names = self.config.replace_deprecated_tool_names()
|
|
@@ -70,6 +73,8 @@ class Prospector:
|
|
|
70
73
|
messages.append(message)
|
|
71
74
|
warnings.warn(msg, category=DeprecationWarning, stacklevel=0)
|
|
72
75
|
|
|
76
|
+
running_tools: dict[str, ToolBase] = {}
|
|
77
|
+
|
|
73
78
|
# Run the tools
|
|
74
79
|
for tool in self.config.get_tools(found_files):
|
|
75
80
|
for name, cls in tools.TOOLS.items():
|
|
@@ -79,6 +84,8 @@ class Prospector:
|
|
|
79
84
|
else:
|
|
80
85
|
toolname = "Unknown"
|
|
81
86
|
|
|
87
|
+
running_tools[toolname] = tool
|
|
88
|
+
|
|
82
89
|
try:
|
|
83
90
|
# Tools can output to stdout/stderr in unexpected places, for example,
|
|
84
91
|
# pydocstyle emits warnings about __all__ and as pyroma exec's the setup.py
|
|
@@ -116,7 +123,7 @@ class Prospector:
|
|
|
116
123
|
)
|
|
117
124
|
messages.append(message)
|
|
118
125
|
|
|
119
|
-
messages = self.process_messages(found_files, messages)
|
|
126
|
+
messages = self.process_messages(found_files, messages, running_tools)
|
|
120
127
|
|
|
121
128
|
summary["message_count"] = len(messages)
|
|
122
129
|
summary["completed"] = datetime.now()
|
prospector/suppression.py
CHANGED
|
@@ -27,12 +27,13 @@ from pathlib import Path
|
|
|
27
27
|
from typing import Optional
|
|
28
28
|
|
|
29
29
|
from prospector import encoding
|
|
30
|
+
from prospector.blender import BLEND_COMBOS
|
|
30
31
|
from prospector.exceptions import FatalProspectorException
|
|
31
32
|
from prospector.message import Message
|
|
33
|
+
from prospector.tools.base import PEP8_IGNORE_LINE_CODE, ToolBase
|
|
32
34
|
|
|
33
35
|
_FLAKE8_IGNORE_FILE = re.compile(r"flake8[:=]\s*noqa", re.IGNORECASE)
|
|
34
36
|
_PEP8_IGNORE_LINE = re.compile(r"#\s*noqa(\s*#.*)?$", re.IGNORECASE)
|
|
35
|
-
_PEP8_IGNORE_LINE_CODE = re.compile(r"#\s*noqa:([^#]*[^# ])(\s*#.*)?$", re.IGNORECASE)
|
|
36
37
|
_PYLINT_SUPPRESSED_MESSAGE = re.compile(r"^Suppressed \'([a-z0-9-]+)\' \(from line \d+\)$")
|
|
37
38
|
|
|
38
39
|
|
|
@@ -51,6 +52,17 @@ class Ignore:
|
|
|
51
52
|
def __str__(self) -> str:
|
|
52
53
|
return self.code if self.source is None else f"{self.source}.{self.code}"
|
|
53
54
|
|
|
55
|
+
def __repr__(self) -> str:
|
|
56
|
+
return f"<{type(self).__name__} {self}>"
|
|
57
|
+
|
|
58
|
+
def __eq__(self, value: object) -> bool:
|
|
59
|
+
if not isinstance(value, Ignore):
|
|
60
|
+
return False
|
|
61
|
+
return self.code == value.code and self.source == value.source
|
|
62
|
+
|
|
63
|
+
def __hash__(self) -> int:
|
|
64
|
+
return hash((self.source, self.code))
|
|
65
|
+
|
|
54
66
|
|
|
55
67
|
def get_noqa_suppressions(file_contents: list[str]) -> tuple[bool, set[int], dict[int, set[Ignore]]]:
|
|
56
68
|
"""
|
|
@@ -71,7 +83,7 @@ def get_noqa_suppressions(file_contents: list[str]) -> tuple[bool, set[int], dic
|
|
|
71
83
|
if _PEP8_IGNORE_LINE.search(line):
|
|
72
84
|
ignore_lines.add(line_number + 1)
|
|
73
85
|
else:
|
|
74
|
-
noqa_match =
|
|
86
|
+
noqa_match = PEP8_IGNORE_LINE_CODE.search(line)
|
|
75
87
|
if noqa_match:
|
|
76
88
|
prospector_ignore = noqa_match.group(1).strip().split(",")
|
|
77
89
|
prospector_ignore = [elem.strip() for elem in prospector_ignore]
|
|
@@ -81,15 +93,6 @@ def get_noqa_suppressions(file_contents: list[str]) -> tuple[bool, set[int], dic
|
|
|
81
93
|
return ignore_whole_file, ignore_lines, messages_to_ignore
|
|
82
94
|
|
|
83
95
|
|
|
84
|
-
_PYLINT_EQUIVALENTS = {
|
|
85
|
-
# TODO: blending has this info already?
|
|
86
|
-
"unused-import": (
|
|
87
|
-
("pyflakes", "FL0001"),
|
|
88
|
-
("frosted", "E101"),
|
|
89
|
-
)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
96
|
def _parse_pylint_informational(
|
|
94
97
|
messages: list[Message],
|
|
95
98
|
) -> tuple[set[Optional[Path]], dict[Optional[Path], dict[int, list[str]]]]:
|
|
@@ -113,17 +116,43 @@ def _parse_pylint_informational(
|
|
|
113
116
|
return ignore_files, ignore_messages
|
|
114
117
|
|
|
115
118
|
|
|
119
|
+
def _process_tool_ignores(
|
|
120
|
+
tools_ignore: dict[Path, dict[int, set[Ignore]]],
|
|
121
|
+
blend_combos_dict: dict[Ignore, set[Ignore]],
|
|
122
|
+
messages_to_ignore: dict[Optional[Path], dict[int, set[Ignore]]],
|
|
123
|
+
) -> None:
|
|
124
|
+
for path, lines_ignore in tools_ignore.items():
|
|
125
|
+
for line, ignores in lines_ignore.items():
|
|
126
|
+
for ignore in ignores:
|
|
127
|
+
if ignore in blend_combos_dict:
|
|
128
|
+
messages_to_ignore[path][line].update(blend_combos_dict[ignore])
|
|
129
|
+
|
|
130
|
+
|
|
116
131
|
def get_suppressions(
|
|
117
|
-
filepaths: list[Path],
|
|
132
|
+
filepaths: list[Path],
|
|
133
|
+
messages: list[Message],
|
|
134
|
+
tools: Optional[dict[str, ToolBase]] = None,
|
|
135
|
+
blending: bool = False,
|
|
136
|
+
blend_combos: Optional[list[list[tuple[str, str]]]] = None,
|
|
118
137
|
) -> tuple[set[Optional[Path]], dict[Path, set[int]], dict[Optional[Path], dict[int, set[Ignore]]]]:
|
|
119
138
|
"""
|
|
120
139
|
Given every message which was emitted by the tools, and the
|
|
121
140
|
list of files to inspect, create a list of files to ignore,
|
|
122
141
|
and a map of filepath -> line-number -> codes to ignore
|
|
123
142
|
"""
|
|
143
|
+
tools = tools or {}
|
|
144
|
+
blend_combos = blend_combos or BLEND_COMBOS
|
|
145
|
+
blend_combos_dict: dict[Ignore, set[Ignore]] = defaultdict(set)
|
|
146
|
+
if blending:
|
|
147
|
+
for combo in blend_combos:
|
|
148
|
+
ignore_combos = {Ignore(tool, code) for tool, code in combo}
|
|
149
|
+
for ignore in ignore_combos:
|
|
150
|
+
blend_combos_dict[ignore] |= ignore_combos
|
|
151
|
+
|
|
124
152
|
paths_to_ignore: set[Optional[Path]] = set()
|
|
125
153
|
lines_to_ignore: dict[Path, set[int]] = defaultdict(set)
|
|
126
154
|
messages_to_ignore: dict[Optional[Path], dict[int, set[Ignore]]] = defaultdict(lambda: defaultdict(set))
|
|
155
|
+
tools_ignore: dict[Path, dict[int, set[Ignore]]] = defaultdict(lambda: defaultdict(set))
|
|
127
156
|
|
|
128
157
|
# First deal with 'noqa' style messages
|
|
129
158
|
for filepath in filepaths:
|
|
@@ -141,6 +170,17 @@ def get_suppressions(
|
|
|
141
170
|
for line, codes_ignore in file_messages_to_ignore.items():
|
|
142
171
|
messages_to_ignore[filepath][line] |= codes_ignore
|
|
143
172
|
|
|
173
|
+
if blending:
|
|
174
|
+
for line_number, line_content in enumerate(file_contents):
|
|
175
|
+
for tool_name, tool in tools.items():
|
|
176
|
+
tool_ignores = tool.get_ignored_codes(line_content)
|
|
177
|
+
for tool_ignore in tool_ignores:
|
|
178
|
+
tools_ignore[filepath][line_number + 1].add(Ignore(tool_name, tool_ignore))
|
|
179
|
+
|
|
180
|
+
# Ignore the blending messages
|
|
181
|
+
if blending:
|
|
182
|
+
_process_tool_ignores(tools_ignore, blend_combos_dict, messages_to_ignore)
|
|
183
|
+
|
|
144
184
|
# Now figure out which messages were suppressed by pylint
|
|
145
185
|
pylint_ignore_files, pylint_ignore_messages = _parse_pylint_informational(messages)
|
|
146
186
|
paths_to_ignore |= pylint_ignore_files
|
|
@@ -149,9 +189,5 @@ def get_suppressions(
|
|
|
149
189
|
for code in codes:
|
|
150
190
|
ignore = Ignore("pylint", code)
|
|
151
191
|
messages_to_ignore[pylint_filepath][line_number].add(ignore)
|
|
152
|
-
if code in _PYLINT_EQUIVALENTS:
|
|
153
|
-
for ignore_source, ignore_code in _PYLINT_EQUIVALENTS[code]:
|
|
154
|
-
ignore = Ignore(ignore_source, ignore_code)
|
|
155
|
-
messages_to_ignore[pylint_filepath][line_number].add(ignore)
|
|
156
192
|
|
|
157
193
|
return paths_to_ignore, lines_to_ignore, messages_to_ignore
|
prospector/tools/base.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import re
|
|
1
2
|
from abc import ABC, abstractmethod
|
|
2
3
|
from collections.abc import Iterable
|
|
3
4
|
from pathlib import Path
|
|
@@ -9,6 +10,8 @@ from prospector.message import Message
|
|
|
9
10
|
if TYPE_CHECKING:
|
|
10
11
|
from prospector.config import ProspectorConfig
|
|
11
12
|
|
|
13
|
+
PEP8_IGNORE_LINE_CODE = re.compile(r"#\s*noqa:([^#]*[^# ])(\s*#.*)?$", re.IGNORECASE)
|
|
14
|
+
|
|
12
15
|
|
|
13
16
|
class ToolBase(ABC):
|
|
14
17
|
@abstractmethod
|
|
@@ -40,3 +43,10 @@ class ToolBase(ABC):
|
|
|
40
43
|
standard prospector Message and Location objects.
|
|
41
44
|
"""
|
|
42
45
|
raise NotImplementedError
|
|
46
|
+
|
|
47
|
+
def get_ignored_codes(self, line: str) -> list[str]:
|
|
48
|
+
"""
|
|
49
|
+
Return a list of error codes that the tool will ignore from a line of code.
|
|
50
|
+
"""
|
|
51
|
+
del line # unused
|
|
52
|
+
return []
|
|
@@ -1,19 +1,31 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import re
|
|
1
3
|
from multiprocessing import Process, Queue
|
|
2
|
-
from typing import
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
from typing import (
|
|
5
|
+
TYPE_CHECKING,
|
|
6
|
+
Any,
|
|
7
|
+
Callable,
|
|
8
|
+
Optional,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
import mypy.api
|
|
12
|
+
import mypy.build
|
|
13
|
+
import mypy.errors
|
|
14
|
+
import mypy.fscache
|
|
15
|
+
import mypy.main
|
|
5
16
|
|
|
6
17
|
from prospector.finder import FileFinder
|
|
7
18
|
from prospector.message import Location, Message
|
|
8
19
|
from prospector.tools import ToolBase
|
|
9
|
-
|
|
10
|
-
__all__ = ("MypyTool",)
|
|
11
|
-
|
|
12
20
|
from prospector.tools.exceptions import BadToolConfig
|
|
13
21
|
|
|
14
22
|
if TYPE_CHECKING:
|
|
15
23
|
from prospector.config import ProspectorConfig
|
|
16
24
|
|
|
25
|
+
_IGNORE_RE = re.compile(r"#\s*type:\s*ignore\[([^#]*[^# ])\](\s*#.*)?$", re.IGNORECASE)
|
|
26
|
+
|
|
27
|
+
__all__ = ("MypyTool",)
|
|
28
|
+
|
|
17
29
|
|
|
18
30
|
def format_message(message: str) -> Message:
|
|
19
31
|
character: Optional[int]
|
|
@@ -58,9 +70,10 @@ def _run_in_subprocess(
|
|
|
58
70
|
class MypyTool(ToolBase):
|
|
59
71
|
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
60
72
|
super().__init__(*args, **kwargs)
|
|
61
|
-
self.checker = api
|
|
73
|
+
self.checker = mypy.api
|
|
62
74
|
self.options = ["--show-column-numbers", "--no-error-summary"]
|
|
63
75
|
self.use_dmypy = False
|
|
76
|
+
self.fscache = mypy.fscache.FileSystemCache()
|
|
64
77
|
|
|
65
78
|
def configure(self, prospector_config: "ProspectorConfig", _: Any) -> None:
|
|
66
79
|
options = prospector_config.tool_options("mypy")
|
|
@@ -90,18 +103,54 @@ class MypyTool(ToolBase):
|
|
|
90
103
|
raise BadToolConfig("mypy", f"The option {name} has an unsupported value type: {type(value)}")
|
|
91
104
|
|
|
92
105
|
def run(self, found_files: FileFinder) -> list[Message]:
|
|
93
|
-
|
|
94
|
-
|
|
106
|
+
args = [str(path) for path in found_files.python_modules]
|
|
107
|
+
args.extend(self.options)
|
|
95
108
|
if self.use_dmypy:
|
|
96
109
|
# Due to dmypy messing with stdout/stderr we call it in a separate
|
|
97
110
|
# process
|
|
98
111
|
q: Queue[str] = Queue(1)
|
|
99
|
-
p = Process(target=_run_in_subprocess, args=(q, self.checker.run_dmypy, ["run", "--"] +
|
|
112
|
+
p = Process(target=_run_in_subprocess, args=(q, self.checker.run_dmypy, ["run", "--"] + args))
|
|
100
113
|
p.start()
|
|
101
114
|
result = q.get()
|
|
102
115
|
p.join()
|
|
103
|
-
else:
|
|
104
|
-
result = self.checker.run(paths)
|
|
105
|
-
report, _ = result[0], result[1:] # noqa
|
|
106
116
|
|
|
107
|
-
|
|
117
|
+
report, _ = result[0], result[1:] # noqa
|
|
118
|
+
return [format_message(message) for message in report.splitlines()]
|
|
119
|
+
else:
|
|
120
|
+
return self._run_std(args)
|
|
121
|
+
|
|
122
|
+
def _run_std(self, args: list[str]) -> list[Message]:
|
|
123
|
+
sources, options = mypy.main.process_options(args, fscache=self.fscache)
|
|
124
|
+
options.output = "json"
|
|
125
|
+
res = mypy.build.build(sources, options, fscache=self.fscache)
|
|
126
|
+
|
|
127
|
+
messages = []
|
|
128
|
+
for mypy_json in res.errors:
|
|
129
|
+
mypy_message = json.loads(mypy_json)
|
|
130
|
+
message = f"{mypy_message['message']}."
|
|
131
|
+
if mypy_message.get("hint", ""):
|
|
132
|
+
message = f"{message}, Hint: {mypy_message['hint']}."
|
|
133
|
+
code = mypy_message["code"]
|
|
134
|
+
messages.append(
|
|
135
|
+
Message(
|
|
136
|
+
"mypy",
|
|
137
|
+
code=code,
|
|
138
|
+
location=Location(
|
|
139
|
+
path=mypy_message["file"],
|
|
140
|
+
module=None,
|
|
141
|
+
function=None,
|
|
142
|
+
line=mypy_message["line"],
|
|
143
|
+
character=mypy_message["column"],
|
|
144
|
+
),
|
|
145
|
+
message=message,
|
|
146
|
+
doc_url=f"{mypy.errors.BASE_RTD_URL}-{code}",
|
|
147
|
+
)
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
return messages
|
|
151
|
+
|
|
152
|
+
def get_ignored_codes(self, line: str) -> list[str]:
|
|
153
|
+
match = _IGNORE_RE.search(line)
|
|
154
|
+
if match:
|
|
155
|
+
return [e.strip() for e in match.group(1).split(",")]
|
|
156
|
+
return []
|
|
@@ -21,6 +21,8 @@ if TYPE_CHECKING:
|
|
|
21
21
|
|
|
22
22
|
_UNUSED_WILDCARD_IMPORT_RE = re.compile(r"^Unused import(\(s\))? (.*) from wildcard import")
|
|
23
23
|
|
|
24
|
+
_IGNORE_RE = re.compile(r"#\s*pylint:\s*disable=([^#]*[^#\s])(\s*#.*)?$", re.IGNORECASE)
|
|
25
|
+
|
|
24
26
|
|
|
25
27
|
def _is_in_dir(subpath: Path, path: Path) -> bool:
|
|
26
28
|
return subpath.parent == path
|
|
@@ -266,3 +268,9 @@ class PylintTool(ToolBase):
|
|
|
266
268
|
|
|
267
269
|
messages = self._collector.get_messages()
|
|
268
270
|
return self.combine(messages)
|
|
271
|
+
|
|
272
|
+
def get_ignored_codes(self, line: str) -> list[str]:
|
|
273
|
+
match = _IGNORE_RE.search(line)
|
|
274
|
+
if match:
|
|
275
|
+
return [e.strip() for e in match.group(1).split(",")]
|
|
276
|
+
return []
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import subprocess # nosec
|
|
3
|
+
from pathlib import Path
|
|
3
4
|
from typing import TYPE_CHECKING, Any
|
|
4
5
|
|
|
5
6
|
from ruff.__main__ import find_ruff_bin
|
|
6
7
|
|
|
7
8
|
from prospector.finder import FileFinder
|
|
8
9
|
from prospector.message import Location, Message
|
|
9
|
-
from prospector.tools.base import ToolBase
|
|
10
|
+
from prospector.tools.base import PEP8_IGNORE_LINE_CODE, ToolBase
|
|
10
11
|
|
|
11
12
|
if TYPE_CHECKING:
|
|
12
13
|
from prospector.config import ProspectorConfig
|
|
@@ -65,6 +66,8 @@ class RuffTool(ToolBase):
|
|
|
65
66
|
if sub_message:
|
|
66
67
|
message_str += f" [{', '.join(f'{k}: {v}' for k, v in sub_message.items())}]"
|
|
67
68
|
|
|
69
|
+
if message.get("filename") is None or found_files.is_excluded(Path(message.get("filename"))):
|
|
70
|
+
continue
|
|
68
71
|
messages.append(
|
|
69
72
|
Message(
|
|
70
73
|
"ruff",
|
|
@@ -84,3 +87,9 @@ class RuffTool(ToolBase):
|
|
|
84
87
|
)
|
|
85
88
|
)
|
|
86
89
|
return messages
|
|
90
|
+
|
|
91
|
+
def get_ignored_codes(self, line: str) -> list[str]:
|
|
92
|
+
match = PEP8_IGNORE_LINE_CODE.search(line)
|
|
93
|
+
if match:
|
|
94
|
+
return [e.strip() for e in match.group(1).split(",")]
|
|
95
|
+
return []
|
|
@@ -2,7 +2,7 @@ prospector/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
2
2
|
prospector/__main__.py,sha256=-gdHYZxwq_P8er7HuZEBImY0pwaFq8uIa78dQdJsTTQ,71
|
|
3
3
|
prospector/autodetect.py,sha256=Ok8S6jpDiGyhQlnRCMWpsLpSAIXWxA-NQphQuPaOm6o,3112
|
|
4
4
|
prospector/blender.py,sha256=ldQSkfoEKv6pd72B9YCYdapeGUzgfhGzieAu7To3l6Y,4926
|
|
5
|
-
prospector/blender_combinations.yaml,sha256=
|
|
5
|
+
prospector/blender_combinations.yaml,sha256=hQMYpwKHjP-DI9yjnNWcXOyWcDEf8U-I2Bg5-78BFV8,30816
|
|
6
6
|
prospector/compat.py,sha256=p_2BOebzUcKbUAd7mW8rn6tIc10R96gJuZS71QI0XY4,360
|
|
7
7
|
prospector/config/__init__.py,sha256=4nYshBncKUvZrwNKmp2bQ2mQ8uRS7GU20xPbiC-nJ9g,14793
|
|
8
8
|
prospector/config/configuration.py,sha256=sNYR5Jc3P7tfIDXQoDMrOX4i2Yde0o9bc21ZXZNn6rw,14046
|
|
@@ -24,7 +24,7 @@ prospector/formatters/xunit.py,sha256=e5ObAWSLm-ekvWs8xsi-OaIL2yoYedlxuJdUhLZ8gk
|
|
|
24
24
|
prospector/formatters/yaml.py,sha256=0RAL5BaaL9A0DfWZ-bdpK1mwgr8zJ_ULVwlnSXVPlDU,684
|
|
25
25
|
prospector/message.py,sha256=HKXdO8bOezRKSnTtjqu0k04Cb7JgL0oPUWakuSBE9s4,3710
|
|
26
26
|
prospector/pathutils.py,sha256=CyZIj4WXGill8OfnqRvcVqZYX0lzL3QcIxpkxCz-dkE,1219
|
|
27
|
-
prospector/postfilter.py,sha256=
|
|
27
|
+
prospector/postfilter.py,sha256=BpmR1g1ZlgQB92_Uk6hRyYoIBUcivvcU8RGLUHXDdcU,2695
|
|
28
28
|
prospector/profiles/__init__.py,sha256=q9zPLVEwo7qoouYFrmENsmByFrKKkr27Dd_Wo9btTJI,683
|
|
29
29
|
prospector/profiles/exceptions.py,sha256=MDky4KXVwfOlW1yCbyp8Y07D8Kfz76jL3z-8T3WQIFI,1062
|
|
30
30
|
prospector/profiles/profile.py,sha256=U8vDdyfka0_Ht9cYT2i_c-xbMcktSpS1h53cU7tGerk,17828
|
|
@@ -44,29 +44,29 @@ prospector/profiles/profiles/strictness_none.yaml,sha256=_Yf-eEl4cVXw6ePqx3V4mvG
|
|
|
44
44
|
prospector/profiles/profiles/strictness_veryhigh.yaml,sha256=whQFEUtkySSEIriEwYOjSr-0SxICOWalNA9Y7FmXopQ,628
|
|
45
45
|
prospector/profiles/profiles/strictness_verylow.yaml,sha256=YxZowcBtA3tAaHJGz2htTdAJ-AXmlHB-o4zEYKPRfJg,833
|
|
46
46
|
prospector/profiles/profiles/test_warnings.yaml,sha256=arUcV9MnqiZJEHURH9bVRSYDhYUegNc-ltFYe_yQW44,23
|
|
47
|
-
prospector/run.py,sha256=
|
|
48
|
-
prospector/suppression.py,sha256=
|
|
47
|
+
prospector/run.py,sha256=Sjh28jI-Bergzr3rxZp7QzRHP9Ue0SPdfcB0TEkMSDQ,8631
|
|
48
|
+
prospector/suppression.py,sha256=qT3TIe8a87mnXPOcRr6m58UodUREExBZxttTlWFTJbY,7654
|
|
49
49
|
prospector/tools/__init__.py,sha256=9tDmxL_kn5jmAACeSi1jtSvT-9tI468Ccn1Up2wUFi0,2956
|
|
50
50
|
prospector/tools/bandit/__init__.py,sha256=iU39U28_YP5QUm8sgU21Ps96czIIl6tSV7qtCxbFvms,3035
|
|
51
|
-
prospector/tools/base.py,sha256=
|
|
51
|
+
prospector/tools/base.py,sha256=xL_uUbhZUyPrDU-2ntgmzhs-DW1e5sfDKb_OA7VtxKQ,2146
|
|
52
52
|
prospector/tools/dodgy/__init__.py,sha256=howLCjFEheW_6ZoyQ15gLbiNNNUr0Pm2qNpLg3kleFY,1648
|
|
53
53
|
prospector/tools/exceptions.py,sha256=Q-u4n6YzZuoMu17XkeKac1o1gBY36JK4MnvWaYrVYL0,170
|
|
54
54
|
prospector/tools/mccabe/__init__.py,sha256=80-aYPqKCREeBqxiIUgsDvxc_GqYxHb5R0JduKHPRaE,3277
|
|
55
|
-
prospector/tools/mypy/__init__.py,sha256=
|
|
55
|
+
prospector/tools/mypy/__init__.py,sha256=G39v_IlcWkG7hm0R4qTwAoU2K-sWyqXHc-kgaawdqys,5092
|
|
56
56
|
prospector/tools/profile_validator/__init__.py,sha256=bAkVG-fKtm3WaEv-We36wqzvtqWv4s06Z7YnRVG7UQ4,8326
|
|
57
57
|
prospector/tools/pycodestyle/__init__.py,sha256=uMpUxqsPsryEsfyfGxpLzwoWUjIvfxIQke4Xvkfbi9A,5970
|
|
58
58
|
prospector/tools/pydocstyle/__init__.py,sha256=WB-AT-c1FeUUUWATUzJbBLeREtu-lxT03bChh4nablo,2776
|
|
59
59
|
prospector/tools/pyflakes/__init__.py,sha256=53NQFODU416KO991NxW14gChjagbSAhhfErx1ll7VUQ,5631
|
|
60
|
-
prospector/tools/pylint/__init__.py,sha256=
|
|
60
|
+
prospector/tools/pylint/__init__.py,sha256=Nixin4odPsTj7q1C2Tud2mU5An1lCc7aKQdGAQLyf8g,11398
|
|
61
61
|
prospector/tools/pylint/collector.py,sha256=7FHgO6OOLGD15_U4DERiXyEbSFnMjGUBeCwdmUlhO8I,1559
|
|
62
62
|
prospector/tools/pylint/linter.py,sha256=YQ9SOna4WjbbauqSgUio6Ss8zN08PCr3aKdK9rMi7Ag,2143
|
|
63
63
|
prospector/tools/pyright/__init__.py,sha256=USqauZofh-8ZSKGwXRXoaM2ItzfSFo2nGwPtLGEWICU,3346
|
|
64
64
|
prospector/tools/pyroma/__init__.py,sha256=GPQRJZfbs_SI0RBTyySz-4SIuM__YoLfXAm7uYVXAS8,3151
|
|
65
|
-
prospector/tools/ruff/__init__.py,sha256=
|
|
65
|
+
prospector/tools/ruff/__init__.py,sha256=r55pEbmjLFWmY1jiQ7aZ2OYBxkEAH5An3-CpL04rdc0,3915
|
|
66
66
|
prospector/tools/utils.py,sha256=cRCogsMCH0lPBhdujPsIY0ovNAL6TAxBMohZRES02-4,1770
|
|
67
67
|
prospector/tools/vulture/__init__.py,sha256=eaTh4X5onNlBMuz1x0rmcRn7x5XDVDgqftjIEd47eWI,3583
|
|
68
|
-
prospector-1.
|
|
69
|
-
prospector-1.
|
|
70
|
-
prospector-1.
|
|
71
|
-
prospector-1.
|
|
72
|
-
prospector-1.
|
|
68
|
+
prospector-1.15.0.dist-info/entry_points.txt,sha256=SxvCGt8MJTEZefHAvwnUc6jDetgCaaYY1Zpifuk8tqU,50
|
|
69
|
+
prospector-1.15.0.dist-info/LICENSE,sha256=WoTRadDy8VbcIKoVzl5Q1QipuD_cexAf3ul4MaVLttc,18044
|
|
70
|
+
prospector-1.15.0.dist-info/WHEEL,sha256=gSF7fibx4crkLz_A-IKR6kcuq0jJ64KNCkG8_bcaEao,88
|
|
71
|
+
prospector-1.15.0.dist-info/METADATA,sha256=hZAMrN74gIl-pGLRyaL7aItQmpqkM8e9aa5P1GMZKaY,9962
|
|
72
|
+
prospector-1.15.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|