Semantic checker for AI-generated Python code.
Project description
aicode-verify
Catch AI-generated Python that looks right but breaks at runtime.
aicode-verify checks Python code without executing it. It catches hallucinated imports, wrong keyword arguments, missing required arguments, and common unsafe patterns such as eval, shell=True, hardcoded secrets, unsafe pickle usage, weak hashes, and SQL f-strings.
It is not a formatter. It is not a style linter.
It is a semantic safety net for code written by LLMs, coding agents, and hurried humans.
Why This Exists
AI-generated Python often fails in ways that style linters cannot see:
- imports that sound real but do not exist
- keyword arguments copied from old docs or imagined APIs
- helper functions called with missing arguments
- unsafe shell, SQL, pickle, or secret-handling snippets
aicode-verify focuses on that layer.
Install
pip install aicode-verify
For local development:
pip install -e ".[dev]"
Quickstart
aicode-verify .
aicode-verify src tests --fail-on high
aicode-verify script.py --format json
cat generated.py | aicode-verify --stdin
--fail-on accepts error, high, or medium.
Examples
Wrong keyword argument:
import math
math.sqrt(value=4)
Output:
AV101 ERROR line 3: math.sqrt() does not accept keyword argument 'value'
Suggestion: This callable does not accept keyword arguments
Hallucinated import:
from math import sqrtt
Output:
AV002 ERROR line 1: 'sqrtt' does not exist in 'math'
Suggestion: Did you mean 'sqrt'?
Alias-aware unsafe subprocess usage:
import subprocess as sp
sp.run(user_input, shell=True)
Output:
AV202 HIGH line 3: subprocess with shell=True enables shell injection
Suggestion: Pass a list of arguments instead: subprocess.run(['cmd', 'arg'])
SQL f-string:
query = f"SELECT * FROM users WHERE id = {user_id}"
Output:
AV204 HIGH line 1: SQL query built with f-string; possible injection surface
Suggestion: Use parameterized queries
Why Not Ruff, Mypy, Pyright, Bandit, or Pytest?
Use them. aicode-verify is designed to sit beside them.
Ruff keeps code clean. mypy and pyright reason about types. Bandit checks security smells. pytest proves behavior.
aicode-verify focuses on mistakes that are especially common in AI-generated Python: hallucinated imports, wrong function arguments, missing required parameters, and unsafe snippets.
Configuration
Add configuration to pyproject.toml:
[tool.aicode-verify]
fail-on = "high"
format = "text"
ignore = ["AV206"]
exclude = ["tests/fixtures/**", "migrations/**"]
CLI flags override config values:
aicode-verify . --config pyproject.toml
aicode-verify . --ignore AV203
aicode-verify --explain AV101
Ignore Comments
Suppress one finding on the next line:
# aicode-verify: ignore-next-line AV203
TEST_API_KEY = "fake-key-for-tests"
Suppress the next line for all rules:
# aicode-verify: ignore
eval(expr)
Inline ignores also work:
eval(expr) # aicode-verify: ignore AV201
Rule Reference
| Rule | Meaning |
|---|---|
| AV001 | Imported module cannot be resolved |
| AV002 | Imported symbol does not exist |
| AV101 | Function call uses an unsupported keyword |
| AV102 | Function call is missing a required argument |
| AV201 | Unsafe eval, exec, or compile usage |
| AV202 | Shell command execution risk |
| AV203 | Possible hardcoded secret |
| AV204 | SQL built with an f-string |
| AV205 | Unsafe pickle deserialization |
| AV206 | Weak hash usage |
Python API
from aicode_verify import format_report, verify
source = "import math\nmath.sqrt(value=4)\n"
findings = verify(source, ignore=["AV203"])
print(format_report(findings, source))
Pre-commit
Add this to .pre-commit-config.yaml:
repos:
- repo: https://github.com/Github-Rajesh/AiCode-Verify
rev: v0.2.0
hooks:
- id: aicode-verify
args: ["--fail-on", "high"]
GitHub Actions
name: aicode-verify
on:
pull_request:
push:
jobs:
verify-ai-code:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install aicode-verify
- run: aicode-verify . --fail-on high
Limitations
aicode-verify does not perform full type inference. Chained calls like df.groupby("x").agg(...) are only checked where the root object can be resolved statically. That keeps the tool fast and practical while leaving room for future stub-based inference.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aicode_verify-0.2.0.tar.gz.
File metadata
- Download URL: aicode_verify-0.2.0.tar.gz
- Upload date:
- Size: 12.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e27cd3029800ef711f6d837c4815165b1658b25558cf27b19cabbdcf6aa4ccc
|
|
| MD5 |
d6b89fe5ed0a381c28690c57395cd3f3
|
|
| BLAKE2b-256 |
3d7be7ce70083c4c2dfddb07fe2b8a0714c06baeb57d52f39417d42fe06df651
|
File details
Details for the file aicode_verify-0.2.0-py3-none-any.whl.
File metadata
- Download URL: aicode_verify-0.2.0-py3-none-any.whl
- Upload date:
- Size: 15.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
28b72177087225860a698634212d349251ae9beb8945d0b2333734b550728e50
|
|
| MD5 |
a9ff2e9d34318b3cefa81b4b1c789a88
|
|
| BLAKE2b-256 |
379408827ead2590e16b969b541d4da65deb59c1b4e75d71ca01d1830955688d
|