Python development — use when the user works with .py files, pyproject.toml, uv, ruff, mypy, pytest, async/await, MicroPython, CLI tools, or PyPI publishing. Covers modern tooling, best practices, library architecture, functional patterns, and production workflows. NOT for TypeScript or JavaScript development (use typescript-development), NOT for React component patterns (use react-development).
Install to Claude Code
npx -y skills add viktorbezdek/skillstack --skill python-development --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Python Development?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/viktorbezdek-python-development)More formats (shields.io, HTML) on the badges page.
---
name: python-development
description: Python development — use when the user works with .py files, pyproject.toml, uv, ruff, mypy, pytest, async/await, MicroPython, CLI tools, or PyPI publishing. Covers modern tooling, best practices, library architecture, functional patterns, and production workflows. NOT for TypeScript or JavaScript development (use typescript-development), NOT for React component patterns (use react-development).
---
# Python Development - Comprehensive Skill
Expert guidance for modern Python development (Python 3.11-3.14+), covering everything from simple scripts to production-grade systems, library architecture, and embedded development.
## When to Use This Skill
Activate this skill when:
- Working with `.py` files, `pyproject.toml`, or `uv.lock`
- Writing, testing, or reviewing Python code
- Managing Python dependencies or virtual environments
- Using commands like `uv`, `pytest`, `ruff`, or `mypy`
- Building CLI applications with Typer/Click
- Designing Python libraries or packages
- Working with async/await patterns
- Developing for embedded systems (MicroPython, RP2350)
- Setting up CI/CD for Python projects
- Publishing packages to PyPI
## When NOT to Use This Skill
- **TypeScript or JavaScript development** → use `typescript-development`
- **React component patterns or hooks** → use `react-development`
- **TDD methodology (Red-Green-Refactor cycle)** → use `test-driven-development` (this skill covers pytest patterns but not the full TDD workflow)
- **Django/Flask framework-specific patterns** → this skill covers Python fundamentals; dedicated framework plugins provide deeper coverage
## Decision Trees
### Tier Selection
```
What are you building?
│
├─ Single-file script, one-off utility, quick data processing
│ └─ MINIMAL tier: PEP 723 inline metadata, no project scaffolding
│
├─ Multi-file project, team development, anything with tests
│ └─ STANDARD tier (default): src/ layout + uv + ruff + mypy + pytest
│
└─ PyPI package, production system requiring CI/CD
└─ FULL tier: Complete tooling + bandit + CI/CD + release workflow
```
**Default to Standard** — it covers most use cases.
### Async vs Sync Decision
```
Does the task involve I/O-bound operations (HTTP, DB, file, network)?
│
├─ No → Use synchronous code (simpler, easier to debug)
│
└─ Yes → Are operations concurrent (many requests at once)?
│
├─ No → Simple async/await with httpx.AsyncClient
│
└─ Yes → asyncio.Semaphore per resource + httpx.AsyncClient
with connection pooling + retry logic
```
### Protocol vs ABC Decision
```
Do you need structural subtyping (duck typing with type safety)?
│
├─ Yes → Protocol
│ └─ Enables dependency injection, avoids inheritance coupling
│
└─ No → Do you need runtime type checking or enforced method implementation?
│
├─ Yes → ABC with @abstractmethod
│
└─ No → Protocol (lighter weight, preferred default)
```
### Library vs Application Architecture Decision
```
Will this code be imported by other projects?
│
├─ Yes → Library architecture:
│ - Protocol-based API surface
│ - py.typed marker
│ - Minimal public exports (__all__)
│ - Stable deprecation policy
│ - pyproject.toml with [project.optional-dependencies]
│
└─ No → Application architecture:
- Direct implementation (no Protocol overhead)
- Simpler project structure
- pyproject.toml with [project.scripts]
```
## Quick Start
### Standard Project Setup
```bash
# Install Python 3.12+ and uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# Create new project
uv init my-project
cd my-project
# Add dependencies
uv add requests pydantic httpx
# Add dev dependencies
uv add --dev pytest pytest-cov ruff mypy
# Run quality checks
uv run ruff check . # Linting
uv run ruff format . # Formatting
uv run mypy . # Type checking
uv run pytest --cov # Tests with coverage
```
## Core Principles
1. **Use uv for everything**: 10-100x faster than pip, all-in-one tool
2. **Type hints everywhere**: Use type annotations for all functions and classes
3. **Ruff for quality**: Single tool for linting and formatting (replaces Black, flake8, isort)
4. **Test with pytest**: Comprehensive tests with fixtures and parametrization
5. **Lock dependencies**: Always maintain `uv.lock` for reproducible builds
6. **PEP 723 for scripts**: Use inline script metadata for single-file scripts
## Modern Python Toolchain
### Package Management: uv
Use current tool documentation when exact flags matter; uv, ruff, mypy, and pytest move quickly. The defaults below are stable project-starting patterns, not a substitute for checking release notes during migrations.
```bash
uv init my-project && cd my-project # Initialize
uv add requests pandas numpy # Add deps
uv add --dev pytest ruff mypy # Add dev deps
uv sync # Sync with lockfile
uv lock --upgrade # Update lockfile
uv run python script.py # Run code
uv run pytest # Run tests
```
### Code Quality: ruff
```bash
ruff check . # Check for issues
ruff check --fix . # Auto-fix issues
ruff format . # Format code
```
### Type Checking: mypy
```bash
mypy . # Type check entire project
mypy --strict . # Strict mode
```
## Project Structure
```
myproject/
├── src/
│ └── myproject/
│ ├── __init__.py
│ ├── main.py
│ └── utils.py
├── tests/
│ ├── __init__.py
│ ├── conftest.py
│ ├── test_main.py
│ └── test_utils.py
├── docs/
├── .gitignore
├── .python-version
├── pyproject.toml
├── uv.lock
└── README.md
```
### pyproject.toml Configuration
```toml
[project]
name = "myproject"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = ["requests>=2.31.0"]
[project.optional-dependencies]
dev = ["pytest>=8.0.0", "ruff>=0.8.0", "mypy>=1.13.0"]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.ruff]
line-length = 100
target-version = "py311"
[tool.ruff.lint]
select = ["E", "F", "I", "N", "W", "B", "Q"]
[tool.mypy]
python_version = "3.11"
strict = true
[tool.pytest.ini_options]
testpaths = ["tests"]
```
## Anti-Patterns to Avoid
| Anti-Pattern | Problem | Solution |
|-------------|---------|----------|
| **Mutable default args** `def f(lst=[])` | Default value is shared across all calls; mutations persist unexpectedly | `def f(lst: list \| None = None)` then `lst = lst or []` inside |
| **`requests.get` in async** | Blocks the event loop; all concurrent tasks stall | `httpx.AsyncClient` for async HTTP; `requests` only in sync code |
| **Classes for data bags** | Boilerplate `__init__`, mutable by default, no equality | `@dataclass(frozen=True)` for immutable value objects, or `NamedTuple` for lightweight records |
| **Deep inheritance hierarchies** | Tight coupling, fragile base class, hard to test | `Protocol` + composition; define behavior by what it does, not what it is |
| **Mutating function args** | Side effects make code unpredictable and hard to test | Return new values; use frozen dataclasses; prefer pure functions |
| **`try/except Exception`** | Swallows all errors including KeyboardInterrupt, SystemExit | Catch specific types: `except (ValueError, KeyError)` |
| **Blocking in async** | `time.sleep()`, `requests.get()`, `subprocess.run()` freeze the event loop | `await asyncio.to_thread(fn)` or `asyncio.sleep()` for non-blocking alternatives |
| **`from module import *`** | Pollutes namespace, makes dependencies invisible, breaks linters | Explicit imports: `from module import ClassA, func_b` |
| **Bare `except:`** | Catches everything including SystemExit/KeyboardInterrupt; hides bugs | `except (SpecificError, AnotherError):` |
| **Using `List[str]` etc.** | Legacy typing; deprecated since Python 3.9 | Use modern syntax: `list[str]`, `dict[str, int]`, `tuple[int, ...]` |
| **Ignoring mypy errors** | Type errors at compile time become runtime crashes | Fix the type; use `# type: ignore[specific-code]` with comment explaining why |
| **Testing with production URLs** | Tests hit real APIs, flaky, slow, depend on network | Mock HTTP calls with `pytest-httpx` or `respx`; test against fixtures |
## Quality Gates
Every Python task must pass:
1. **Format-first**: `uv run ruff format .`
2. **Linting**: `uv run ruff check .`
3. **Type checking**: `uv run mypy .`
4. **Tests**: `uv run pytest` (>80% coverage)
5. **Modern patterns**: No legacy typing (use `list[str]` not `List[str]`)
For critical code (payments, auth, security):
- Coverage >95%
- Security scan: `uv run bandit -r src/`
See [Extended Patterns](references/extended-patterns.md) for detailed code examples, testing patterns, async patterns, itertools/functools usage, library architecture, workflow routing, and complete reference file listings.
## Official Documentation
- Python: https://docs.python.org/
- uv: https://docs.astral.sh/uv/
- Ruff: https://docs.astral.sh/ruff/
- mypy: https://mypy-lang.org/
- pytest: https://docs.pytest.org/
- PEPs: https://peps.python.org/
Scanned 5/28/2026
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!