python-qv 0.1.0__py3-none-any.whl → 0.1.2__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,492 @@
1
+ Metadata-Version: 2.5
2
+ Name: python-qv
3
+ Version: 0.1.2
4
+ Summary: Diagnose why a Python project is unhealthy — explain root cause and suggest safe fixes.
5
+ Project-URL: Homepage, https://github.com/inzamol/qv
6
+ Project-URL: Repository, https://github.com/inzamol/qv
7
+ Project-URL: Documentation, https://inzamol.github.io/qv/
8
+ Project-URL: Issues, https://github.com/inzamol/qv/issues
9
+ Author: Inzamul Hoque
10
+ License-Expression: MIT
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Software Development :: Bug Tracking
20
+ Classifier: Topic :: Software Development :: Quality Assurance
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: click>=8.1.0
23
+ Requires-Dist: packaging>=23.2
24
+ Requires-Dist: pydantic>=2.5.0
25
+ Requires-Dist: rich>=13.7.0
26
+ Requires-Dist: tomli>=2.0.1; python_version < '3.11'
27
+ Provides-Extra: dev
28
+ Requires-Dist: pre-commit>=3.7.0; extra == 'dev'
29
+ Requires-Dist: pyright>=1.1.350; extra == 'dev'
30
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
31
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
32
+ Requires-Dist: ruff>=0.4.0; extra == 'dev'
33
+ Requires-Dist: tox-uv>=1.7.0; extra == 'dev'
34
+ Requires-Dist: tox>=4.15.0; extra == 'dev'
35
+ Provides-Extra: docs
36
+ Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
37
+ Requires-Dist: mkdocs<2.0.0,>=1.6.0; extra == 'docs'
38
+ Requires-Dist: pymdown-extensions>=10.7.0; extra == 'docs'
39
+ Description-Content-Type: text/markdown
40
+
41
+ # 🔍 qv
42
+
43
+ <div align="center">
44
+
45
+ **Diagnose why your Python project is unhealthy — understand the root cause and get safe, actionable fixes.**
46
+
47
+ [![PyPI Version](https://img.shields.io/badge/pypi-v0.1.0-blue.svg)](https://pypi.org/project/python-qv/)
48
+ [![Python Versions](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue)](https://pypi.org/project/python-qv/)
49
+ [![CI Status](https://github.com/inzamol/qv/actions/workflows/ci.yml/badge.svg)](https://github.com/inzamol/qv/actions/workflows/ci.yml)
50
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
51
+
52
+ [Installation](#-installation) • [Quick Start](#-quick-start) • [Interactive TUI](#-interactive-tui-explorer) • [Features](#-what-it-detects) • [CLI Commands](#-cli-commands) • [CI/CD Integration](#-cicd-integration) • [Documentation](docs/getting_started.md)
53
+
54
+ </div>
55
+
56
+ ---
57
+
58
+ ## 💡 Why qv?
59
+
60
+ Python projects rarely fail because of Python syntax. They fail because of **ecosystem friction**:
61
+ - Incompatible transitive dependency constraints that break your resolver.
62
+ - Missing dependencies you forgot to add to `pyproject.toml`.
63
+ - Docker containers running Python 3.10 while your team develops on 3.12.
64
+ - Silent circular imports that only crash at runtime when certain modules load.
65
+
66
+ Instead of parsing hundreds of lines of cryptic resolver logs, **`qv`** scans your project in milliseconds, pinpoints the root cause, shows the exact evidence, and gives you a copy-paste command to fix it.
67
+
68
+ ```text
69
+ 🔍 qv
70
+ Project: payment-service
71
+ Python: 3.12.7
72
+ Package Manager: uv
73
+
74
+ 🔴 1 Errors 🟡 1 Warnings 🟢 48 Checks Passed
75
+
76
+ ┌────────────────── 🔴 DEP-001 Dependency constraint conflict ─────────────────┐
77
+ │ celery 5.4.0 requires kombu<5.4.0,>=5.3.0, but installed is kombu 5.5.2. │
78
+ │ │
79
+ │ Evidence: │
80
+ │ • celery declared requirement: kombu<5.4.0,>=5.3.0 │
81
+ │ • Installed kombu version: 5.5.2 in active environment │
82
+ │ │
83
+ │ Suggested fix: │
84
+ │ Upgrade celery or pin kombu to <5.4.0,>=5.3.0. │
85
+ │ $ uv add 'kombu<5.4.0,>=5.3.0' │
86
+ └──────────────────────────────────────────────────────────────────────────────┘
87
+
88
+ Health Score: 85/100
89
+ ```
90
+
91
+ ---
92
+
93
+ ## 📦 Installation
94
+
95
+ Install `python-qv` into your virtual environment (provides the `qv` CLI):
96
+
97
+ ```bash
98
+ # Using pip
99
+ pip install python-qv
100
+
101
+ # Using uv
102
+ uv add python-qv --dev
103
+
104
+ # Run directly without installing (via uvx or pipx)
105
+ uvx python-qv scan
106
+ # or
107
+ pipx run python-qv scan
108
+ ```
109
+
110
+ ---
111
+
112
+ ## 🚀 Quick Start
113
+
114
+ ### 1. Run a Health Scan
115
+
116
+ Run `qv scan` inside any Python repository:
117
+
118
+ ```bash
119
+ qv scan
120
+ ```
121
+
122
+ ### 2. Launch the Interactive TUI Explorer
123
+
124
+ Explore findings interactively with keyboard navigation, live details, dependency tree view, and 1-key remediation:
125
+
126
+ ```bash
127
+ qv inspect
128
+ # or
129
+ qv ui
130
+ ```
131
+
132
+ ### 3. Generate a Self-Contained HTML Report
133
+
134
+ Export a standalone, interactive HTML report with score meters, search filters, and dark/light modes:
135
+
136
+ ```bash
137
+ qv scan --html report.html
138
+ ```
139
+
140
+ ### 4. Understand Any Flagged Issue
141
+
142
+ Need more context on why a rule triggered? Run `explain`:
143
+
144
+ ```bash
145
+ qv explain DEP-001
146
+ ```
147
+
148
+ ### 5. Add Project Configuration
149
+
150
+ To add default configuration to your `pyproject.toml`:
151
+
152
+ ```bash
153
+ qv init
154
+ ```
155
+
156
+ ---
157
+
158
+ ## 🖥️ Interactive TUI Explorer
159
+
160
+ Run `qv inspect` (or `qv ui`) for a full terminal dashboard:
161
+
162
+ ```text
163
+ ┌────────────────────────────────────────────── qv Explorer ──────────────────────────────────────────────┐
164
+ │ 🔍 qv Explorer • Project: all-in-one-demo • Health Score: 40/100 │
165
+ │ Python: 3.12.7 | Package Manager: PIP | Errors: 3 | Warnings: 3 | Checks Passed: 49 │
166
+ ├────────────────────────── Findings (1/6) ──────────────────────────┬──────────────── Details: DEP-001 ──┤
167
+ │ Sev Rule Title │ [ERROR] DEP-001: Constraint conflict│
168
+ │ 👉 ERR DEP-001 Dependency constraint conflict │ celery requires kombu<5.4.0,>=5.3.0│
169
+ │ ERR DEP-002 Missing dependency: httpx │ Location: pyproject.toml │
170
+ │ ERR DEP-002 Missing dependency: pydantic │ │
171
+ │ WARN DEP-003 Unused declared dependency: requests │ Remediation: │
172
+ │ WARN DEP-003 Unused declared dependency: pyyaml │ 👉 Pin kombu to <5.4.0,>=5.3.0 │
173
+ │ ... 1 more below ... │ $ pip install 'kombu<5.4.0' │
174
+ ├────────────────────────────────────────────────────────────────────┴────────────────────────────────────┤
175
+ │ [↑/k, ↓/j] Navigate • [Enter] Expand • [f] Apply Fix • [t] Tree View • [q] Quit │
176
+ └─────────────────────────────────────────────────────────────────────────────────────────────────────────┘
177
+ ```
178
+
179
+ - **`↑ / k` & `↓ / j`**: Scroll smoothly through findings.
180
+ - **`f`**: Apply automated remediation fix for the active finding.
181
+ - **`t`**: Toggle between Findings view and live Dependency Tree.
182
+ - **`Enter`**: Expand details panel.
183
+
184
+ ---
185
+
186
+ ## 🔍 What It Detects
187
+
188
+ | Category | Rule ID | Description | Default Severity |
189
+ |---|---|---|---|
190
+ | **Dependencies** | `DEP-001` | Incompatible package version constraints across dependency tree | `ERROR` |
191
+ | | `DEP-002` | Third-party packages imported in code but missing from `pyproject.toml` | `ERROR` |
192
+ | | `DEP-003` | Declared dependencies that are never imported anywhere in project | `WARNING` |
193
+ | | `DEP-004` | Package requires a Python version incompatible with target runtime | `WARNING` |
194
+ | | `DEP-005` | Installed virtualenv version does not match declared manifest pin | `WARNING` |
195
+ | **Environment** | `ENV-001` | Active interpreter version differs from project `requires-python` | `WARNING` |
196
+ | | `ENV-002` | Dockerfile base image Python version differs from project runtime | `WARNING` |
197
+ | | `ENV-003` | CI matrix does not cover the Python versions declared in project | `WARNING` |
198
+ | **Architecture** | `IMP-001` | Circular import cycles across local modules | `ERROR` |
199
+ | | `IMP-002` | Unresolved relative or internal module imports | `ERROR` |
200
+ | **Packaging** | `PKG-001` | Missing PEP 621 metadata (name, version, etc.) | `WARNING` |
201
+ | | `PKG-002` | Invalid syntax or malformed keys in `pyproject.toml` | `ERROR` |
202
+
203
+ 👉 *See full explanations and remediation steps in the [Rules Catalog](docs/rules.md).*
204
+
205
+ ---
206
+
207
+ ## 🛠️ CLI Commands & Examples
208
+
209
+ ### 1. `qv scan` — Full Project Diagnostics
210
+ Run a comprehensive health audit scanning dependencies, runtime environment, imports, and packaging.
211
+
212
+ ```bash
213
+ # Scan current repository
214
+ qv scan
215
+
216
+ # Scan a specific directory or microservice
217
+ qv scan ./services/payment
218
+
219
+ # Strict mode: fail CI if any warnings exist (exit code 1)
220
+ qv scan --strict
221
+
222
+ # Generate a self-contained interactive HTML dashboard
223
+ qv scan --html report.html
224
+
225
+ # Output SARIF format for GitHub Code Scanning / IDE integration
226
+ qv scan --sarif -o results.sarif
227
+
228
+ # Output machine-readable JSON
229
+ qv scan --json -o results.json
230
+
231
+ # Offline / Airgapped mode (skips remote package index checks)
232
+ qv scan --offline
233
+
234
+ # Emit GitHub Actions workflow command annotations (::error:: and ::warning::)
235
+ qv scan --ci --github-annotations
236
+ ```
237
+
238
+ ---
239
+
240
+ ### 2. `qv inspect` (or `qv ui`) — Interactive Terminal Dashboard
241
+ Explore diagnostic findings, view evidence, inspect circular import trees, and apply fixes interactively with keyboard shortcuts.
242
+
243
+ ```bash
244
+ # Launch interactive dashboard for current repository
245
+ qv inspect
246
+
247
+ # Inspect another project
248
+ qv inspect ../another-service
249
+
250
+ # Airgapped / offline TUI
251
+ qv inspect --offline
252
+ ```
253
+
254
+ *Controls: `↑`/`k` and `↓`/`j` to navigate, `Enter` to expand details, `f` to apply fix, `t` to toggle dependency tree, `q` to quit.*
255
+
256
+ ---
257
+
258
+ ### 3. `qv fix` — Safe Automated Remediation
259
+ Automatically generate and apply deterministic fixes to your project manifest and configuration.
260
+
261
+ ```bash
262
+ # Interactive wizard (prompts before applying each fix)
263
+ qv fix
264
+
265
+ # Preview proposed file diffs and commands without modifying disk
266
+ qv fix --dry-run
267
+
268
+ # Automatically apply all safe fixes without prompting
269
+ qv fix -y
270
+
271
+ # Fix only a specific rule (e.g. missing dependencies)
272
+ qv fix --rule DEP-002 -y
273
+
274
+ # Apply fixes and execute package manager sync commands
275
+ qv fix --sync -y
276
+ ```
277
+
278
+ ---
279
+
280
+ ### 4. `qv tree` (or `qv graph`) — Dependency & Architecture Visualizer
281
+ Render color-coded visual trees of package dependencies and source module import graphs.
282
+
283
+ ```bash
284
+ # Render complete overview (dependency tree + import architecture)
285
+ qv tree
286
+
287
+ # Visualize direct & transitive dependencies up to depth 2
288
+ qv tree --dependencies --depth 2
289
+ # or shorthand:
290
+ qv tree -d -L 2
291
+
292
+ # Visualize internal module import graph and circular import cycles
293
+ qv tree --imports
294
+ # or shorthand:
295
+ qv tree -i
296
+
297
+ # Export tree hierarchy and cycle statistics as JSON
298
+ qv tree --json > tree.json
299
+ ```
300
+
301
+ ---
302
+
303
+ ### 5. `qv explain` — Rule Catalog & Fix Advice
304
+ Look up detailed explanations, common causes, evidence criteria, and remediation advice for any diagnostic rule.
305
+
306
+ ```bash
307
+ # Explain dependency constraint conflicts
308
+ qv explain DEP-001
309
+
310
+ # Explain missing undeclared imports
311
+ qv explain DEP-002
312
+
313
+ # Explain circular import loops
314
+ qv explain IMP-001
315
+
316
+ # Explain Python/Docker environment drift
317
+ qv explain ENV-002
318
+ ```
319
+
320
+ ---
321
+
322
+ ### 6. Subsystem-Focused Scans
323
+ Run focused audits on specific components when troubleshooting or in modular CI pipelines:
324
+
325
+ ```bash
326
+ # Check dependencies only (conflicts, missing, unused, incompatible Python)
327
+ qv dependency
328
+
329
+ # Check environment drift only (interpreter version, Dockerfile, CI matrix)
330
+ qv environment
331
+
332
+ # Check AST & imports only (circular import loops, unresolvable modules)
333
+ qv architecture
334
+ ```
335
+
336
+ ---
337
+
338
+ ### 7. `qv init` — Project Configuration Setup
339
+ Initialize or update `pyproject.toml` with default `[tool.qv]` configuration rules and path exclusions without overwriting existing settings.
340
+
341
+ ```bash
342
+ # Initialize [tool.qv] in pyproject.toml
343
+ qv init
344
+ ```
345
+
346
+ ---
347
+
348
+ ### 8. `qv version` — Version Information
349
+ ```bash
350
+ qv version
351
+ # or
352
+ qv --version
353
+ ```
354
+
355
+ 👉 *See full option matrices in the [CLI Reference](docs/cli_reference.md).*
356
+
357
+ ---
358
+
359
+ ## ⚙️ Configuration
360
+
361
+ Configure `qv` in your `pyproject.toml`:
362
+
363
+ ```toml
364
+ [tool.qv]
365
+
366
+ # Override severity for any rule (error, warning, info, off)
367
+ [tool.qv.rules]
368
+ DEP-001 = "error"
369
+ DEP-003 = "warning"
370
+ ENV-002 = "info"
371
+
372
+ # Ignore specific rules
373
+ [tool.qv.ignore]
374
+ rules = ["DEP-004"]
375
+
376
+ # Exclude directories from scanning
377
+ [tool.qv.paths]
378
+ exclude = [
379
+ ".venv",
380
+ "build",
381
+ "dist",
382
+ "legacy_scripts",
383
+ ]
384
+
385
+ # Set expected target Python version
386
+ [tool.qv.runtime]
387
+ python = "3.12"
388
+ ```
389
+
390
+ 👉 *Learn more in the [Configuration Guide](docs/configuration.md).*
391
+
392
+ ---
393
+
394
+ ## 🤖 CI/CD Integration
395
+
396
+ ### Official GitHub Action
397
+
398
+ You can use the official `qv` GitHub Action directly in `.github/workflows/ci.yml`:
399
+
400
+ ```yaml
401
+ name: Health & Dependency Scan
402
+
403
+ on: [push, pull_request]
404
+
405
+ jobs:
406
+ qv:
407
+ runs-on: ubuntu-latest
408
+ steps:
409
+ - uses: actions/checkout@v4
410
+ - name: Run qv Health Scan
411
+ uses: inzamol/qv@v1
412
+ with:
413
+ strict: true
414
+ html_report: report.html
415
+ sarif_report: qv.sarif
416
+ github_annotations: true
417
+ ```
418
+
419
+ ### GitHub Actions (Manual setup with SARIF code scanning)
420
+
421
+ ```yaml
422
+ name: Health & Dependency Scan
423
+
424
+ on: [push, pull_request]
425
+
426
+ jobs:
427
+ qv:
428
+ runs-on: ubuntu-latest
429
+ steps:
430
+ - uses: actions/checkout@v4
431
+ - uses: astral-sh/setup-uv@v3
432
+
433
+ # Run scan with PR annotations
434
+ - name: Run qv
435
+ run: uv run qv scan --ci --github-annotations
436
+
437
+ # Generate SARIF report for GitHub Code Scanning
438
+ - name: Generate SARIF report
439
+ run: uv run qv scan --sarif -o qv.sarif
440
+ if: always()
441
+
442
+ - name: Upload SARIF to GitHub Security
443
+ uses: github/codeql-action/upload-sarif@v3
444
+ with:
445
+ sarif_file: qv.sarif
446
+ if: always()
447
+ ```
448
+
449
+ ### Pre-commit Hook Integration
450
+
451
+ Add `qv` directly to your `.pre-commit-config.yaml` to catch dependency drift and circular imports before committing:
452
+
453
+ ```yaml
454
+ repos:
455
+ - repo: https://github.com/inzamol/qv
456
+ rev: v0.1.0
457
+ hooks:
458
+ # Diagnose health before committing
459
+ - id: qv-scan
460
+ args: [--strict, --offline]
461
+
462
+ # Optional: Auto-remediate safe issues on commit
463
+ # - id: qv-fix
464
+ ```
465
+
466
+ 👉 *See full details in [CI/CD & Pre-commit Integration](docs/ci_integration.md).*
467
+
468
+ ---
469
+
470
+ ## 🎯 Design Principles
471
+
472
+ - **Diagnose first. Explain second. Fix safely.**
473
+ - **No destructive auto-mutations**: Remediations provide the exact commands/diffs for you to review and apply.
474
+ - **Local-first & Blazing fast**: Zero network calls required; scans complete in under a second.
475
+ - **Package-manager agnostic**: Works out of the box with `uv`, Poetry, `pip`, PDM, and Pipenv.
476
+
477
+ ---
478
+
479
+ ## 📚 Complete Documentation
480
+
481
+ - 🚀 [Getting Started Guide](docs/getting_started.md)
482
+ - 📖 [CLI Reference](docs/cli_reference.md)
483
+ - 📋 [Diagnostic Rules Catalog](docs/rules.md)
484
+ - ⚙️ [Configuration Guide](docs/configuration.md)
485
+ - 🤖 [CI/CD & SARIF Integration](docs/ci_integration.md)
486
+ - 🤝 [Contributing Guidelines](docs/contributing.md)
487
+
488
+ ---
489
+
490
+ ## 📄 License
491
+
492
+ Distributed under the [MIT License](LICENSE).
@@ -0,0 +1,46 @@
1
+ qv/__init__.py,sha256=ytQrd73EtfTFFFPArsLrgOJNI9NNyUwp_B8_rlbd-Fg,100
2
+ qv/__main__.py,sha256=tG1eQDuox_m4xSLYLEC8KXwxKhL-IJno7CsCgdrw9Bs,112
3
+ qv/analyzers/__init__.py,sha256=_d-1_NpNFMDu1cT-SqTKRBBeipboWZlRt5zZ0tsVPk0,25
4
+ qv/analyzers/ci/__init__.py,sha256=W0Kr4IJBwjysEJPY-D3wNeDMWVFOFQzZt71LIzRDGfY,20
5
+ qv/analyzers/dependencies/__init__.py,sha256=AfzPubOgDrmbfPVe8I5egJ6tswolYzWsDwXjW-Maqhg,129
6
+ qv/analyzers/dependencies/analyzer.py,sha256=ENQPbqhzb7YxNqqz9rStoii2TMTLEEB1BXK9uc9ghAc,15022
7
+ qv/analyzers/docker/__init__.py,sha256=zQsRHV9IiRbjpb9AKmKzaMPtlXp1iSQCBSvyKDo-2q8,24
8
+ qv/analyzers/environment/__init__.py,sha256=5EtSq3sQIJJxKAfpwWiCul3VHWMA94y3-QBi5pjHVb8,128
9
+ qv/analyzers/environment/drift.py,sha256=ZPWCsGMr-vLjIoOnt97fCSgQfwsL_C8z36OfxGiyw-g,10267
10
+ qv/analyzers/imports/__init__.py,sha256=bShRWSwJunl5mbkHI738-jTut0RGStVQhtdzCae-fuo,112
11
+ qv/analyzers/imports/analyzer.py,sha256=a6pOHZ35SK6fpZwiSg0oup60yObPk-Tk80CP_KRA_tA,14580
12
+ qv/analyzers/packaging/__init__.py,sha256=owgIeiZUNwhn-gPLbho1jCqA72cg1f8u_6wsqDqsgdk,123
13
+ qv/analyzers/packaging/analyzer.py,sha256=-57OYQPsS6uIN8u_1LR2CQRT8sOcDmYYCtGkgFo4jo0,4776
14
+ qv/analyzers/security/__init__.py,sha256=VOpkxOxoC_7HpyuSKJi35y88ErKMtQ9w31HXDkaxhi4,384
15
+ qv/analyzers/security/analyzer.py,sha256=DQAm3kex4v63ta8mFeI0gs4OCDvQYPfECLv1vzaujIQ,4629
16
+ qv/analyzers/security/lockfile_parser.py,sha256=XkrJ-bwkv82wIojFsyzkqe4flCJWIliS1DEJNj9E59M,6565
17
+ qv/analyzers/security/osv_client.py,sha256=Y9s8VeY3dSpUd-VBqOvdSSB8KgBzeti1K8niJY2G8IM,4961
18
+ qv/cli/__init__.py,sha256=EUnPKm0L_oVbU1jAO_Icle4TXMCVGpd_aFTQ4iaueik,88
19
+ qv/cli/main.py,sha256=aiDn3sjPVijPrNrW5YqyFBsO2KEL5h-V4rXhnNzzNP0,18806
20
+ qv/core/analyzer.py,sha256=FPiEjghPbi-RVCOxODE_BRlkvtMsnrgbakhq7-YORuc,503
21
+ qv/core/config.py,sha256=0ARPWbLCV_RJhJZOVomldnuztxeLhkQPPkoiOrTO9Jw,3792
22
+ qv/core/context.py,sha256=kAI_QENd6c9kRiIE5Ejt2Um4MZsQ3TL9ubkl3w5AJF0,2575
23
+ qv/core/engine.py,sha256=foFddOmcSFuLWqmqYdcXWC-6vh_27IsgUF2l7XJrBJ4,4496
24
+ qv/core/models.py,sha256=aQQTmyaBJsdof7oh8Onu2C2DLqQA6YbpLxQ0zB5utXw,4096
25
+ qv/core/project.py,sha256=pHpDbjhYs_8iZiIluXUcj_zwTZPwbKHyXDIWfTxgCFM,18218
26
+ qv/frameworks/__init__.py,sha256=5XnOOPd2Kyb9uG3Z7MjqZO1emDZs5F1sCAmI4yjWMPI,25
27
+ qv/integrations/__init__.py,sha256=xBWG_BBOAn4l43MnjXmhbu4qjiMdYq32pVjmDO0Q8iM,37
28
+ qv/remediation/__init__.py,sha256=oHIxQraTgQVQUZ_kIorPR4t-YDVe7ygpn_dqXq_dmIU,252
29
+ qv/remediation/engine.py,sha256=QkmrHqAyV7Zf1Z0OtWvxySJlzjUxKAmz63bJPiWHlsE,12741
30
+ qv/remediation/models.py,sha256=y8zWfbbhjWCjiBks1cpcvLODNavvnj2sR_uqR1TbjYw,1600
31
+ qv/reporters/__init__.py,sha256=c5HE52PVODdUwtCb_06bugj4aZ9gHqqJ0QaOCt1R1es,381
32
+ qv/reporters/base.py,sha256=LvtGAy5xocwB8gqYuAvFEIO73ov7BwXa06Azj_Pnuu4,329
33
+ qv/reporters/github_annotator.py,sha256=o8Msz9hIhXYtIrqdhCk9aq64sgZjZyz6Yr1cda7ruCI,3480
34
+ qv/reporters/html_reporter.py,sha256=WZHYu_ND1GVNUHjgUK4ts97KPp1DqbkoYp3_-eOgnoU,18142
35
+ qv/reporters/json_reporter.py,sha256=RRzEZAMpOw8HGEVbYV8n_PCJ0PrIvFlOgAGptUxvtvY,446
36
+ qv/reporters/sarif.py,sha256=CZEtjmqB7sNCc4qZJBLtm_7cT_gYa8frI1jl9JHzuyU,3062
37
+ qv/reporters/terminal.py,sha256=H5c5-HMKSZ2PIHx-ZE4XA5bhMH826JHzBav0EKFqU44,4549
38
+ qv/rules/registry.py,sha256=sz-S59_AAE0dzTe4wb77q2xymwQra0mXmEDrXf-FuMo,8596
39
+ qv/tui/__init__.py,sha256=otEuHr1bZ6rRMF2WkgPmv6z2Ws1cmnvFqr9Semhe_6A,100
40
+ qv/tui/app.py,sha256=Db08g5SMYsLZZ4ncrh_9ElIw_TyiRoh5gDiGkoF6mPI,11841
41
+ qv/visualizers/__init__.py,sha256=0kMeoXfdUJalMeZms5EwrFEYMpXmx30dJxITr9ahLCU,132
42
+ qv/visualizers/tree.py,sha256=Jf7w4HZzvxvmCIiGea1PzaUoCKN2ByAVdM8vXLHId-c,8043
43
+ python_qv-0.1.2.dist-info/METADATA,sha256=P7c1fy7JlOGs60A338evg0PvW6EkUwBxhJAcwW_cuPU,16415
44
+ python_qv-0.1.2.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
45
+ python_qv-0.1.2.dist-info/entry_points.txt,sha256=y0aZqfDPndkJ2yXxBM2RLL1qriH72zWEKSj4nJtc2q4,94
46
+ python_qv-0.1.2.dist-info/RECORD,,
qv/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """qv - Package-manager-agnostic diagnostic platform for Python projects."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.1.2"
qv/__main__.py ADDED
@@ -0,0 +1,6 @@
1
+ """Entrypoint for python -m qv execution."""
2
+
3
+ from qv.cli.main import cli
4
+
5
+ if __name__ == "__main__":
6
+ cli()
@@ -12,11 +12,70 @@ from qv.core.context import ProjectContext
12
12
  from qv.core.models import Diagnostic, Evidence, Suggestion
13
13
  from qv.rules.registry import get_rule_definition
14
14
 
15
+ PEP594_REMOVED_MODULES = {
16
+ "distutils",
17
+ "imp",
18
+ "cgi",
19
+ "pipes",
20
+ "asyncore",
21
+ "asynchat",
22
+ "smtpd",
23
+ "crypt",
24
+ "chunk",
25
+ "telnetlib",
26
+ "mailcap",
27
+ "nntplib",
28
+ "audioop",
29
+ }
30
+
31
+ ALL_PYTHON_3_STDLIB = {
32
+ "tomllib", # Added in Python 3.11
33
+ "zoneinfo", # Added in Python 3.9
34
+ "wsgiref",
35
+ "concurrent",
36
+ "ctypes",
37
+ "curses",
38
+ "email",
39
+ "html",
40
+ "mimetypes",
41
+ "tarfile",
42
+ "zipfile",
43
+ "gzip",
44
+ "bz2",
45
+ "lzma",
46
+ "venv",
47
+ "ensurepip",
48
+ "trace",
49
+ "tracemalloc",
50
+ "secrets",
51
+ "token",
52
+ "tokenize",
53
+ "profile",
54
+ "cProfile",
55
+ "pstats",
56
+ "timeit",
57
+ "gc",
58
+ "signal",
59
+ "errno",
60
+ "selectors",
61
+ "sched",
62
+ "queue",
63
+ "site",
64
+ "stat",
65
+ "reprlib",
66
+ "copy",
67
+ "copyreg",
68
+ "fnmatch",
69
+ "linecache",
70
+ "posixpath",
71
+ "ntpath",
72
+ "genericpath",
73
+ }
74
+
15
75
  # Known Python standard library modules (Python 3.10+)
16
76
  STDLIB_MODULES = (
17
- set(sys.stdlib_module_names)
18
- if hasattr(sys, "stdlib_module_names")
19
- else {
77
+ (set(sys.stdlib_module_names) if hasattr(sys, "stdlib_module_names") else set())
78
+ | {
20
79
  "abc",
21
80
  "argparse",
22
81
  "ast",
@@ -70,6 +129,8 @@ STDLIB_MODULES = (
70
129
  "zipfile",
71
130
  "__future__",
72
131
  }
132
+ | ALL_PYTHON_3_STDLIB
133
+ | PEP594_REMOVED_MODULES
73
134
  )
74
135
 
75
136
  # Known tools/packages that may not be imported directly in application code
@@ -185,7 +246,7 @@ class DependencyAnalyzer:
185
246
  context.project_name.lower(),
186
247
  }
187
248
  for sf in context.source_files:
188
- parts = sf.relative_path.parts
249
+ parts = list(sf.relative_path.parts)
189
250
  if parts:
190
251
  if parts[0] in ("src", "lib") and len(parts) > 1:
191
252
  local_modules.add(parts[1].replace(".py", "").lower().replace("-", "_"))