# 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](#herramientas-configuradas) - [Instalación](#instalación) - [Uso Rápido](#uso-rápido) - [Herramientas Individuales](#herramientas-individuales) - [Pre-commit Hooks](#pre-commit-hooks) - [Integración con Docker](#integración-con-docker) - [CI/CD](#cicd) - [Configuración de IDEs](#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) ```bash # Instalar todas las dependencias de desarrollo make install-dev ``` ### Opción 2: Usando pip directamente ```bash # 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 ```bash # Construir imagen con herramientas de desarrollo docker-compose exec backend pip install -r requirements-dev.txt ``` ## Uso Rápido ### Formatear Código Automáticamente ```bash # Usando Make make format # O manualmente bash scripts/format.sh ``` Este comando ejecutará automáticamente: 1. **isort** - Ordena los imports 2. **black** - Formatea el código 3. **autopep8** - Aplica correcciones adicionales de PEP8 ### Verificar Calidad de Código ```bash # Usando Make make lint # O manualmente bash scripts/lint.sh ``` Este comando ejecutará: 1. Black (verificación sin modificar) 2. isort (verificación) 3. Flake8 (PEP8) 4. Pylint (análisis estático) 5. Bandit (seguridad) 6. MyPy (type checking) ### Ver Todos los Comandos Disponibles ```bash make help ``` ## Herramientas Individuales ### Black - Formateador de Código ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash # 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 ```bash pre-commit install ``` ### Ejecutar Hooks Manualmente ```bash # 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) ```bash git commit --no-verify -m "mensaje" ``` ### Actualizar Hooks ```bash pre-commit autoupdate ``` ## Integración con Docker ### Ejecutar Linting en Docker ```bash # 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 ```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`: ```yaml 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`: ```yaml 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`: ```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 1. **Configurar Black**: - Settings → Tools → External Tools → Add - Name: Black - Program: `black` - Arguments: `$FilePath$` 2. **Configurar Flake8**: - Settings → Tools → External Tools → Add - Name: Flake8 - Program: `flake8` - Arguments: `$FilePath$` 3. **Configurar File Watcher**: - Settings → Tools → File Watchers → Add - File type: Python - Program: `black` ## Métricas de Calidad ### Cobertura de Tests ```bash # Ejecutar tests con cobertura make coverage # Ver reporte HTML open htmlcov/index.html ``` ### Complejidad Ciclomática ```bash # Instalar radon pip install radon # Analizar complejidad radon cc . -a -nb # Generar reporte JSON radon cc . -j > complexity-report.json ``` ### Mantenibilidad ```bash # Í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: ```bash # 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: ```python # 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: ```python 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: ```bash make install-dev ``` ### Error: "pre-commit: command not found" ```bash pip install pre-commit pre-commit install ``` ### Conflictos entre Black e isort La configuración está ajustada para que sean compatibles. Si hay conflictos: ```bash # Ejecutar en orden isort . black . ``` ### Demasiados errores de Flake8 Puedes ajustar las reglas en `.flake8` o formatear automáticamente: ```bash make format ``` ## Referencias - [PEP 8 – Style Guide for Python Code](https://peps.python.org/pep-0008/) - [Black Documentation](https://black.readthedocs.io/) - [Flake8 Documentation](https://flake8.pycqa.org/) - [Pylint Documentation](https://pylint.pycqa.org/) - [isort Documentation](https://pycqa.github.io/isort/) - [Pre-commit Documentation](https://pre-commit.com/)