python-patterns/SKILL.md
Pythonic idioms, PEP 8 standards, type hints, and best practices for building robust, efficient, and maintainable Python applications.
npx skillsauth add lidge-jun/cli-jaw-skills python-patternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Idiomatic Python patterns and best practices for building robust, efficient, and maintainable applications.
Full code examples: references/code-examples.md
Python prioritizes readability. Code should be obvious and easy to understand.
# Good: Clear and readable
def get_active_users(users: list[User]) -> list[User]:
return [user for user in users if user.is_active]
Avoid magic; be clear about what your code does.
Python prefers exception handling over checking conditions.
# Good: EAFP style
try:
return dictionary[key]
except KeyError:
return default_value
Use built-in types directly. Fall back to typing module for Python 3.8.
# Python 3.9+
def process_items(items: list[str]) -> dict[str, int]:
return {item: len(item) for item in items}
from typing import TypeVar, Union
JSON = Union[dict[str, Any], list[Any], str, int, float, bool, None]
T = TypeVar('T')
def first(items: list[T]) -> T | None:
return items[0] if items else None
from typing import Protocol
class Renderable(Protocol):
def render(self) -> str: ...
def render_all(items: list[Renderable]) -> str:
return "\n".join(item.render() for item in items)
except:raise ... from e to preserve tracebacksdef load_config(path: str) -> Config:
try:
with open(path) as f:
return Config.from_json(f.read())
except FileNotFoundError as e:
raise ConfigError(f"Config file not found: {path}") from e
except json.JSONDecodeError as e:
raise ConfigError(f"Invalid JSON in config: {path}") from e
Use with for all resource management. Create custom context managers with @contextmanager or __enter__/__exit__.
from contextlib import contextmanager
@contextmanager
def timer(name: str):
start = time.perf_counter()
yield
elapsed = time.perf_counter() - start
print(f"{name} took {elapsed:.4f} seconds")
# Generator for lazy evaluation — avoids building full list in memory
total = sum(x * x for x in range(1_000_000))
Keep comprehensions simple — if they need multiple conditions or nested loops, use a function instead.
@dataclass for data containers with auto-generated methods__post_init__ for validationNamedTuple for immutable datafrom dataclasses import dataclass, field
@dataclass
class User:
id: str
name: str
email: str
created_at: datetime = field(default_factory=datetime.now)
is_active: bool = True
@functools.wraps to preserve function metadataimport functools
def timer(func: Callable) -> Callable:
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
elapsed = time.perf_counter() - start
print(f"{func.__name__} took {elapsed:.4f}s")
return result
return wrapper
| Task Type | Tool | Why |
|-----------|------|-----|
| I/O-bound (network, files) | ThreadPoolExecutor | GIL released during I/O |
| CPU-bound (compute) | ProcessPoolExecutor | Separate processes bypass GIL |
| Concurrent I/O (async) | asyncio + aiohttp | Single-thread event loop |
# Threading for I/O-bound tasks
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
future_to_url = {executor.submit(fetch_url, url): url for url in urls}
for future in concurrent.futures.as_completed(future_to_url):
url = future_to_url[future]
results[url] = future.result()
myproject/
├── src/mypackage/
│ ├── __init__.py
│ ├── main.py
│ ├── api/
│ ├── models/
│ └── utils/
├── tests/
├── pyproject.toml
└── README.md
Use isort for automatic sorting.
__init__.py Exports__version__ = "1.0.0"
from mypackage.models import User, Post
from mypackage.utils import format_name
__all__ = ["User", "Post", "format_name"]
__slots__: reduces memory for classes with many instancesstr.join(): O(n) vs O(n²) for string concatenation in loopspathlib.Path: prefer over os.path for path operations# Formatting
black .
isort .
# Linting
ruff check .
# Type checking
mypy .
# Testing
pytest --cov=mypackage --cov-report=html
# Security
bandit -r .
pip-audit
[project]
name = "mypackage"
version = "1.0.0"
requires-python = ">=3.9"
dependencies = ["requests>=2.31.0", "pydantic>=2.0.0"]
[project.optional-dependencies]
dev = ["pytest>=7.4.0", "black>=23.0.0", "ruff>=0.1.0", "mypy>=1.5.0"]
[tool.black]
line-length = 88
target-version = ['py39']
[tool.ruff]
line-length = 88
select = ["E", "F", "I", "N", "W"]
[tool.mypy]
python_version = "3.9"
warn_return_any = true
disallow_untyped_defs = true
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "--cov=mypackage --cov-report=term-missing"
| Idiom | Description |
|-------|-------------|
| EAFP | Easier to Ask Forgiveness than Permission |
| Context managers | Use with for resource management |
| List comprehensions | For simple transformations |
| Generators | For lazy evaluation and large datasets |
| Type hints | Annotate function signatures |
| Dataclasses | For data containers with auto-generated methods |
| __slots__ | For memory optimization |
| f-strings | For string formatting (Python 3.6+) |
| pathlib.Path | For path operations (Python 3.4+) |
| enumerate | For index-element pairs in loops |
| Anti-Pattern | Fix |
|---|---|
| Mutable default args (def f(x=[])) | Use None and create inside |
| type(obj) == list | Use isinstance(obj, list) |
| value == None | Use value is None |
| from module import * | Explicit imports |
| Bare except: | Catch specific exceptions |
| String concatenation in loops | Use str.join() |
Python code should be readable, explicit, and follow the principle of least surprise. When in doubt, prioritize clarity over cleverness.
development
Goal execution guidelines with PABCD integration, verification tiers, documentation workflow, and AI-driven planning
tools
A CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.
development
Use this skill any time a spreadsheet file is the primary input or output (.xlsx, .xlsm, .csv, .tsv). This includes: creating, reading, editing, analyzing, or formatting spreadsheets; cleaning messy tabular data; converting between formats; and data visualization with charts. Also use for pandas-based data analysis when the deliverable is a spreadsheet. Do NOT trigger when the primary deliverable is a Word document, HTML report, standalone Python script, database pipeline, or Google Sheets API integration.
tools
Use this skill when the user wants to build a financial model, 3-statement model, DCF valuation, cap table, scenario analysis, or financial projections in Excel. Trigger on: 'financial model', '3-statement model', 'DCF', 'cap table', 'pro forma', 'projections', 'sensitivity analysis', 'waterfall', 'debt schedule', 'break-even', 'discounted cash flow', 'capitalization table', 'fundraising model', 'WACC calculation', 'scenario analysis model'. Input is a text prompt with assumptions. Output is a single .xlsx file with formula-driven, interconnected statement sheets.