Configura pre-commit para ejecutar validaciones automáticas antes de cada commit y evita que problemas de calidad lleguen a GitHub. Con Ruff como linter y formatter, más MyPy para tipos y reglas de seguridad de Bandit, tu código en Python cumple estándares desde el primer intento.
¿Qué es pre-commit y cómo garantiza calidad en cada commit?
Pre-commit es un framework que simplifica la configuración de hooks que se ejecutan automáticamente cada vez que haces un commit. Al instalarlo y crear el archivo de configuración pre-commit.config.yml, puedes activar reglas como corrección de fin de archivo, eliminación de espacios en blanco y validación de YAML. Al correr pre-commit install, el hook se integra en la carpeta .git para que todo commit pase por estas comprobaciones.
¿Qué reglas básicas conviene activar?
end-of-file-fixer: asegura una línea vacía al final del archivo.
trailing-whitespace: elimina espacios en blanco innecesarios.
check-yaml: valida la sintaxis de archivos YAML.
¿Cómo instalar y configurar pre-commit con Ruff y MyPy?
Primero instala pre-commit como dependencia de desarrollo y valida que responde en la terminal. Si avisa que falta configuración, crea pre-commit.config.yml y añade tus reglas. Luego ejecuta pre-commit install: se activará el hook local.
Herramientas clave: Ruff como linter y formatter. MyPy como analizador estático de tipos.
Archivo de proyecto: pyproject.toml con la configuración de Ruff y reglas como Bandit.
Habilidad práctica: interpretar mensajes de error y corregirlos antes del commit.
# Instalar el hook en el repositoriopre-commit install# Flujo de trabajo básicogit status
gitadd.git commit -m "mensaje"
Un ejemplo minimal de estructura para pre-commit.config.yml con las reglas mencionadas:
Genera un cambio que viole una regla: por ejemplo, una línea muy larga.
Ejecuta git add y git commit con un mensaje como “intento de commit malo”.
El primer commit puede instalar dependencias de hooks automáticamente.
Verás que Ruff bloquea el commit con el detalle del error: la línea supera el límite.
¿Cómo integrar MyPy en los hooks?
Añade mirrors-mypy con un ref que coincida con tu versión, por ejemplo: "1.8.0".
Guarda cambios y recuerda: si modificas pre-commit.config.yml, debes hacer git add de ese archivo para que el hook lo tenga en cuenta.
Reintenta el commit y confirma que MyPy ejecute sus comprobaciones.
¿Cómo validar, evitar errores y aplicar seguridad con Bandit?
Puedes necesitar terminar un commit urgente y omitir las verificaciones de estilo. En ese caso, usa la opción --no-verify al final del comando de commit. Úsala con responsabilidad.
git commit -m "mensaje urgente" --no-verify
Para seguridad, activa reglas de Bandit desde la configuración de Ruff en tu pyproject.toml. Un caso típico es la regla S307, que alerta sobre el uso inseguro de eval.
# Ejemplo inseguro: Bandit S307user_input =input("Ingresa una expresión:")resultado =eval(user_input)# Inseguro: ejecución arbitraria de código
Al intentar el commit, pre-commit mostrará: “función insegura, considera cambiarla”.
Elimina el uso de eval y vuelve a ejecutar git add y git commit.
El commit pasará cuando el código cumpla las reglas activadas.
¿Qué buenas prácticas mejoran tu flujo?
Configúralo desde el inicio del proyecto para estándares consistentes.
Incluye solo herramientas esenciales para no ralentizar los commits.
Combínalo con continuous integration y continuous deployment para doble validación: local y remota.
¿Te funcionó esta guía y activaste tus hooks con Ruff y MyPy? Comparte en comentarios qué reglas usas y qué errores te ayudan a prevenir.
2. ⌨️ Ejecuta pre-commit para comprobar funcionamiento.
3. 📝 Crea pre-commit.config.yml si falta.
4. 🔗 Activa los hooks:
pre-commit install
🔑 Herramientas conectadas
· 🐕 Ruff: linter + formatter.
· 🧠 MyPy: análisis de tipos.
· 🔐 Bandit: seguridad.
🟣 4. Flujo diario con Git
git status → inspeccionas
git add . → preparas cambios
git commit → se ejecutan hooks automáticamente
🔴 5. Configuración mínima
🧱 Estructura típica dentro de pre-commit.config.yml:
repos:
- repo: ...
rev: ...
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
- id: check-yaml
- repo: ... # Ruff
rev: ...
hooks:
- id: ruff
- id: ruff-format
- repo: ... # MyPy
rev: "1.8.0"
hooks:
- id: mypy
🟡 6. Prueba gráfica: ¿Ruff funciona?
1. 🖊️ Escribe una línea demasiado larga.
2. ➕ git add archivo.py
3. 🛑 git commit → Ruff bloquea el commit.
4. 🔧 Corrige el error.
5. ✔️ Vuelves a commitear y pasa.
🟤 7. Activar MyPy en los hooks
· 📌 Añade mirrors-mypy con su versión correcta.
· ➕ Haz git add pre-commit.config.yml.
· 🧪 Intenta hacer commit → se ejecuta MyPy.
Resumen:
■■■■■■■
Pre-commit Hooks
Los pre-commit hooks validan automáticamente el código antes de cada commit, con el objetivo de automatizar las verificaciones antes de hacer push al repositorio.
Para su funcionamiento, se requiere un archivo .pre-commit-config.yaml en la raíz del proyecto. Además, el sistema creará un archivo .log para registrar las ejecuciones. Es necesario ejecutar pre-commit install para activar los hooks en el repositorio local.
Si queremos utilizar herramientas como Ruff o MyPy en el flujo de pre-commit, debemos agregarlas explícitamente en el archivo .yaml de configuración.
Un aspecto clave es que podemos usar git commit -m "mensaje" --no-verify para saltarse temporalmente la validación cuando sea necesario.
Entre las reglas de Ruff disponibles, destaca Bandit, que se especializa en detectar posibles riesgos de seguridad. Por ejemplo, identifica el uso peligroso de eval(), ya que si un usuario tiene acceso a ingresar inputs dentro de esta función, podría acceder a definiciones internas del programa y comprometer su seguridad.
Recomendaciones
- Configurar los pre-commit hooks desde el inicio del proyecto
- Incluir solo las validaciones necesarias para no ralentizar el flujo de trabajo
- Combinar con CI/CD para establecer una doble capa de validación
Creo que si no se define --config-file=pyproject.toml en el hook de mypy, mypy usaria por defecto el pyproject.toml.
Si quieres hacer la prueba seria chevere.
Pues tiene toda la razón!! Hice la prueba haciendo lo siguiente: cree 2 archivos de configuración (pyproject y pyproject1), luego eliminé el argumento donde le indico el config-file y volvíe a ejecutar. El resultado se ve en la primera imagen. Después volví a añadir el argumento con el config-file pero esta vez indicando el archivo pyproject1 y el resultado se ve en la segunda imagen. Muy interesante la prueba, muchas gracias !!