python-code-quality 0.1.13__py3-none-any.whl → 0.1.14__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.
- py_cq/__init__.py +0 -4
- py_cq/cli.py +8 -1
- py_cq/config/config.yaml +12 -6
- py_cq/execution_engine.py +18 -6
- py_cq/localtypes.py +1 -0
- py_cq/parsers/__init__.py +1 -0
- py_cq/parsers/interrogateparser.py +4 -4
- py_cq/tool_registry.py +1 -0
- {python_code_quality-0.1.13.dist-info → python_code_quality-0.1.14.dist-info}/METADATA +40 -46
- {python_code_quality-0.1.13.dist-info → python_code_quality-0.1.14.dist-info}/RECORD +12 -12
- {python_code_quality-0.1.13.dist-info → python_code_quality-0.1.14.dist-info}/WHEEL +0 -0
- {python_code_quality-0.1.13.dist-info → python_code_quality-0.1.14.dist-info}/entry_points.txt +0 -0
py_cq/__init__.py
CHANGED
|
@@ -4,7 +4,3 @@ The module defines a single function, `hello`, which returns the string
|
|
|
4
4
|
`'Hello from py_cq!'`. It can serve as a minimal example, placeholder, or
|
|
5
5
|
testing stub in larger applications."""
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
def hello() -> str:
|
|
9
|
-
"""Returns the greeting string `'Hello from py_cq!'`."""
|
|
10
|
-
return "Hello from py_cq!"
|
py_cq/cli.py
CHANGED
|
@@ -84,6 +84,7 @@ def _apply_user_config(base: dict[str, ToolConfig], user_cfg: dict) -> dict[str,
|
|
|
84
84
|
run_in_target_env=tool_data.get("run_in_target_env", False),
|
|
85
85
|
extra_deps=tool_data.get("extra_deps", []),
|
|
86
86
|
parser_config=tool_data.get("parser_config", {}),
|
|
87
|
+
exclude_format=tool_data.get("exclude_format", ""),
|
|
87
88
|
)
|
|
88
89
|
except KeyError as e:
|
|
89
90
|
raise typer.BadParameter(f"[tool.cq.tools.{tool_id}] missing required field {e}")
|
|
@@ -131,6 +132,9 @@ def check(
|
|
|
131
132
|
skip: str | None = typer.Option(
|
|
132
133
|
None, "--skip", help="Comma-separated tool IDs to skip (e.g. bandit,vulture)"
|
|
133
134
|
),
|
|
135
|
+
exclude: str | None = typer.Option(
|
|
136
|
+
None, "--exclude", help="Comma-separated paths to exclude (e.g. demo,docs)"
|
|
137
|
+
),
|
|
134
138
|
):
|
|
135
139
|
"""Feed the results from 11+ code quality tools to an LLM. Try: cq check . -o llm""" # --help
|
|
136
140
|
path_obj = Path(path)
|
|
@@ -165,9 +169,12 @@ def check(
|
|
|
165
169
|
if skip:
|
|
166
170
|
drop = set(skip.split(","))
|
|
167
171
|
effective_registry = {k: v for k, v in effective_registry.items() if k not in drop}
|
|
172
|
+
config_excludes: list[str] = user_cfg.get("exclude", [])
|
|
173
|
+
cli_excludes: list[str] = [e.strip() for e in exclude.split(",")] if exclude else []
|
|
174
|
+
excludes = list(dict.fromkeys(config_excludes + cli_excludes))
|
|
168
175
|
if clear_cache:
|
|
169
176
|
tool_cache.clear()
|
|
170
|
-
tool_results = run_tools(effective_registry.values(), path, workers, early_exit=(output == OutputMode.LLM))
|
|
177
|
+
tool_results = run_tools(effective_registry.values(), path, workers, early_exit=(output == OutputMode.LLM), excludes=excludes)
|
|
171
178
|
# for tr in tool_results:
|
|
172
179
|
# log.debug(json.dumps(tr.to_dict(), indent=2))
|
|
173
180
|
combined_metrics = aggregate_metrics(path=path, metrics=tool_results)
|
py_cq/config/config.yaml
CHANGED
|
@@ -8,14 +8,16 @@ python:
|
|
|
8
8
|
error_threshold: 0.9999
|
|
9
9
|
|
|
10
10
|
ruff:
|
|
11
|
-
command: "{python} -m ruff check --output-format concise --no-cache \"{context_path}\""
|
|
11
|
+
command: "{python} -m ruff check --output-format concise --no-cache \"{context_path}\"{exclude}"
|
|
12
|
+
exclude_format: " --exclude {path}"
|
|
12
13
|
parser: "RuffParser"
|
|
13
14
|
order: 2
|
|
14
15
|
warning_threshold: 0.9999
|
|
15
16
|
error_threshold: 0.9
|
|
16
17
|
|
|
17
18
|
ty:
|
|
18
|
-
command: "{python} -m ty check --output-format concise --color never \"{context_path}\""
|
|
19
|
+
command: "{python} -m ty check --output-format concise --color never \"{context_path}\"{exclude}"
|
|
20
|
+
exclude_format: " --exclude {path}"
|
|
19
21
|
parser: "TyParser"
|
|
20
22
|
order: 3
|
|
21
23
|
warning_threshold: 0.9999
|
|
@@ -25,14 +27,16 @@ python:
|
|
|
25
27
|
- ty
|
|
26
28
|
|
|
27
29
|
bandit:
|
|
28
|
-
command: "{python} -m bandit -r \"{context_path}\" -f json -q -s B101 --severity-level medium --exclude \"{input_path_posix}/.venv,{input_path_posix}/tests\""
|
|
30
|
+
command: "{python} -m bandit -r \"{context_path}\" -f json -q -s B101 --severity-level medium --exclude \"{input_path_posix}/.venv,{input_path_posix}/tests{exclude}\""
|
|
31
|
+
exclude_format: ",{input_path_posix}/{path}"
|
|
29
32
|
parser: "BanditParser"
|
|
30
33
|
order: 4
|
|
31
34
|
warning_threshold: 0.9999
|
|
32
35
|
error_threshold: 0.8
|
|
33
36
|
|
|
34
37
|
pytest:
|
|
35
|
-
command: "{python} -m pytest -v \"{context_path}\""
|
|
38
|
+
command: "{python} -m pytest -v \"{context_path}\"{exclude}"
|
|
39
|
+
exclude_format: " --ignore {path}"
|
|
36
40
|
parser: "PytestParser"
|
|
37
41
|
order: 5
|
|
38
42
|
warning_threshold: 1.0
|
|
@@ -74,14 +78,16 @@ python:
|
|
|
74
78
|
error_threshold: 0.3
|
|
75
79
|
|
|
76
80
|
vulture:
|
|
77
|
-
command: "{python} -m vulture \"{context_path}\" --min-confidence 80 --exclude .venv,dist,.*_cache,docs,.git"
|
|
81
|
+
command: "{python} -m vulture \"{context_path}\" --min-confidence 80 --exclude .venv,dist,.*_cache,docs,.git{exclude}"
|
|
82
|
+
exclude_format: ",{path}"
|
|
78
83
|
parser: "VultureParser"
|
|
79
84
|
order: 10
|
|
80
85
|
warning_threshold: 0.9999
|
|
81
86
|
error_threshold: 0.8
|
|
82
87
|
|
|
83
88
|
interrogate:
|
|
84
|
-
command: "{python} -m interrogate \"{context_path}\" -v --fail-under 0"
|
|
89
|
+
command: "{python} -m interrogate \"{context_path}\" -e tests{exclude} -v --fail-under 0"
|
|
90
|
+
exclude_format: " -e {path}"
|
|
85
91
|
parser: "InterrogateParser"
|
|
86
92
|
order: 11
|
|
87
93
|
warning_threshold: 0.8
|
py_cq/execution_engine.py
CHANGED
|
@@ -53,7 +53,17 @@ def _dep_in_venv(dep: str, project_root: Path) -> bool:
|
|
|
53
53
|
return False
|
|
54
54
|
|
|
55
55
|
|
|
56
|
-
def
|
|
56
|
+
def _build_exclude_str(exclude_format: str, excludes: list[str], **extra_vars: str) -> str:
|
|
57
|
+
if not exclude_format or not excludes:
|
|
58
|
+
return ""
|
|
59
|
+
parts = []
|
|
60
|
+
for exc in excludes:
|
|
61
|
+
abs_posix_path = Path(exc).resolve().as_posix()
|
|
62
|
+
parts.append(exclude_format.format(path=exc, abs_posix_path=abs_posix_path, **extra_vars))
|
|
63
|
+
return "".join(parts)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def run_tool(tool_config: ToolConfig, context_path: str, excludes: list[str] | None = None) -> RawResult:
|
|
57
67
|
"""Runs a tool defined by its configuration and returns the execution result.
|
|
58
68
|
|
|
59
69
|
Args:
|
|
@@ -72,7 +82,7 @@ def run_tool(tool_config: ToolConfig, context_path: str) -> RawResult:
|
|
|
72
82
|
>>> result.return_code
|
|
73
83
|
0"""
|
|
74
84
|
python = sys.executable
|
|
75
|
-
path = context_path
|
|
85
|
+
path = str(Path(context_path))
|
|
76
86
|
if tool_config.run_in_target_env:
|
|
77
87
|
uv = shutil.which("uv")
|
|
78
88
|
if uv:
|
|
@@ -87,10 +97,12 @@ def run_tool(tool_config: ToolConfig, context_path: str) -> RawResult:
|
|
|
87
97
|
project_root_path = Path(abs_dir)
|
|
88
98
|
missing_deps = [d for d in tool_config.extra_deps if not _dep_in_venv(d, project_root_path)]
|
|
89
99
|
with_flags = " ".join(f"--with {dep}" for dep in missing_deps)
|
|
90
|
-
|
|
100
|
+
no_sync = "--no-sync" if sys.executable.startswith(abs_dir) else ""
|
|
101
|
+
python = f'"{uv}" run {no_sync} --directory "{abs_dir}" {with_flags}'.strip()
|
|
91
102
|
abs_context_path = str(Path(context_path).resolve())
|
|
92
103
|
input_path_posix = Path(context_path).as_posix().rstrip("/")
|
|
93
|
-
|
|
104
|
+
exclude = _build_exclude_str(tool_config.exclude_format, excludes or [], input_path_posix=input_path_posix)
|
|
105
|
+
command = tool_config.command.format(context_path=path, abs_context_path=abs_context_path, input_path_posix=input_path_posix, python=python, exclude=exclude)
|
|
94
106
|
cache_key = f"{command}:{get_context_hash(context_path)}"
|
|
95
107
|
if cache_key in _cache:
|
|
96
108
|
log.info(f"Cache hit: {command}")
|
|
@@ -110,7 +122,7 @@ def run_tool(tool_config: ToolConfig, context_path: str) -> RawResult:
|
|
|
110
122
|
return raw_result
|
|
111
123
|
|
|
112
124
|
|
|
113
|
-
def run_tools(tool_configs: Collection[ToolConfig], path: str, max_workers: int = 0, early_exit: bool = False) -> list[ToolResult]:
|
|
125
|
+
def run_tools(tool_configs: Collection[ToolConfig], path: str, max_workers: int = 0, early_exit: bool = False, excludes: list[str] | None = None) -> list[ToolResult]:
|
|
114
126
|
"""Run multiple tools and return their parsed results.
|
|
115
127
|
|
|
116
128
|
Runs each tool specified in *tool_configs* on the file or directory at
|
|
@@ -152,7 +164,7 @@ def run_tools(tool_configs: Collection[ToolConfig], path: str, max_workers: int
|
|
|
152
164
|
>>> results = run_tools(configs, '/path/to/project', parallel=True)"""
|
|
153
165
|
def _run_and_parse(tool_config: ToolConfig) -> tuple[int, ToolResult]:
|
|
154
166
|
t0 = time.perf_counter()
|
|
155
|
-
raw_result = run_tool(tool_config, path)
|
|
167
|
+
raw_result = run_tool(tool_config, path, excludes)
|
|
156
168
|
tr = tool_config.parser_class(tool_config.parser_config).parse(raw_result)
|
|
157
169
|
tr.duration_s = time.perf_counter() - t0
|
|
158
170
|
return tool_config.order, tr
|
py_cq/localtypes.py
CHANGED
|
@@ -22,6 +22,7 @@ class ToolConfig:
|
|
|
22
22
|
run_in_target_env: bool = False # If True, run in target project's env via uv
|
|
23
23
|
extra_deps: list[str] = field(default_factory=list) # Extra deps to inject via uv --with
|
|
24
24
|
parser_config: dict[str, Any] = field(default_factory=dict)
|
|
25
|
+
exclude_format: str = "" # Per-path template for --exclude injection, e.g. " --exclude {path}"
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
@dataclass
|
py_cq/parsers/__init__.py
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Tool Response parsers"""
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
Interrogate is invoked with ``-v --fail-under 0``, producing a table of
|
|
4
4
|
per-file docstring coverage on stdout::
|
|
5
5
|
|
|
6
|
-
| src/foo.py | 5 | 2 | 60% |
|
|
7
|
-
| TOTAL | 5 | 2 | 60% |
|
|
6
|
+
| src/foo.py | 5 | 2 | 3 | 60% |
|
|
7
|
+
| TOTAL | 5 | 2 | 3 | 60.0% |
|
|
8
8
|
|
|
9
9
|
The parser extracts per-file coverage and the TOTAL row, storing the TOTAL
|
|
10
10
|
as the ``doc_coverage`` metric (0.0–1.0).
|
|
@@ -14,7 +14,7 @@ import re
|
|
|
14
14
|
|
|
15
15
|
from py_cq.localtypes import AbstractParser, RawResult, ToolResult
|
|
16
16
|
|
|
17
|
-
_ROW_RE = re.compile(r"^\|\s+(.+?)\s+\|\s+(\d+)\s+\|\s+(\d+)\s+\|\s+(\d+)%\s
|
|
17
|
+
_ROW_RE = re.compile(r"^\|\s+(.+?)\s+\|\s+(\d+)\s+\|\s+(\d+)\s+\|\s+\d+\s+\|\s+(\d+(?:\.\d+)?)%\s*\|")
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class InterrogateParser(AbstractParser):
|
|
@@ -30,7 +30,7 @@ class InterrogateParser(AbstractParser):
|
|
|
30
30
|
name = m.group(1).strip()
|
|
31
31
|
total = int(m.group(2))
|
|
32
32
|
miss = int(m.group(3))
|
|
33
|
-
cover =
|
|
33
|
+
cover = float(m.group(4))
|
|
34
34
|
if name == "TOTAL":
|
|
35
35
|
total_coverage = cover / 100.0
|
|
36
36
|
elif total > 0:
|
py_cq/tool_registry.py
CHANGED
|
@@ -30,6 +30,7 @@ def load_tool_configs() -> dict[str, ToolConfig]:
|
|
|
30
30
|
run_in_target_env=tool_data.get("run_in_target_env", False),
|
|
31
31
|
extra_deps=tool_data.get("extra_deps", []),
|
|
32
32
|
parser_config=tool_data.get("parser_config", {}),
|
|
33
|
+
exclude_format=tool_data.get("exclude_format", ""),
|
|
33
34
|
)
|
|
34
35
|
return registry
|
|
35
36
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-code-quality
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.14
|
|
4
4
|
Summary: Python Code Quality Analysis Tool - feed the results from 11 CQ tools straight into an LLM. Minimal tokens.
|
|
5
5
|
Author: Chris Kilner
|
|
6
6
|
Author-email: Chris Kilner <chris@rhiza.fr>
|
|
@@ -35,39 +35,15 @@ Description-Content-Type: text/markdown
|
|
|
35
35
|
[](https://pypi.org/project/python-code-quality/)
|
|
36
36
|
[](LICENSE)
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
Why? It removes the mental burden of understanding all these tools and parsing their results.
|
|
41
|
-
|
|
42
|
-
The primary workflow is:
|
|
38
|
+
Run 11+ code quality tools, aggregate results into one score, and surface the single most critical defect as a focused markdown prompt — ready to pipe to any LLM.
|
|
43
39
|
|
|
44
40
|
```bash
|
|
45
|
-
|
|
46
|
-
cq check .
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
```python
|
|
50
|
-
`data/problems/travelling_salesman/ts_bad.py:21` — **F841**: Local variable `unused_variable` is assigned to but never used
|
|
51
|
-
|
|
52
|
-
18: min_dist = float("inf")
|
|
53
|
-
19: nearest_city = None
|
|
54
|
-
20: for city in cities:
|
|
55
|
-
21: unused_variable = 67
|
|
56
|
-
22: dist = calc_dist(current_city, city)
|
|
57
|
-
23: if dist < min_dist:
|
|
58
|
-
24: min_dist = dist
|
|
59
|
-
25: nearest_city = city
|
|
60
|
-
|
|
61
|
-
Please fix only this issue. After fixing, run `cq check . -o llm` to verify.
|
|
62
|
-
```
|
|
63
|
-
Feed to an LLM with edit tools and repeat until there are no issues, e.g.
|
|
64
|
-
|
|
65
|
-
```python
|
|
66
|
-
cq check . -o llm | claude -p "fix this"
|
|
67
|
-
# or
|
|
68
|
-
cq check . -o llm | ollama run gpt-oss:20b "Explain how to fix this"
|
|
41
|
+
cq check . -o llm # top defect as markdown, pipe to an LLM
|
|
42
|
+
cq check . # table overview of all scores
|
|
43
|
+
cq check . -o score # numeric score only, exits 1 on errors (CI gate)
|
|
69
44
|
```
|
|
70
45
|
|
|
46
|
+

|
|
71
47
|
|
|
72
48
|
## Install
|
|
73
49
|
|
|
@@ -114,6 +90,7 @@ cq check . -o raw # Raw tool output for debug
|
|
|
114
90
|
cq check path/to/file.py # Just one file (skips pytest and coverage)
|
|
115
91
|
cq check . --only ruff,ty # Run only specific tools
|
|
116
92
|
cq check . --skip bandit # Skip specific tools
|
|
93
|
+
cq check . --exclude demo # Exclude paths from all tools
|
|
117
94
|
cq check . --workers 1 # Run sequentially if you like things slow
|
|
118
95
|
cq check . --clear-cache # Clear cached results before running (rarely needed)
|
|
119
96
|
cq config path/to/project/ # Show effective tool configuration
|
|
@@ -133,10 +110,17 @@ Add a stop hook to your project's `.claude/settings.json` so Claude automaticall
|
|
|
133
110
|
```json
|
|
134
111
|
{
|
|
135
112
|
"hooks": {
|
|
136
|
-
"Stop": [
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
113
|
+
"Stop": [
|
|
114
|
+
{
|
|
115
|
+
"matcher": "",
|
|
116
|
+
"hooks": [
|
|
117
|
+
{
|
|
118
|
+
"type": "command",
|
|
119
|
+
"command": "cq check . -o score && echo 'CQ: all clear' || cq check . -o llm; true"
|
|
120
|
+
}
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
]
|
|
140
124
|
}
|
|
141
125
|
}
|
|
142
126
|
```
|
|
@@ -252,6 +236,9 @@ Add a `[tool.cq]` section to your project's `pyproject.toml`:
|
|
|
252
236
|
# Skip tools that are slow or not relevant to your project
|
|
253
237
|
disable = ["coverage", "interrogate"]
|
|
254
238
|
|
|
239
|
+
# Exclude paths from all tools (merged with --exclude CLI flag)
|
|
240
|
+
exclude = ["demo", "docs"]
|
|
241
|
+
|
|
255
242
|
# Lines of source context shown around each defect in LLM output (default: 15)
|
|
256
243
|
context_lines = 15
|
|
257
244
|
|
|
@@ -270,21 +257,23 @@ Tool IDs match the keys in `config/config.yaml`: `compile`, `ruff`, `ty`, `bandi
|
|
|
270
257
|
python:
|
|
271
258
|
|
|
272
259
|
compile:
|
|
273
|
-
command: "{python} -m compileall -r 10 -j 8 {context_path} -x .*venv"
|
|
260
|
+
command: "{python} -m compileall -r 10 -j 8 \"{context_path}\" -x .*venv"
|
|
274
261
|
parser: "CompileParser"
|
|
275
262
|
order: 1
|
|
276
263
|
warning_threshold: 0.9999
|
|
277
264
|
error_threshold: 0.9999
|
|
278
265
|
|
|
279
266
|
ruff:
|
|
280
|
-
command: "{python} -m ruff check --output-format concise --no-cache {context_path}"
|
|
267
|
+
command: "{python} -m ruff check --output-format concise --no-cache \"{context_path}\"{exclude}"
|
|
268
|
+
exclude_format: " --exclude {path}"
|
|
281
269
|
parser: "RuffParser"
|
|
282
270
|
order: 2
|
|
283
271
|
warning_threshold: 0.9999
|
|
284
272
|
error_threshold: 0.9
|
|
285
273
|
|
|
286
274
|
ty:
|
|
287
|
-
command: "{python} -m ty check --output-format concise --color never {context_path}"
|
|
275
|
+
command: "{python} -m ty check --output-format concise --color never \"{context_path}\"{exclude}"
|
|
276
|
+
exclude_format: " --exclude {path}"
|
|
288
277
|
parser: "TyParser"
|
|
289
278
|
order: 3
|
|
290
279
|
warning_threshold: 0.9999
|
|
@@ -294,22 +283,26 @@ python:
|
|
|
294
283
|
- ty
|
|
295
284
|
|
|
296
285
|
bandit:
|
|
297
|
-
command: "{python} -m bandit -r {context_path} -f json -q -s B101 --severity-level medium --exclude {input_path_posix}/.venv,{input_path_posix}/tests"
|
|
286
|
+
command: "{python} -m bandit -r \"{context_path}\" -f json -q -s B101 --severity-level medium --exclude \"{input_path_posix}/.venv,{input_path_posix}/tests{exclude}\""
|
|
287
|
+
exclude_format: ",{input_path_posix}/{path}"
|
|
298
288
|
parser: "BanditParser"
|
|
299
289
|
order: 4
|
|
300
290
|
warning_threshold: 0.9999
|
|
301
291
|
error_threshold: 0.8
|
|
302
292
|
|
|
303
293
|
pytest:
|
|
304
|
-
command: "{python} -m pytest -v {context_path}"
|
|
294
|
+
command: "{python} -m pytest -v \"{context_path}\"{exclude}"
|
|
295
|
+
exclude_format: " --ignore {path}"
|
|
305
296
|
parser: "PytestParser"
|
|
306
297
|
order: 5
|
|
307
298
|
warning_threshold: 1.0
|
|
308
299
|
error_threshold: 1.0
|
|
309
300
|
run_in_target_env: true
|
|
301
|
+
extra_deps:
|
|
302
|
+
- pytest
|
|
310
303
|
|
|
311
304
|
coverage:
|
|
312
|
-
command: "{python} -m coverage run --omit=*/tests/*,*/test_*.py -m pytest {context_path} && {python} -m coverage report --omit=*/tests/*,*/test_*.py"
|
|
305
|
+
command: "{python} -m coverage run --omit=*/tests/*,*/test_*.py -m pytest \"{context_path}\" && {python} -m coverage report --omit=*/tests/*,*/test_*.py"
|
|
313
306
|
parser: "CoverageParser"
|
|
314
307
|
order: 6
|
|
315
308
|
warning_threshold: 0.9
|
|
@@ -320,40 +313,41 @@ python:
|
|
|
320
313
|
- pytest
|
|
321
314
|
|
|
322
315
|
radon-cc:
|
|
323
|
-
command: "{python} -m radon cc --json {context_path}"
|
|
316
|
+
command: "{python} -m radon cc --json \"{context_path}\""
|
|
324
317
|
parser: "ComplexityParser"
|
|
325
318
|
order: 7
|
|
326
319
|
warning_threshold: 0.6
|
|
327
320
|
error_threshold: 0.4
|
|
328
321
|
|
|
329
322
|
radon-mi:
|
|
330
|
-
command: "{python} -m radon mi -s --json {context_path}"
|
|
323
|
+
command: "{python} -m radon mi -s --json \"{context_path}\""
|
|
331
324
|
parser: "MaintainabilityParser"
|
|
332
325
|
order: 8
|
|
333
326
|
warning_threshold: 0.6
|
|
334
327
|
error_threshold: 0.4
|
|
335
328
|
|
|
336
329
|
radon-hal:
|
|
337
|
-
command: "{python} -m radon hal -f --json {context_path}"
|
|
330
|
+
command: "{python} -m radon hal -f --json \"{context_path}\""
|
|
338
331
|
parser: "HalsteadParser"
|
|
339
332
|
order: 9
|
|
340
333
|
warning_threshold: 0.5
|
|
341
334
|
error_threshold: 0.3
|
|
342
335
|
|
|
343
336
|
vulture:
|
|
344
|
-
command: "{python} -m vulture {context_path} --min-confidence 80 --exclude .venv,dist,.*_cache,docs,.git"
|
|
337
|
+
command: "{python} -m vulture \"{context_path}\" --min-confidence 80 --exclude .venv,dist,.*_cache,docs,.git{exclude}"
|
|
338
|
+
exclude_format: ",{path}"
|
|
345
339
|
parser: "VultureParser"
|
|
346
340
|
order: 10
|
|
347
341
|
warning_threshold: 0.9999
|
|
348
342
|
error_threshold: 0.8
|
|
349
343
|
|
|
350
344
|
interrogate:
|
|
351
|
-
command: "{python} -m interrogate {context_path} -v --fail-under 0"
|
|
345
|
+
command: "{python} -m interrogate \"{context_path}\" -e tests{exclude} -v --fail-under 0"
|
|
346
|
+
exclude_format: " -e {path}"
|
|
352
347
|
parser: "InterrogateParser"
|
|
353
348
|
order: 11
|
|
354
349
|
warning_threshold: 0.8
|
|
355
350
|
error_threshold: 0.3
|
|
356
|
-
|
|
357
351
|
```
|
|
358
352
|
|
|
359
353
|
## Respect
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
py_cq/__init__.py,sha256=
|
|
2
|
-
py_cq/cli.py,sha256=
|
|
1
|
+
py_cq/__init__.py,sha256=U2ysDtSFdv2mlXZz4w1Q42pfgfi6YY_3Ln24bkZq14I,260
|
|
2
|
+
py_cq/cli.py,sha256=RRQVPVOwG-EMYndMUhBfqBqm1S1kcaObhKOdfxrrYl0,11963
|
|
3
3
|
py_cq/config/__init__.py,sha256=f0wc51O_3kGDTZUnCbGv8_zWnC5yYGl4NWcf2buSImQ,670
|
|
4
|
-
py_cq/config/config.yaml,sha256=
|
|
4
|
+
py_cq/config/config.yaml,sha256=TPZJogpWbyf0Ml2mHrHzTNyTik3k07KPVGsA1wT9GEc,2696
|
|
5
5
|
py_cq/context_hash.py,sha256=h-i7Rhd7AUfLv9SkQvE79bjJvTsm_ZwoVwSmUKXWmfM,2977
|
|
6
|
-
py_cq/execution_engine.py,sha256=
|
|
6
|
+
py_cq/execution_engine.py,sha256=nAsCvldUfDagZnfOwXf4A37VQLxCGiv12T8ymutflC4,8697
|
|
7
7
|
py_cq/language_detector.py,sha256=6av5HaimcZ54RkN69xQmGgC0mxtTvGzPV3SL8NGG8Uc,1116
|
|
8
8
|
py_cq/llm_formatter.py,sha256=l74O5iqNWMR16789Xncoi93xOqgQJhW5IQK9_OyA9mE,1632
|
|
9
|
-
py_cq/localtypes.py,sha256=
|
|
9
|
+
py_cq/localtypes.py,sha256=UGI2kl1xB2TedKGByth3URiqJKY56YZMNds1hnLEzvU,6228
|
|
10
10
|
py_cq/main.py,sha256=VKoXI8R8rB2fEROBYoTVURfinLqyh8XTNIIWAOtH7dw,380
|
|
11
11
|
py_cq/metric_aggregator.py,sha256=M2ymo62S7p7qPUqjjoiPg4IVyXQhLMuTr9-jxLiFjCY,853
|
|
12
|
-
py_cq/parsers/__init__.py,sha256=
|
|
12
|
+
py_cq/parsers/__init__.py,sha256=YS3wPS0cMNU80zkdSZBEZOkqDKE6Jk--0Xd_bX7VMcA,27
|
|
13
13
|
py_cq/parsers/banditparser.py,sha256=Ju_CkuXtkVn1Th9aQ6mv6fTUTpb9pc1YD8Nzt_nMgFQ,2326
|
|
14
14
|
py_cq/parsers/common.py,sha256=thbziNjqaf-SY3Y0W-KmPwzlcC-YCV98Z8jubUJM7_4,5203
|
|
15
15
|
py_cq/parsers/compileparser.py,sha256=YsT7ePUDRjsUHTLqgRv4x6jJBCTt6cbm1mgxplzxETg,6256
|
|
@@ -17,7 +17,7 @@ py_cq/parsers/complexityparser.py,sha256=2t1-wmNjUu65fULcIm5jcgv7ZLWwjakyiY_r-Fx
|
|
|
17
17
|
py_cq/parsers/coverageparser.py,sha256=n4h_RCxKvJoYgp356PA4laAmFcngjQ41b_GXZvKkVgc,4041
|
|
18
18
|
py_cq/parsers/exitcodeparser.py,sha256=ZFL3EbPhGvFjm2qZhfLD1_5dNjR9ULYNQpKgy0Z_dGo,729
|
|
19
19
|
py_cq/parsers/halsteadparser.py,sha256=ZCN7LP1iUZ91tf3tlspKAPQrTEa78XVdE9Fjn9yPvYk,9008
|
|
20
|
-
py_cq/parsers/interrogateparser.py,sha256=
|
|
20
|
+
py_cq/parsers/interrogateparser.py,sha256=gk9pJ7yFXMzLjk6PP0X8fxW_gAE2DTIoWMsPqF2xIXs,2260
|
|
21
21
|
py_cq/parsers/linecountparser.py,sha256=nxWvFntuR8T6FDGpafrlevvt-jR3rwkbVo_t2JX4TF0,1067
|
|
22
22
|
py_cq/parsers/maintainabilityparser.py,sha256=Ax0ZFA6zzqYIWZH1hP1_GUtdVn2LIJ8SKWtqVNdszYs,3411
|
|
23
23
|
py_cq/parsers/pytestparser.py,sha256=3N1X4wKhJ2h-2U1GuM3gHWHpHxU9f0LPGcPaojra9W4,6377
|
|
@@ -26,8 +26,8 @@ py_cq/parsers/ruffparser.py,sha256=ZdIya4sct2PrsOyfKfMGmXHLh3Qu7HtFqXNY9IuNFog,2
|
|
|
26
26
|
py_cq/parsers/typarser.py,sha256=zrI0KS65MUGPxYPP74B6BRyTbjcPhKyQPjH2KZIyxN0,2495
|
|
27
27
|
py_cq/parsers/vultureparser.py,sha256=U6zC7P0ATA_N4SB90BahKF5QHMITf_z-NsOgrh_Q5rA,1995
|
|
28
28
|
py_cq/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
-
py_cq/tool_registry.py,sha256=
|
|
30
|
-
python_code_quality-0.1.
|
|
31
|
-
python_code_quality-0.1.
|
|
32
|
-
python_code_quality-0.1.
|
|
33
|
-
python_code_quality-0.1.
|
|
29
|
+
py_cq/tool_registry.py,sha256=UfmwJH8rtmTY9kX02QaE4OJIWyboTMcXUavgb9R4fxc,1648
|
|
30
|
+
python_code_quality-0.1.14.dist-info/WHEEL,sha256=M4DeIjVCA49okfALADZoWX5JOGwnmHb-JOpQHtI-1c0,80
|
|
31
|
+
python_code_quality-0.1.14.dist-info/entry_points.txt,sha256=cfWbTw7eYO6Trv1-Z_odL6Zta9CqYU6Vk9lAHdfB60Q,40
|
|
32
|
+
python_code_quality-0.1.14.dist-info/METADATA,sha256=HR_8B9uca6SBAn7f74rMAnTOJ6LzODc5AF0w0Uiic28,12496
|
|
33
|
+
python_code_quality-0.1.14.dist-info/RECORD,,
|
|
File without changes
|
{python_code_quality-0.1.13.dist-info → python_code_quality-0.1.14.dist-info}/entry_points.txt
RENAMED
|
File without changes
|