python-development
SKILL.md
Python Development
Comprehensive guide for writing idiomatic, type-safe, and performant Python 3.12+ code following modern best practices.
When to Use This Skill
- Writing new Python modules or packages
- Structuring Python project layout
- Implementing async services or I/O-bound code
- Applying Pythonic idioms and patterns
- Setting up Python projects with UV
Core Principles
1. Pythonic Code
- Follow the Zen of Python (
import this) - Prefer explicit over implicit
- Use list/dict/set comprehensions when they improve readability
- Leverage context managers for resource handling
- Apply decorators for cross-cutting concerns
- Use generators for memory-efficient iteration
2. Type Safety
- Add type hints for all function signatures and class attributes
- Use
typingmodule features:Optional,Union,TypeVar,Generic,Protocol - Prefer
TypedDictfor structured dictionaries - Use
Literaltypes for constants - Enable strict mypy checking when possible
- Leverage Pydantic for runtime validation
3. Code Quality Standards
- Follow PEP 8 style guidelines
- Use Ruff for formatting and linting (replaces Black, flake8, isort)
- Write comprehensive docstrings (Google style preferred)
- Ensure test coverage exceeds 90% with pytest
- Use meaningful variable and function names
4. Error Handling
- Create custom exception hierarchies for domain errors
- Use specific exceptions over generic ones
- Apply proper exception chaining with
from - Log errors with appropriate context
- Never silence exceptions without explicit reason
5. Async Programming
- Use
async/awaitfor I/O-bound operations - Prefer
asynciofor concurrent I/O - Use
concurrent.futuresfor CPU-bound tasks - Apply proper async context managers
- Handle cancellation and timeouts gracefully
Project Structure
src/
├── {package_name}/
│ ├── __init__.py
│ ├── main.py # Entry point
│ ├── models/ # Domain models (Pydantic/dataclasses)
│ ├── services/ # Business logic
│ ├── api/ # API layer (FastAPI/Flask)
│ └── utils/ # Shared utilities
tests/
├── conftest.py # Shared fixtures
├── unit/ # Unit tests
└── integration/ # Integration tests
pyproject.toml # Project configuration
Code Patterns
Protocol for Interfaces
from typing import Protocol
class Repository(Protocol):
def get(self, id: str) -> dict | None: ...
def save(self, entity: dict) -> None: ...
def delete(self, id: str) -> bool: ...
Dataclass with Validation
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class Module:
name: str
version: str
dependencies: list[str] = field(default_factory=list)
description: Optional[str] = None
def __post_init__(self) -> None:
if not self.name:
raise ValueError("Module name cannot be empty")
Context Manager Pattern
from contextlib import contextmanager
from typing import Iterator
@contextmanager
def managed_resource(name: str) -> Iterator[Resource]:
resource = acquire_resource(name)
try:
yield resource
finally:
resource.cleanup()
Async Service Pattern
import asyncio
from typing import AsyncIterator
async def process_items(items: list[str]) -> AsyncIterator[Result]:
async with aiohttp.ClientSession() as session:
tasks = [process_item(session, item) for item in items]
for result in asyncio.as_completed(tasks):
yield await result
Custom Exception Hierarchy
class AppError(Exception):
"""Base application error."""
def __init__(self, message: str, code: str = "UNKNOWN") -> None:
self.message = message
self.code = code
super().__init__(message)
class NotFoundError(AppError):
def __init__(self, resource: str, id: str) -> None:
super().__init__(f"{resource} '{id}' not found", code="NOT_FOUND")
class ValidationError(AppError):
def __init__(self, field: str, reason: str) -> None:
super().__init__(f"Validation failed for '{field}': {reason}", code="VALIDATION")
Package Management with UV
# Install dependencies
uv sync
# Add a dependency
uv add {package}
# Add a dev dependency
uv add --dev {package}
# Run a command
uv run python -m pytest
# Run the application
uv run python -m {package_name}
Quality Commands
# Format code
uv run ruff format .
# Lint code
uv run ruff check .
# Fix auto-fixable lint issues
uv run ruff check --fix .
# Type check
uv run mypy .
# Run tests with coverage
uv run pytest --cov={package_name} --cov-report=term-missing
# Run all quality checks
uv run ruff format . && uv run ruff check . && uv run mypy . && uv run pytest
Testing Patterns
Pytest Fixtures
import pytest
from typing import Generator
@pytest.fixture
def sample_config() -> dict:
return {"key": "value", "count": 42}
@pytest.fixture
def mock_service(mocker) -> Generator[MockService, None, None]:
service = MockService()
mocker.patch("module.Service", return_value=service)
yield service
Parameterized Tests
import pytest
@pytest.mark.parametrize(
"input_value,expected",
[
("hello", "HELLO"),
("world", "WORLD"),
("", ""),
],
)
def test_uppercase(input_value: str, expected: str) -> None:
assert input_value.upper() == expected
Development Workflow
- Analyze First — Review existing code patterns,
pyproject.toml, and project conventions - Implement with Quality — Start with clear interfaces (Protocols or ABCs), use dataclasses or Pydantic, add type hints as you code
- Test Thoroughly — Write tests alongside implementation, use pytest fixtures, parameterize edge cases
- Validate Quality — Run
ruff check,ruff format,mypy, andpytest
Guidelines
- Check
pyproject.tomlfor project-specific configurations - Follow existing patterns in the codebase
- Maintain consistency with established conventions
- Update tests when modifying functionality
- Document public APIs with docstrings
- Reference PEPs when relevant
- Consider performance implications and mention trade-offs
Weekly Installs
1
Repository
franciscosanche…factu-esFirst Seen
13 days ago
Security Audits
Installed on
mcpjam1
claude-code1
junie1
windsurf1
zencoder1
crush1