9.3 KiB
Guía de Linting y Calidad de Código
Esta guía explica cómo usar las herramientas de linting y formateo configuradas en el proyecto para mantener un código Python de alta calidad siguiendo PEP8 y mejores prácticas.
Tabla de Contenidos
- Herramientas Configuradas
- Instalación
- Uso Rápido
- Herramientas Individuales
- Pre-commit Hooks
- Integración con Docker
- CI/CD
- Configuración de IDEs
Herramientas Configuradas
Formateo Automático
- Black: Formateador de código opinionado (PEP8)
- isort: Ordenador de imports
- autopep8: Corrector automático de PEP8
Linting (Análisis Estático)
- Flake8: Verificador de estilo PEP8
- pycodestyle: Verificador oficial de PEP8
- Pylint: Analizador estático completo
- Bandit: Verificador de seguridad
Type Checking
- MyPy: Verificador de tipos estáticos
- django-stubs: Type hints para Django
- djangorestframework-stubs: Type hints para DRF
Testing
- pytest: Framework de testing
- pytest-django: Plugin para Django
- pytest-cov: Cobertura de tests
- coverage: Reporte de cobertura
Instalación
Opción 1: Usando Make (Recomendado)
# Instalar todas las dependencias de desarrollo
make install-dev
Opción 2: Usando pip directamente
# Instalar dependencias de producción
pip install -r requirements.txt
# Instalar dependencias de desarrollo
pip install -r requirements-dev.txt
# Instalar pre-commit hooks
pre-commit install
Opción 3: En Docker
# Construir imagen con herramientas de desarrollo
docker-compose exec backend pip install -r requirements-dev.txt
Uso Rápido
Formatear Código Automáticamente
# Usando Make
make format
# O manualmente
bash scripts/format.sh
Este comando ejecutará automáticamente:
- isort - Ordena los imports
- black - Formatea el código
- autopep8 - Aplica correcciones adicionales de PEP8
Verificar Calidad de Código
# Usando Make
make lint
# O manualmente
bash scripts/lint.sh
Este comando ejecutará:
- Black (verificación sin modificar)
- isort (verificación)
- Flake8 (PEP8)
- Pylint (análisis estático)
- Bandit (seguridad)
- MyPy (type checking)
Ver Todos los Comandos Disponibles
make help
Herramientas Individuales
Black - Formateador de Código
# Verificar formato sin modificar
black --check --diff .
# Formatear todo el código
black .
# Formatear archivo específico
black path/to/file.py
Configuración: pyproject.toml - Longitud de línea: 120
isort - Ordenador de Imports
# Verificar imports sin modificar
isort --check-only --diff .
# Ordenar imports
isort .
# Ordenar archivo específico
isort path/to/file.py
Configuración: pyproject.toml - Compatible con Black
Flake8 - Verificador PEP8
# Verificar todo el proyecto
flake8 .
# Verificar directorio específico
flake8 authentication/
# Verificar archivo específico
flake8 path/to/file.py
# Ignorar reglas específicas
flake8 --ignore=E501,W503 .
Configuración: .flake8
Pylint - Análisis Estático
# Analizar todo el código
pylint authentication attendance events mac_attendance
# Analizar archivo específico
pylint path/to/file.py
# Generar reporte de calificación
pylint --output-format=text authentication/ | tee pylint-report.txt
Configuración: pyproject.toml
Bandit - Verificador de Seguridad
# Verificar seguridad en todo el proyecto
bandit -r . -c pyproject.toml
# Verificar directorio específico
bandit -r authentication/
# Generar reporte detallado
bandit -r . -f json -o bandit-report.json
Configuración: pyproject.toml
MyPy - Type Checking
# Verificar tipos
mypy --config-file=pyproject.toml .
# Verificar archivo específico
mypy path/to/file.py
# Generar reporte HTML
mypy --html-report mypy-report .
Configuración: pyproject.toml
Pre-commit Hooks
Los pre-commit hooks ejecutan automáticamente las herramientas de linting antes de cada commit.
Instalar Hooks
pre-commit install
Ejecutar Hooks Manualmente
# Ejecutar en archivos staged
pre-commit run
# Ejecutar en todos los archivos
pre-commit run --all-files
# Usando Make
make pre-commit-all
Saltar Hooks (No Recomendado)
git commit --no-verify -m "mensaje"
Actualizar Hooks
pre-commit autoupdate
Integración con Docker
Ejecutar Linting en Docker
# Formatear código
docker-compose exec backend bash scripts/format.sh
# Verificar código
docker-compose exec backend bash scripts/lint.sh
# Usando Make
docker-compose exec backend make format
docker-compose exec backend make lint
Agregar al Dockerfile
# En Dockerfile.backend, agregar antes del CMD
COPY requirements-dev.txt .
RUN pip install -r requirements-dev.txt
# Ejecutar linting en el build
RUN flake8 . || true
CI/CD
GitHub Actions
Crear .github/workflows/lint.yml:
name: Lint
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install -r backend/requirements-dev.txt
- name: Run linters
run: |
cd backend
make lint
GitLab CI
Crear .gitlab-ci.yml:
lint:
stage: test
image: python:3.11
script:
- cd backend
- pip install -r requirements-dev.txt
- make lint
Configuración de IDEs
Visual Studio Code
Crear .vscode/settings.json:
{
"python.linting.enabled": true,
"python.linting.flake8Enabled": true,
"python.linting.pylintEnabled": true,
"python.linting.banditEnabled": true,
"python.linting.mypyEnabled": true,
"python.formatting.provider": "black",
"python.formatting.blackArgs": ["--line-length", "120"],
"python.sortImports.args": ["--profile", "black"],
"[python]": {
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.organizeImports": true
}
},
"python.linting.flake8Args": ["--config=backend/.flake8"],
"python.linting.pylintArgs": ["--rcfile=backend/pyproject.toml"]
}
PyCharm
-
Configurar Black:
- Settings → Tools → External Tools → Add
- Name: Black
- Program:
black - Arguments:
$FilePath$
-
Configurar Flake8:
- Settings → Tools → External Tools → Add
- Name: Flake8
- Program:
flake8 - Arguments:
$FilePath$
-
Configurar File Watcher:
- Settings → Tools → File Watchers → Add
- File type: Python
- Program:
black
Métricas de Calidad
Cobertura de Tests
# Ejecutar tests con cobertura
make coverage
# Ver reporte HTML
open htmlcov/index.html
Complejidad Ciclomática
# Instalar radon
pip install radon
# Analizar complejidad
radon cc . -a -nb
# Generar reporte JSON
radon cc . -j > complexity-report.json
Mantenibilidad
# Índice de mantenibilidad
radon mi . -s
# Mostrar solo archivos con baja mantenibilidad
radon mi . -s -n C
Consejos y Mejores Prácticas
1. Formateo Automático
Ejecuta make format antes de cada commit para mantener el código formateado.
2. Pre-commit Hooks
Deja que los pre-commit hooks trabajen por ti. No los saltes a menos que sea absolutamente necesario.
3. Gradual
Si el proyecto tiene mucho código legacy, puedes aplicar linting gradualmente:
# Solo en archivos modificados
git diff --name-only | xargs flake8
4. Ignorar Reglas Específicas
Si necesitas ignorar una regla en una línea específica:
# noqa: E501
long_line = "Esta línea es muy larga pero es necesaria" # noqa: E501
# Para múltiples reglas
code = "something" # noqa: E501,W503
5. Documentación
Mantén docstrings en funciones importantes:
def calculate_attendance(student_id: int, event_id: int) -> float:
"""
Calcula el porcentaje de asistencia de un estudiante.
Args:
student_id: ID del estudiante
event_id: ID del evento
Returns:
Porcentaje de asistencia (0-100)
Raises:
ValueError: Si el estudiante o evento no existe
"""
pass
Solución de Problemas
Error: "command not found"
Asegúrate de haber instalado las dependencias:
make install-dev
Error: "pre-commit: command not found"
pip install pre-commit
pre-commit install
Conflictos entre Black e isort
La configuración está ajustada para que sean compatibles. Si hay conflictos:
# Ejecutar en orden
isort .
black .
Demasiados errores de Flake8
Puedes ajustar las reglas en .flake8 o formatear automáticamente:
make format