# Python Anti Patterns > Úsalo al revisar código Python en busca de antipatrones comunes: como checklist antes de finalizar implementaciones o al depurar problemas derivados de malas prácticas conocidas. Fuente: https://skillsagentes.com/skills/wshobson/agents/python-anti-patterns Markdown: https://skillsagentes.com/skills/wshobson/agents/python-anti-patterns.md Repositorio: https://github.com/wshobson/agents Autor: wshobson Licencia: MIT Actualizado: hace 6 meses Coste de contexto: 55 tok instalada, 2k tok al activarse, 2k tok con todos los archivos del bundle Bundle: 1 archivo, 8 KB Permisos que pide: ninguno declarado ## Instalación Un skill son archivos markdown: los mismos archivos valen para cualquier agente y lo único que cambia es el directorio de destino, es decir la bandera `--agent`. Añade `-g` para instalarlo en todos los proyectos de la máquina. ```bash # Claude Code npx -y skills add wshobson/agents --skill python-anti-patterns --agent claude-code # Cursor npx -y skills add wshobson/agents --skill python-anti-patterns --agent cursor # Codex npx -y skills add wshobson/agents --skill python-anti-patterns --agent codex # Gemini CLI npx -y skills add wshobson/agents --skill python-anti-patterns --agent gemini # Windsurf npx -y skills add wshobson/agents --skill python-anti-patterns --agent windsurf # Cline npx -y skills add wshobson/agents --skill python-anti-patterns --agent cline ``` ## Qué hace - Proporciona una checklist de antipatrones comunes en Python (infraestructura, arquitectura, errores, recursos, tipos, testing) - Muestra ejemplos BAD/GOOD con el fix recomendado para cada antipatrón - Ofrece una tabla resumen de antipatrones y sus soluciones para revisión rápida ## Cuándo usarla - Al revisar código antes de un merge - Al depurar problemas misteriosos que podrían venir de malas prácticas conocidas - Antes de finalizar una implementación - Al establecer estándares de código de equipo o refactorizar código legacy ## Cuándo no - Cuando se busca orientación sobre patrones positivos y arquitectura (usar el skill python-design-patterns en su lugar) ## Qué la activa - "Revisa este código Python en busca de antipatrones antes de mergear" - "Ayúdame a depurar por qué este servicio falla silenciosamente" - "Dame un checklist para revisar buenas prácticas en este módulo Python" - "Refactoriza este código legacy siguiendo buenas prácticas de Python" ## Archivos - SKILL.md — 8 KB ## SKILL.md Reproducido tal cual desde wshobson/agents bajo MIT. Esta sección es el documento original y está en inglés. # Python Anti-Patterns Checklist A reference checklist of common mistakes and anti-patterns in Python code. Review this before finalizing implementations to catch issues early. ## When to Use This Skill - Reviewing code before merge - Debugging mysterious issues - Teaching or learning Python best practices - Establishing team coding standards - Refactoring legacy code **Note:** This skill focuses on what to avoid. For guidance on positive patterns and architecture, see the `python-design-patterns` skill. ## Infrastructure Anti-Patterns ### Scattered Timeout/Retry Logic ```python # BAD: Timeout logic duplicated everywhere def fetch_user(user_id): try: return requests.get(url, timeout=30) except Timeout: logger.warning("Timeout fetching user") return None def fetch_orders(user_id): try: return requests.get(url, timeout=30) except Timeout: logger.warning("Timeout fetching orders") return None ``` **Fix:** Centralize in decorators or client wrappers. ```python # GOOD: Centralized retry logic @retry(stop=stop_after_attempt(3), wait=wait_exponential()) def http_get(url: str) -> Response: return requests.get(url, timeout=30) ``` ### Double Retry ```python # BAD: Retrying at multiple layers @retry(max_attempts=3) # Application retry def call_service(): return client.request() # Client also has retry configured! ``` **Fix:** Retry at one layer only. Know your infrastructure's retry behavior. ### Hard-Coded Configuration ```python # BAD: Secrets and config in code DB_HOST = "prod-db.example.com" API_KEY = "sk-12345" def connect(): return psycopg.connect(f"host={DB_HOST}...") ``` **Fix:** Use environment variables with typed settings. ```python # GOOD from pydantic_settings import BaseSettings class Settings(BaseSettings): db_host: str = Field(alias="DB_HOST") api_key: str = Field(alias="API_KEY") settings = Settings() ``` ## Architecture Anti-Patterns ### Exposed Internal Types ```python # BAD: Leaking ORM model to API @app.get("/users/{id}") def get_user(id: str) -> UserModel: # SQLAlchemy model return db.query(UserModel).get(id) ``` **Fix:** Use DTOs/response models. ```python # GOOD @app.get("/users/{id}") def get_user(id: str) -> UserResponse: user = db.query(UserModel).get(id) return UserResponse.from_orm(user) ``` ### Mixed I/O and Business Logic ```python # BAD: SQL embedded in business logic def calculate_discount(user_id: str) -> float: user = db.query("SELECT * FROM users WHERE id = ?", user_id) orders = db.query("SELECT * FROM orders WHERE user_id = ?", user_id) # Business logic mixed with data access if len(orders) > 10: return 0.15 return 0.0 ``` **Fix:** Repository pattern. Keep business logic pure. ```python # GOOD def calculate_discount(user: User, orders: list[Order]) -> float: # Pure business logic, easily testable if len(orders) > 10: return 0.15 return 0.0 ``` ## Error Handling Anti-Patterns ### Bare Exception Handling ```python # BAD: Swallowing all exceptions try: process() except Exception: pass # Silent failure - bugs hidden forever ``` **Fix:** Catch specific exceptions. Log or handle appropriately. ```python # GOOD try: process() except ConnectionError as e: logger.warning("Connection failed, will retry", error=str(e)) raise except ValueError as e: logger.error("Invalid input", error=str(e)) raise BadRequestError(str(e)) ``` ### Ignored Partial Failures ```python # BAD: Stops on first error def process_batch(items): results = [] for item in items: result = process(item) # Raises on error - batch aborted results.append(result) return results ``` **Fix:** Capture both successes and failures. ```python # GOOD def process_batch(items) -> BatchResult: succeeded = {} failed = {} for idx, item in enumerate(items): try: succeeded[idx] = process(item) except Exception as e: failed[idx] = e return BatchResult(succeeded, failed) ``` ### Missing Input Validation ```python # BAD: No validation def create_user(data: dict): return User(**data) # Crashes deep in code on bad input ``` **Fix:** Validate early at API boundaries. ```python # GOOD def create_user(data: dict) -> User: validated = CreateUserInput.model_validate(data) return User.from_input(validated) ``` ## Resource Anti-Patterns ### Unclosed Resources ```python # BAD: File never closed def read_file(path): f = open(path) return f.read() # What if this raises? ``` **Fix:** Use context managers. ```python # GOOD def read_file(path): with open(path) as f: return f.read() ``` ### Blocking in Async ```python # BAD: Blocks the entire event loop async def fetch_data(): time.sleep(1) # Blocks everything! response = requests.get(url) # Also blocks! ``` **Fix:** Use async-native libraries. ```python # GOOD async def fetch_data(): await asyncio.sleep(1) async with httpx.AsyncClient() as client: response = await client.get(url) ``` ## Type Safety Anti-Patterns ### Missing Type Hints ```python # BAD: No types def process(data): return data["value"] * 2 ``` **Fix:** Annotate all public functions. ```python # GOOD def process(data: dict[str, int]) -> int: return data["value"] * 2 ``` ### Untyped Collections ```python # BAD: Generic list without type parameter def get_users() -> list: ... ``` **Fix:** Use type parameters. ```python # GOOD def get_users() -> list[User]: ... ``` ## Testing Anti-Patterns ### Only Testing Happy Paths ```python # BAD: Only tests success case def test_create_user(): user = service.create_user(valid_data) assert user.id is not None ``` **Fix:** Test error conditions and edge cases. ```python # GOOD def test_create_user_success(): user = service.create_user(valid_data) assert user.id is not None def test_create_user_invalid_email(): with pytest.raises(ValueError, match="Invalid email"): service.create_user(invalid_email_data) def test_create_user_duplicate_email(): service.create_user(valid_data) with pytest.raises(ConflictError): service.create_user(valid_data) ``` ### Over-Mocking ```python # BAD: Mocking everything def test_user_service(): mock_repo = Mock() mock_cache = Mock() mock_logger = Mock() mock_metrics = Mock() # Test doesn't verify real behavior ``` **Fix:** Use integration tests for critical paths. Mock only external services. ## Quick Review Checklist Before finalizing code, verify: - [ ] No scattered timeout/retry logic (centralized) - [ ] No double retry (app + infrastructure) - [ ] No hard-coded configuration or secrets - [ ] No exposed internal types (ORM models, protobufs) - [ ] No mixed I/O and business logic - [ ] No bare `except Exception: pass` - [ ] No ignored partial failures in batches - [ ] No missing input validation - [ ] No unclosed resources (using context managers) - [ ] No blocking calls in async code - [ ] All public functions have type hints - [ ] Collections have type parameters - [ ] Error paths are tested - [ ] Edge cases are covered ## Common Fixes Summary | Anti-Pattern | Fix | |-------------|-----| | Scattered retry logic | Centralized decorators | | Hard-coded config | Environment variables + pydantic-settings | | Exposed ORM models | DTO/response schemas | | Mixed I/O + logic | Repository pattern | | Bare except | Catch specific exceptions | | Batch stops on error | Return BatchResult with successes/failures | | No validation | Validate at boundaries with Pydantic | | Unclosed resources | Context managers | | Blocking in async | Async-native libraries | | Missing types | Type annotations on all public APIs | | Only happy path tests | Test errors and edge cases | ## Dónde encaja - Categoría: [Testing y QA](https://skillsagentes.com/categorias/testing-qa.md) — Flujos de testing unitario, de integración y end-to-end. - Creador: [wshobson](https://skillsagentes.com/creators/wshobson.md) — 183 skills en el directorio - [Todas las skills](https://skillsagentes.com/skills.md) - [Ranking de instalaciones](https://skillsagentes.com/ranking.md) ## Skills relacionadas - [Eval Harness First](https://skillsagentes.com/skills/wshobson/agents/eval-harness-first.md): Construye el eval harness que condiciona cada fine-tuning: golden sets, graders por modo de fallo, calibración de juez y baselines del modelo base. - [Wcag Audit Patterns](https://skillsagentes.com/skills/wshobson/agents/wcag-audit-patterns.md): Realiza auditorías de accesibilidad WCAG 2.2 con pruebas automatizadas, verificación manual y guía de remediación. Útil para auditar sitios, corregir violaciones y aplicar patrones de diseño accesible. - [Temporal Python Testing](https://skillsagentes.com/skills/wshobson/agents/temporal-python-testing.md): Prueba workflows de Temporal con pytest, time-skipping y estrategias de mocking: testing unitario, de integración, de replay y configuración de desarrollo local. - [Parallel Debugging](https://skillsagentes.com/skills/wshobson/agents/parallel-debugging.md): Depura problemas complejos con hipótesis en competencia, investigación paralela, recolección de evidencia y arbitraje de causa raíz. - [Javascript Testing Patterns](https://skillsagentes.com/skills/wshobson/agents/javascript-testing-patterns.md): Implementa estrategias de testing con Jest, Vitest y Testing Library: tests unitarios, de integración y end-to-end, con mocking, fixtures y TDD/BDD. --- Skills Agentes · [Índice de páginas en markdown](https://skillsagentes.com/sitemap.md) · [Inicio](https://skillsagentes.com/index.md)