Skip to main content

Semantic upgrade assistant and compatibility codemods for Python dependencies.

Project description

PyCompatRepair (pycomprepair)

CI PyPI version PyPI downloads License: Apache 2.0 Python versions Code style: ruff Checked with mypy

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 sobre libcst.
  • Plugin Pydantic v2: BaseSettings, Configmodel_config, @validator@field_validator, .dict().model_dump(), .parse_obj().model_validate(), etc.
  • Plugin FastAPI: deprecated on_eventlifespan, Depends con use_cache deprecated, etc.
  • Plugin SQLAlchemy 2.0: from sqlalchemy.ext.declarative import declarative_basesqlalchemy.orm, session.query(M).get(pk)session.get(M, pk), avisos sobre declarative_base() y Query.update/delete.
  • Plugin Django 5.0: smart_text/force_textsmart_str/force_str, ugettext*gettext*, aviso sobre django.utils.timezone.utc y Meta.index_together.
  • CLI (pycomprepair) con scan, 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

pycomprepair-0.2.0.tar.gz (52.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pycomprepair-0.2.0-py3-none-any.whl (52.6 kB view details)

Uploaded Python 3

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

Hashes for pycomprepair-0.2.0.tar.gz
Algorithm Hash digest
SHA256 b56a8b671762ca611a3038332810b5b97db05786abb4e3e1008a659991348353
MD5 17906c1017e6a9e1c0b3c4c36bc58ebf
BLAKE2b-256 c9245b686ae94a2ebd122fbf9cc5bbdc767fb78959ad6fb8438af8da4fc28a50

See more details on using hashes here.

Provenance

The following attestation bundles were made for pycomprepair-0.2.0.tar.gz:

Publisher: release.yml on alvaroo-fdez/pycomprepair

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for pycomprepair-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1a665749a1197a3274d3241cd5caa52fc88530c1c855c866d355a6aaa94eff79
MD5 b5e59c0b80a581926f3ead65d2abcdf1
BLAKE2b-256 eeabbc1340452ab403c50d80411f2f6960c094643585f0a6f6dea56a6b907a3a

See more details on using hashes here.

Provenance

The following attestation bundles were made for pycomprepair-0.2.0-py3-none-any.whl:

Publisher: release.yml on alvaroo-fdez/pycomprepair

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page