CodexDoctor 1.0.0
CodexDoctor is a Python static-analysis and safe auto-fix tool. It reviews Python source without importing or executing the target project, reports actionable diagnostics, can apply a deliberately limited set of automatic repairs, and produces terminal or JSON reports for local work and CI.
Static analysis cannot understand every runtime path or business rule. CodexDoctor is designed to find likely problems early, not to certify that code is bug-free or secure. Review diagnostics and every diff; run your tests and type checker.
Highlights
- Read-only analysis by default: source files are not changed by
scan. - Syntax and import checks: syntax locations, likely unresolved third-party/local imports,
src/layouts, relative imports, and common optional-import guards. - Code-quality checks: unused imports, mutable defaults, very long/extremely high-complexity functions, broad or silently ignored exceptions, repeated constant dictionary keys, identity comparisons against ordinary literals, and selected network calls without timeouts.
- Security heuristics: dynamic code execution, unsafe pickle/dill/shelve loading, unsafe YAML loading, shell invocation, unsafe temporary names, hardcoded credential-like strings, SQL string construction, disabled TLS verification, weak hashes, and non-cryptographic randomness used in security-sensitive contexts.
- Optional Ruff integration: when Ruff is installed, its diagnostics are included. Ruff is not a required runtime dependency.
- Conservative auto-fixing: trims exterior trailing whitespace, adds a missing final newline, and invokes Ruff's safe fixes when available. Original files are backed up under
.codexdoctor/backups/by default. - Developer workflow: deterministic reports, JSON output, configurable CI exit thresholds, Python API, typed package marker, tests, GitHub Actions CI, and PyPI publishing workflow.
Requirements and installation
- Python 3.10 or newer (CI is configured for Python 3.10–3.15).
- No mandatory third-party runtime dependencies.
Install the core tool:
python -m pip install --upgrade codexdoctor
Install with Ruff integration:
python -m pip install "codexdoctor[quality]"
Confirm installation:
codexdoctor --version
codexdoctor help
Quick start
Scan the current directory (does not edit files):
codexdoctor scan
Scan a chosen project:
codexdoctor scan path/to/project
Apply supported safe fixes to the current project and rescan it:
codexdoctor scan fix
Apply safe fixes to a specific project:
codexdoctor scan fix path/to/project
The equivalent dedicated fixer command is:
codexdoctor fix path/to/project
Important: scan fix does not promise to repair every diagnostic. It applies only transformations that are safe to automate with the available tools. A warning about program logic, missing dependencies, application behavior, or a security design decision requires human review.
Command reference
codexdoctor scan [PATH]
| Option | Purpose |
|---|---|
--format text|json |
Select readable terminal or JSON output |
--output FILE |
Save the report to a file |
--exclude-dir NAME |
Exclude a directory; repeatable |
--include-hidden |
Include hidden Python files and directories |
--max-file-size MIB |
Skip individual files larger than the limit; default 2 MiB |
--no-import-check |
Disable import-resolution checks |
--no-security-check |
Disable security heuristics |
--no-structure-check |
Disable project-structure suggestions |
--no-quality-check |
Disable built-in quality checks |
--no-ruff |
Disable optional Ruff analysis |
--fix |
Apply safe fixes, then scan again |
--fail-on never|error|warning|info |
Select CI exit threshold; default error |
Examples:
codexdoctor scan . --format json
codexdoctor scan . --format json --output codexdoctor-report.json
codexdoctor scan . --exclude-dir generated --exclude-dir legacy
codexdoctor scan . --include-hidden --max-file-size 5
codexdoctor scan . --fail-on warning
codexdoctor scan . --no-import-check --no-security-check
codexdoctor scan . --no-quality-check --no-ruff
codexdoctor scan . --fix
codexdoctor fix [PATH]
| Option | Purpose |
|---|---|
--exclude-dir NAME |
Exclude a directory; repeatable |
--include-hidden |
Include hidden Python files and directories |
--max-file-size MIB |
Maximum source file size; default 2 MiB |
--no-backup |
Disable backups (not recommended) |
--no-ruff-fix |
Do not invoke Ruff's safe fixes |
Example:
codexdoctor fix . --exclude-dir generated
codexdoctor help
Prints the full built-in usage guide, analysis scope, auto-fix policy, common commands, exit codes, and important limitations. Standard --help is also available on the root and subcommands.
How automatic fixing works
- CodexDoctor discovers Python files using the same conservative directory exclusions as the scanner.
- It stores original file bytes in
.codexdoctor/backups/<UTC_TIMESTAMP>/, preserving relative paths. - Built-in cleanup removes trailing spaces/tabs outside multiline string literals and adds a missing final newline.
- If Ruff is installed and enabled,
ruff check --fix-onlyis run on the selected source files. Ruff's unsafe fixes are not requested. - Changed files are written atomically, then
scan fixruns the analysis again and displays the remaining diagnostics.
The built-in fixer does not attempt to invent code, rewrite control flow, remove imports based on guesses, install packages, run project code, or alter application logic. Backups are excluded from subsequent scans. Ruff labels fixes as safe, but even a labeled-safe rewrite can interact with dynamic Python behavior. Always inspect the diff and test the application.
Diagnostics overview
The exact list can grow between releases. Current built-in checks include:
| Code | Meaning |
|---|---|
PY_SYNTAX |
Source cannot be parsed by the running Python interpreter |
IMPORT_NOT_FOUND |
Import is not located in the active interpreter or indexed project files |
PY_UNUSED_IMPORT |
Imported name is not referenced in the source file |
PY_MUTABLE_DEFAULT |
Function has a mutable default argument |
PY_BARE_EXCEPT / PY_BROAD_EXCEPT |
Exception handler catches too broadly |
PY_SILENT_EXCEPT |
Exception handler silently ignores the error |
PY_FUNCTION_TOO_LONG / PY_HIGH_COMPLEXITY |
Function may be difficult to maintain or test |
PY_DUPLICATE_DICT_KEY |
Constant dictionary key is repeated |
PY_IDENTITY_LITERAL |
is/is not is used with a non-singleton literal |
PY_HTTP_NO_TIMEOUT |
Recognized HTTP call has no explicit timeout |
SEC_EVAL / SEC_EXEC |
Dynamic evaluation/execution call |
SEC_UNSAFE_DESERIALIZATION |
Potentially unsafe Python-object deserialization |
SEC_UNSAFE_YAML |
YAML loading without a recognized safe loader |
SEC_SUBPROCESS_SHELL / SEC_OS_SHELL |
Shell invocation pattern |
SEC_TEMPFILE_MKTEMP |
Race-prone temporary-name generation |
SEC_HARDCODED_SECRET |
Credential-like string assigned to a sensitive variable name |
SEC_SQL_STRING_BUILD |
Dynamically composed SQL string passed to execute() |
SEC_TLS_VERIFY_DISABLED |
TLS certificate verification disabled |
SEC_WEAK_HASH |
MD5/SHA-1 use that may be unsuitable for security purposes |
SEC_NONCRYPTO_RANDOM |
random API use that may be unsuitable for secrets |
RUFF_* |
A diagnostic emitted by optional Ruff integration |
PROJECT_NO_README, PROJECT_NO_TESTS, PROJECT_NO_PACKAGING |
Informational project-structure suggestions |
Severity indicates the analyzer's level of concern, not a mathematical guarantee. Some rules intentionally produce advisory results.
JSON output and CI
codexdoctor scan . --format json --output report.json --fail-on warning
Exit statuses:
0: scan completed and no finding met the selected failure threshold.1: at least one finding met the selected--fail-onthreshold.2: invalid arguments or an operational failure.
JSON includes the schema version, tool version, root path, Python file count, environment, counts, and structured diagnostics. Consumers should check schema_version when integrating the report into other software.
Python API
from codexdoctor import ScanOptions, scan, fix_project
options = ScanOptions(
exclude_dirs=("generated", "legacy"),
max_file_size=4 * 1024 * 1024,
check_imports=True,
check_security=True,
check_quality=True,
check_ruff=True,
)
report = scan("./my_project", options=options)
print(report.summary())
for finding in report.findings:
print(finding.severity, finding.code, finding.path, finding.line)
# Explicitly requested, conservative repair pass:
fix_report = fix_project("./my_project", options=options, backup=True)
print(f"Changed {fix_report.files_changed} file(s)")
scan() does not write to the project. fix_project() is the explicit mutating API and backs up originals by default.
What CodexDoctor does not claim to do
- It is not a complete type checker, test runner, formatter, dependency vulnerability database, malware scanner, or penetration-testing tool.
- It does not prove that code is correct, performant, race-free, or secure.
- It cannot reliably infer every dynamic import, plugin registration, reflection path, runtime-generated module, framework lifecycle, or business invariant.
- Import checks use the environment that runs CodexDoctor; that environment can differ from the target application's deployment environment.
- Built-in analysis is AST-based and heuristic. Findings can be false positives or false negatives.
- Ruff adds another independent rule set only when installed. The result is still not an exhaustive code review.
- Safe auto-fixing is intentionally incomplete. No automatic tool should silently rewrite arbitrary application logic.
For stronger checks, also run your project's test suite, a type checker such as mypy or Pyright, a dedicated dependency scanner, and manual review.
Development
python -m pip install -e ".[dev]"
python -m pytest
python -m compileall -q src tests
python -m build
python -m twine check dist/*
Project layout:
CodexDoctor/
├── .github/workflows/ # CI and Trusted Publishing
├── src/codexdoctor/
│ ├── analyzers/ # syntax, import, quality, security, Ruff
│ ├── core/ # models, project index, scanner, safe fixer
│ ├── reporters/ # terminal and JSON
│ ├── cli.py
│ └── __main__.py
├── tests/
├── README.md
├── README.fa.md
├── pyproject.toml
└── LICENSE
See CONTRIBUTING.md, SECURITY.md, and PUBLISHING.md.
License
MIT. See LICENSE.
Metadata
Release files for codexdoctor 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| codexdoctor-1.0.0.tar.gz | 46.6 kB | Without provenance | Details for codexdoctor-1.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| codexdoctor-1.0.0-py3-none-any.whl | Python 3 | none | any | Details for codexdoctor-1.0.0-py3-none-any.whl |
Total release size: 78.5 kB
Release files / codexdoctor-1.0.0.tar.gz
| Download URL | codexdoctor-1.0.0.tar.gz |
|---|---|
| Size | 46.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ff2722caced0e2dd57fae7d87db9a31b70fe0b45c02f6006fd3d2859fb8e92c3
|
|
BLAKE2b-256 checksum How to use checksums |
622bb1f01b64759a706d45e8f672d0974e9c809bb28738ce51926353de0ee30c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.12
|
Release files / codexdoctor-1.0.0-py3-none-any.whl
| Download URL | codexdoctor-1.0.0-py3-none-any.whl |
|---|---|
| Size | 31.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ed9ef265cc943012e69b467f0e325b3c934ed3865ad87f39755a59973e165985
|
|
BLAKE2b-256 checksum How to use checksums |
6b8f33c270c7234261328f9afaa13afec526985433931438bc898d7bf3258143
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.12
|
Security for codexdoctor 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.