python-code-quality 0.1.4__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.
@@ -0,0 +1,188 @@
1
+ Metadata-Version: 2.4
2
+ Name: python-code-quality
3
+ Version: 0.1.4
4
+ Summary: Python Code Quality Analysis Tool - feed the results from 11 CQ CQ straight into an LLM.
5
+ Project-URL: Homepage, https://github.com/rhiza-fr/py-cq
6
+ Project-URL: Repository, https://github.com/rhiza-fr/py-cq
7
+ Author-email: Chris Kilner <chris@rhiza.fr>
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Requires-Python: >=3.12
11
+ Requires-Dist: bandit>=1.8.0
12
+ Requires-Dist: coverage>=7.8.2
13
+ Requires-Dist: diskcache>=5.6.3
14
+ Requires-Dist: interrogate>=1.7.0
15
+ Requires-Dist: pytest-cov>=6.1.1
16
+ Requires-Dist: pytest-json-report>=1.5.0
17
+ Requires-Dist: pytest>=8.4.0
18
+ Requires-Dist: pyyaml>=6.0.2
19
+ Requires-Dist: radon>=6.0.1
20
+ Requires-Dist: rich>=14.0.0
21
+ Requires-Dist: ruff>=0.14.1
22
+ Requires-Dist: ty>=0.0.17
23
+ Requires-Dist: typer>=0.16.0
24
+ Requires-Dist: vulture>=2.14
25
+ Description-Content-Type: text/markdown
26
+
27
+ # CQ - Python Code Quality Analysis Tool
28
+
29
+ Python Code Quality Analysis Tool - feed the results from 11 CQ tools straight into an LLM. The primary workflow is:
30
+
31
+ ```bash
32
+ cq check -o llm # get the single most critical defect as markdown
33
+ ```
34
+
35
+ Feed that output to an LLM, apply the fix, repeat until the score is clean.
36
+
37
+ ## Install
38
+
39
+ ```bash
40
+ uv tool install python-code-quality
41
+
42
+ # or
43
+ git pull https://github.com/rhiza-fr/py-cq.git
44
+ cd py-cq
45
+ uv tool install .
46
+ ```
47
+
48
+ ## Tools
49
+
50
+ CQ runs these tools in *parallel*:
51
+
52
+ | Priority | Tool | Measures |
53
+ |----------|------|----------|
54
+ | 1 | compileall | Syntax errors |
55
+ | 2 | bandit | Security vulnerabilities |
56
+ | 3 | ruff | Lint / style |
57
+ | 4 | ty | Type errors |
58
+ | 5 | pytest | Test pass rate |
59
+ | 6 | coverage | Test coverage |
60
+ | 7 | radon cc | Cyclomatic complexity |
61
+ | 8 | radon mi | Maintainability index |
62
+ | 9 | radon hal | Halstead volume / bug estimate |
63
+ | 10 | vulture | Dead code |
64
+ | 11 | interrogate | Docstring coverage |
65
+
66
+ ## Usage
67
+
68
+ ```bash
69
+ # LLM workflow: get the top defect as markdown (primary use case)
70
+ cq check -o llm
71
+
72
+ # Rich table with all metrics (default, also saves .cq.json)
73
+ cq check
74
+
75
+ # Numeric score only — useful in CI or scripts
76
+ cq check -o score
77
+
78
+ # Full JSON output
79
+ cq check -o json
80
+
81
+ # Explicit path (defaults to current directory)
82
+ cq check path/to/project/
83
+ cq check path/to/file.py
84
+
85
+ # Run sequentially (1 worker) instead of in parallel
86
+ cq check --workers 1
87
+
88
+ # Clear cached results before running
89
+ cq check --clear-cache
90
+
91
+ # Save table output to a custom file
92
+ cq check --out-file custom_results.json
93
+
94
+ # Show effective tool configuration (thresholds, enabled/disabled status)
95
+ cq config
96
+ cq config path/to/project/
97
+ ```
98
+
99
+ ## Output
100
+
101
+ ```bash
102
+ > cq check .
103
+ ```
104
+
105
+ ```python
106
+ ┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━┓
107
+ ┃ Tool ┃ Time ┃ Metric ┃ Score ┃ Status ┃
108
+ ┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━┩
109
+ │ compile │ 0.42s │ compile │ 1.000 │ OK │
110
+ │ bandit │ 0.56s │ security │ 1.000 │ OK │
111
+ │ ruff │ 0.17s │ lint │ 1.000 │ OK │
112
+ │ ty │ 0.33s │ type_check │ 1.000 │ OK │
113
+ │ pytest │ 0.91s │ tests │ 1.000 │ OK │
114
+ │ coverage │ 1.26s │ coverage │ 0.910 │ OK │
115
+ │ radon cc │ 0.32s │ simplicity │ 0.982 │ OK │
116
+ │ radon mi │ 0.38s │ maintainability │ 0.869 │ OK │
117
+ │ radon hal │ 0.30s │ file_bug_free │ 0.928 │ OK │
118
+ │ radon hal │ │ file_smallness │ 0.851 │ OK │
119
+ │ radon hal │ │ functions_bug_free │ 0.913 │ OK │
120
+ │ radon hal │ │ functions_smallness │ 0.724 │ OK │
121
+ │ vulture │ 0.32s │ dead_code │ 1.000 │ OK │
122
+ │ interrogate │ 0.36s │ doc_coverage │ 1.000 │ OK │
123
+ │ │ │ Score │ 0.965 │ │
124
+ └──────────────────┴──────────┴───────────────────────────┴─────────┴──────────┘
125
+ ```
126
+ ```bash
127
+ > cq check . -o score
128
+ ```
129
+ ```python
130
+ 0.9662730667181059 # this is designed to approach but not reach 1.0
131
+ ```
132
+
133
+ ```bash
134
+ > cq check . -o llm
135
+ ```
136
+
137
+ ```md
138
+ `data/problems/travelling_salesman/ts_bad.py:21` — **F841**: Local variable `unused_variable` is assigned to but never used
139
+
140
+ 18: min_dist = float("inf")
141
+ 19: nearest_city = None
142
+ 20: for city in cities:
143
+ 21: unused_variable = 67
144
+ 22: dist = calc_dist(current_city, city)
145
+ 23: if dist < min_dist:
146
+ 24: min_dist = dist
147
+ 25: nearest_city = city
148
+
149
+ Please fix only this issue. After fixing, run `cq check . -o llm` to verify.
150
+ ```
151
+
152
+ ## Configuration
153
+
154
+ Add a `[tool.cq]` section to your project's `pyproject.toml`:
155
+
156
+ ```toml
157
+ [tool.cq]
158
+ # Skip tools that are slow or not relevant to your project
159
+ disable = ["coverage", "interrogate"]
160
+
161
+ # Override warning/error thresholds per tool
162
+ [tool.cq.thresholds.coverage]
163
+ warning = 0.9
164
+ error = 0.7
165
+ ```
166
+
167
+ Tool IDs match the keys in `config/tools.yaml`: `compilation`, `bandit`, `ruff`, `ty`, `pytest`, `coverage`, `complexity`, `maintainability`, `halstead`, `vulture`, `interrogate`.
168
+
169
+ ## LLM workflow
170
+
171
+ `-o llm` selects the single worst-scoring tool and formats its top defect as
172
+ concise markdown. The LLM fixes it, you re-run `cq check -o llm`, and repeat
173
+ until all tools are green. Priority order ensures the most critical category
174
+ (security, type errors, failing tests) is fixed before cosmetic ones.
175
+
176
+ ## Tools
177
+
178
+ Many thanks to all the wonderful maintainers of :
179
+
180
+ - [compileall](https://docs.python.org/3/library/compileall.html)
181
+ - [bandit](https://github.com/PyCQA/bandit)
182
+ - [ruff](https://github.com/astral-sh/ruff)
183
+ - [ty](https://github.com/astral-sh/ty)
184
+ - [pytest](https://github.com/pytest-dev/pytest)
185
+ - [coverage.py](https://github.com/nedbat/coveragepy)
186
+ - [radon](https://github.com/rubik/radon)
187
+ - [vulture](https://github.com/jendrikseipp/vulture)
188
+ - [interrogate](https://github.com/econchick/interrogate)
@@ -0,0 +1,31 @@
1
+ py_cq/__init__.py,sha256=rS7kf1RU1zZskvJlkbZaMqEpdRYPspwDPAFbxzF3tXg,373
2
+ py_cq/cli.py,sha256=M0t5noGEt-a1TmTaDvsGKfApcpOZnXjXHiUo_tSdcjk,8586
3
+ py_cq/context_hash.py,sha256=h-i7Rhd7AUfLv9SkQvE79bjJvTsm_ZwoVwSmUKXWmfM,2977
4
+ py_cq/execution_engine.py,sha256=-2W1ySKKiyr_MAEuCbYqtpsmcIFmiAMGd4iB6jpyA6Y,6498
5
+ py_cq/llm_formatter.py,sha256=tOjoWIFEq3ZRGKLcwAnLswQ00B79sM3yJT3K3bh857A,1577
6
+ py_cq/localtypes.py,sha256=Ix871IDcZh8_EldhOrmvR4TPxvWfDi0YhZVSGpI6pl0,5961
7
+ py_cq/main.py,sha256=VKoXI8R8rB2fEROBYoTVURfinLqyh8XTNIIWAOtH7dw,380
8
+ py_cq/metric_aggregator.py,sha256=M2ymo62S7p7qPUqjjoiPg4IVyXQhLMuTr9-jxLiFjCY,853
9
+ py_cq/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ py_cq/storage.py,sha256=J8360OUnGFyQAl_jJ6Eoy5hn7DDpShQvqaU6dFtfrkc,916
11
+ py_cq/tool_registry.py,sha256=9QFqeXxrK7NF-qMd9ZxP5zfqc0nsHVQAbrbAqinAA4g,1535
12
+ py_cq/config/__init__.py,sha256=JZgIe38Lq0XYd-zwOVzi6SxobYBc4lofhidmU4T9_oU,730
13
+ py_cq/config/tools.yaml,sha256=Cjzw58vMOkreZA9EXMzQK5WTfY2YrihnPfNzStvGRQg,2495
14
+ py_cq/parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ py_cq/parsers/banditparser.py,sha256=6Kk3yfNB438Sl2ZfEHeViQ3hlTO0cazNQnJbHJ4RnKc,2131
16
+ py_cq/parsers/common.py,sha256=FWkQIm03IKoCB7pvW4MRbQKjC_quINIKkGq5xKk86qM,3506
17
+ py_cq/parsers/compileparser.py,sha256=GcIcKGVSL8W3zTwfA7WzD045-gNdSeSkljOrPA0qG0M,6496
18
+ py_cq/parsers/complexityparser.py,sha256=2t1-wmNjUu65fULcIm5jcgv7ZLWwjakyiY_r-Fx1QQg,3983
19
+ py_cq/parsers/coverageparser.py,sha256=xDNlLNEsA0U3z4GV02iEq97IL90-UJAQrhMlFzpIdy0,4013
20
+ py_cq/parsers/halsteadparser.py,sha256=Rj690m_C4KRdlfrTC_bXtT5_-oJPKT38I7V-v1CDoJY,8980
21
+ py_cq/parsers/interrogateparser.py,sha256=eMROINtyZE2eHrRxVU0jA-nYTdvr0PZ8iERVn7kPH5o,2197
22
+ py_cq/parsers/maintainabilityparser.py,sha256=Ax0ZFA6zzqYIWZH1hP1_GUtdVn2LIJ8SKWtqVNdszYs,3411
23
+ py_cq/parsers/pytestparser.py,sha256=FrAaNJfDHZmEr_vRYQpp04qRj4Cq3jaDhpnAFxLv5dQ,4047
24
+ py_cq/parsers/ruffparser.py,sha256=WMJhsYA5wwBcIhqGSfjBxy78RGv_iCJJ1Qdmt1dqTOw,2567
25
+ py_cq/parsers/typarser.py,sha256=bC6-P-NGBMJBLyr1DkX1yMtnTS8afuRO0Keb_XyBeg0,2787
26
+ py_cq/parsers/vultureparser.py,sha256=fe-LPagivKGtmf6Kyu_gT0OrWJjowAsJ2OhXQiv_zQY,1888
27
+ python_code_quality-0.1.4.dist-info/METADATA,sha256=IdFzOrXj1Cn-EdAoNJ-zoxEYqWBI3_pEJ1bRYCKa_co,6745
28
+ python_code_quality-0.1.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
29
+ python_code_quality-0.1.4.dist-info/entry_points.txt,sha256=j5Q_gGr0b7389lddt1JlZ7gcL4Z7RHxuDhij_G-IhBY,39
30
+ python_code_quality-0.1.4.dist-info/licenses/LICENSE,sha256=Bpuh8tbf37so8M5NtRGTLmT5ue7diJ17223L9f9nsT0,1086
31
+ python_code_quality-0.1.4.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ cq = py_cq.main:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Chris Kilner <chris@rhiza.fr>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.