mirror of
https://github.com/wshobson/agents.git
synced 2026-03-18 09:37:15 +00:00
Add Comprehensive Python Development Skills (#419)
* Add extra python skills covering code style, design patterns, resilience, resource management, testing patterns, and type safety ...etc * fix: correct code examples in Python skills - Clarify Python version requirements for type statement (3.10+ vs 3.12+) - Add missing ValidationError import in configuration example - Add missing httpx import and url parameter in async example --------- Co-authored-by: Seth Hobson <wshobson@gmail.com>
This commit is contained in:
360
plugins/python-development/skills/python-code-style/SKILL.md
Normal file
360
plugins/python-development/skills/python-code-style/SKILL.md
Normal file
@@ -0,0 +1,360 @@
|
||||
---
|
||||
name: python-code-style
|
||||
description: Python code style, linting, formatting, naming conventions, and documentation standards. Use when writing new code, reviewing style, configuring linters, writing docstrings, or establishing project standards.
|
||||
---
|
||||
|
||||
# Python Code Style & Documentation
|
||||
|
||||
Consistent code style and clear documentation make codebases maintainable and collaborative. This skill covers modern Python tooling, naming conventions, and documentation standards.
|
||||
|
||||
## When to Use This Skill
|
||||
|
||||
- Setting up linting and formatting for a new project
|
||||
- Writing or reviewing docstrings
|
||||
- Establishing team coding standards
|
||||
- Configuring ruff, mypy, or pyright
|
||||
- Reviewing code for style consistency
|
||||
- Creating project documentation
|
||||
|
||||
## Core Concepts
|
||||
|
||||
### 1. Automated Formatting
|
||||
|
||||
Let tools handle formatting debates. Configure once, enforce automatically.
|
||||
|
||||
### 2. Consistent Naming
|
||||
|
||||
Follow PEP 8 conventions with meaningful, descriptive names.
|
||||
|
||||
### 3. Documentation as Code
|
||||
|
||||
Docstrings should be maintained alongside the code they describe.
|
||||
|
||||
### 4. Type Annotations
|
||||
|
||||
Modern Python code should include type hints for all public APIs.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Install modern tooling
|
||||
pip install ruff mypy
|
||||
|
||||
# Configure in pyproject.toml
|
||||
[tool.ruff]
|
||||
line-length = 120
|
||||
target-version = "py312" # Adjust based on your project's minimum Python version
|
||||
|
||||
[tool.mypy]
|
||||
strict = true
|
||||
```
|
||||
|
||||
## Fundamental Patterns
|
||||
|
||||
### Pattern 1: Modern Python Tooling
|
||||
|
||||
Use `ruff` as an all-in-one linter and formatter. It replaces flake8, isort, and black with a single fast tool.
|
||||
|
||||
```toml
|
||||
# pyproject.toml
|
||||
[tool.ruff]
|
||||
line-length = 120
|
||||
target-version = "py312" # Adjust based on your project's minimum Python version
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = [
|
||||
"E", # pycodestyle errors
|
||||
"W", # pycodestyle warnings
|
||||
"F", # pyflakes
|
||||
"I", # isort
|
||||
"B", # flake8-bugbear
|
||||
"C4", # flake8-comprehensions
|
||||
"UP", # pyupgrade
|
||||
"SIM", # flake8-simplify
|
||||
]
|
||||
ignore = ["E501"] # Line length handled by formatter
|
||||
|
||||
[tool.ruff.format]
|
||||
quote-style = "double"
|
||||
indent-style = "space"
|
||||
```
|
||||
|
||||
Run with:
|
||||
|
||||
```bash
|
||||
ruff check --fix . # Lint and auto-fix
|
||||
ruff format . # Format code
|
||||
```
|
||||
|
||||
### Pattern 2: Type Checking Configuration
|
||||
|
||||
Configure strict type checking for production code.
|
||||
|
||||
```toml
|
||||
# pyproject.toml
|
||||
[tool.mypy]
|
||||
python_version = "3.12"
|
||||
strict = true
|
||||
warn_return_any = true
|
||||
warn_unused_ignores = true
|
||||
disallow_untyped_defs = true
|
||||
disallow_incomplete_defs = true
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = "tests.*"
|
||||
disallow_untyped_defs = false
|
||||
```
|
||||
|
||||
Alternative: Use `pyright` for faster checking.
|
||||
|
||||
```toml
|
||||
[tool.pyright]
|
||||
pythonVersion = "3.12"
|
||||
typeCheckingMode = "strict"
|
||||
```
|
||||
|
||||
### Pattern 3: Naming Conventions
|
||||
|
||||
Follow PEP 8 with emphasis on clarity over brevity.
|
||||
|
||||
**Files and Modules:**
|
||||
|
||||
```python
|
||||
# Good: Descriptive snake_case
|
||||
user_repository.py
|
||||
order_processing.py
|
||||
http_client.py
|
||||
|
||||
# Avoid: Abbreviations
|
||||
usr_repo.py
|
||||
ord_proc.py
|
||||
http_cli.py
|
||||
```
|
||||
|
||||
**Classes and Functions:**
|
||||
|
||||
```python
|
||||
# Classes: PascalCase
|
||||
class UserRepository:
|
||||
pass
|
||||
|
||||
class HTTPClientFactory: # Acronyms stay uppercase
|
||||
pass
|
||||
|
||||
# Functions and variables: snake_case
|
||||
def get_user_by_email(email: str) -> User | None:
|
||||
retry_count = 3
|
||||
max_connections = 100
|
||||
```
|
||||
|
||||
**Constants:**
|
||||
|
||||
```python
|
||||
# Module-level constants: SCREAMING_SNAKE_CASE
|
||||
MAX_RETRY_ATTEMPTS = 3
|
||||
DEFAULT_TIMEOUT_SECONDS = 30
|
||||
API_BASE_URL = "https://api.example.com"
|
||||
```
|
||||
|
||||
### Pattern 4: Import Organization
|
||||
|
||||
Group imports in a consistent order: standard library, third-party, local.
|
||||
|
||||
```python
|
||||
# Standard library
|
||||
import os
|
||||
from collections.abc import Callable
|
||||
from typing import Any
|
||||
|
||||
# Third-party packages
|
||||
import httpx
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy import Column
|
||||
|
||||
# Local imports
|
||||
from myproject.models import User
|
||||
from myproject.services import UserService
|
||||
```
|
||||
|
||||
Use absolute imports exclusively:
|
||||
|
||||
```python
|
||||
# Preferred
|
||||
from myproject.utils import retry_decorator
|
||||
|
||||
# Avoid relative imports
|
||||
from ..utils import retry_decorator
|
||||
```
|
||||
|
||||
## Advanced Patterns
|
||||
|
||||
### Pattern 5: Google-Style Docstrings
|
||||
|
||||
Write docstrings for all public classes, methods, and functions.
|
||||
|
||||
**Simple Function:**
|
||||
|
||||
```python
|
||||
def get_user(user_id: str) -> User:
|
||||
"""Retrieve a user by their unique identifier."""
|
||||
...
|
||||
```
|
||||
|
||||
**Complex Function:**
|
||||
|
||||
```python
|
||||
def process_batch(
|
||||
items: list[Item],
|
||||
max_workers: int = 4,
|
||||
on_progress: Callable[[int, int], None] | None = None,
|
||||
) -> BatchResult:
|
||||
"""Process items concurrently using a worker pool.
|
||||
|
||||
Processes each item in the batch using the configured number of
|
||||
workers. Progress can be monitored via the optional callback.
|
||||
|
||||
Args:
|
||||
items: The items to process. Must not be empty.
|
||||
max_workers: Maximum concurrent workers. Defaults to 4.
|
||||
on_progress: Optional callback receiving (completed, total) counts.
|
||||
|
||||
Returns:
|
||||
BatchResult containing succeeded items and any failures with
|
||||
their associated exceptions.
|
||||
|
||||
Raises:
|
||||
ValueError: If items is empty.
|
||||
ProcessingError: If the batch cannot be processed.
|
||||
|
||||
Example:
|
||||
>>> result = process_batch(items, max_workers=8)
|
||||
>>> print(f"Processed {len(result.succeeded)} items")
|
||||
"""
|
||||
...
|
||||
```
|
||||
|
||||
**Class Docstring:**
|
||||
|
||||
```python
|
||||
class UserService:
|
||||
"""Service for managing user operations.
|
||||
|
||||
Provides methods for creating, retrieving, updating, and
|
||||
deleting users with proper validation and error handling.
|
||||
|
||||
Attributes:
|
||||
repository: The data access layer for user persistence.
|
||||
logger: Logger instance for operation tracking.
|
||||
|
||||
Example:
|
||||
>>> service = UserService(repository, logger)
|
||||
>>> user = service.create_user(CreateUserInput(...))
|
||||
"""
|
||||
|
||||
def __init__(self, repository: UserRepository, logger: Logger) -> None:
|
||||
"""Initialize the user service.
|
||||
|
||||
Args:
|
||||
repository: Data access layer for users.
|
||||
logger: Logger for tracking operations.
|
||||
"""
|
||||
self.repository = repository
|
||||
self.logger = logger
|
||||
```
|
||||
|
||||
### Pattern 6: Line Length and Formatting
|
||||
|
||||
Set line length to 120 characters for modern displays while maintaining readability.
|
||||
|
||||
```python
|
||||
# Good: Readable line breaks
|
||||
def create_user(
|
||||
email: str,
|
||||
name: str,
|
||||
role: UserRole = UserRole.MEMBER,
|
||||
notify: bool = True,
|
||||
) -> User:
|
||||
...
|
||||
|
||||
# Good: Chain method calls clearly
|
||||
result = (
|
||||
db.query(User)
|
||||
.filter(User.active == True)
|
||||
.order_by(User.created_at.desc())
|
||||
.limit(10)
|
||||
.all()
|
||||
)
|
||||
|
||||
# Good: Format long strings
|
||||
error_message = (
|
||||
f"Failed to process user {user_id}: "
|
||||
f"received status {response.status_code} "
|
||||
f"with body {response.text[:100]}"
|
||||
)
|
||||
```
|
||||
|
||||
### Pattern 7: Project Documentation
|
||||
|
||||
**README Structure:**
|
||||
|
||||
```markdown
|
||||
# Project Name
|
||||
|
||||
Brief description of what the project does.
|
||||
|
||||
## Installation
|
||||
|
||||
\`\`\`bash
|
||||
pip install myproject
|
||||
\`\`\`
|
||||
|
||||
## Quick Start
|
||||
|
||||
\`\`\`python
|
||||
from myproject import Client
|
||||
|
||||
client = Client(api_key="...")
|
||||
result = client.process(data)
|
||||
\`\`\`
|
||||
|
||||
## Configuration
|
||||
|
||||
Document environment variables and configuration options.
|
||||
|
||||
## Development
|
||||
|
||||
\`\`\`bash
|
||||
pip install -e ".[dev]"
|
||||
pytest
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
**CHANGELOG Format (Keep a Changelog):**
|
||||
|
||||
```markdown
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- New feature X
|
||||
|
||||
### Changed
|
||||
- Modified behavior of Y
|
||||
|
||||
### Fixed
|
||||
- Bug in Z
|
||||
```
|
||||
|
||||
## Best Practices Summary
|
||||
|
||||
1. **Use ruff** - Single tool for linting and formatting
|
||||
2. **Enable strict mypy** - Catch type errors before runtime
|
||||
3. **120 character lines** - Modern standard for readability
|
||||
4. **Descriptive names** - Clarity over brevity
|
||||
5. **Absolute imports** - More maintainable than relative
|
||||
6. **Google-style docstrings** - Consistent, readable documentation
|
||||
7. **Document public APIs** - Every public function needs a docstring
|
||||
8. **Keep docs updated** - Treat documentation as code
|
||||
9. **Automate in CI** - Run linters on every commit
|
||||
10. **Target Python 3.10+** - For new projects, Python 3.12+ is recommended for modern language features
|
||||
Reference in New Issue
Block a user