Estándares y Guías de Estilo de Código
Los estándares de Python de toda la flota extienden PEP 8 con reglas de tipado, diseño de proyecto, manejo de errores y expectativas de revisión, aplicados por Ruff 0.9+, pyright en rutas modificadas y plantillas que copian los nuevos repositorios.
Receta
Tarjeta de referencia rápida - lista para copiar y pegar.
# pyproject.toml (línea base de la flota)
[tool.ruff]
line-length = 100
target-version = "py314"
select = ["E", "F", "I", "UP", "B", "ASYNC", "S"]
[tool.pyright]
pythonVersion = "3.14"
typeCheckingMode = "standard"src/<paquete>/
api/ # Solo HTTP
domain/ # sin importaciones de FastAPI/Django
infra/ # DB, colas, E/S externaCuándo recurrir a esto:
- Arranque de nuevo servicio
- Debates de PR que repiten los mismos argumentos de estilo
- Auditoría de seguridad solicita consistencia
- Lista de verificación de incorporación
Ejemplo de Trabajo
"""domain/orders.py - cumple con los estándares de la flota."""
from __future__ import annotations
from dataclasses import dataclass
from decimal import Decimal
@dataclass(frozen=True)
class OrderTotal:
subtotal: Decimal
tax: Decimal
@property
def grand_total(self) -> Decimal:
return self.subtotal + self.tax
def compute_total(subtotal: Decimal, tax_rate: Decimal) -> OrderTotal:
tax = (subtotal * tax_rate).quantize(Decimal("0.01"))
return OrderTotal(subtotal=subtotal, tax=tax)# api/routes/orders.py - límite delgado
from fastapi import APIRouter
from pydantic import BaseModel
from domain.orders import compute_total
router = APIRouter()
class TotalRequest(BaseModel):
subtotal: float
tax_rate: float
@router.post("/total")
def total(body: TotalRequest) -> dict[str, float]:
result = compute_total(body.subtotal, body.tax_rate)
return {"grand_total": float(result.grand_total)}Lo que esto demuestra:
- El módulo de dominio tiene tipos y no importaciones de framework
- El dinero usa Decimal en el dominio; float solo en el límite HTTP con política de conversión explícita
- El enrutador se mantiene delgado; las reglas de negocio son probables sin HTTP
- Los estándares se alinean con el diseño de referencia de SaaS
Inmersión Profunda
Cómo Funciona
- Automatizar detalles menores - Ruff formatea y analiza en CI; los humanos revisan el diseño.
- Tipado - Funciones públicas anotadas;
Anyrequiere justificación con comentario. - Importaciones - isort a través de Ruff; sin importaciones de estrella en código de producción.
- Errores - Jerarquía de excepciones personalizadas por servicio; sin
exceptdesnudo. - Seguridad - Reglas Bandit/S en Ruff para problemas comunes.
Estándares Más Allá de PEP 8
| Tema | Regla de la flota |
|---|---|
| Asíncrono | Sin E/S bloqueante en async def sin to_thread |
| SQL | Consultas parametrizadas; se prefiere ORM |
| Registro (Logging) | structlog JSON; sin f-string en el mensaje de registro |
| Pruebas | pytest; fixtures sobre estado global |
| Configuración | pydantic-settings; sin dispersión cruda de os.environ |
Notas de Python
uv run ruff check .
uv run ruff format --check .
uv run pyright src/Trampas
- 100% perfección de estilo antes que características - La velocidad muere. Solución: Automatizar; aceptar el legado con estrictez en rutas modificadas.
- Plantillas de repositorio inconsistentes - Cada servicio diferente. Solución: Plantilla interna de Cookiecutter actualizada trimestralmente.
- Decimal en todas partes en JSON - Dolor de serialización. Solución: Política: Dominio Decimal, float/str en API con validación.
- Ignorar reglas ASYNC - Incidentes posteriores. Solución: ASYNC en la selección predeterminada de Ruff.
- Documento de estándares no leído - Enlace desde la plantilla de PR y mensajes del linter.
Alternativas
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| Solo Black (sin Ruff) | Legado | Flota nueva (Ruff reemplaza ambos) |
| mypy estricto en todo el repositorio | Greenfield pequeño | Monolito legado grande |
| Guía de estilo de Google verbatim | Necesita referencia externa | La flota tiene diseño personalizado |
| Sin estándares | Cierre inminente | Flota activa multi-escuadrón |
Preguntas Frecuentes
¿PEP 8 vs guía de la flota?
Línea base PEP 8; la flota añade reglas de diseño, tipado, asíncrono y seguridad.
¿Longitud de línea 88 o 100?
Esta flota usa 100; elija una para toda la organización.
¿Excepciones de Django?
Permitir importaciones de Django en las capas apps/ y services/ según el ADR de la plantilla de Django.
¿Estándares de Notebooks?
Los notebooks no están en la ruta de producción; el código promovido debe pasar el mismo lint en los módulos.
¿Aceptar código sin tipar del legado?
Sí; módulos nuevos tipados; puerta de ruta modificada en CI.
¿Quién actualiza los estándares?
El gremio de plataforma trimestralmente; RFC para cambios controvertidos.
¿fmt al guardar?
Recomendado; CI es la fuente de verdad.
¿Código generado por terceros?
Excluir en ruff por archivo-ignorar; documentar rutas.
¿Estilo de Docstring?
Estilo Google o NumPy, una opción; opcionalmente aplicado en código nuevo.
¿Enlace al artículo PEP 8?
Relacionado
- Convenciones de Documentación - estándares de documentación
- Guías de Contribución - proceso de PR
- Linting y Formateo - herramientas
- Mejores Prácticas de Pistas de Tipo - profundidad de tipado
- Reglas de Python - lista de reglas
Versiones de Stack: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.