Semantic upgrade assistant and compatibility codemods for Python dependencies.
Project description
PyCompatRepair (pycomprepair)
Asistente de upgrades semánticos y codemods de compatibilidad para dependencias Python.
pycomprepair analiza el código de tu proyecto frente a una versión actual y una versión objetivo de una librería, detecta call-sites incompatibles y aplica codemods verificables con --dry-run, diff legible y posibilidad de rollback.
A diferencia de herramientas como pyupgrade (solo sintaxis del lenguaje) o bump-pydantic (solo Pydantic v1→v2), pycomprepair está pensado como un núcleo extensible con un sistema de plugins por ecosistema. El MVP incluye:
- Núcleo: extracción de firmas con
griffe, detección de incompatibilidades, motor de codemods sobrelibcst. - Plugin Pydantic v2:
BaseSettings,Config→model_config,@validator→@field_validator,.dict()→.model_dump(),.parse_obj()→.model_validate(), etc. - Plugin FastAPI: deprecated
on_event→lifespan,Dependsconuse_cachedeprecated, etc. - Plugin SQLAlchemy 2.0:
from sqlalchemy.ext.declarative import declarative_base→sqlalchemy.orm,session.query(M).get(pk)→session.get(M, pk), avisos sobredeclarative_base()yQuery.update/delete. - Plugin Django 5.0:
smart_text/force_text→smart_str/force_str,ugettext*→gettext*, aviso sobredjango.utils.timezone.utcyMeta.index_together. - CLI (
pycomprepair) conscan,repair,report.
Instalación
pip install pycomprepair
o, si usas uv:
uv pip install pycomprepair
Requiere Python 3.10+.
Para desarrollo local sobre el repositorio:
uv venv
uv pip install -e ".[dev]"
Uso rápido
# Escanear el proyecto y detectar incompatibilidades
pycomprepair scan ./src --target "pydantic>=2.0,<3.0"
# Aplicar codemods en modo dry-run (muestra diff, no escribe)
pycomprepair repair ./src --target "pydantic>=2.0,<3.0" --dry-run
# Aplicar de verdad
pycomprepair repair ./src --target "pydantic>=2.0,<3.0"
# Generar reporte HTML/Markdown
pycomprepair report ./src --target "pydantic>=2.0,<3.0" --format markdown
Configuración por proyecto
Para evitar repetir --target y demás flags en cada llamada, PyCompatRepair lee
configuración de un fichero pycomprepair.toml (o de una sección
[tool.pycomprepair] en tu pyproject.toml). La búsqueda sube por los
directorios padre desde la ruta que pases en la CLI, así que puedes ponerlo en
la raíz del repo:
# pycomprepair.toml
target = "pydantic>=2.0,<3.0"
min_confidence = 0.8
unsafe_fixes = false
ignore = ["PYD002", "DJA004"] # códigos de regla que no quieres ver
Equivalente dentro de pyproject.toml:
[tool.pycomprepair]
target = "pydantic>=2.0,<3.0"
ignore = ["PYD002"]
Los flags de la CLI tienen prioridad sobre la configuración, y la configuración
sobre los valores por defecto. Con esto, pycomprepair scan ./src ya basta
una vez configurado el proyecto.
Descubrimiento dinámico (discover)
Más allá de los plugins manuales, pycomprepair puede consultar la API
real de un paquete instalado mediante griffe
y avisarte de imports que ya no existen en esa versión. Es la forma más rápida
de auditar tu código frente al venv objetivo:
# Crea un venv con la versión a la que quieres migrar
uv pip install "django==5.0.*"
# Encuentra imports rotos respecto a la Django instalada
pycomprepair discover ./src --package django
Cada importación cuyo símbolo no figura en la API cargada genera un issue
DSC001. A partir de la 0.2.0, discover además realiza un análisis ligero
de accesos a atributos (código DSC002) que detecta usos del tipo:
import numpy as np
x = arr.astype(np.float) # DSC002: numpy.float fue eliminado
import django
ts = django.utils.timezone.utc # DSC002: removido en Django 5.0
El análisis es conservador: ignora nombres reasignados, parámetros de
función y cualquier cadena que pase por una función (su valor de retorno
es opaco), de modo que el ruido en CI es muy bajo. Esto convierte a
discover en un linter semántico de compatibilidad y no solo en un
verificador de imports.
Salida SARIF para GitHub Code Scanning
pycomprepair report puede emitir SARIF 2.1.0 para integrarse de
forma nativa con la pestaña Security → Code scanning de GitHub:
pycomprepair report ./src --target "django>=5.0,<5.1" \
--format sarif --output pycomprepair.sarif
En el workflow:
- run: pycomprepair report ./src --target "django>=5.0" --format sarif --output pcr.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: pcr.sarif
category: pycomprepair
Cada regla aparece deduplicada en tool.driver.rules con su severidad por
defecto y cada issue se sube como un result con physicalLocation que
apunta al fichero (ruta relativa al directorio escaneado) y la línea/columna
exacta.
Pre-commit
PyCompatRepair publica pre-commit-hooks.yaml, así que basta con añadirlo a
tu .pre-commit-config.yaml:
repos:
- repo: https://github.com/alvaroo-fdez/pycomprepair
rev: v0.2.0
hooks:
- id: pycomprepair-scan
# Opcionalmente, valida también contra la API instalada:
- id: pycomprepair-discover
args: ["--package", "django"]
Hooks disponibles:
| Hook | Equivalente CLI |
|---|---|
pycomprepair-scan |
pycomprepair scan . |
pycomprepair-repair-check |
pycomprepair repair . --dry-run |
pycomprepair-discover |
pycomprepair discover . (+ paquetes) |
Úsalo como GitHub Action
PyCompatRepair se distribuye también como composite action, así que puedes añadir un job de compatibilidad a cualquier repositorio Python en cinco líneas:
# .github/workflows/pycomprepair.yml
name: Compatibility check
on: [pull_request]
permissions:
contents: read
pull-requests: write # solo si activas comment-on-pr
jobs:
pycomprepair:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: alvaroo-fdez/pycomprepair@main
with:
path: src
target: "pydantic>=2.0,<3.0"
mode: scan # "scan" (default) o "repair"
fail-on-issues: "true"
comment-on-pr: "true" # publica/actualiza un comentario idempotente
Inputs principales:
| Input | Default | Descripción |
|---|---|---|
path |
. |
Ruta a escanear/reparar. |
target |
— | Requisito objetivo, p.ej. "pydantic>=2.0,<3.0". |
mode |
scan |
scan solo detecta; repair además incluye diffs en el reporte. |
fail-on-issues |
true |
Falla el job si se detectan incompatibilidades. |
comment-on-pr |
false |
Publica/actualiza un comentario en el PR con el reporte (idempotente). |
version |
— | Especificador opcional, p.ej. ==0.1.0 para fijar versión. |
git-ref |
— | Instala desde un ref del repo (útil para probar cambios sin publicar). |
skip-install |
false |
Salta la instalación si ya tienes pycomprepair en el PATH. |
El reporte siempre se publica en el step summary del job; los outputs
issues-count y report-path quedan disponibles para pasos posteriores.
Arquitectura
src/pycomprepair/
├── core/ # Diff de firmas, registro de plugins, modelos de issue
├── codemods/ # Helpers libcst reutilizables
├── plugins/ # Plugins por ecosistema (pydantic, fastapi, ...)
├── report/ # Renderers Markdown/HTML
└── cli.py # CLI Typer
Licencia
Apache-2.0. Ver LICENSE.
Project details
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 pycomprepair-0.2.0.tar.gz.
File metadata
- Download URL: pycomprepair-0.2.0.tar.gz
- Upload date:
- Size: 52.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b56a8b671762ca611a3038332810b5b97db05786abb4e3e1008a659991348353
|
|
| MD5 |
17906c1017e6a9e1c0b3c4c36bc58ebf
|
|
| BLAKE2b-256 |
c9245b686ae94a2ebd122fbf9cc5bbdc767fb78959ad6fb8438af8da4fc28a50
|
Provenance
The following attestation bundles were made for pycomprepair-0.2.0.tar.gz:
Publisher:
release.yml on alvaroo-fdez/pycomprepair
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pycomprepair-0.2.0.tar.gz -
Subject digest:
b56a8b671762ca611a3038332810b5b97db05786abb4e3e1008a659991348353 - Sigstore transparency entry: 1574991017
- Sigstore integration time:
-
Permalink:
alvaroo-fdez/pycomprepair@54392603426bee9f2e6706a8445fb2a15466e862 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/alvaroo-fdez
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@54392603426bee9f2e6706a8445fb2a15466e862 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pycomprepair-0.2.0-py3-none-any.whl.
File metadata
- Download URL: pycomprepair-0.2.0-py3-none-any.whl
- Upload date:
- Size: 52.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1a665749a1197a3274d3241cd5caa52fc88530c1c855c866d355a6aaa94eff79
|
|
| MD5 |
b5e59c0b80a581926f3ead65d2abcdf1
|
|
| BLAKE2b-256 |
eeabbc1340452ab403c50d80411f2f6960c094643585f0a6f6dea56a6b907a3a
|
Provenance
The following attestation bundles were made for pycomprepair-0.2.0-py3-none-any.whl:
Publisher:
release.yml on alvaroo-fdez/pycomprepair
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pycomprepair-0.2.0-py3-none-any.whl -
Subject digest:
1a665749a1197a3274d3241cd5caa52fc88530c1c855c866d355a6aaa94eff79 - Sigstore transparency entry: 1574991080
- Sigstore integration time:
-
Permalink:
alvaroo-fdez/pycomprepair@54392603426bee9f2e6706a8445fb2a15466e862 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/alvaroo-fdez
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@54392603426bee9f2e6706a8445fb2a15466e862 -
Trigger Event:
push
-
Statement type: