pyneat-cli 3.0.4__tar.gz → 3.0.6__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-3.0.4 → pyneat_cli-3.0.6}/PKG-INFO +1 -1
- pyneat_cli-3.0.6/pyneat/__init__.py +371 -0
- pyneat_cli-3.0.6/pyneat/__main__.py +24 -0
- pyneat_cli-3.0.6/pyneat/benchmark.py +542 -0
- pyneat_cli-3.0.6/pyneat/cli.py +1800 -0
- pyneat_cli-3.0.6/pyneat/config.py +453 -0
- pyneat_cli-3.0.6/pyneat/config_loader.py +294 -0
- pyneat_cli-3.0.6/pyneat/core/__init__.py +81 -0
- pyneat_cli-3.0.6/pyneat/core/atomic.py +215 -0
- pyneat_cli-3.0.6/pyneat/core/engine.py +652 -0
- pyneat_cli-3.0.6/pyneat/core/manifest.py +1205 -0
- pyneat_cli-3.0.6/pyneat/core/marker_cleanup.py +152 -0
- pyneat_cli-3.0.6/pyneat/core/scope_guard.py +152 -0
- pyneat_cli-3.0.6/pyneat/core/semantic_guard.py +248 -0
- pyneat_cli-3.0.6/pyneat/core/type_shield.py +226 -0
- pyneat_cli-3.0.6/pyneat/core/types.py +759 -0
- pyneat_cli-3.0.6/pyneat/plugins/__init__.py +55 -0
- pyneat_cli-3.0.6/pyneat/plugins/base.py +313 -0
- pyneat_cli-3.0.6/pyneat/plugins/builtin/__init__.py +109 -0
- pyneat_cli-3.0.6/pyneat/pre_commit.py +120 -0
- pyneat_cli-3.0.6/pyneat/rules/__init__.py +76 -0
- pyneat_cli-3.0.6/pyneat/rules/ai_bugs.py +715 -0
- pyneat_cli-3.0.6/pyneat/rules/base.py +92 -0
- pyneat_cli-3.0.6/pyneat/rules/comments.py +179 -0
- pyneat_cli-3.0.6/pyneat/rules/conservative.py +36 -0
- pyneat_cli-3.0.6/pyneat/rules/csharp/__init__.py +28 -0
- pyneat_cli-3.0.6/pyneat/rules/csharp/security.py +426 -0
- pyneat_cli-3.0.6/pyneat/rules/dataclass.py +313 -0
- pyneat_cli-3.0.6/pyneat/rules/deadcode.py +517 -0
- pyneat_cli-3.0.6/pyneat/rules/debug.py +392 -0
- pyneat_cli-3.0.6/pyneat/rules/destructive.py +43 -0
- pyneat_cli-3.0.6/pyneat/rules/duplication.py +131 -0
- pyneat_cli-3.0.6/pyneat/rules/fstring.py +261 -0
- pyneat_cli-3.0.6/pyneat/rules/go/__init__.py +32 -0
- pyneat_cli-3.0.6/pyneat/rules/go/security.py +483 -0
- pyneat_cli-3.0.6/pyneat/rules/go/unchecked_error.py +81 -0
- pyneat_cli-3.0.6/pyneat/rules/imports.py +184 -0
- pyneat_cli-3.0.6/pyneat/rules/init_protection.py +218 -0
- pyneat_cli-3.0.6/pyneat/rules/is_not_none.py +129 -0
- pyneat_cli-3.0.6/pyneat/rules/isolated.py +164 -0
- pyneat_cli-3.0.6/pyneat/rules/java/__init__.py +28 -0
- pyneat_cli-3.0.6/pyneat/rules/java/security.py +482 -0
- pyneat_cli-3.0.6/pyneat/rules/javascript/__init__.py +34 -0
- pyneat_cli-3.0.6/pyneat/rules/javascript/security.py +669 -0
- pyneat_cli-3.0.6/pyneat/rules/javascript/strict_equality.py +71 -0
- pyneat_cli-3.0.6/pyneat/rules/javascript/var_to_const.py +66 -0
- pyneat_cli-3.0.6/pyneat/rules/magic_numbers.py +149 -0
- pyneat_cli-3.0.6/pyneat/rules/match_case.py +376 -0
- pyneat_cli-3.0.6/pyneat/rules/multilang/__init__.py +58 -0
- pyneat_cli-3.0.6/pyneat/rules/multilang/base.py +253 -0
- pyneat_cli-3.0.6/pyneat/rules/multilang/debug_statements.py +194 -0
- pyneat_cli-3.0.6/pyneat/rules/multilang/deep_nesting.py +80 -0
- pyneat_cli-3.0.6/pyneat/rules/multilang/empty_catch.py +90 -0
- pyneat_cli-3.0.6/pyneat/rules/multilang/redundant_comments.py +158 -0
- pyneat_cli-3.0.6/pyneat/rules/multilang/remove_todos.py +73 -0
- pyneat_cli-3.0.6/pyneat/rules/multilang/unused_function.py +151 -0
- pyneat_cli-3.0.6/pyneat/rules/multilang/unused_import.py +253 -0
- pyneat_cli-3.0.6/pyneat/rules/naming.py +332 -0
- pyneat_cli-3.0.6/pyneat/rules/performance.py +354 -0
- pyneat_cli-3.0.6/pyneat/rules/php/__init__.py +28 -0
- pyneat_cli-3.0.6/pyneat/rules/php/security.py +437 -0
- pyneat_cli-3.0.6/pyneat/rules/quality.py +124 -0
- pyneat_cli-3.0.6/pyneat/rules/range_len_pattern.py +215 -0
- pyneat_cli-3.0.6/pyneat/rules/redundant.py +190 -0
- pyneat_cli-3.0.6/pyneat/rules/refactoring.py +258 -0
- pyneat_cli-3.0.6/pyneat/rules/registry.py +250 -0
- pyneat_cli-3.0.6/pyneat/rules/ruby/__init__.py +28 -0
- pyneat_cli-3.0.6/pyneat/rules/ruby/security.py +401 -0
- pyneat_cli-3.0.6/pyneat/rules/rust/__init__.py +28 -0
- pyneat_cli-3.0.6/pyneat/rules/rust/security.py +410 -0
- pyneat_cli-3.0.6/pyneat/rules/safe.py +37 -0
- pyneat_cli-3.0.6/pyneat/rules/secret_classifier.py +252 -0
- pyneat_cli-3.0.6/pyneat/rules/security.py +1212 -0
- pyneat_cli-3.0.6/pyneat/rules/security_pack/__init__.py +77 -0
- pyneat_cli-3.0.6/pyneat/rules/security_pack/critical.py +59 -0
- pyneat_cli-3.0.6/pyneat/rules/security_pack/high.py +39 -0
- pyneat_cli-3.0.6/pyneat/rules/security_pack/info.py +39 -0
- pyneat_cli-3.0.6/pyneat/rules/security_pack/low.py +39 -0
- pyneat_cli-3.0.6/pyneat/rules/security_pack/medium.py +44 -0
- pyneat_cli-3.0.6/pyneat/rules/security_registry.py +1991 -0
- pyneat_cli-3.0.6/pyneat/rules/taint_analysis.py +306 -0
- pyneat_cli-3.0.6/pyneat/rules/typing.py +287 -0
- pyneat_cli-3.0.6/pyneat/rules/universal/__init__.py +69 -0
- pyneat_cli-3.0.6/pyneat/rules/universal/arrow_antipattern.py +62 -0
- pyneat_cli-3.0.6/pyneat/rules/universal/base.py +123 -0
- pyneat_cli-3.0.6/pyneat/rules/universal/debug_artifacts.py +136 -0
- pyneat_cli-3.0.6/pyneat/rules/universal/empty_catch.py +59 -0
- pyneat_cli-3.0.6/pyneat/rules/universal/hardcoded_secrets.py +81 -0
- pyneat_cli-3.0.6/pyneat/rules/universal/todos.py +52 -0
- pyneat_cli-3.0.6/pyneat/rules/unused.py +332 -0
- pyneat_cli-3.0.6/pyneat/scanner/rust_scanner.py +329 -0
- pyneat_cli-3.0.6/pyneat/tools/__init__.py +20 -0
- pyneat_cli-3.0.6/pyneat/tools/github_fuzz/__init__.py +322 -0
- pyneat_cli-3.0.6/pyneat/tools/github_fuzz/__main__.py +720 -0
- pyneat_cli-3.0.6/pyneat/tools/github_fuzz/debug_logger.py +471 -0
- pyneat_cli-3.0.6/pyneat/tools/github_fuzz/fuzz_runner.py +628 -0
- pyneat_cli-3.0.6/pyneat/tools/github_fuzz/github_client.py +413 -0
- pyneat_cli-3.0.6/pyneat/tools/osv_client.py +269 -0
- pyneat_cli-3.0.6/pyneat/tools/sbom_generator.py +291 -0
- pyneat_cli-3.0.6/pyneat/tools/security/advisory_db.py +741 -0
- pyneat_cli-3.0.6/pyneat/tools/security/dependency_scanner.py +393 -0
- pyneat_cli-3.0.6/pyneat/tools/vulnerability_scanner.py +422 -0
- pyneat_cli-3.0.6/pyneat/utils/naming.py +68 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/__init__.py +371 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/__main__.py +24 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/benchmark.py +542 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/cli.py +1800 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/config.py +453 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/config_loader.py +294 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/core/__init__.py +81 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/core/atomic.py +215 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/core/engine.py +652 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/core/manifest.py +1205 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/core/marker_cleanup.py +152 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/core/scope_guard.py +152 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/core/semantic_guard.py +248 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/core/type_shield.py +226 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/core/types.py +759 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/plugins/__init__.py +55 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/plugins/base.py +313 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/plugins/builtin/__init__.py +109 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/pre_commit.py +120 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/__init__.py +76 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/ai_bugs.py +715 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/base.py +92 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/comments.py +179 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/conservative.py +36 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/csharp/__init__.py +28 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/csharp/security.py +426 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/dataclass.py +313 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/deadcode.py +517 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/debug.py +392 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/destructive.py +43 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/duplication.py +131 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/fstring.py +261 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/go/__init__.py +32 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/go/security.py +483 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/go/unchecked_error.py +81 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/imports.py +184 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/init_protection.py +218 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/is_not_none.py +129 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/isolated.py +164 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/java/__init__.py +28 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/java/security.py +482 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/javascript/__init__.py +34 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/javascript/security.py +669 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/javascript/strict_equality.py +71 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/javascript/var_to_const.py +66 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/magic_numbers.py +149 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/match_case.py +376 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/multilang/__init__.py +58 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/multilang/base.py +253 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/multilang/debug_statements.py +194 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/multilang/deep_nesting.py +80 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/multilang/empty_catch.py +90 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/multilang/redundant_comments.py +158 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/multilang/remove_todos.py +73 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/multilang/unused_function.py +151 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/multilang/unused_import.py +253 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/naming.py +332 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/performance.py +354 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/php/__init__.py +28 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/php/security.py +437 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/quality.py +124 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/range_len_pattern.py +215 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/redundant.py +190 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/refactoring.py +258 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/registry.py +250 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/ruby/__init__.py +28 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/ruby/security.py +401 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/rust/__init__.py +28 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/rust/security.py +410 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/safe.py +37 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/secret_classifier.py +252 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/security.py +1212 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/security_pack/__init__.py +77 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/security_pack/critical.py +59 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/security_pack/high.py +39 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/security_pack/info.py +39 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/security_pack/low.py +39 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/security_pack/medium.py +44 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/security_registry.py +1991 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/taint_analysis.py +306 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/typing.py +287 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/universal/__init__.py +69 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/universal/arrow_antipattern.py +62 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/universal/base.py +123 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/universal/debug_artifacts.py +136 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/universal/empty_catch.py +59 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/universal/hardcoded_secrets.py +81 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/universal/todos.py +52 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/rules/unused.py +332 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/scanner/rust_scanner.py +329 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/tools/__init__.py +20 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/tools/github_fuzz/__init__.py +322 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/tools/github_fuzz/__main__.py +720 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/tools/github_fuzz/debug_logger.py +471 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/tools/github_fuzz/fuzz_runner.py +628 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/tools/github_fuzz/github_client.py +413 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/tools/osv_client.py +269 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/tools/sbom_generator.py +291 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/tools/security/advisory_db.py +741 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/tools/security/dependency_scanner.py +393 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/tools/vulnerability_scanner.py +422 -0
- pyneat_cli-3.0.6/pyneat-rs/pyneat/utils/naming.py +68 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyproject.toml +2 -1
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/LICENSE +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/README.md +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/Cargo.lock +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/Cargo.toml +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/IMPROVEMENTS.md +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/README.md +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/bench_python.py +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/benches/rule_benchmark.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/benches/scanner_benchmark.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/benches/test_utils.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/benchmark.py +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/benchmark_results.json +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/build.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/compare_with_competitors.py +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/ai_security/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/ai_security/rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/fixer/apply_fix.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/fixer/diff.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/fixer/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/integrations/github.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/integrations/gitlab.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/integrations/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/integrations/sonarqube.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/lib.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/lib_tests.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/lsp/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/main.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/ast_rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/base.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/extended_security.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/php_rules/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/php_rules/php.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/quality.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec024.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec025.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec026.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec042.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec043.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec044.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec060.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec061.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec062.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec063.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec064.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec065.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec066.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec067.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec068.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec069.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec070.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec071.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/sec072.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/rules/security.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/sarif/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/sarif/writer.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/base.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/csharp/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/csharp/parser.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/csharp/quality_rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/csharp/rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/go/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/go/parser.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/go/rules/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/go/rules/rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/java/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/java/parser.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/java/quality_rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/java/rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/java/security_rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/javascript/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/javascript/parser.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/javascript/quality_rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/javascript/rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/javascript/security_rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/ln_ast.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/ln_ast_converter.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/multilang.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/php/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/php/parser.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/php/quality_rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/php/rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/php/security_rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/ruby/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/ruby/parser.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/ruby/quality_rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/ruby/rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/ruby/security_rules/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/ruby/security_rules/security_rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/rust/mod.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/rust/parser.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/rust/quality_rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/rust/rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/rust/security_rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/src/scanner/tree_sitter.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/test-samples/sample.clean.js +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/test-samples/sample.cs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/test-samples/sample.go +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/test-samples/sample.java +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/test-samples/sample.js +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/test-samples/sample.php +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/test-samples/sample.rb +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/test-samples/sample.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/test-samples/simple.go +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/test-samples/vuln.go +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/test_code.py +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/test_rust.py +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/test_scanner.py +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/tests/test_multilang.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat-rs/tests/test_rules.rs +0 -0
- {pyneat_cli-3.0.4 → pyneat_cli-3.0.6}/pyneat_rs/__init__.pyi +0 -0
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
"""PyNeat - Neat Python AI Code Cleaner.
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PyNEAT Authors
|
|
4
|
+
|
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
|
6
|
+
it under the terms of the GNU Affero General Public License as published
|
|
7
|
+
by the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
(at your option) any later version.
|
|
9
|
+
|
|
10
|
+
This program is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU Affero General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
For commercial licensing, contact: khanhnam.copywriting@gmail.com
|
|
19
|
+
|
|
20
|
+
A quick-start example:
|
|
21
|
+
|
|
22
|
+
from pyneat import clean_code, RuleEngine, CodeFile
|
|
23
|
+
|
|
24
|
+
# Simplest usage - just pass code as a string
|
|
25
|
+
result = clean_code("x == None")
|
|
26
|
+
print(result) # "x is None"
|
|
27
|
+
|
|
28
|
+
# With options
|
|
29
|
+
result = clean_code("print('debug')", remove_debug=True)
|
|
30
|
+
print(result) # "pass"
|
|
31
|
+
|
|
32
|
+
# Advanced: custom engine
|
|
33
|
+
from pyneat import RuleEngine, DebugCleaner, IsNotNoneRule
|
|
34
|
+
engine = RuleEngine([DebugCleaner(mode="safe"), IsNotNoneRule()])
|
|
35
|
+
result = engine.process_code_file(CodeFile(path=Path("demo.py"), content=source))
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
from pathlib import Path
|
|
39
|
+
from typing import List, Optional, Dict, Any
|
|
40
|
+
|
|
41
|
+
from .core.engine import RuleEngine
|
|
42
|
+
from .core.types import (
|
|
43
|
+
CodeFile,
|
|
44
|
+
RuleConfig,
|
|
45
|
+
TransformationResult,
|
|
46
|
+
RuleConflict,
|
|
47
|
+
RuleRange,
|
|
48
|
+
AgentMarker,
|
|
49
|
+
# Security types
|
|
50
|
+
SecuritySeverity,
|
|
51
|
+
SecurityFinding,
|
|
52
|
+
DependencyFinding,
|
|
53
|
+
CWE_SEVERITY_MAP,
|
|
54
|
+
OWASP_SEVERITY_MAP,
|
|
55
|
+
)
|
|
56
|
+
from .rules.imports import ImportCleaningRule
|
|
57
|
+
from .rules.naming import NamingConventionRule
|
|
58
|
+
from .rules.refactoring import RefactoringRule
|
|
59
|
+
from .rules.security import SecurityScannerRule
|
|
60
|
+
from .rules.quality import CodeQualityRule
|
|
61
|
+
from .rules.performance import PerformanceRule
|
|
62
|
+
from .rules.debug import DebugCleaner
|
|
63
|
+
from .rules.comments import CommentCleaner
|
|
64
|
+
from .rules.unused import UnusedImportRule
|
|
65
|
+
from .rules.redundant import RedundantExpressionRule
|
|
66
|
+
from .rules.is_not_none import IsNotNoneRule
|
|
67
|
+
from .rules.magic_numbers import MagicNumberRule
|
|
68
|
+
from .rules.range_len_pattern import RangeLenRule
|
|
69
|
+
from .rules.deadcode import DeadCodeRule
|
|
70
|
+
from .rules.fstring import FStringRule
|
|
71
|
+
from .rules.typing import TypingRule
|
|
72
|
+
from .rules.match_case import MatchCaseRule
|
|
73
|
+
from .rules.dataclass import DataclassSuggestionRule
|
|
74
|
+
from .rules.init_protection import InitFileProtectionRule
|
|
75
|
+
|
|
76
|
+
# Security registry
|
|
77
|
+
from .rules.security_registry import SECURITY_RULES_REGISTRY, get_security_rule, get_all_rule_ids
|
|
78
|
+
|
|
79
|
+
# Manifest export
|
|
80
|
+
from .core.manifest import ManifestExporter, MarkerParser, export_to_sarif, export_to_codeclimate, export_to_markdown
|
|
81
|
+
from .core.marker_cleanup import MarkerCleanup
|
|
82
|
+
|
|
83
|
+
# AI bug rules
|
|
84
|
+
from .rules.ai_bugs import AIBugRule
|
|
85
|
+
from .rules.duplication import CodeDuplicationRule
|
|
86
|
+
from .rules.naming import NamingInconsistencyRule
|
|
87
|
+
|
|
88
|
+
__version__ = "3.0.3"
|
|
89
|
+
|
|
90
|
+
__all__ = [
|
|
91
|
+
# Core
|
|
92
|
+
'RuleEngine', 'CodeFile', 'RuleConfig', 'TransformationResult',
|
|
93
|
+
'RuleConflict', 'RuleRange', 'AgentMarker',
|
|
94
|
+
# Security types
|
|
95
|
+
'SecuritySeverity', 'SecurityFinding', 'DependencyFinding',
|
|
96
|
+
'CWE_SEVERITY_MAP', 'OWASP_SEVERITY_MAP',
|
|
97
|
+
# Rules — Default-on (safe)
|
|
98
|
+
'SecurityScannerRule', 'CodeQualityRule', 'PerformanceRule',
|
|
99
|
+
'TypingRule', 'RangeLenRule', 'IsNotNoneRule',
|
|
100
|
+
# Rules — Conservative (use --enable-* flags)
|
|
101
|
+
'UnusedImportRule', 'InitFileProtectionRule', 'FStringRule',
|
|
102
|
+
'DataclassSuggestionRule', 'MagicNumberRule',
|
|
103
|
+
# Rules — Destructive (use --enable-* flags, can break code)
|
|
104
|
+
'ImportCleaningRule', 'NamingConventionRule', 'RefactoringRule',
|
|
105
|
+
'DebugCleaner', 'CommentCleaner', 'RedundantExpressionRule',
|
|
106
|
+
'DeadCodeRule', 'MatchCaseRule',
|
|
107
|
+
# Security registry
|
|
108
|
+
'SECURITY_RULES_REGISTRY', 'get_security_rule', 'get_all_rule_ids',
|
|
109
|
+
# Manifest export
|
|
110
|
+
'ManifestExporter', 'MarkerParser', 'export_to_sarif', 'export_to_codeclimate',
|
|
111
|
+
'export_to_markdown', 'MarkerCleanup',
|
|
112
|
+
# AI bug rules
|
|
113
|
+
'AIBugRule', 'CodeDuplicationRule', 'NamingInconsistencyRule',
|
|
114
|
+
# Convenience functions
|
|
115
|
+
'clean_code', 'clean_file', 'analyze_code',
|
|
116
|
+
# Fuzz testing tool
|
|
117
|
+
'github_fuzz',
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
# Lazy import for the fuzz testing module (avoids import overhead for normal users)
|
|
121
|
+
def __getattr__(name: str):
|
|
122
|
+
if name == 'github_fuzz':
|
|
123
|
+
from pyneat.tools import github_fuzz
|
|
124
|
+
return github_fuzz
|
|
125
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
# --------------------------------------------------------------------------
|
|
129
|
+
# Convenience functions
|
|
130
|
+
# --------------------------------------------------------------------------
|
|
131
|
+
|
|
132
|
+
def clean_code(
|
|
133
|
+
content: str,
|
|
134
|
+
remove_debug: bool = False,
|
|
135
|
+
fix_is_not_none: bool = True,
|
|
136
|
+
fix_redundant: bool = False,
|
|
137
|
+
convert_fstrings: bool = False,
|
|
138
|
+
remove_dead_code: bool = False,
|
|
139
|
+
remove_unused_imports: bool = False,
|
|
140
|
+
enable_security: bool = False,
|
|
141
|
+
check_conflicts: bool = False,
|
|
142
|
+
path: Optional[Path] = None,
|
|
143
|
+
# Aggressive rules — must be explicitly enabled
|
|
144
|
+
enable_import_cleaning: bool = False,
|
|
145
|
+
enable_naming: bool = False,
|
|
146
|
+
enable_refactoring: bool = False,
|
|
147
|
+
enable_comment_clean: bool = False,
|
|
148
|
+
) -> str:
|
|
149
|
+
"""Clean Python source code and return the transformed result.
|
|
150
|
+
|
|
151
|
+
This is the simplest way to use PyNeat — just pass a code string.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
content: The Python source code to clean.
|
|
155
|
+
remove_debug: Remove debug print/log calls (default: False).
|
|
156
|
+
fix_is_not_none: Fix `x != None` -> `x is not None` (default: True, safe).
|
|
157
|
+
fix_redundant: Simplify redundant expressions (default: False).
|
|
158
|
+
convert_fstrings: Convert .format() to f-strings (default: False).
|
|
159
|
+
remove_dead_code: Remove unused functions/classes (default: False).
|
|
160
|
+
remove_unused_imports: Remove genuinely unused imports (default: False).
|
|
161
|
+
enable_security: Enable security scanning (default: False).
|
|
162
|
+
check_conflicts: Detect overlapping rule modifications (default: False).
|
|
163
|
+
path: Optional file path for error messages.
|
|
164
|
+
enable_import_cleaning: Rewrite/reorder all imports (default: False, destructive).
|
|
165
|
+
enable_naming: Rename classes to PascalCase (default: False, destructive).
|
|
166
|
+
enable_refactoring: Refactor nested if, change except behavior (default: False, destructive).
|
|
167
|
+
enable_comment_clean: Remove TODO/FIXME comments (default: False, destructive).
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
The transformed code as a string.
|
|
171
|
+
|
|
172
|
+
Example:
|
|
173
|
+
from pyneat import clean_code
|
|
174
|
+
result = clean_code("x != None")
|
|
175
|
+
print(result) # "x is not None"
|
|
176
|
+
|
|
177
|
+
result = clean_code("print('debug')", remove_debug=True)
|
|
178
|
+
print(result) # ""
|
|
179
|
+
"""
|
|
180
|
+
path = path or Path("<string>")
|
|
181
|
+
|
|
182
|
+
# SAFE rules — always available, on by default for safe fixes
|
|
183
|
+
rules: List[Any] = []
|
|
184
|
+
if fix_is_not_none:
|
|
185
|
+
rules.append(IsNotNoneRule(RuleConfig(enabled=True)))
|
|
186
|
+
|
|
187
|
+
# CONSERVATIVE rules — opt-in
|
|
188
|
+
if remove_debug:
|
|
189
|
+
rules.append(DebugCleaner(mode="safe"))
|
|
190
|
+
if fix_redundant:
|
|
191
|
+
rules.append(RedundantExpressionRule(RuleConfig(enabled=True)))
|
|
192
|
+
if convert_fstrings:
|
|
193
|
+
rules.append(FStringRule(RuleConfig(enabled=True)))
|
|
194
|
+
if remove_dead_code:
|
|
195
|
+
rules.append(DeadCodeRule(RuleConfig(enabled=True)))
|
|
196
|
+
if remove_unused_imports:
|
|
197
|
+
rules.append(InitFileProtectionRule(RuleConfig(enabled=True)))
|
|
198
|
+
rules.append(UnusedImportRule(RuleConfig(enabled=True)))
|
|
199
|
+
if enable_security:
|
|
200
|
+
rules.append(SecurityScannerRule(RuleConfig(enabled=True)))
|
|
201
|
+
|
|
202
|
+
# DESTRUCTIVE rules — opt-in, must be explicitly enabled
|
|
203
|
+
if enable_import_cleaning:
|
|
204
|
+
rules.append(ImportCleaningRule(RuleConfig(enabled=True)))
|
|
205
|
+
if enable_naming:
|
|
206
|
+
rules.append(NamingConventionRule(RuleConfig(enabled=True)))
|
|
207
|
+
if enable_refactoring:
|
|
208
|
+
rules.append(RefactoringRule(RuleConfig(enabled=True)))
|
|
209
|
+
if enable_comment_clean:
|
|
210
|
+
rules.append(CommentCleaner(RuleConfig(enabled=True)))
|
|
211
|
+
|
|
212
|
+
if not rules:
|
|
213
|
+
return content
|
|
214
|
+
|
|
215
|
+
engine = RuleEngine(rules)
|
|
216
|
+
result = engine.process_code_file(
|
|
217
|
+
CodeFile(path=path, content=content),
|
|
218
|
+
check_conflicts=check_conflicts,
|
|
219
|
+
)
|
|
220
|
+
return result.transformed_content
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def clean_file(
|
|
224
|
+
path: Path,
|
|
225
|
+
in_place: bool = False,
|
|
226
|
+
backup: bool = False,
|
|
227
|
+
remove_debug: bool = False,
|
|
228
|
+
fix_is_not_none: bool = True,
|
|
229
|
+
fix_redundant: bool = False,
|
|
230
|
+
convert_fstrings: bool = False,
|
|
231
|
+
remove_dead_code: bool = False,
|
|
232
|
+
remove_unused_imports: bool = False,
|
|
233
|
+
enable_security: bool = False,
|
|
234
|
+
# Aggressive rules — must be explicitly enabled
|
|
235
|
+
enable_import_cleaning: bool = False,
|
|
236
|
+
enable_naming: bool = False,
|
|
237
|
+
enable_refactoring: bool = False,
|
|
238
|
+
enable_comment_clean: bool = False,
|
|
239
|
+
) -> TransformationResult:
|
|
240
|
+
"""Clean a Python file and return the result.
|
|
241
|
+
|
|
242
|
+
Args:
|
|
243
|
+
path: Path to the Python file to clean.
|
|
244
|
+
in_place: Write changes back to the file (default: False).
|
|
245
|
+
backup: Create a .bak backup before modifying (default: False).
|
|
246
|
+
remove_debug: Remove debug print/log calls (default: False).
|
|
247
|
+
fix_is_not_none: Fix `x != None` -> `x is not None` (default: True, safe).
|
|
248
|
+
fix_redundant: Simplify redundant expressions (default: False).
|
|
249
|
+
convert_fstrings: Convert .format() to f-strings (default: False).
|
|
250
|
+
remove_dead_code: Remove unused functions/classes (default: False).
|
|
251
|
+
remove_unused_imports: Remove genuinely unused imports (default: False).
|
|
252
|
+
enable_security: Enable security scanning (default: False).
|
|
253
|
+
enable_import_cleaning: Rewrite/reorder all imports (default: False, destructive).
|
|
254
|
+
enable_naming: Rename classes to PascalCase (default: False, destructive).
|
|
255
|
+
enable_refactoring: Refactor nested if, change except behavior (default: False, destructive).
|
|
256
|
+
enable_comment_clean: Remove TODO/FIXME comments (default: False, destructive).
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
TransformationResult with success status and details.
|
|
260
|
+
|
|
261
|
+
Example:
|
|
262
|
+
from pyneat import clean_file
|
|
263
|
+
result = clean_file(Path("my_script.py"), in_place=True)
|
|
264
|
+
if result.success:
|
|
265
|
+
print(f"Made {len(result.changes_made)} changes")
|
|
266
|
+
"""
|
|
267
|
+
import shutil
|
|
268
|
+
|
|
269
|
+
# SAFE rules
|
|
270
|
+
rules: List[Any] = []
|
|
271
|
+
if fix_is_not_none:
|
|
272
|
+
rules.append(IsNotNoneRule(RuleConfig(enabled=True)))
|
|
273
|
+
|
|
274
|
+
# CONSERVATIVE rules
|
|
275
|
+
if remove_debug:
|
|
276
|
+
rules.append(DebugCleaner(mode="safe"))
|
|
277
|
+
if fix_redundant:
|
|
278
|
+
rules.append(RedundantExpressionRule(RuleConfig(enabled=True)))
|
|
279
|
+
if convert_fstrings:
|
|
280
|
+
rules.append(FStringRule(RuleConfig(enabled=True)))
|
|
281
|
+
if remove_dead_code:
|
|
282
|
+
rules.append(DeadCodeRule(RuleConfig(enabled=True)))
|
|
283
|
+
if remove_unused_imports:
|
|
284
|
+
rules.append(InitFileProtectionRule(RuleConfig(enabled=True)))
|
|
285
|
+
rules.append(UnusedImportRule(RuleConfig(enabled=True)))
|
|
286
|
+
if enable_security:
|
|
287
|
+
rules.append(SecurityScannerRule(RuleConfig(enabled=True)))
|
|
288
|
+
|
|
289
|
+
# DESTRUCTIVE rules — opt-in
|
|
290
|
+
if enable_import_cleaning:
|
|
291
|
+
rules.append(ImportCleaningRule(RuleConfig(enabled=True)))
|
|
292
|
+
if enable_naming:
|
|
293
|
+
rules.append(NamingConventionRule(RuleConfig(enabled=True)))
|
|
294
|
+
if enable_refactoring:
|
|
295
|
+
rules.append(RefactoringRule(RuleConfig(enabled=True)))
|
|
296
|
+
if enable_comment_clean:
|
|
297
|
+
rules.append(CommentCleaner(RuleConfig(enabled=True)))
|
|
298
|
+
|
|
299
|
+
engine = RuleEngine(rules)
|
|
300
|
+
result = engine.process_file(path)
|
|
301
|
+
|
|
302
|
+
if in_place and result.success and result.original.content != result.transformed_content:
|
|
303
|
+
if backup:
|
|
304
|
+
backup_path = path.with_suffix(path.suffix + ".bak")
|
|
305
|
+
shutil.copy2(path, backup_path)
|
|
306
|
+
|
|
307
|
+
with open(path, 'w', encoding='utf-8') as f:
|
|
308
|
+
f.write(result.transformed_content)
|
|
309
|
+
|
|
310
|
+
return result
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def analyze_code(
|
|
314
|
+
content: str,
|
|
315
|
+
path: Optional[Path] = None,
|
|
316
|
+
check_conflicts: bool = False,
|
|
317
|
+
) -> Dict[str, Any]:
|
|
318
|
+
"""Analyze code without auto-fixing, returning a report of detected issues.
|
|
319
|
+
|
|
320
|
+
Use this when you want to audit code quality without modifying it.
|
|
321
|
+
|
|
322
|
+
Args:
|
|
323
|
+
content: Python source code to analyze.
|
|
324
|
+
path: Optional file path.
|
|
325
|
+
check_conflicts: Include rule conflict detection (default: False).
|
|
326
|
+
|
|
327
|
+
Returns:
|
|
328
|
+
Dictionary with analysis results:
|
|
329
|
+
{
|
|
330
|
+
'success': bool,
|
|
331
|
+
'issues': List[str], # issues detected by rules
|
|
332
|
+
'conflicts': List[str], # rule conflicts (if check_conflicts=True)
|
|
333
|
+
'change_count': int,
|
|
334
|
+
'error': Optional[str],
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
Example:
|
|
338
|
+
from pyneat import analyze_code
|
|
339
|
+
report = analyze_code("x == None; print('debug')")
|
|
340
|
+
for issue in report['issues']:
|
|
341
|
+
print(f" - {issue}")
|
|
342
|
+
"""
|
|
343
|
+
path = path or Path("<string>")
|
|
344
|
+
rules: List[Any] = [
|
|
345
|
+
SecurityScannerRule(RuleConfig(enabled=True)),
|
|
346
|
+
CodeQualityRule(RuleConfig(enabled=True)),
|
|
347
|
+
PerformanceRule(RuleConfig(enabled=True)),
|
|
348
|
+
TypingRule(RuleConfig(enabled=True)),
|
|
349
|
+
RangeLenRule(RuleConfig(enabled=True)),
|
|
350
|
+
IsNotNoneRule(RuleConfig(enabled=True)),
|
|
351
|
+
RedundantExpressionRule(RuleConfig(enabled=True)),
|
|
352
|
+
]
|
|
353
|
+
|
|
354
|
+
engine = RuleEngine(rules)
|
|
355
|
+
result = engine.process_code_file(
|
|
356
|
+
CodeFile(path=path, content=content),
|
|
357
|
+
check_conflicts=check_conflicts,
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
conflicts = [
|
|
361
|
+
c for c in result.changes_made
|
|
362
|
+
if "CONFLICT" in c
|
|
363
|
+
]
|
|
364
|
+
|
|
365
|
+
return {
|
|
366
|
+
'success': result.success,
|
|
367
|
+
'issues': result.changes_made,
|
|
368
|
+
'conflicts': conflicts,
|
|
369
|
+
'change_count': len(result.changes_made),
|
|
370
|
+
'error': result.error,
|
|
371
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Entry point for running pyneat as a module.
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PyNEAT Authors
|
|
4
|
+
|
|
5
|
+
This program is free software: you can redistribute it and/or modify
|
|
6
|
+
it under the terms of the GNU Affero General Public License as published
|
|
7
|
+
by the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
(at your option) any later version.
|
|
9
|
+
|
|
10
|
+
This program is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU Affero General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
For commercial licensing, contact: khanhnam.copywriting@gmail.com
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from pyneat.cli import cli
|
|
22
|
+
|
|
23
|
+
if __name__ == '__main__':
|
|
24
|
+
cli()
|