python-qv 0.1.0__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.
Files changed (53) hide show
  1. python_qv-0.1.0/.github/workflows/ci.yml +37 -0
  2. python_qv-0.1.0/.github/workflows/publish.yml +135 -0
  3. python_qv-0.1.0/.gitignore +61 -0
  4. python_qv-0.1.0/CONTRIBUTING.md +19 -0
  5. python_qv-0.1.0/PKG-INFO +281 -0
  6. python_qv-0.1.0/README.md +248 -0
  7. python_qv-0.1.0/docs/ci_integration.md +68 -0
  8. python_qv-0.1.0/docs/cli_reference.md +100 -0
  9. python_qv-0.1.0/docs/configuration.md +71 -0
  10. python_qv-0.1.0/docs/contributing.md +79 -0
  11. python_qv-0.1.0/docs/getting_started.md +88 -0
  12. python_qv-0.1.0/docs/rules.md +84 -0
  13. python_qv-0.1.0/pyproject.toml +97 -0
  14. python_qv-0.1.0/src/qv/__init__.py +3 -0
  15. python_qv-0.1.0/src/qv/analyzers/__init__.py +1 -0
  16. python_qv-0.1.0/src/qv/analyzers/ci/__init__.py +1 -0
  17. python_qv-0.1.0/src/qv/analyzers/dependencies/__init__.py +5 -0
  18. python_qv-0.1.0/src/qv/analyzers/dependencies/analyzer.py +347 -0
  19. python_qv-0.1.0/src/qv/analyzers/docker/__init__.py +1 -0
  20. python_qv-0.1.0/src/qv/analyzers/environment/__init__.py +5 -0
  21. python_qv-0.1.0/src/qv/analyzers/environment/drift.py +164 -0
  22. python_qv-0.1.0/src/qv/analyzers/imports/__init__.py +5 -0
  23. python_qv-0.1.0/src/qv/analyzers/imports/analyzer.py +160 -0
  24. python_qv-0.1.0/src/qv/analyzers/packaging/__init__.py +5 -0
  25. python_qv-0.1.0/src/qv/analyzers/packaging/analyzer.py +117 -0
  26. python_qv-0.1.0/src/qv/analyzers/security/__init__.py +1 -0
  27. python_qv-0.1.0/src/qv/cli/__init__.py +5 -0
  28. python_qv-0.1.0/src/qv/cli/main.py +253 -0
  29. python_qv-0.1.0/src/qv/core/analyzer.py +21 -0
  30. python_qv-0.1.0/src/qv/core/config.py +122 -0
  31. python_qv-0.1.0/src/qv/core/context.py +105 -0
  32. python_qv-0.1.0/src/qv/core/engine.py +116 -0
  33. python_qv-0.1.0/src/qv/core/models.py +132 -0
  34. python_qv-0.1.0/src/qv/core/project.py +330 -0
  35. python_qv-0.1.0/src/qv/frameworks/__init__.py +1 -0
  36. python_qv-0.1.0/src/qv/integrations/__init__.py +1 -0
  37. python_qv-0.1.0/src/qv/reporters/__init__.py +13 -0
  38. python_qv-0.1.0/src/qv/reporters/base.py +15 -0
  39. python_qv-0.1.0/src/qv/reporters/json_reporter.py +16 -0
  40. python_qv-0.1.0/src/qv/reporters/sarif.py +85 -0
  41. python_qv-0.1.0/src/qv/reporters/terminal.py +126 -0
  42. python_qv-0.1.0/src/qv/rules/registry.py +151 -0
  43. python_qv-0.1.0/tests/analyzers/test_dependencies.py +143 -0
  44. python_qv-0.1.0/tests/analyzers/test_environment.py +68 -0
  45. python_qv-0.1.0/tests/analyzers/test_imports.py +69 -0
  46. python_qv-0.1.0/tests/analyzers/test_packaging.py +67 -0
  47. python_qv-0.1.0/tests/conftest.py +64 -0
  48. python_qv-0.1.0/tests/reporters/test_reporters.py +48 -0
  49. python_qv-0.1.0/tests/test_cli.py +62 -0
  50. python_qv-0.1.0/tests/test_config.py +43 -0
  51. python_qv-0.1.0/tests/test_models.py +52 -0
  52. python_qv-0.1.0/tests/test_rules.py +19 -0
  53. python_qv-0.1.0/uv.lock +562 -0
@@ -0,0 +1,37 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Install uv
20
+ uses: astral-sh/setup-uv@v3
21
+ with:
22
+ version: "latest"
23
+
24
+ - name: Set up Python ${{ matrix.python-version }}
25
+ run: uv python install ${{ matrix.python-version }}
26
+
27
+ - name: Install dependencies
28
+ run: uv sync --all-extras --dev
29
+
30
+ - name: Lint with Ruff
31
+ run: uv run ruff check .
32
+
33
+ - name: Format check with Ruff
34
+ run: uv run ruff format --check .
35
+
36
+ - name: Run tests
37
+ run: uv run pytest --cov=qv --cov-report=term-missing
@@ -0,0 +1,135 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ push:
7
+ tags:
8
+ - "v[0-9]+.[0-9]+.[0-9]+"
9
+ - "v[0-9]+.[0-9]+.[0-9]+-*"
10
+ workflow_dispatch:
11
+ inputs:
12
+ target:
13
+ description: "Target repository (pypi or testpypi)"
14
+ required: true
15
+ default: "pypi"
16
+ type: choice
17
+ options:
18
+ - pypi
19
+ - testpypi
20
+
21
+ concurrency:
22
+ group: ${{ github.workflow }}-${{ github.ref }}
23
+ cancel-in-progress: true
24
+
25
+ jobs:
26
+ validate:
27
+ name: Run Test Suite (Pre-flight)
28
+ runs-on: ubuntu-latest
29
+ strategy:
30
+ fail-fast: false
31
+ matrix:
32
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
33
+
34
+ steps:
35
+ - uses: actions/checkout@v4
36
+
37
+ - name: Install uv
38
+ uses: astral-sh/setup-uv@v5
39
+ with:
40
+ version: "latest"
41
+
42
+ - name: Set up Python ${{ matrix.python-version }}
43
+ run: uv python install ${{ matrix.python-version }}
44
+
45
+ - name: Install dependencies
46
+ run: uv sync --all-extras --dev
47
+
48
+ - name: Lint and type check
49
+ run: |
50
+ uv run ruff check .
51
+ uv run ruff format --check .
52
+
53
+ - name: Run test suite
54
+ run: uv run pytest --cov=qv --cov-report=term-missing
55
+
56
+ build:
57
+ name: Build & Verify Distributions
58
+ needs: [validate]
59
+ runs-on: ubuntu-latest
60
+ permissions:
61
+ contents: read
62
+ id-token: write
63
+ attestations: write
64
+
65
+ steps:
66
+ - uses: actions/checkout@v4
67
+
68
+ - name: Install uv
69
+ uses: astral-sh/setup-uv@v5
70
+ with:
71
+ version: "latest"
72
+
73
+ - name: Build sdist and wheel
74
+ run: uv build
75
+
76
+ - name: Verify package metadata with Twine
77
+ run: uvx twine check --strict dist/*
78
+
79
+ - name: Generate build provenance attestation
80
+ uses: actions/attest-build-provenance@v2
81
+ with:
82
+ subject-path: "dist/*"
83
+
84
+ - name: Store built packages as artifacts
85
+ uses: actions/upload-artifact@v4
86
+ with:
87
+ name: python-package-distributions
88
+ path: dist/
89
+ if-no-files-found: error
90
+
91
+ publish-to-pypi:
92
+ name: Publish to PyPI
93
+ needs: [build]
94
+ if: (github.event_name == 'release' && github.event.action == 'published') || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) || (github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'pypi')
95
+ runs-on: ubuntu-latest
96
+ environment:
97
+ name: pypi
98
+ url: https://pypi.org/p/python-qv
99
+ permissions:
100
+ id-token: write # Mandatory for PyPI Trusted Publishing (OIDC)
101
+
102
+ steps:
103
+ - name: Download distribution packages
104
+ uses: actions/download-artifact@v4
105
+ with:
106
+ name: python-package-distributions
107
+ path: dist/
108
+
109
+ - name: Publish package to PyPI
110
+ uses: pypa/gh-action-pypi-publish@release/v1
111
+ with:
112
+ attestations: true
113
+
114
+ publish-to-testpypi:
115
+ name: Publish to TestPyPI
116
+ needs: [build]
117
+ if: github.event_name == 'workflow_dispatch' && github.event.inputs.target == 'testpypi'
118
+ runs-on: ubuntu-latest
119
+ environment:
120
+ name: testpypi
121
+ url: https://test.pypi.org/p/python-qv
122
+ permissions:
123
+ id-token: write # Mandatory for Trusted Publishing (OIDC)
124
+
125
+ steps:
126
+ - name: Download distribution packages
127
+ uses: actions/download-artifact@v4
128
+ with:
129
+ name: python-package-distributions
130
+ path: dist/
131
+
132
+ - name: Publish package to TestPyPI
133
+ uses: pypa/gh-action-pypi-publish@release/v1
134
+ with:
135
+ repository-url: https://test.pypi.org/legacy/
@@ -0,0 +1,61 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # Virtual environments
30
+ .env
31
+ .venv
32
+ env/
33
+ venv/
34
+ ENV/
35
+ env.bak/
36
+ venv.bak/
37
+
38
+ # Testing and linting
39
+ .pytest_cache/
40
+ .coverage
41
+ htmlcov/
42
+ .tox/
43
+ .nox/
44
+ .ruff_cache/
45
+ .mypy_cache/
46
+ .pyright/
47
+
48
+ # IDEs and editors
49
+ .vscode/
50
+ .idea/
51
+ *.swp
52
+ *.swo
53
+ *~
54
+
55
+ # OS artifacts
56
+ .DS_Store
57
+ Thumbs.db
58
+
59
+ # Internal developer design docs
60
+ dev_docs/
61
+
@@ -0,0 +1,19 @@
1
+ # Contributing to qv
2
+
3
+ Thank you for contributing to `qv`!
4
+
5
+ Please check our detailed [Contributor Guide](docs/contributing.md) for instructions on setting up your local environment, running tests, and adding new diagnostic rules.
6
+
7
+ ## Quick Commands
8
+
9
+ ```bash
10
+ # Setup
11
+ uv sync --extra dev
12
+
13
+ # Run test suite
14
+ uv run pytest
15
+
16
+ # Format and lint
17
+ uv run ruff check .
18
+ uv run ruff format .
19
+ ```
@@ -0,0 +1,281 @@
1
+ Metadata-Version: 2.5
2
+ Name: python-qv
3
+ Version: 0.1.0
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://github.com/inzamol/qv#readme
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: pyright>=1.1.350; extra == 'dev'
29
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
30
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
31
+ Requires-Dist: ruff>=0.4.0; extra == 'dev'
32
+ Description-Content-Type: text/markdown
33
+
34
+ # 🔍 qv
35
+
36
+ <div align="center">
37
+
38
+ **Diagnose why your Python project is unhealthy — understand the root cause and get safe, actionable fixes.**
39
+
40
+ [![PyPI Version](https://img.shields.io/pypi/v/python-qv.svg?color=blue)](https://pypi.org/project/python-qv/)
41
+ [![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/)
42
+ [![CI Status](https://github.com/inzamol/qv/actions/workflows/ci.yml/badge.svg)](https://github.com/inzamol/qv/actions/workflows/ci.yml)
43
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
44
+
45
+ [Installation](#-installation) • [Quick Start](#-quick-start) • [Features](#-what-it-detects) • [CLI Commands](#-cli-commands) • [CI/CD Integration](#-cicd-integration) • [Documentation](docs/getting_started.md)
46
+
47
+ </div>
48
+
49
+ ---
50
+
51
+ ## 💡 Why qv?
52
+
53
+ Python projects rarely fail because of Python syntax. They fail because of **ecosystem friction**:
54
+ - Incompatible transitive dependency constraints that break your resolver.
55
+ - Missing dependencies you forgot to add to `pyproject.toml`.
56
+ - Docker containers running Python 3.10 while your team develops on 3.12.
57
+ - Silent circular imports that only crash at runtime when certain modules load.
58
+
59
+ 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.
60
+
61
+ ```text
62
+ 🔍 qv
63
+ Project: payment-service
64
+ Python: 3.12.7
65
+ Package Manager: uv
66
+
67
+ 🔴 1 Errors 🟡 1 Warnings 🟢 48 Checks Passed
68
+
69
+ ┌────────────────── 🔴 DEP-001 Dependency constraint conflict ─────────────────┐
70
+ │ celery 5.4.0 requires kombu<5.4.0,>=5.3.0, but installed is kombu 5.5.2. │
71
+ │ │
72
+ │ Evidence: │
73
+ │ • celery declared requirement: kombu<5.4.0,>=5.3.0 │
74
+ │ • Installed kombu version: 5.5.2 in active environment │
75
+ │ │
76
+ │ Suggested fix: │
77
+ │ Upgrade celery or pin kombu to <5.4.0,>=5.3.0. │
78
+ │ $ uv add 'kombu<5.4.0,>=5.3.0' │
79
+ └──────────────────────────────────────────────────────────────────────────────┘
80
+
81
+ Health Score: 85/100
82
+ ```
83
+
84
+ ---
85
+
86
+ ## 📦 Installation
87
+
88
+ Install `python-qv` into your virtual environment (provides the `qv` CLI):
89
+
90
+ ```bash
91
+ # Using pip
92
+ pip install python-qv
93
+
94
+ # Using uv
95
+ uv add python-qv --dev
96
+
97
+ # Run directly without installing (via uvx or pipx)
98
+ uvx python-qv scan
99
+ # or
100
+ pipx run python-qv scan
101
+ ```
102
+
103
+ ---
104
+
105
+ ## 🚀 Quick Start
106
+
107
+ ### 1. Run a Health Scan
108
+
109
+ Run `qv scan` inside any Python repository:
110
+
111
+ ```bash
112
+ qv scan
113
+ ```
114
+
115
+ ### 2. Understand Any Flagged Issue
116
+
117
+ Need more context on why a rule triggered? Run `explain`:
118
+
119
+ ```bash
120
+ qv explain DEP-001
121
+ ```
122
+
123
+ ### 3. Add Project Configuration
124
+
125
+ To add default configuration to your `pyproject.toml`:
126
+
127
+ ```bash
128
+ qv init
129
+ ```
130
+
131
+ ---
132
+
133
+ ## 🔍 What It Detects
134
+
135
+ | Category | Rule ID | Description | Default Severity |
136
+ |---|---|---|---|
137
+ | **Dependencies** | `DEP-001` | Incompatible package version constraints across dependency tree | `ERROR` |
138
+ | | `DEP-002` | Third-party packages imported in code but missing from `pyproject.toml` | `ERROR` |
139
+ | | `DEP-003` | Declared dependencies that are never imported anywhere in project | `WARNING` |
140
+ | | `DEP-004` | Package requires a Python version incompatible with target runtime | `WARNING` |
141
+ | | `DEP-005` | Installed virtualenv version does not match declared manifest pin | `WARNING` |
142
+ | **Environment** | `ENV-001` | Active interpreter version differs from project `requires-python` | `WARNING` |
143
+ | | `ENV-002` | Dockerfile base image Python version differs from project runtime | `WARNING` |
144
+ | | `ENV-003` | CI matrix does not cover the Python versions declared in project | `WARNING` |
145
+ | **Architecture** | `IMP-001` | Circular import cycles across local modules | `ERROR` |
146
+ | | `IMP-002` | Unresolved relative or internal module imports | `ERROR` |
147
+ | **Packaging** | `PKG-001` | Missing PEP 621 metadata (name, version, etc.) | `WARNING` |
148
+ | | `PKG-002` | Invalid syntax or malformed keys in `pyproject.toml` | `ERROR` |
149
+
150
+ 👉 *See full explanations and remediation steps in the [Rules Catalog](docs/rules.md).*
151
+
152
+ ---
153
+
154
+ ## 🛠️ CLI Commands
155
+
156
+ ```bash
157
+ # Full project diagnostic scan
158
+ qv scan
159
+
160
+ # Scan another folder
161
+ qv scan ./services/billing
162
+
163
+ # Strict mode: fail CI on warnings as well as errors
164
+ qv scan --strict
165
+
166
+ # Output machine-readable formats
167
+ qv scan --json
168
+ qv scan --sarif -o results.sarif
169
+
170
+ # Run focused subsystem scans
171
+ qv dependency # Check package constraints & imports
172
+ qv environment # Check Python, Docker & CI version drift
173
+ qv architecture # Check for circular imports & dead paths
174
+
175
+ # Explain a rule
176
+ qv explain DEP-002
177
+
178
+ # Check installed version
179
+ qv version
180
+ ```
181
+
182
+ 👉 *See detailed options in the [CLI Reference](docs/cli_reference.md).*
183
+
184
+ ---
185
+
186
+ ## ⚙️ Configuration
187
+
188
+ Configure `qv` in your `pyproject.toml`:
189
+
190
+ ```toml
191
+ [tool.qv]
192
+
193
+ # Override severity for any rule (error, warning, info, off)
194
+ [tool.qv.rules]
195
+ DEP-001 = "error"
196
+ DEP-003 = "warning"
197
+ ENV-002 = "info"
198
+
199
+ # Ignore specific rules
200
+ [tool.qv.ignore]
201
+ rules = ["DEP-004"]
202
+
203
+ # Exclude directories from scanning
204
+ [tool.qv.paths]
205
+ exclude = [
206
+ ".venv",
207
+ "build",
208
+ "dist",
209
+ "legacy_scripts",
210
+ ]
211
+
212
+ # Set expected target Python version
213
+ [tool.qv.runtime]
214
+ python = "3.12"
215
+ ```
216
+
217
+ 👉 *Learn more in the [Configuration Guide](docs/configuration.md).*
218
+
219
+ ---
220
+
221
+ ## 🤖 CI/CD Integration
222
+
223
+ ### GitHub Actions (with SARIF code scanning)
224
+
225
+ Add this step to your GitHub Actions workflow (`.github/workflows/ci.yml`):
226
+
227
+ ```yaml
228
+ name: Health & Dependency Scan
229
+
230
+ on: [push, pull_request]
231
+
232
+ jobs:
233
+ qv:
234
+ runs-on: ubuntu-latest
235
+ steps:
236
+ - uses: actions/checkout@v4
237
+ - uses: astral-sh/setup-uv@v3
238
+
239
+ # Run scan in CI mode
240
+ - name: Run qv
241
+ run: uv run qv scan --ci
242
+
243
+ # Optional: Generate SARIF report for GitHub Code Scanning
244
+ - name: Generate SARIF report
245
+ run: uv run qv scan --sarif -o qv.sarif
246
+ if: always()
247
+
248
+ - name: Upload SARIF to GitHub Security
249
+ uses: github/codeql-action/upload-sarif@v3
250
+ with:
251
+ sarif_file: qv.sarif
252
+ if: always()
253
+ ```
254
+
255
+ 👉 *See full details in [CI/CD Integration](docs/ci_integration.md).*
256
+
257
+ ---
258
+
259
+ ## 🎯 Design Principles
260
+
261
+ - **Diagnose first. Explain second. Fix safely.**
262
+ - **No destructive auto-mutations**: Remediations provide the exact commands/diffs for you to review and apply.
263
+ - **Local-first & Blazing fast**: Zero network calls required; scans complete in under a second.
264
+ - **Package-manager agnostic**: Works out of the box with `uv`, Poetry, `pip`, PDM, and Pipenv.
265
+
266
+ ---
267
+
268
+ ## 📚 Complete Documentation
269
+
270
+ - 🚀 [Getting Started Guide](docs/getting_started.md)
271
+ - 📖 [CLI Reference](docs/cli_reference.md)
272
+ - 📋 [Diagnostic Rules Catalog](docs/rules.md)
273
+ - ⚙️ [Configuration Guide](docs/configuration.md)
274
+ - 🤖 [CI/CD & SARIF Integration](docs/ci_integration.md)
275
+ - 🤝 [Contributing Guidelines](docs/contributing.md)
276
+
277
+ ---
278
+
279
+ ## 📄 License
280
+
281
+ Distributed under the [MIT License](LICENSE).