python-code-validator 0.1.1__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.
- python_code_validator-0.1.1/LICENSE +21 -0
- python_code_validator-0.1.1/PKG-INFO +308 -0
- python_code_validator-0.1.1/README.md +256 -0
- python_code_validator-0.1.1/pyproject.toml +61 -0
- python_code_validator-0.1.1/setup.cfg +4 -0
- python_code_validator-0.1.1/src/code_validator/__init__.py +25 -0
- python_code_validator-0.1.1/src/code_validator/__main__.py +11 -0
- python_code_validator-0.1.1/src/code_validator/cli.py +88 -0
- python_code_validator-0.1.1/src/code_validator/components/__init__.py +0 -0
- python_code_validator-0.1.1/src/code_validator/components/ast_utils.py +40 -0
- python_code_validator-0.1.1/src/code_validator/components/definitions.py +88 -0
- python_code_validator-0.1.1/src/code_validator/components/factories.py +243 -0
- python_code_validator-0.1.1/src/code_validator/components/scope_handler.py +59 -0
- python_code_validator-0.1.1/src/code_validator/config.py +99 -0
- python_code_validator-0.1.1/src/code_validator/core.py +100 -0
- python_code_validator-0.1.1/src/code_validator/exceptions.py +48 -0
- python_code_validator-0.1.1/src/code_validator/output.py +90 -0
- python_code_validator-0.1.1/src/code_validator/rules_library/__init__.py +0 -0
- python_code_validator-0.1.1/src/code_validator/rules_library/basic_rules.py +167 -0
- python_code_validator-0.1.1/src/code_validator/rules_library/constraint_logic.py +257 -0
- python_code_validator-0.1.1/src/code_validator/rules_library/selector_nodes.py +319 -0
- python_code_validator-0.1.1/src/python_code_validator.egg-info/PKG-INFO +308 -0
- python_code_validator-0.1.1/src/python_code_validator.egg-info/SOURCES.txt +28 -0
- python_code_validator-0.1.1/src/python_code_validator.egg-info/dependency_links.txt +1 -0
- python_code_validator-0.1.1/src/python_code_validator.egg-info/entry_points.txt +2 -0
- python_code_validator-0.1.1/src/python_code_validator.egg-info/requires.txt +13 -0
- python_code_validator-0.1.1/src/python_code_validator.egg-info/top_level.txt +1 -0
- python_code_validator-0.1.1/tests/test_components.py +215 -0
- python_code_validator-0.1.1/tests/test_scope_handler.py +41 -0
- python_code_validator-0.1.1/tests/test_validator.py +336 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Ivan Kovach
|
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.
|
@@ -0,0 +1,308 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: python-code-validator
|
3
|
+
Version: 0.1.1
|
4
|
+
Summary: A flexible framework for static validation of Python code based on JSON rules.
|
5
|
+
Author-email: Qu1nel <covach.qn@gmail.com>
|
6
|
+
License: MIT License
|
7
|
+
|
8
|
+
Copyright (c) 2025 Ivan Kovach
|
9
|
+
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
12
|
+
in the Software without restriction, including without limitation the rights
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
15
|
+
furnished to do so, subject to the following conditions:
|
16
|
+
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
18
|
+
copies or substantial portions of the Software.
|
19
|
+
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
26
|
+
SOFTWARE.
|
27
|
+
|
28
|
+
Project-URL: Homepage, https://github.com/Qu1nel/PythonCodeValidator
|
29
|
+
Project-URL: Bug Tracker, https://github.com/Qu1nel/PythonCodeValidator/issues
|
30
|
+
Keywords: validation,linter,static analysis,testing,education
|
31
|
+
Classifier: Development Status :: 3 - Alpha
|
32
|
+
Classifier: Programming Language :: Python :: 3
|
33
|
+
Classifier: Programming Language :: Python :: 3.11
|
34
|
+
Classifier: Programming Language :: Python :: 3.12
|
35
|
+
Classifier: License :: OSI Approved :: MIT License
|
36
|
+
Classifier: Operating System :: OS Independent
|
37
|
+
Requires-Python: >=3.11
|
38
|
+
Description-Content-Type: text/markdown
|
39
|
+
License-File: LICENSE
|
40
|
+
Provides-Extra: dev
|
41
|
+
Requires-Dist: ruff>=0.4.0; extra == "dev"
|
42
|
+
Requires-Dist: flake8>=7.0.0; extra == "dev"
|
43
|
+
Requires-Dist: build; extra == "dev"
|
44
|
+
Requires-Dist: twine; extra == "dev"
|
45
|
+
Requires-Dist: coverage>=7.5.0; extra == "dev"
|
46
|
+
Provides-Extra: docs
|
47
|
+
Requires-Dist: sphinx>=7.0.0; extra == "docs"
|
48
|
+
Requires-Dist: furo; extra == "docs"
|
49
|
+
Requires-Dist: myst-parser; extra == "docs"
|
50
|
+
Requires-Dist: sphinx-design; extra == "docs"
|
51
|
+
Dynamic: license-file
|
52
|
+
|
53
|
+
<div align="center">
|
54
|
+
<br/>
|
55
|
+
<!-- <img src=".github/assets/logo.png" alt="logo" width="200" height="auto" /> -->
|
56
|
+
<h1>Python Code Validator</h1>
|
57
|
+
<p>
|
58
|
+
<b>A flexible, AST-based framework for static validation of Python code using declarative JSON rules.</b>
|
59
|
+
</p>
|
60
|
+
<br/>
|
61
|
+
|
62
|
+
<!-- Badges -->
|
63
|
+
<p>
|
64
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/stargazers"><img src="https://img.shields.io/github/stars/Qu1nel/PythonCodeValidator" alt="GitHub Stars"></a>
|
65
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/network/members"><img src="https://img.shields.io/github/forks/Qu1nel/PythonCodeValidator" alt="GitHub Forks"></a>
|
66
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/graphs/contributors"><img src="https://img.shields.io/github/contributors/Qu1nel/PythonCodeValidator" alt="Contributors"></a>
|
67
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/issues/"><img src="https://img.shields.io/github/issues/Qu1nel/PythonCodeValidator" alt="Open Issues"></a>
|
68
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/commits/main"><img src="https://img.shields.io/github/last-commit/Qu1nel/PythonCodeValidator" alt="Last Commit"></a>
|
69
|
+
</p>
|
70
|
+
<p>
|
71
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/actions/workflows/ci.yml"><img src="https://github.com/Qu1nel/PythonCodeValidator/actions/workflows/ci.yml/badge.svg" alt="CI Status"></a>
|
72
|
+
<a href="https://app.codecov.io/gh/Qu1nel/PythonCodeValidator"><img src="https://codecov.io/gh/Qu1nel/PythonCodeValidator/graph/badge.svg" alt="Coverage"></a>
|
73
|
+
<a href="https://pypi.org/project/python-code-validator/"><img src="https://img.shields.io/pypi/v/python-code-validator.svg" alt="PyPI Version"></a>
|
74
|
+
<a href="https://pypi.org/project/python-code-validator/"><img src="https://img.shields.io/pypi/pyversions/python-code-validator.svg" alt="Python Versions"></a>
|
75
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/blob/main/LICENSE"><img src="https://img.shields.io/github/license/Qu1nel/PythonCodeValidator" alt="License"></a>
|
76
|
+
</p>
|
77
|
+
|
78
|
+
<h4>
|
79
|
+
<a href="#-quick-usage-example">Usage Examples</a>
|
80
|
+
<span>·</span>
|
81
|
+
<a href="https://[your-project].readthedocs.io">Full Documentation</a>
|
82
|
+
<span>·</span>
|
83
|
+
<a href="#">AI documentation</a>
|
84
|
+
<span>·</span>
|
85
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/blob/main/docs/how_it_works/index.md">Developer's Guide</a>
|
86
|
+
<span>·</span>
|
87
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/issues/new?template=1-bug-report.md">Report a Bug</a>
|
88
|
+
<span>·</span>
|
89
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/issues/new?template=4-feature-request.md">Request Feature</a>
|
90
|
+
</h4>
|
91
|
+
</div>
|
92
|
+
|
93
|
+
<br/>
|
94
|
+
|
95
|
+
---
|
96
|
+
|
97
|
+
## Table of Contents
|
98
|
+
|
99
|
+
- [About The Project](#-about-the-project)
|
100
|
+
- [The Power of Combinatorics](#-the-power-of-combinatorics)
|
101
|
+
- [Key Features](#-key-features)
|
102
|
+
- [Getting Started](#-getting-started)
|
103
|
+
- [Installation](#installation)
|
104
|
+
- [Usage Examples](#-quick-usage-example)
|
105
|
+
- [Example 1: Simple Check](#example-1-simple-check)
|
106
|
+
- [Example 2: Advanced Check](#example-2-advanced-check)
|
107
|
+
- [Documentation](#-documentation)
|
108
|
+
- [Contributing](#-contributing)
|
109
|
+
- [License](#-license)
|
110
|
+
- [Contact](#Contact)
|
111
|
+
|
112
|
+
## 📖 About The Project
|
113
|
+
|
114
|
+
**Python Code Validator** is an engine designed for educational platforms and automated testing systems. It solves a key
|
115
|
+
problem: **how to verify that a student's code meets specific structural and stylistic requirements *before* running
|
116
|
+
resource-intensive dynamic tests.**
|
117
|
+
|
118
|
+
Instead of writing complex Python scripts for each new validation rule, you can define them declaratively in a simple,
|
119
|
+
powerful **JSON format**. This allows teachers and curriculum developers to easily create and adapt validation scenarios
|
120
|
+
without deep programming knowledge. The framework analyzes the code's Abstract Syntax Tree (AST), providing a deep and
|
121
|
+
reliable way to enforce best practices.
|
122
|
+
|
123
|
+
## 📈 The Power of Combinatorics
|
124
|
+
|
125
|
+
The framework's power lies in its combinatorial architecture. It is built on a small set of primitive "bricks":
|
126
|
+
**Selectors** ($S$) that define *what* to find in the code, and **Constraints** ($C$) that define *what condition* to
|
127
|
+
check.
|
128
|
+
|
129
|
+
The number of unique validation rules ($R$) is not a sum, but a product of these components. A single rule can be
|
130
|
+
represented as:
|
131
|
+
|
132
|
+
$$R_{\text{single}} = S \times C$$
|
133
|
+
|
134
|
+
With approximately $10$ types of selectors and $10$ types of constraints, this already provides ~$100$ unique checks.
|
135
|
+
However,
|
136
|
+
the true flexibility comes from logical composition, allowing for a near-infinite number of validation scenarios:
|
137
|
+
|
138
|
+
$$R_{\text{total}} \approx S \times \sum_{k=1}^{|C|} \binom{|C|}{k} = S \times (2^{|C|} - 1)$$
|
139
|
+
|
140
|
+
This design provides **thousands of potential validation scenarios** out-of-the-box, offering extreme flexibility with
|
141
|
+
minimal complexity.
|
142
|
+
|
143
|
+
## ✨ Key Features
|
144
|
+
|
145
|
+
- **Declarative JSON Rules**: Define validation logic in a human-readable format.
|
146
|
+
- **Powerful Static Analysis**:
|
147
|
+
- ✅ Check syntax and PEP8 compliance (`flake8`).
|
148
|
+
- ✅ Enforce or forbid specific `import` statements.
|
149
|
+
- ✅ Verify class structure, inheritance, and function signatures.
|
150
|
+
- ✅ Forbid "magic numbers" or specific function calls like `eval`.
|
151
|
+
- **Precise Scoping**: Apply rules globally, or narrowly to a specific function, class, or method.
|
152
|
+
- **Extensible Architecture**: Easily add new, custom checks by creating new Selector or Constraint components.
|
153
|
+
|
154
|
+
## 🚀 Getting Started
|
155
|
+
|
156
|
+
### Installation
|
157
|
+
|
158
|
+
**1. For Users (from PyPI):**
|
159
|
+
|
160
|
+
Install the package with one command. This will make the `validate-code` command-line tool available.
|
161
|
+
|
162
|
+
```bash
|
163
|
+
pip install python-code-validator
|
164
|
+
```
|
165
|
+
|
166
|
+
**2. For Users (from source):**
|
167
|
+
|
168
|
+
If you want to install directly from the repository:
|
169
|
+
|
170
|
+
```bash
|
171
|
+
git clone https://github.com/Qu1nel/PythonCodeValidator.git
|
172
|
+
cd PythonCodeValidator
|
173
|
+
pip install .
|
174
|
+
```
|
175
|
+
|
176
|
+
**3. For Developers:**
|
177
|
+
|
178
|
+
To set up a full development environment, see the [Contributing Guidelines](./CONTRIBUTING.md).
|
179
|
+
|
180
|
+
## ⚡ Quick Usage Example
|
181
|
+
|
182
|
+
The validator is a command-line tool named `validate-code`.
|
183
|
+
|
184
|
+
### Example 1: Simple Check
|
185
|
+
|
186
|
+
Let's check if a required function exists.
|
187
|
+
|
188
|
+
**`solution_simple.py`:**
|
189
|
+
|
190
|
+
```python
|
191
|
+
# This file is missing the 'solve' function
|
192
|
+
def main():
|
193
|
+
print("Hello")
|
194
|
+
```
|
195
|
+
|
196
|
+
**`rules_simple.json`:**
|
197
|
+
|
198
|
+
```json
|
199
|
+
{
|
200
|
+
"validation_rules": [
|
201
|
+
{
|
202
|
+
"rule_id": 1,
|
203
|
+
"message": "Required function 'solve' is missing.",
|
204
|
+
"check": {
|
205
|
+
"selector": {
|
206
|
+
"type": "function_def",
|
207
|
+
"name": "solve"
|
208
|
+
},
|
209
|
+
"constraint": {
|
210
|
+
"type": "is_required"
|
211
|
+
}
|
212
|
+
}
|
213
|
+
}
|
214
|
+
]
|
215
|
+
}
|
216
|
+
```
|
217
|
+
|
218
|
+
**Running the validator:**
|
219
|
+
|
220
|
+
```bash
|
221
|
+
$ validate-code solution_simple.py rules_simple.json
|
222
|
+
Starting validation for: solution_simple.py
|
223
|
+
Required function 'solve' is missing.
|
224
|
+
Validation failed.
|
225
|
+
```
|
226
|
+
|
227
|
+
### Example 2: Advanced Check
|
228
|
+
|
229
|
+
Let's enforce a complex rule: "In our game class, the `update` method must not contain any `print` statements."
|
230
|
+
|
231
|
+
**`game.py`:**
|
232
|
+
|
233
|
+
```python
|
234
|
+
import arcade
|
235
|
+
|
236
|
+
|
237
|
+
class MyGame(arcade.Window):
|
238
|
+
def update(self, delta_time):
|
239
|
+
print("Debugging player position...") # Forbidden call
|
240
|
+
self.player.x += 1
|
241
|
+
```
|
242
|
+
|
243
|
+
**`rules_advanced.json`:**
|
244
|
+
|
245
|
+
```json
|
246
|
+
{
|
247
|
+
"validation_rules": [
|
248
|
+
{
|
249
|
+
"rule_id": 101,
|
250
|
+
"message": "Do not use 'print' inside the 'update' method.",
|
251
|
+
"check": {
|
252
|
+
"selector": {
|
253
|
+
"type": "function_call",
|
254
|
+
"name": "print",
|
255
|
+
"in_scope": {
|
256
|
+
"class": "MyGame",
|
257
|
+
"method": "update"
|
258
|
+
}
|
259
|
+
},
|
260
|
+
"constraint": {
|
261
|
+
"type": "is_forbidden"
|
262
|
+
}
|
263
|
+
}
|
264
|
+
}
|
265
|
+
]
|
266
|
+
}
|
267
|
+
```
|
268
|
+
|
269
|
+
**Running the validator:**
|
270
|
+
|
271
|
+
```bash
|
272
|
+
$ validate-code game.py rules_advanced.json
|
273
|
+
Starting validation for: game.py
|
274
|
+
Do not use 'print' inside the 'update' method.
|
275
|
+
Validation failed.
|
276
|
+
```
|
277
|
+
|
278
|
+
## 📚 Documentation
|
279
|
+
|
280
|
+
- **Full User Guide & JSON Specification**: Our complete documentation is hosted on
|
281
|
+
**[Read the Docs](https://[your-project].readthedocs.io)**.
|
282
|
+
- **Developer's Guide**: For a deep dive into the architecture, see the
|
283
|
+
**[How It Works guide](./docs/how_it_works/index.md)**.
|
284
|
+
- **Interactive AI-Powered Docs**: *(Coming Soon)* An interactive documentation experience.
|
285
|
+
|
286
|
+
## 🤝 Contributing
|
287
|
+
|
288
|
+
Contributions make the open-source community an amazing place to learn, inspire, and create. Any contributions you make
|
289
|
+
are **greatly appreciated**.
|
290
|
+
|
291
|
+
Please read our **[Contributing Guidelines](./CONTRIBUTING.md)** to get started. This project adheres to the
|
292
|
+
**[Code of Conduct](./CODE_OF_CONDUCT.md)**.
|
293
|
+
|
294
|
+
## 📜 License
|
295
|
+
|
296
|
+
Distributed under the MIT License. See `LICENSE` for more information.
|
297
|
+
|
298
|
+
---
|
299
|
+
|
300
|
+
### Contact
|
301
|
+
|
302
|
+
Developed by **[Ivan Kovach (@Qu1nel)](https://github.com/Qu1nel)**.
|
303
|
+
|
304
|
+
Email: **[covach.qn@gmail.com](mailto:covach.qn@gmail.com)** Telegram: **[@qnllnq](https://t.me/qnllnq)**
|
305
|
+
|
306
|
+
<br/>
|
307
|
+
|
308
|
+
<p align="right"><a href="./LICENSE">MIT</a> © <a href="https://github.com/Qu1nel/">Ivan Kovach</a></p>
|
@@ -0,0 +1,256 @@
|
|
1
|
+
<div align="center">
|
2
|
+
<br/>
|
3
|
+
<!-- <img src=".github/assets/logo.png" alt="logo" width="200" height="auto" /> -->
|
4
|
+
<h1>Python Code Validator</h1>
|
5
|
+
<p>
|
6
|
+
<b>A flexible, AST-based framework for static validation of Python code using declarative JSON rules.</b>
|
7
|
+
</p>
|
8
|
+
<br/>
|
9
|
+
|
10
|
+
<!-- Badges -->
|
11
|
+
<p>
|
12
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/stargazers"><img src="https://img.shields.io/github/stars/Qu1nel/PythonCodeValidator" alt="GitHub Stars"></a>
|
13
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/network/members"><img src="https://img.shields.io/github/forks/Qu1nel/PythonCodeValidator" alt="GitHub Forks"></a>
|
14
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/graphs/contributors"><img src="https://img.shields.io/github/contributors/Qu1nel/PythonCodeValidator" alt="Contributors"></a>
|
15
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/issues/"><img src="https://img.shields.io/github/issues/Qu1nel/PythonCodeValidator" alt="Open Issues"></a>
|
16
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/commits/main"><img src="https://img.shields.io/github/last-commit/Qu1nel/PythonCodeValidator" alt="Last Commit"></a>
|
17
|
+
</p>
|
18
|
+
<p>
|
19
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/actions/workflows/ci.yml"><img src="https://github.com/Qu1nel/PythonCodeValidator/actions/workflows/ci.yml/badge.svg" alt="CI Status"></a>
|
20
|
+
<a href="https://app.codecov.io/gh/Qu1nel/PythonCodeValidator"><img src="https://codecov.io/gh/Qu1nel/PythonCodeValidator/graph/badge.svg" alt="Coverage"></a>
|
21
|
+
<a href="https://pypi.org/project/python-code-validator/"><img src="https://img.shields.io/pypi/v/python-code-validator.svg" alt="PyPI Version"></a>
|
22
|
+
<a href="https://pypi.org/project/python-code-validator/"><img src="https://img.shields.io/pypi/pyversions/python-code-validator.svg" alt="Python Versions"></a>
|
23
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/blob/main/LICENSE"><img src="https://img.shields.io/github/license/Qu1nel/PythonCodeValidator" alt="License"></a>
|
24
|
+
</p>
|
25
|
+
|
26
|
+
<h4>
|
27
|
+
<a href="#-quick-usage-example">Usage Examples</a>
|
28
|
+
<span>·</span>
|
29
|
+
<a href="https://[your-project].readthedocs.io">Full Documentation</a>
|
30
|
+
<span>·</span>
|
31
|
+
<a href="#">AI documentation</a>
|
32
|
+
<span>·</span>
|
33
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/blob/main/docs/how_it_works/index.md">Developer's Guide</a>
|
34
|
+
<span>·</span>
|
35
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/issues/new?template=1-bug-report.md">Report a Bug</a>
|
36
|
+
<span>·</span>
|
37
|
+
<a href="https://github.com/Qu1nel/PythonCodeValidator/issues/new?template=4-feature-request.md">Request Feature</a>
|
38
|
+
</h4>
|
39
|
+
</div>
|
40
|
+
|
41
|
+
<br/>
|
42
|
+
|
43
|
+
---
|
44
|
+
|
45
|
+
## Table of Contents
|
46
|
+
|
47
|
+
- [About The Project](#-about-the-project)
|
48
|
+
- [The Power of Combinatorics](#-the-power-of-combinatorics)
|
49
|
+
- [Key Features](#-key-features)
|
50
|
+
- [Getting Started](#-getting-started)
|
51
|
+
- [Installation](#installation)
|
52
|
+
- [Usage Examples](#-quick-usage-example)
|
53
|
+
- [Example 1: Simple Check](#example-1-simple-check)
|
54
|
+
- [Example 2: Advanced Check](#example-2-advanced-check)
|
55
|
+
- [Documentation](#-documentation)
|
56
|
+
- [Contributing](#-contributing)
|
57
|
+
- [License](#-license)
|
58
|
+
- [Contact](#Contact)
|
59
|
+
|
60
|
+
## 📖 About The Project
|
61
|
+
|
62
|
+
**Python Code Validator** is an engine designed for educational platforms and automated testing systems. It solves a key
|
63
|
+
problem: **how to verify that a student's code meets specific structural and stylistic requirements *before* running
|
64
|
+
resource-intensive dynamic tests.**
|
65
|
+
|
66
|
+
Instead of writing complex Python scripts for each new validation rule, you can define them declaratively in a simple,
|
67
|
+
powerful **JSON format**. This allows teachers and curriculum developers to easily create and adapt validation scenarios
|
68
|
+
without deep programming knowledge. The framework analyzes the code's Abstract Syntax Tree (AST), providing a deep and
|
69
|
+
reliable way to enforce best practices.
|
70
|
+
|
71
|
+
## 📈 The Power of Combinatorics
|
72
|
+
|
73
|
+
The framework's power lies in its combinatorial architecture. It is built on a small set of primitive "bricks":
|
74
|
+
**Selectors** ($S$) that define *what* to find in the code, and **Constraints** ($C$) that define *what condition* to
|
75
|
+
check.
|
76
|
+
|
77
|
+
The number of unique validation rules ($R$) is not a sum, but a product of these components. A single rule can be
|
78
|
+
represented as:
|
79
|
+
|
80
|
+
$$R_{\text{single}} = S \times C$$
|
81
|
+
|
82
|
+
With approximately $10$ types of selectors and $10$ types of constraints, this already provides ~$100$ unique checks.
|
83
|
+
However,
|
84
|
+
the true flexibility comes from logical composition, allowing for a near-infinite number of validation scenarios:
|
85
|
+
|
86
|
+
$$R_{\text{total}} \approx S \times \sum_{k=1}^{|C|} \binom{|C|}{k} = S \times (2^{|C|} - 1)$$
|
87
|
+
|
88
|
+
This design provides **thousands of potential validation scenarios** out-of-the-box, offering extreme flexibility with
|
89
|
+
minimal complexity.
|
90
|
+
|
91
|
+
## ✨ Key Features
|
92
|
+
|
93
|
+
- **Declarative JSON Rules**: Define validation logic in a human-readable format.
|
94
|
+
- **Powerful Static Analysis**:
|
95
|
+
- ✅ Check syntax and PEP8 compliance (`flake8`).
|
96
|
+
- ✅ Enforce or forbid specific `import` statements.
|
97
|
+
- ✅ Verify class structure, inheritance, and function signatures.
|
98
|
+
- ✅ Forbid "magic numbers" or specific function calls like `eval`.
|
99
|
+
- **Precise Scoping**: Apply rules globally, or narrowly to a specific function, class, or method.
|
100
|
+
- **Extensible Architecture**: Easily add new, custom checks by creating new Selector or Constraint components.
|
101
|
+
|
102
|
+
## 🚀 Getting Started
|
103
|
+
|
104
|
+
### Installation
|
105
|
+
|
106
|
+
**1. For Users (from PyPI):**
|
107
|
+
|
108
|
+
Install the package with one command. This will make the `validate-code` command-line tool available.
|
109
|
+
|
110
|
+
```bash
|
111
|
+
pip install python-code-validator
|
112
|
+
```
|
113
|
+
|
114
|
+
**2. For Users (from source):**
|
115
|
+
|
116
|
+
If you want to install directly from the repository:
|
117
|
+
|
118
|
+
```bash
|
119
|
+
git clone https://github.com/Qu1nel/PythonCodeValidator.git
|
120
|
+
cd PythonCodeValidator
|
121
|
+
pip install .
|
122
|
+
```
|
123
|
+
|
124
|
+
**3. For Developers:**
|
125
|
+
|
126
|
+
To set up a full development environment, see the [Contributing Guidelines](./CONTRIBUTING.md).
|
127
|
+
|
128
|
+
## ⚡ Quick Usage Example
|
129
|
+
|
130
|
+
The validator is a command-line tool named `validate-code`.
|
131
|
+
|
132
|
+
### Example 1: Simple Check
|
133
|
+
|
134
|
+
Let's check if a required function exists.
|
135
|
+
|
136
|
+
**`solution_simple.py`:**
|
137
|
+
|
138
|
+
```python
|
139
|
+
# This file is missing the 'solve' function
|
140
|
+
def main():
|
141
|
+
print("Hello")
|
142
|
+
```
|
143
|
+
|
144
|
+
**`rules_simple.json`:**
|
145
|
+
|
146
|
+
```json
|
147
|
+
{
|
148
|
+
"validation_rules": [
|
149
|
+
{
|
150
|
+
"rule_id": 1,
|
151
|
+
"message": "Required function 'solve' is missing.",
|
152
|
+
"check": {
|
153
|
+
"selector": {
|
154
|
+
"type": "function_def",
|
155
|
+
"name": "solve"
|
156
|
+
},
|
157
|
+
"constraint": {
|
158
|
+
"type": "is_required"
|
159
|
+
}
|
160
|
+
}
|
161
|
+
}
|
162
|
+
]
|
163
|
+
}
|
164
|
+
```
|
165
|
+
|
166
|
+
**Running the validator:**
|
167
|
+
|
168
|
+
```bash
|
169
|
+
$ validate-code solution_simple.py rules_simple.json
|
170
|
+
Starting validation for: solution_simple.py
|
171
|
+
Required function 'solve' is missing.
|
172
|
+
Validation failed.
|
173
|
+
```
|
174
|
+
|
175
|
+
### Example 2: Advanced Check
|
176
|
+
|
177
|
+
Let's enforce a complex rule: "In our game class, the `update` method must not contain any `print` statements."
|
178
|
+
|
179
|
+
**`game.py`:**
|
180
|
+
|
181
|
+
```python
|
182
|
+
import arcade
|
183
|
+
|
184
|
+
|
185
|
+
class MyGame(arcade.Window):
|
186
|
+
def update(self, delta_time):
|
187
|
+
print("Debugging player position...") # Forbidden call
|
188
|
+
self.player.x += 1
|
189
|
+
```
|
190
|
+
|
191
|
+
**`rules_advanced.json`:**
|
192
|
+
|
193
|
+
```json
|
194
|
+
{
|
195
|
+
"validation_rules": [
|
196
|
+
{
|
197
|
+
"rule_id": 101,
|
198
|
+
"message": "Do not use 'print' inside the 'update' method.",
|
199
|
+
"check": {
|
200
|
+
"selector": {
|
201
|
+
"type": "function_call",
|
202
|
+
"name": "print",
|
203
|
+
"in_scope": {
|
204
|
+
"class": "MyGame",
|
205
|
+
"method": "update"
|
206
|
+
}
|
207
|
+
},
|
208
|
+
"constraint": {
|
209
|
+
"type": "is_forbidden"
|
210
|
+
}
|
211
|
+
}
|
212
|
+
}
|
213
|
+
]
|
214
|
+
}
|
215
|
+
```
|
216
|
+
|
217
|
+
**Running the validator:**
|
218
|
+
|
219
|
+
```bash
|
220
|
+
$ validate-code game.py rules_advanced.json
|
221
|
+
Starting validation for: game.py
|
222
|
+
Do not use 'print' inside the 'update' method.
|
223
|
+
Validation failed.
|
224
|
+
```
|
225
|
+
|
226
|
+
## 📚 Documentation
|
227
|
+
|
228
|
+
- **Full User Guide & JSON Specification**: Our complete documentation is hosted on
|
229
|
+
**[Read the Docs](https://[your-project].readthedocs.io)**.
|
230
|
+
- **Developer's Guide**: For a deep dive into the architecture, see the
|
231
|
+
**[How It Works guide](./docs/how_it_works/index.md)**.
|
232
|
+
- **Interactive AI-Powered Docs**: *(Coming Soon)* An interactive documentation experience.
|
233
|
+
|
234
|
+
## 🤝 Contributing
|
235
|
+
|
236
|
+
Contributions make the open-source community an amazing place to learn, inspire, and create. Any contributions you make
|
237
|
+
are **greatly appreciated**.
|
238
|
+
|
239
|
+
Please read our **[Contributing Guidelines](./CONTRIBUTING.md)** to get started. This project adheres to the
|
240
|
+
**[Code of Conduct](./CODE_OF_CONDUCT.md)**.
|
241
|
+
|
242
|
+
## 📜 License
|
243
|
+
|
244
|
+
Distributed under the MIT License. See `LICENSE` for more information.
|
245
|
+
|
246
|
+
---
|
247
|
+
|
248
|
+
### Contact
|
249
|
+
|
250
|
+
Developed by **[Ivan Kovach (@Qu1nel)](https://github.com/Qu1nel)**.
|
251
|
+
|
252
|
+
Email: **[covach.qn@gmail.com](mailto:covach.qn@gmail.com)** Telegram: **[@qnllnq](https://t.me/qnllnq)**
|
253
|
+
|
254
|
+
<br/>
|
255
|
+
|
256
|
+
<p align="right"><a href="./LICENSE">MIT</a> © <a href="https://github.com/Qu1nel/">Ivan Kovach</a></p>
|
@@ -0,0 +1,61 @@
|
|
1
|
+
[build-system]
|
2
|
+
requires = ["setuptools>=61.0"]
|
3
|
+
build-backend = "setuptools.build_meta"
|
4
|
+
|
5
|
+
|
6
|
+
[project]
|
7
|
+
name = "python-code-validator"
|
8
|
+
version = "0.1.1"
|
9
|
+
authors = [{ name = "Qu1nel", email = "covach.qn@gmail.com" }]
|
10
|
+
description = "A flexible framework for static validation of Python code based on JSON rules."
|
11
|
+
readme = "README.md"
|
12
|
+
requires-python = ">=3.11"
|
13
|
+
license = { file = "LICENSE" }
|
14
|
+
keywords = ["validation", "linter", "static analysis", "testing", "education"]
|
15
|
+
classifiers = [
|
16
|
+
"Development Status :: 3 - Alpha",
|
17
|
+
"Programming Language :: Python :: 3",
|
18
|
+
"Programming Language :: Python :: 3.11",
|
19
|
+
"Programming Language :: Python :: 3.12",
|
20
|
+
"License :: OSI Approved :: MIT License",
|
21
|
+
"Operating System :: OS Independent",
|
22
|
+
]
|
23
|
+
|
24
|
+
|
25
|
+
[project.urls]
|
26
|
+
"Homepage" = "https://github.com/Qu1nel/PythonCodeValidator"
|
27
|
+
"Bug Tracker" = "https://github.com/Qu1nel/PythonCodeValidator/issues"
|
28
|
+
|
29
|
+
|
30
|
+
[project.scripts]
|
31
|
+
validate-code = "code_validator.cli:run_from_cli"
|
32
|
+
|
33
|
+
|
34
|
+
[project.optional-dependencies]
|
35
|
+
dev = [
|
36
|
+
"ruff>=0.4.0",
|
37
|
+
"flake8>=7.0.0",
|
38
|
+
"build",
|
39
|
+
"twine",
|
40
|
+
"coverage>=7.5.0",
|
41
|
+
]
|
42
|
+
docs = [
|
43
|
+
"sphinx>=7.0.0",
|
44
|
+
"furo",
|
45
|
+
"myst-parser",
|
46
|
+
"sphinx-design",
|
47
|
+
]
|
48
|
+
|
49
|
+
|
50
|
+
[tool.ruff]
|
51
|
+
line-length = 120
|
52
|
+
exclude = ["tests/fixtures"]
|
53
|
+
|
54
|
+
[tool.ruff.lint]
|
55
|
+
select = ["E", "F", "W", "I", "C", "B"]
|
56
|
+
ignore = []
|
57
|
+
mccabe.max-complexity = 15
|
58
|
+
|
59
|
+
|
60
|
+
[tool.ruff.format]
|
61
|
+
quote-style = "double"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
"""A flexible framework for static validation of Python code.
|
2
|
+
|
3
|
+
This package provides a comprehensive toolkit for statically analyzing Python source
|
4
|
+
code based on a declarative set of rules defined in a JSON format. It allows
|
5
|
+
for checking syntax, style, structure, and constraints without executing the code.
|
6
|
+
|
7
|
+
Key components exposed by this package include:
|
8
|
+
- StaticValidator: The main orchestrator for running the validation process.
|
9
|
+
- AppConfig: A dataclass for configuring the validator's behavior.
|
10
|
+
- ExitCode: An Enum defining exit codes for CLI operations.
|
11
|
+
- Custom Exceptions: For fine-grained error handling during validation.
|
12
|
+
"""
|
13
|
+
|
14
|
+
from .config import AppConfig, ExitCode
|
15
|
+
from .core import StaticValidator
|
16
|
+
from .exceptions import RuleParsingError, ValidationFailedError
|
17
|
+
|
18
|
+
__all__ = [
|
19
|
+
"StaticValidator",
|
20
|
+
"AppConfig",
|
21
|
+
"ExitCode",
|
22
|
+
"ValidationFailedError",
|
23
|
+
"RuleParsingError",
|
24
|
+
]
|
25
|
+
__version__ = "0.1.0"
|