flake8-diff-only 0.1.3__tar.gz → 0.1.5__tar.gz
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.
- {flake8_diff_only-0.1.3 → flake8_diff_only-0.1.5}/PKG-INFO +1 -1
- flake8_diff_only-0.1.5/flake8_diff_only/__init__.py +1 -0
- flake8_diff_only-0.1.5/flake8_diff_only/checker.py +12 -0
- flake8_diff_only-0.1.5/flake8_diff_only/patch.py +22 -0
- flake8_diff_only-0.1.5/flake8_diff_only/types.py +1 -0
- flake8_diff_only-0.1.5/flake8_diff_only/utils.py +40 -0
- {flake8_diff_only-0.1.3 → flake8_diff_only-0.1.5}/pyproject.toml +76 -76
- flake8_diff_only-0.1.3/flake8_diff_only/__init__.py +0 -0
- flake8_diff_only-0.1.3/flake8_diff_only/checker.py +0 -99
- {flake8_diff_only-0.1.3 → flake8_diff_only-0.1.5}/LICENSE.md +0 -0
- {flake8_diff_only-0.1.3 → flake8_diff_only-0.1.5}/README.md +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
from flake8_diff_only import patch # noqa: F401
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import flake8.checker
|
2
|
+
|
3
|
+
from flake8_diff_only.utils import get_changed_lines
|
4
|
+
|
5
|
+
_original_run_checks = flake8.checker.FileChecker.run_checks
|
6
|
+
|
7
|
+
|
8
|
+
def _patched_run_checks(self) -> tuple[str, list, list] | None: # type: ignore
|
9
|
+
if not hasattr(self, "_changed_lines"):
|
10
|
+
self._changed_lines = get_changed_lines(self.filename)
|
11
|
+
|
12
|
+
results = _original_run_checks(self)
|
13
|
+
if results is None or not self._changed_lines:
|
14
|
+
return None
|
15
|
+
|
16
|
+
self.filename, self.results, self.statistics = results
|
17
|
+
self.results = list(filter(lambda r: r[1] in self._changed_lines, self.results))
|
18
|
+
|
19
|
+
return self.filename, self.results, self.statistics
|
20
|
+
|
21
|
+
|
22
|
+
flake8.checker.FileChecker.run_checks = _patched_run_checks
|
@@ -0,0 +1 @@
|
|
1
|
+
LineNumber = int
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import subprocess
|
2
|
+
|
3
|
+
from flake8_diff_only.types import LineNumber
|
4
|
+
|
5
|
+
|
6
|
+
def get_changed_lines(filename: str) -> set[LineNumber]:
|
7
|
+
"""
|
8
|
+
Получаем множество изменённых строк из git diff.
|
9
|
+
"""
|
10
|
+
changed_lines: set[LineNumber] = set()
|
11
|
+
|
12
|
+
diff_cmd = ["git", "diff", "--unified=0", "--no-color", "--cached", filename]
|
13
|
+
try:
|
14
|
+
output = subprocess.check_output(diff_cmd, stderr=subprocess.DEVNULL).decode()
|
15
|
+
except subprocess.CalledProcessError:
|
16
|
+
return changed_lines
|
17
|
+
|
18
|
+
for line in output.splitlines():
|
19
|
+
if line.startswith("@@"):
|
20
|
+
# Парсим хедер ханка: @@ -old,+new @@
|
21
|
+
try:
|
22
|
+
new_section = line.split(" ")[2]
|
23
|
+
start_line, length = _parse_diff_range(new_section)
|
24
|
+
lines = set(range(start_line, start_line + length))
|
25
|
+
changed_lines.update(lines)
|
26
|
+
except Exception:
|
27
|
+
continue
|
28
|
+
return changed_lines
|
29
|
+
|
30
|
+
|
31
|
+
def _parse_diff_range(range_str: str) -> tuple[LineNumber, int]:
|
32
|
+
"""
|
33
|
+
Парсит формат вроде '+12,3' или '+45' → (start_line, length)
|
34
|
+
"""
|
35
|
+
range_str = range_str.lstrip("+")
|
36
|
+
if "," in range_str:
|
37
|
+
start, length = map(int, range_str.split(","))
|
38
|
+
else:
|
39
|
+
start, length = int(range_str), 1
|
40
|
+
return start, length
|
@@ -1,76 +1,76 @@
|
|
1
|
-
[build-system]
|
2
|
-
build-backend = "poetry.core.masonry.api"
|
3
|
-
requires = [ "poetry-core>=2.0" ]
|
4
|
-
|
5
|
-
[project]
|
6
|
-
name = "flake8-diff-only"
|
7
|
-
version = "0.1.
|
8
|
-
description = "Flake8 plugin to show errors only on changed lines"
|
9
|
-
readme = "README.md"
|
10
|
-
|
11
|
-
license = {text = "MIT"}
|
12
|
-
|
13
|
-
requires-python = ">=3.9.0"
|
14
|
-
|
15
|
-
authors = [
|
16
|
-
{name = "Холоднов Эмиль",email = "emil.kholod@gmail.com"}
|
17
|
-
]
|
18
|
-
|
19
|
-
keywords = ["flake8", "plugin", "quotes", "code quality"]
|
20
|
-
classifiers = [
|
21
|
-
'Environment :: Console',
|
22
|
-
'Framework :: Flake8',
|
23
|
-
'Intended Audience :: Developers',
|
24
|
-
'Operating System :: OS Independent',
|
25
|
-
'License :: OSI Approved :: MIT License',
|
26
|
-
'Programming Language :: Python',
|
27
|
-
'Programming Language :: Python :: 3',
|
28
|
-
'Programming Language :: Python :: 3.8',
|
29
|
-
'Programming Language :: Python :: 3.9',
|
30
|
-
'Programming Language :: Python :: 3.10',
|
31
|
-
'Programming Language :: Python :: 3.11',
|
32
|
-
'Programming Language :: Python :: 3.12',
|
33
|
-
'Topic :: Software Development :: Libraries :: Python Modules',
|
34
|
-
'Topic :: Software Development :: Quality Assurance',
|
35
|
-
]
|
36
|
-
|
37
|
-
[project.urls]
|
38
|
-
Homepage = "https://github.com/emilkholod/flake8-diff-only"
|
39
|
-
Repository = "https://github.com/emilkholod/flake8-diff-only"
|
40
|
-
Issues = "https://github.com/emilkholod/flake8-diff-only/issues"
|
41
|
-
|
42
|
-
[project.entry-points."flake8.extension"]
|
43
|
-
FDO = "flake8_diff_only.checker:Flake8DiffOnlyChecker"
|
44
|
-
|
45
|
-
[tool.isort]
|
46
|
-
profile = "black"
|
47
|
-
filter_files = true
|
48
|
-
line_length = 88
|
49
|
-
src_paths = "flake8_diff_only"
|
50
|
-
|
51
|
-
[tool.flake8]
|
52
|
-
max-line-length = 88
|
53
|
-
extend-ignore = [
|
54
|
-
"DC100", "D100",
|
55
|
-
]
|
56
|
-
exclude = [
|
57
|
-
".git",
|
58
|
-
"__pycache__",
|
59
|
-
]
|
60
|
-
inline-quotes = '"'
|
61
|
-
|
62
|
-
[tool.mypy]
|
63
|
-
strict = true
|
64
|
-
|
65
|
-
[[tool.mypy.overrides]]
|
66
|
-
module = ["tests.*"]
|
67
|
-
|
68
|
-
disallow_untyped_defs = false
|
69
|
-
disallow_incomplete_defs = false
|
70
|
-
|
71
|
-
[tool.poetry.dependencies]
|
72
|
-
flake8 = ">=5.0.0,<7.3.0"
|
73
|
-
|
74
|
-
[tool.poetry.group.dev.dependencies]
|
75
|
-
pytest = "^8.3.5"
|
76
|
-
pytest-cov = "^6.1.1"
|
1
|
+
[build-system]
|
2
|
+
build-backend = "poetry.core.masonry.api"
|
3
|
+
requires = [ "poetry-core>=2.0" ]
|
4
|
+
|
5
|
+
[project]
|
6
|
+
name = "flake8-diff-only"
|
7
|
+
version = "0.1.5"
|
8
|
+
description = "Flake8 plugin to show errors only on changed lines"
|
9
|
+
readme = "README.md"
|
10
|
+
|
11
|
+
license = {text = "MIT"}
|
12
|
+
|
13
|
+
requires-python = ">=3.9.0"
|
14
|
+
|
15
|
+
authors = [
|
16
|
+
{name = "Холоднов Эмиль",email = "emil.kholod@gmail.com"}
|
17
|
+
]
|
18
|
+
|
19
|
+
keywords = ["flake8", "plugin", "quotes", "code quality"]
|
20
|
+
classifiers = [
|
21
|
+
'Environment :: Console',
|
22
|
+
'Framework :: Flake8',
|
23
|
+
'Intended Audience :: Developers',
|
24
|
+
'Operating System :: OS Independent',
|
25
|
+
'License :: OSI Approved :: MIT License',
|
26
|
+
'Programming Language :: Python',
|
27
|
+
'Programming Language :: Python :: 3',
|
28
|
+
'Programming Language :: Python :: 3.8',
|
29
|
+
'Programming Language :: Python :: 3.9',
|
30
|
+
'Programming Language :: Python :: 3.10',
|
31
|
+
'Programming Language :: Python :: 3.11',
|
32
|
+
'Programming Language :: Python :: 3.12',
|
33
|
+
'Topic :: Software Development :: Libraries :: Python Modules',
|
34
|
+
'Topic :: Software Development :: Quality Assurance',
|
35
|
+
]
|
36
|
+
|
37
|
+
[project.urls]
|
38
|
+
Homepage = "https://github.com/emilkholod/flake8-diff-only"
|
39
|
+
Repository = "https://github.com/emilkholod/flake8-diff-only"
|
40
|
+
Issues = "https://github.com/emilkholod/flake8-diff-only/issues"
|
41
|
+
|
42
|
+
[project.entry-points."flake8.extension"]
|
43
|
+
FDO = "flake8_diff_only.checker:Flake8DiffOnlyChecker"
|
44
|
+
|
45
|
+
[tool.isort]
|
46
|
+
profile = "black"
|
47
|
+
filter_files = true
|
48
|
+
line_length = 88
|
49
|
+
src_paths = "flake8_diff_only"
|
50
|
+
|
51
|
+
[tool.flake8]
|
52
|
+
max-line-length = 88
|
53
|
+
extend-ignore = [
|
54
|
+
"DC100", "D100",
|
55
|
+
]
|
56
|
+
exclude = [
|
57
|
+
".git",
|
58
|
+
"__pycache__",
|
59
|
+
]
|
60
|
+
inline-quotes = '"'
|
61
|
+
|
62
|
+
[tool.mypy]
|
63
|
+
strict = true
|
64
|
+
|
65
|
+
[[tool.mypy.overrides]]
|
66
|
+
module = ["tests.*"]
|
67
|
+
|
68
|
+
disallow_untyped_defs = false
|
69
|
+
disallow_incomplete_defs = false
|
70
|
+
|
71
|
+
[tool.poetry.dependencies]
|
72
|
+
flake8 = ">=5.0.0,<7.3.0"
|
73
|
+
|
74
|
+
[tool.poetry.group.dev.dependencies]
|
75
|
+
pytest = "^8.3.5"
|
76
|
+
pytest-cov = "^6.1.1"
|
File without changes
|
@@ -1,99 +0,0 @@
|
|
1
|
-
from __future__ import annotations
|
2
|
-
|
3
|
-
import ast
|
4
|
-
import subprocess
|
5
|
-
from typing import ClassVar
|
6
|
-
|
7
|
-
FilePath = str
|
8
|
-
LineNumber = int
|
9
|
-
|
10
|
-
|
11
|
-
class Flake8DiffOnlyChecker:
|
12
|
-
name = "flake8-diff-only"
|
13
|
-
version = "0.1.3"
|
14
|
-
|
15
|
-
_instance: ClassVar[Flake8DiffOnlyChecker | None] = None
|
16
|
-
_diff_lines: ClassVar[dict[FilePath, set[LineNumber]]]
|
17
|
-
|
18
|
-
def __new__( # type: ignore[no-untyped-def]
|
19
|
-
cls, *args, **kwargs
|
20
|
-
) -> Flake8DiffOnlyChecker:
|
21
|
-
if cls._instance is None:
|
22
|
-
cls._instance = super().__new__(cls)
|
23
|
-
cls._diff_lines = cls._load_git_diff()
|
24
|
-
return cls._instance
|
25
|
-
|
26
|
-
def __init__(self, tree: ast.AST, filename: str):
|
27
|
-
self.filename = filename
|
28
|
-
self.tree = tree
|
29
|
-
|
30
|
-
def run(self): # type: ignore[no-untyped-def]
|
31
|
-
# Если файл не изменён — пропускаем
|
32
|
-
if self.filename not in self._diff_lines:
|
33
|
-
return
|
34
|
-
|
35
|
-
# Получаем список изменённых строк
|
36
|
-
changed_lines = Flake8DiffOnlyChecker._diff_lines[self.filename]
|
37
|
-
|
38
|
-
# Получаем все ошибки от других плагинов
|
39
|
-
for lineno, col_offset, message, checker in self._original_errors():
|
40
|
-
if lineno in changed_lines:
|
41
|
-
yield lineno, col_offset, message, checker
|
42
|
-
|
43
|
-
def _original_errors(self) -> list: # type: ignore[type-arg]
|
44
|
-
"""
|
45
|
-
Заглушка: Этот метод не реализует собственную логику проверки.
|
46
|
-
Он нужен только как перехватчик для других плагинов.
|
47
|
-
Фактически, flake8 вызовет ВСЕ плагины, а наш просто отфильтрует их вывод.
|
48
|
-
Поэтому мы не генерируем ошибок тут.
|
49
|
-
"""
|
50
|
-
return []
|
51
|
-
|
52
|
-
@classmethod
|
53
|
-
def _load_git_diff(cls) -> dict[FilePath, set[LineNumber]]:
|
54
|
-
"""
|
55
|
-
Получаем список изменённых строк из git diff.
|
56
|
-
Возвращает словарь: { 'filename': set(linenos) }
|
57
|
-
"""
|
58
|
-
diff_cmd = ["git", "diff", "--unified=0", "--no-color", "--cached"]
|
59
|
-
try:
|
60
|
-
output = subprocess.check_output(
|
61
|
-
diff_cmd, stderr=subprocess.DEVNULL
|
62
|
-
).decode()
|
63
|
-
except subprocess.CalledProcessError:
|
64
|
-
return {}
|
65
|
-
|
66
|
-
result: dict[FilePath, set[LineNumber]] = {}
|
67
|
-
current_file: str | None = None
|
68
|
-
|
69
|
-
for line in output.splitlines():
|
70
|
-
if line.startswith("+++ b/"):
|
71
|
-
current_file = line[6:]
|
72
|
-
elif line.startswith("@@"):
|
73
|
-
# Парсим хедер ханка: @@ -old,+new @@
|
74
|
-
try:
|
75
|
-
new_section = line.split(" ")[2]
|
76
|
-
start_line, length = Flake8DiffOnlyChecker._parse_diff_range(
|
77
|
-
new_section
|
78
|
-
)
|
79
|
-
lines = set(range(start_line, start_line + length))
|
80
|
-
if current_file:
|
81
|
-
current_file_lines: set[LineNumber] = result.setdefault(
|
82
|
-
current_file, set()
|
83
|
-
)
|
84
|
-
current_file_lines.update(lines)
|
85
|
-
except Exception:
|
86
|
-
continue
|
87
|
-
return result
|
88
|
-
|
89
|
-
@staticmethod
|
90
|
-
def _parse_diff_range(range_str: str) -> tuple[LineNumber, int]:
|
91
|
-
"""
|
92
|
-
Парсит формат вроде '+12,3' или '+45' → (start_line, length)
|
93
|
-
"""
|
94
|
-
range_str = range_str.lstrip("+")
|
95
|
-
if "," in range_str:
|
96
|
-
start, length = map(int, range_str.split(","))
|
97
|
-
else:
|
98
|
-
start, length = int(range_str), 1
|
99
|
-
return start, length
|
File without changes
|
File without changes
|