pyneat-cli 2.2.2__tar.gz → 2.3.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.
- {pyneat_cli-2.2.2/pyneat_cli.egg-info → pyneat_cli-2.3.0}/PKG-INFO +181 -69
- pyneat_cli-2.3.0/README.md +403 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/__init__.py +17 -2
- pyneat_cli-2.3.0/pyneat/core/__init__.py +59 -0
- pyneat_cli-2.3.0/pyneat/core/manifest.py +403 -0
- pyneat_cli-2.3.0/pyneat/core/marker_cleanup.py +152 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/core/types.py +553 -457
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/__init__.py +63 -60
- pyneat_cli-2.3.0/pyneat/rules/ai_bugs.py +712 -0
- pyneat_cli-2.3.0/pyneat/rules/duplication.py +131 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/naming.py +332 -226
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/performance.py +20 -2
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/typing.py +286 -291
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0/pyneat_cli.egg-info}/PKG-INFO +181 -69
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat_cli.egg-info/SOURCES.txt +4 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyproject.toml +1 -1
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/setup.py +1 -1
- pyneat_cli-2.2.2/README.md +0 -291
- pyneat_cli-2.2.2/pyneat/core/__init__.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/LICENSE +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/__main__.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/benchmark.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/cli.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/config.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/core/atomic.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/core/engine.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/core/scope_guard.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/core/semantic_guard.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/core/type_shield.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/pre_commit.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/base.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/comments.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/conservative.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/dataclass.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/deadcode.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/debug.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/destructive.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/fstring.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/imports.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/init_protection.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/is_not_none.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/isolated.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/magic_numbers.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/match_case.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/quality.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/range_len_pattern.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/redundant.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/refactoring.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/safe.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/security.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/security_pack/__init__.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/security_pack/critical.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/security_pack/high.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/security_pack/info.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/security_pack/low.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/security_pack/medium.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/security_registry.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/rules/unused.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/scanner/rust_scanner.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/tools/__init__.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/tools/github_fuzz/__init__.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/tools/github_fuzz/__main__.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/tools/github_fuzz/debug_logger.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/tools/github_fuzz/fuzz_runner.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/tools/github_fuzz/github_client.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/tools/security/advisory_db.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/tools/security/dependency_scanner.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat/utils/naming.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat_cli.egg-info/dependency_links.txt +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat_cli.egg-info/entry_points.txt +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat_cli.egg-info/requires.txt +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/pyneat_cli.egg-info/top_level.txt +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/setup.cfg +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/tests/test_engine.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/tests/test_fuzz.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/tests/test_fuzz_github.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/tests/test_integration.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/tests/test_layers.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/tests/test_rust_scanner.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/tests/test_semantic_integrity.py +0 -0
- {pyneat_cli-2.2.2 → pyneat_cli-2.3.0}/tests/test_smoke.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyneat-cli
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Neat Python AI Code Cleaner — removes AI-generated code artifacts, dead code, and security vulnerabilities
|
|
5
5
|
License: GNU AGPL-3.0-or-later
|
|
6
6
|
Keywords: ai,code-cleaner,python,linter,formatter,security,dead-code,refactoring,ast,auto-fix
|
|
@@ -32,62 +32,104 @@ Dynamic: license-file
|
|
|
32
32
|
|
|
33
33
|
# PyNeat: The Anti-Spaghetti Code Cleaner
|
|
34
34
|
|
|
35
|
-
**PyNeat 2.
|
|
35
|
+
**PyNeat 2.3.0** is an aggressive, AST-based Python code refactoring tool designed to clean up messy, legacy, or AI-generated code. Unlike standard formatters that only fix whitespace, PyNeat performs deep structural surgery on your logic in a single optimized pass using LibCST.
|
|
36
36
|
|
|
37
37
|
## Features
|
|
38
38
|
|
|
39
|
-
###
|
|
39
|
+
### Package System
|
|
40
|
+
|
|
41
|
+
PyNeat uses a **3-tier package system** to balance safety vs. aggressiveness:
|
|
42
|
+
|
|
43
|
+
| Package | Description | Safety |
|
|
44
|
+
|---------|-------------|--------|
|
|
45
|
+
| `safe` (default) | Always-on rules that won't break code | **100% safe** |
|
|
46
|
+
| `conservative` | Adds cleanup rules, may change style | Safe |
|
|
47
|
+
| `destructive` | Aggressive refactoring, may break code | **Review changes** |
|
|
48
|
+
|
|
49
|
+
### Safe Package (Default — Always On)
|
|
50
|
+
|
|
51
|
+
These rules run automatically, no flags needed:
|
|
40
52
|
|
|
41
53
|
| Rule | Description |
|
|
42
54
|
|------|-------------|
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
55
|
+
| `IsNotNoneRule` | Fixes `x != None` → `x is not None` (PEP8) |
|
|
56
|
+
| `RangeLenRule` | Fixes `range(len())` anti-pattern |
|
|
57
|
+
| `TypingRule` | Suggests type annotations |
|
|
58
|
+
| `CodeQualityRule` | Detects magic numbers, empty except blocks |
|
|
59
|
+
| `PerformanceRule` | Detects inefficient loops |
|
|
60
|
+
| `SecurityScannerRule` | Detects vulnerabilities (os.system, pickle, secrets) |
|
|
48
61
|
|
|
49
|
-
###
|
|
62
|
+
### Conservative Package (`--package conservative`)
|
|
63
|
+
|
|
64
|
+
Adds cleanup rules, safe to use:
|
|
50
65
|
|
|
51
66
|
| Flag | Rule | Description |
|
|
52
67
|
|------|------|-------------|
|
|
53
|
-
| `--enable-
|
|
54
|
-
| `--enable-
|
|
55
|
-
| `--enable-
|
|
56
|
-
| `--enable-
|
|
57
|
-
| `--
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
|
70
|
-
|
|
71
|
-
|
|
|
72
|
-
|
|
|
73
|
-
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
68
|
+
| `--enable-unused` | `UnusedImportRule` | Removes genuinely unused imports |
|
|
69
|
+
| `--enable-fstring` | `FStringRule` | Converts `.format()` to f-strings |
|
|
70
|
+
| `--enable-dataclass` | `DataclassSuggestionRule` | Suggests `@dataclass` decorator |
|
|
71
|
+
| `--enable-magic-numbers` | `MagicNumberRule` | Flags magic numbers |
|
|
72
|
+
| `--safe-debug-clean` | `DebugCleaner` (safe) | Removes debug-like prints |
|
|
73
|
+
|
|
74
|
+
### Destructive Package (`--package destructive`)
|
|
75
|
+
|
|
76
|
+
Aggressive rules that **may break code** — always review changes:
|
|
77
|
+
|
|
78
|
+
| Flag | Rule | Description |
|
|
79
|
+
|------|------|-------------|
|
|
80
|
+
| `--enable-all` | All rules | Enable everything (shortcut) |
|
|
81
|
+
| `--enable-import-cleaning` | `ImportCleaningRule` | Rewrite/reorder all imports |
|
|
82
|
+
| `--enable-naming` | `NamingConventionRule` | Rename classes to PascalCase |
|
|
83
|
+
| `--enable-refactoring` | `RefactoringRule` | Flatten nested if (Arrow Anti-pattern) |
|
|
84
|
+
| `--enable-comment-clean` | `CommentCleaner` | Remove TODO/FIXME comments |
|
|
85
|
+
| `--enable-redundant` | `RedundantExpressionRule` | Simplify `x == True`, `str(str(x))` |
|
|
86
|
+
| `--enable-dead-code` | `DeadCodeRule` | Remove unused functions/classes |
|
|
87
|
+
| `--enable-match-case` | `MatchCaseRule` | Suggest match-case (Python 3.10+) |
|
|
88
|
+
| `--aggressive-clean` | `DebugCleaner` (aggressive) | Remove ALL print calls |
|
|
89
|
+
|
|
90
|
+
## What It Fixes
|
|
91
|
+
|
|
92
|
+
### AgentMarker — Issue Tracking Metadata
|
|
93
|
+
- `AgentMarker` dataclass tracks each issue with full metadata (rule_id, severity, line, CWE, confidence, auto-fix diff)
|
|
94
|
+
- Auto-exports as `# PYNAGENT: {...}` comments in source code
|
|
95
|
+
- `to_dict()`, `to_json()`, `to_comment()` methods for integration
|
|
96
|
+
|
|
97
|
+
### Manifest Export — CI/CD Integration
|
|
98
|
+
- `ManifestExporter` writes `.pyneat.manifest.json` with all markers
|
|
99
|
+
- `export_to_sarif()` — SARIF 2.1.0 format (GitHub Security, Azure DevOps)
|
|
100
|
+
- `export_to_codeclimate()` — Code Climate format
|
|
101
|
+
- `export_to_markdown()` — Human-readable report
|
|
102
|
+
|
|
103
|
+
### MarkerCleanup — Stale Marker Removal
|
|
104
|
+
- `MarkerCleanup` class removes markers after issues are fixed
|
|
105
|
+
- `remove_stale_markers()` — only removes markers not in remaining_issues
|
|
106
|
+
- `remove_all_markers()` — strips all PYNAGENT comments
|
|
107
|
+
|
|
108
|
+
### AI Bug Detection (`AIBugRule`)
|
|
109
|
+
- **Resource Leaks**: `open()` without `with`, `requests` without timeout
|
|
110
|
+
- **Boundary Errors**: `list[0]` without empty check, `.split()[0]`
|
|
111
|
+
- **Phantom Packages**: generic import names (utils, helpers, ai)
|
|
112
|
+
- **Fake Parameters**: `param1=x`, `fake=True`, `dummy_arg`
|
|
113
|
+
- **Redundant I/O**: Same API call 3+ times with identical args
|
|
114
|
+
- **Naming Inconsistency**: Mixed camelCase/snake_case in same file
|
|
115
|
+
|
|
116
|
+
### CLI Enhancements
|
|
117
|
+
- `--package` system: `safe` (default) → `conservative` → `destructive`
|
|
118
|
+
- `--enable-all` — enable all destructive rules at once
|
|
119
|
+
- `--dry-run` + `--diff` — preview changes before writing
|
|
120
|
+
- `--backup` + `--in-place` — safe file modification
|
|
121
|
+
- `--export-manifest` — auto-export PYNAGENT manifest
|
|
122
|
+
|
|
123
|
+
### Pre-commit + GitHub Actions
|
|
124
|
+
- Auto-generate `.pyneat.manifest.json` on commit
|
|
125
|
+
- CI/CD job for automated manifest export on push/PR
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## What It Fixes
|
|
88
130
|
|
|
89
131
|
1. Flattens deeply nested `if/else` (Arrow Anti-pattern)
|
|
90
|
-
2. Converts `x
|
|
132
|
+
2. Converts `x != None` to `x is not None` (PEP8)
|
|
91
133
|
3. Fixes literal identity comparisons (`is 200` to `== 200`)
|
|
92
134
|
4. Upgrades `type(x) == list` to `isinstance()`
|
|
93
135
|
5. Removes debug artifacts: `print()`, `pdb`, `console.log`
|
|
@@ -98,10 +140,11 @@ Dynamic: license-file
|
|
|
98
140
|
10. Simplifies redundant expressions (`x == True` -> `x`)
|
|
99
141
|
11. Auto-fixes `yaml.load()` to use `SafeLoader`
|
|
100
142
|
12. Warns about command injection, pickle RCE, weak crypto
|
|
143
|
+
13. Detects AI-generated code bugs (resource leaks, phantom packages, fake params)
|
|
101
144
|
|
|
102
|
-
### Security Scanning
|
|
145
|
+
### Security Scanning
|
|
103
146
|
|
|
104
|
-
|
|
147
|
+
`SecurityScannerRule` runs automatically in all packages. Detects and auto-fixes vulnerabilities:
|
|
105
148
|
|
|
106
149
|
| Vulnerability | Detection | Auto-fix |
|
|
107
150
|
|-------------|-----------|----------|
|
|
@@ -112,13 +155,14 @@ When enabled, detects and auto-fixes security vulnerabilities in AI-generated co
|
|
|
112
155
|
| Weak Crypto | `random` for tokens, `hashlib.md5/sha1` | Warning only |
|
|
113
156
|
| Pickle Deserialize | `pickle.loads()` | Warning only (RCE risk) |
|
|
114
157
|
| Debug Mode | `DEBUG=True` in production | Warning only |
|
|
115
|
-
| Weak SECRET_KEY | Short/common keys | Warning + suggestion |
|
|
116
158
|
| Hardcoded Secrets | `api_key`, `password`, `token` in code | Warning + env vars suggestion |
|
|
117
159
|
| Template Injection | `render_template_string()` | Warning only (SSTI risk) |
|
|
118
160
|
| Empty except blocks | `except: pass` | **Auto-fixed to `raise`** |
|
|
119
161
|
| Path Traversal | `open()` with user input | Warning only |
|
|
120
162
|
| XXE | XML parsing without safe settings | Warning only |
|
|
121
163
|
|
|
164
|
+
Use `pyneat check` for detailed scan with severity levels and CVSS scores.
|
|
165
|
+
|
|
122
166
|
### Rust Acceleration (`--rust`)
|
|
123
167
|
|
|
124
168
|
For maximum performance, enable the Rust scanner:
|
|
@@ -150,40 +194,92 @@ pip install -e .
|
|
|
150
194
|
|
|
151
195
|
## Usage
|
|
152
196
|
|
|
153
|
-
### Clean a single file
|
|
197
|
+
### CLI — Clean a single file
|
|
154
198
|
|
|
155
199
|
```bash
|
|
200
|
+
# Default (safe package) — runs automatically, no flags needed
|
|
156
201
|
pyneat clean your_messy_file.py
|
|
202
|
+
|
|
203
|
+
# Preview changes without writing
|
|
204
|
+
pyneat clean your_messy_file.py --dry-run --diff
|
|
205
|
+
|
|
206
|
+
# In-place modification (with backup first)
|
|
207
|
+
pyneat clean your_messy_file.py --in-place --backup
|
|
208
|
+
|
|
209
|
+
# Conservative package — adds cleanup rules
|
|
210
|
+
pyneat clean your_messy_file.py --package conservative
|
|
211
|
+
|
|
212
|
+
# Destructive package — aggressive refactoring (may break code!)
|
|
213
|
+
pyneat clean your_messy_file.py --package destructive
|
|
214
|
+
|
|
215
|
+
# Enable ALL rules at once
|
|
216
|
+
pyneat clean your_messy_file.py --package destructive --enable-all
|
|
157
217
|
```
|
|
158
218
|
|
|
159
|
-
|
|
219
|
+
### CLI — Clean entire directory
|
|
160
220
|
|
|
161
221
|
```bash
|
|
162
|
-
|
|
222
|
+
# Preview all changes first
|
|
223
|
+
pyneat clean-dir ./src --dry-run --diff
|
|
224
|
+
|
|
225
|
+
# In-place with parallel processing
|
|
226
|
+
pyneat clean-dir ./src --pattern "*.py" --in-place --backup --parallel
|
|
163
227
|
```
|
|
164
228
|
|
|
165
|
-
###
|
|
229
|
+
### CLI — Security scan (no auto-fix)
|
|
166
230
|
|
|
167
231
|
```bash
|
|
168
|
-
|
|
232
|
+
# Scan for vulnerabilities
|
|
233
|
+
pyneat check your_file.py --severity --cvss
|
|
234
|
+
|
|
235
|
+
# Fail CI if CRITICAL issues found
|
|
236
|
+
pyneat check ./src --fail-on critical --format sarif --output report.sarif
|
|
169
237
|
```
|
|
170
238
|
|
|
171
|
-
###
|
|
239
|
+
### CLI — Other commands
|
|
172
240
|
|
|
173
241
|
```bash
|
|
174
|
-
|
|
242
|
+
# List all rules by package
|
|
243
|
+
pyneat rules
|
|
244
|
+
|
|
245
|
+
# Explain a security rule
|
|
246
|
+
pyneat explain SEC-001
|
|
247
|
+
|
|
248
|
+
# Ignore a rule (per-instance or global)
|
|
249
|
+
pyneat ignore SEC-003 --file app.py --line 42 --reason "already sanitized"
|
|
175
250
|
```
|
|
176
251
|
|
|
177
|
-
###
|
|
252
|
+
### Python API
|
|
178
253
|
|
|
179
|
-
```
|
|
180
|
-
pyneat
|
|
254
|
+
```python
|
|
255
|
+
from pyneat import clean_code, clean_file, analyze_code
|
|
256
|
+
|
|
257
|
+
# Simplest — pass code as a string
|
|
258
|
+
result = clean_code("x == None") # "x is not None"
|
|
259
|
+
result = clean_code("print('debug')", remove_debug=True) # ""
|
|
260
|
+
|
|
261
|
+
# Clean a file
|
|
262
|
+
from pathlib import Path
|
|
263
|
+
result = clean_file(Path("app.py"), in_place=True)
|
|
264
|
+
print(f"Made {len(result.changes_made)} changes")
|
|
265
|
+
|
|
266
|
+
# Analyze only — no auto-fix
|
|
267
|
+
report = analyze_code("x == None; print('debug')")
|
|
268
|
+
for issue in report['issues']:
|
|
269
|
+
print(f" - {issue}")
|
|
181
270
|
```
|
|
182
271
|
|
|
183
|
-
###
|
|
272
|
+
### Python API — Custom engine
|
|
184
273
|
|
|
185
|
-
```
|
|
186
|
-
pyneat
|
|
274
|
+
```python
|
|
275
|
+
from pyneat import RuleEngine, CodeFile, RuleConfig
|
|
276
|
+
from pyneat.rules import IsNotNoneRule, DebugCleaner
|
|
277
|
+
|
|
278
|
+
engine = RuleEngine([
|
|
279
|
+
IsNotNoneRule(),
|
|
280
|
+
DebugCleaner(mode="safe"),
|
|
281
|
+
])
|
|
282
|
+
result = engine.process_code_file(CodeFile(path=Path("demo.py"), content=source))
|
|
187
283
|
```
|
|
188
284
|
|
|
189
285
|
## Configuration
|
|
@@ -192,11 +288,27 @@ PyNeat respects `pyproject.toml` settings under `[tool.pyneat]`:
|
|
|
192
288
|
|
|
193
289
|
```toml
|
|
194
290
|
[tool.pyneat]
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
291
|
+
# Default package: safe, conservative, or destructive
|
|
292
|
+
package = "safe"
|
|
293
|
+
|
|
294
|
+
# Conservative rules
|
|
198
295
|
enable_unused_imports = true
|
|
199
|
-
|
|
296
|
+
enable_fstring = false
|
|
297
|
+
enable_dataclass = false
|
|
298
|
+
enable_magic_numbers = false
|
|
299
|
+
debug_clean_mode = "off" # off, safe, or aggressive
|
|
300
|
+
|
|
301
|
+
# Destructive rules (use with caution!)
|
|
302
|
+
enable_import_cleaning = false
|
|
303
|
+
enable_naming = false
|
|
304
|
+
enable_refactoring = false
|
|
305
|
+
enable_comment_clean = false
|
|
306
|
+
enable_redundant = false
|
|
307
|
+
enable_dead_code = false
|
|
308
|
+
enable_match_case = false
|
|
309
|
+
|
|
310
|
+
# Auto-export manifest on commit
|
|
311
|
+
export_manifest = false
|
|
200
312
|
```
|
|
201
313
|
|
|
202
314
|
## Pre-commit Integration
|
|
@@ -209,11 +321,11 @@ repos:
|
|
|
209
321
|
hooks:
|
|
210
322
|
- id: pyneat-clean
|
|
211
323
|
name: PyNeat AI Code Cleaner
|
|
212
|
-
entry: pyneat clean --in-place
|
|
324
|
+
entry: pyneat clean --package conservative --in-place
|
|
213
325
|
language: system
|
|
214
326
|
types: [python]
|
|
215
327
|
pass_filenames: true
|
|
216
|
-
args: ['--enable-unused', '--
|
|
328
|
+
args: ['--enable-unused', '--dry-run']
|
|
217
329
|
```
|
|
218
330
|
|
|
219
331
|
Install:
|
|
@@ -231,7 +343,7 @@ scripts\setup-pre-commit.bat
|
|
|
231
343
|
Add code quality checks to your CI/CD pipeline:
|
|
232
344
|
|
|
233
345
|
```yaml
|
|
234
|
-
# .github/workflows/
|
|
346
|
+
# .github/workflows/ci.yml
|
|
235
347
|
name: PyNeat Code Quality
|
|
236
348
|
on: [push, pull_request]
|
|
237
349
|
jobs:
|
|
@@ -246,7 +358,7 @@ jobs:
|
|
|
246
358
|
run: pyneat clean-dir . --dry-run
|
|
247
359
|
```
|
|
248
360
|
|
|
249
|
-
Or copy the full template from [`.github/workflows/
|
|
361
|
+
Or copy the full template from [`.github/workflows/ci.yml`](.github/workflows/ci.yml).
|
|
250
362
|
|
|
251
363
|
## VSCode Extension
|
|
252
364
|
|