skills/python/SKILL.md
Guides Python development with modern idioms, tooling, and project structure. ALWAYS trigger on "python project", "pyproject.toml", "ruff", "mypy", "pytest", "poetry", "python setup", "type hints", "pydantic", "dataclass", "async python", "asyncio", "python anti-pattern", "python best practices", "python tooling", "python lint". Use when setting up Python projects, configuring tooling, choosing data modeling approaches, or writing tests. Different from testing skill which covers general test strategy; this covers Python-specific pytest patterns and tooling configs.
npx skillsauth add aj-geddes/unicorn-team pythonInstall 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.
# Union with | operator
def process(value: int | str | None) -> dict[str, int]: ...
# Type aliases
type UserID = int
type Config = dict[str, str | int | bool]
# See references/type-hints-advanced.md for:
# - Generics and TypeVars
# - Protocols (structural typing)
# - Function overloading
# Fixtures
@pytest.fixture
def sample_user():
return {"name": "Alice", "email": "[email protected]"}
# Parametrize
@pytest.mark.parametrize("input,expected", [
(0, 0), (1, 1), (2, 4),
])
def test_square(input, expected):
assert input ** 2 == expected
# Mock with pytest-mock
def test_api(mocker):
mock_get = mocker.patch("requests.get")
mock_get.return_value.json.return_value = {"status": "ok"}
result = fetch_data()
assert result["status"] == "ok"
Coverage target: 80%+
pytest --cov=myapp --cov-report=term-missing --cov-fail-under=80
See references/testing-pytest.md for advanced fixtures, mocking patterns, markers, plugins.
Replaces Black, isort, flake8, pyupgrade.
ruff check --fix . && ruff format .
# pyproject.toml
[tool.ruff]
line-length = 88
target-version = "py310"
[tool.ruff.lint]
select = ["E", "W", "F", "I", "N", "UP", "B", "C4", "SIM"]
ignore = ["E501"]
[tool.ruff.format]
quote-style = "double"
[tool.mypy]
python_version = "3.10"
strict = true
warn_return_any = true
disallow_untyped_defs = true
poetry init
poetry add requests
poetry add --group dev pytest pytest-cov ruff mypy
poetry install
poetry run pytest
See references/tooling-config.md for complete ruff rule sets, mypy options, pre-commit hooks, CI/CD.
# Concurrent execution
async def fetch_all(urls: list[str]) -> list[dict]:
return await asyncio.gather(*[fetch_data(url) for url in urls])
# Async context manager
class AsyncDatabase:
async def __aenter__(self):
self.connection = await connect()
return self
async def __aexit__(self, *args):
await self.connection.close()
See references/async-patterns.md for task management, semaphores, queues, error handling, pitfalls.
| Use case | Choose | Why |
|----------|--------|-----|
| Internal data, simple containers | @dataclass | Stdlib, fast, no deps |
| Performance-critical, immutable | @dataclass(frozen=True, slots=True) | Minimal overhead |
| External/untrusted data, APIs | pydantic.BaseModel | Auto-validation, serialization |
| Config from environment | pydantic_settings.BaseSettings | Env var parsing, type coercion |
# Dataclass: internal data
@dataclass(frozen=True)
class Point:
x: float
y: float
# Pydantic: external data with validation
class UserCreate(BaseModel):
name: str = Field(..., min_length=1, max_length=100)
email: EmailStr
age: int = Field(..., ge=0, le=150)
@field_validator("email")
@classmethod
def normalize_email(cls, v: str) -> str:
return v.lower().strip()
See references/dataclasses-pydantic.md for advanced features, nested models, settings, JSON schema.
| Anti-pattern | Fix |
|-------------|-----|
| Mutable default def f(x=[]) | def f(x=None) then x = x or [] |
| Bare except: | except SpecificError as e: |
| == None / == True | is None / is True |
| Modify list while iterating | List comprehension filter |
| f = open() without with | with open() as f: |
| String concat in loop += | "".join(...) |
| Manual index counter | enumerate() |
| type(x) == list | isinstance(x, list) |
| print() debugging | logging.getLogger(__name__) |
| Star imports from x import * | Explicit imports |
# 1. Initialize
poetry init
poetry add <dependencies>
poetry add --group dev pytest pytest-cov ruff mypy pre-commit
# 2. Configure pyproject.toml
# [tool.ruff], [tool.mypy], [tool.pytest.ini_options]
# 3. Install hooks
pre-commit install
# 4. Full quality check
ruff check --fix . && ruff format . && mypy . && pytest --cov=myapp --cov-fail-under=80
ruff format . && ruff check --fix . # Format + lint
mypy . # Type check
pytest --cov=myapp --cov-report=term-missing --cov-fail-under=80 # Test + coverage
development
Orchestrates long-running, multi-iteration tasks with Fable-5-style checkpointing, resume packs, self-paced scheduling, and per-iteration enforcement gates. ALWAYS trigger on "long running task", "keep working", "work overnight", "autonomous loop", "checkpoint", "resume where we left off", "iterate until done", "multi-session task", "self-pacing", "background build". Use when a task spans multiple iterations, sessions, or context windows. Different from orchestrator which routes a single pass -- this skill manages state, pacing, and enforcement across iterations.
tools
Coordinates the 10X Unicorn agent team with cost-aware model tiering, MCP-aware routing, and workflow fan-out. ALWAYS trigger on "implement", "build", "create", "design system", "deploy", "learn new language", "refactor", "fix bug", "set up CI", "code review", "how long will this take", "estimate", "architecture", "add feature", "write code", "debug", "review PR", "set up pipeline", "migrate", "optimize". Use for any multi-step task, implementation request, architecture decision, or quality enforcement. Different from individual agent skills which handle execution -- this skill handles coordination, routing, model selection, and quality gates.
development
Guides the user through test-first development and test strategy decisions. ALWAYS trigger on "write tests", "TDD", "test coverage", "mock", "test fails", "flaky test", "how to test", "unit test", "integration test", "e2e test", "test structure", "what to test", "test organization", "coverage report", "testing strategy", "arrange act assert". Use when writing new tests, choosing test types, setting up mocking, debugging flaky tests, improving coverage, or designing testable code. Different from qa-security agent which focuses on code review and security audits rather than test authoring.
development
Guides deliberate management of technical debt: recognition, tracking, prioritization, and paydown. ALWAYS trigger on "technical debt", "code shortcut", "pay down debt", "debt tracking", "just for now", "temporary hack", "hardcoded value", "copy-paste code", "missing tests", "TODO cleanup", "refactor plan", "debt priority", "interest cost", "boy scout rule", "code quality backlog". Use when taking a shortcut, discovering suboptimal code, planning debt paydown, or quantifying ongoing cost of compromises.