|
1 |
| -# PythonCodeValidator |
| 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?style=flat-square" alt="GitHub Stars"></a> |
| 13 | + <a href="https://github.com/Qu1nel/PythonCodeValidator/network/members"><img src="https://img.shields.io/github/forks/Qu1nel/PythonCodeValidator?style=flat-square" alt="GitHub Forks"></a> |
| 14 | + <a href="https://github.com/Qu1nel/PythonCodeValidator/graphs/contributors"><img src="https://img.shields.io/github/contributors/Qu1nel/PythonCodeValidator?style=flat-square" alt="Contributors"></a> |
| 15 | + <a href="https://github.com/Qu1nel/PythonCodeValidator/issues/"><img src="https://img.shields.io/github/issues/Qu1nel/PythonCodeValidator?style=flat-square" 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?style=flat-square" 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?style=flat-square" 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?style=flat-square" 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.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 | +$$ R_{\text{single}} = S \times C $$ |
| 80 | +With approximately 10 types of selectors and 10 types of constraints, this already provides ~100 unique checks. However, |
| 81 | +the true flexibility comes from logical composition, allowing for a near-infinite number of validation scenarios: |
| 82 | +$$ R_{\text{total}} \approx S \times \sum_{k=1}^{|C|} \binom{|C|}{k} = S \times (2^{|C|} - 1) $$ |
| 83 | +This design provides **thousands of potential validation scenarios** out-of-the-box, offering extreme flexibility with |
| 84 | +minimal complexity. |
| 85 | + |
| 86 | +## ✨ Key Features |
| 87 | + |
| 88 | +- **Declarative JSON Rules**: Define validation logic in a human-readable format. |
| 89 | +- **Powerful Static Analysis**: |
| 90 | + - ✅ Check syntax and PEP8 compliance (`flake8`). |
| 91 | + - ✅ Enforce or forbid specific `import` statements. |
| 92 | + - ✅ Verify class structure, inheritance, and function signatures. |
| 93 | + - ✅ Forbid "magic numbers" or specific function calls like `eval`. |
| 94 | +- **Precise Scoping**: Apply rules globally, or narrowly to a specific function, class, or method. |
| 95 | +- **Extensible Architecture**: Easily add new, custom checks by creating new Selector or Constraint components. |
| 96 | + |
| 97 | +## 🚀 Getting Started |
| 98 | + |
| 99 | +### Installation |
| 100 | + |
| 101 | +**1. For Users (from PyPI):** |
| 102 | + |
| 103 | +Install the package with one command. This will make the `validate-code` command-line tool available. |
| 104 | + |
| 105 | +```bash |
| 106 | +pip install python-code-validator |
| 107 | +``` |
| 108 | + |
| 109 | +**2. For Users (from source):** |
| 110 | + |
| 111 | +If you want to install directly from the repository: |
| 112 | + |
| 113 | +```bash |
| 114 | +git clone https://github.com/Qu1nel/PythonCodeValidator.git |
| 115 | +cd PythonCodeValidator |
| 116 | +pip install . |
| 117 | +``` |
| 118 | + |
| 119 | +**3. For Developers:** |
| 120 | + |
| 121 | +To set up a full development environment, see the [Contributing Guidelines](./CONTRIBUTING.md). |
| 122 | + |
| 123 | +## ⚡ Quick Usage Example |
| 124 | + |
| 125 | +The validator is a command-line tool named `validate-code`. |
| 126 | + |
| 127 | +### Example 1: Simple Check |
| 128 | + |
| 129 | +Let's check if a required function exists. |
| 130 | + |
| 131 | +**`solution_simple.py`:** |
| 132 | + |
| 133 | +```python |
| 134 | +# This file is missing the 'solve' function |
| 135 | +def main(): |
| 136 | + print("Hello") |
| 137 | +``` |
| 138 | + |
| 139 | +**`rules_simple.json`:** |
| 140 | + |
| 141 | +```json |
| 142 | +{ |
| 143 | + "validation_rules": [ |
| 144 | + { |
| 145 | + "rule_id": 1, |
| 146 | + "message": "Required function 'solve' is missing.", |
| 147 | + "check": { |
| 148 | + "selector": { |
| 149 | + "type": "function_def", |
| 150 | + "name": "solve" |
| 151 | + }, |
| 152 | + "constraint": { |
| 153 | + "type": "is_required" |
| 154 | + } |
| 155 | + } |
| 156 | + } |
| 157 | + ] |
| 158 | +} |
| 159 | +``` |
| 160 | + |
| 161 | +**Running the validator:** |
| 162 | + |
| 163 | +```bash |
| 164 | +$ validate-code solution_simple.py rules_simple.json |
| 165 | +Starting validation for: solution_simple.py |
| 166 | +Required function 'solve' is missing. |
| 167 | +Validation failed. |
| 168 | +``` |
| 169 | + |
| 170 | +### Example 2: Advanced Check |
| 171 | + |
| 172 | +Let's enforce a complex rule: "In our game class, the `update` method must not contain any `print` statements." |
| 173 | + |
| 174 | +**`game.py`:** |
| 175 | + |
| 176 | +```python |
| 177 | +import arcade |
| 178 | + |
| 179 | + |
| 180 | +class MyGame(arcade.Window): |
| 181 | + def update(self, delta_time): |
| 182 | + print("Debugging player position...") # Forbidden call |
| 183 | + self.player.x += 1 |
| 184 | +``` |
| 185 | + |
| 186 | +**`rules_advanced.json`:** |
| 187 | + |
| 188 | +```json |
| 189 | +{ |
| 190 | + "validation_rules": [ |
| 191 | + { |
| 192 | + "rule_id": 101, |
| 193 | + "message": "Do not use 'print' inside the 'update' method.", |
| 194 | + "check": { |
| 195 | + "selector": { |
| 196 | + "type": "function_call", |
| 197 | + "name": "print", |
| 198 | + "in_scope": { |
| 199 | + "class": "MyGame", |
| 200 | + "method": "update" |
| 201 | + } |
| 202 | + }, |
| 203 | + "constraint": { |
| 204 | + "type": "is_forbidden" |
| 205 | + } |
| 206 | + } |
| 207 | + } |
| 208 | + ] |
| 209 | +} |
| 210 | +``` |
| 211 | + |
| 212 | +**Running the validator:** |
| 213 | + |
| 214 | +```bash |
| 215 | +$ validate-code game.py rules_advanced.json |
| 216 | +Starting validation for: game.py |
| 217 | +Do not use 'print' inside the 'update' method. |
| 218 | +Validation failed. |
| 219 | +``` |
| 220 | + |
| 221 | +## 📚 Documentation |
| 222 | + |
| 223 | +- **Full User Guide & JSON Specification**: Our complete documentation is hosted on * |
| 224 | + *[Read the Docs](https://[your-project].readthedocs.io)**. |
| 225 | +- **Developer's Guide**: For a deep dive into the architecture, see the **[How It Works guide](./docs/how-it-works.md) |
| 226 | + **. |
| 227 | +- **Interactive AI-Powered Docs**: *(Coming Soon)* An interactive documentation experience. |
| 228 | + |
| 229 | +## 🤝 Contributing |
| 230 | + |
| 231 | +Contributions make the open-source community an amazing place to learn, inspire, and create. Any contributions you make |
| 232 | +are **greatly appreciated**. |
| 233 | + |
| 234 | +Please read our **[Contributing Guidelines](./CONTRIBUTING.md)** to get started. This project adheres to the * |
| 235 | +*[Code of Conduct](./CODE_OF_CONDUCT.md)**. |
| 236 | + |
| 237 | +## 📜 License |
| 238 | + |
| 239 | +Distributed under the MIT License. See `LICENSE` for more information. |
| 240 | + |
| 241 | +--- |
| 242 | + |
| 243 | +### Contact |
| 244 | + |
| 245 | +Developed by **[Ivan Kovach (@Qu1nel)](https://github.com/Qu1nel)**. |
| 246 | + |
| 247 | +Email: **[covach.qn@gmail.com](mailto:covach.qn@gmail.com)** Telegram: **[@qnllnq](https://t.me/qnllnq)** |
| 248 | + |
| 249 | +<br/> |
| 250 | + |
| 251 | +<p align="right"><a href="./LICENSE">MIT</a> © <a href="https://github.com/Qu1nel/">Ivan Kovach</a></p> |
0 commit comments