python-development

Core Python language concepts, idioms, and best practices.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "python-development" with this command: npx skills add laurigates/claude-plugins/laurigates-claude-plugins-python-development

Python Development

Core Python language concepts, idioms, and best practices.

Core Expertise

  • Python Language: Modern Python 3.10+ features and idioms

  • Best Practices: Pythonic code, design patterns, SOLID principles

  • Debugging: Interactive debugging and profiling techniques

  • Performance: Optimization strategies and profiling

  • Async Programming: async/await patterns and asyncio

Modern Python Features (3.10+)

Type Hints

Modern syntax (Python 3.10+)

def process_items( items: list[str], # Not List[str] mapping: dict[str, int], # Not Dict[str, int] optional: str | None = None, # Not Optional[str] ) -> tuple[bool, str]: # Not Tuple[bool, str] """Process items with modern type hints.""" return True, "success"

Type aliases

type UserId = int type UserDict = dict[str, str | int]

def get_user(user_id: UserId) -> UserDict: return {"id": user_id, "name": "Alice"}

Pattern Matching (3.10+)

def handle_command(command: dict) -> str: match command: case {"action": "create", "item": item}: return f"Creating {item}" case {"action": "delete", "item": item}: return f"Deleting {item}" case {"action": "list"}: return "Listing items" case _: return "Unknown command"

Structural Pattern Matching

def process_response(response): match response: case {"status": 200, "data": data}: return process_success(data) case {"status": 404}: raise NotFoundError() case {"status": code} if code >= 500: raise ServerError(code)

Python Idioms

Context Managers

File handling

with open("file.txt") as f: content = f.read()

Custom context manager

from contextlib import contextmanager

@contextmanager def database_connection(): conn = create_connection() try: yield conn finally: conn.close()

with database_connection() as conn: conn.execute("SELECT * FROM users")

List Comprehensions

List comprehension

squares = [x**2 for x in range(10)]

Dict comprehension

word_lengths = {word: len(word) for word in ["hello", "world"]}

Set comprehension

unique_lengths = {len(word) for word in ["hello", "world", "hi"]}

Generator expression

sum_of_squares = sum(x**2 for x in range(1000000)) # Memory efficient

Iterators and Generators

def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b

Use generator

fib = fibonacci() first_ten = [next(fib) for _ in range(10)]

Generator expression

even_squares = (x**2 for x in range(10) if x % 2 == 0)

Debugging

Interactive Debugging

import pdb

def problematic_function(): value = calculate() pdb.set_trace() # Debugger breakpoint return process(value)

Debug on error

python -m pdb script.py

pytest with debugger

uv run pytest --pdb # Drop into pdb on failure uv run pytest --pdb --pdbcls=IPython.terminal.debugger:TerminalPdb

Performance Profiling

CPU profiling

uv run python -m cProfile -s cumtime script.py | head -20

Line-by-line profiling (temporary dependency)

uv run --with line-profiler kernprof -l -v script.py

Memory profiling (temporary dependency)

uv run --with memory-profiler python -m memory_profiler script.py

Real-time profiling (ephemeral tool)

uvx py-spy top -- python script.py

Quick profiling with scalene

uv run --with scalene python -m scalene script.py

Built-in Debugging Tools

Trace execution

import sys

def trace_calls(frame, event, arg): if event == 'call': print(f"Calling {frame.f_code.co_name}") return trace_calls

sys.settrace(trace_calls)

Memory tracking

import tracemalloc

tracemalloc.start()

... code to profile

snapshot = tracemalloc.take_snapshot() top_stats = snapshot.statistics('lineno') for stat in top_stats[:10]: print(stat)

Async Programming

Basic async/await

import asyncio

async def fetch_data(url: str) -> dict: async with httpx.AsyncClient() as client: response = await client.get(url) return response.json()

async def main(): result = await fetch_data("https://api.example.com") print(result)

asyncio.run(main())

Concurrent Tasks

async def process_multiple(): # Run concurrently results = await asyncio.gather( fetch_data("url1"), fetch_data("url2"), fetch_data("url3"), ) return results

With timeout

async def with_timeout(): try: result = await asyncio.wait_for(fetch_data("url"), timeout=5.0) except asyncio.TimeoutError: print("Request timed out")

Design Patterns

Dependency Injection

from typing import Protocol

class Database(Protocol): def query(self, sql: str) -> list: ...

def get_users(db: Database) -> list: return db.query("SELECT * FROM users")

Factory Pattern

def create_handler(handler_type: str): match handler_type: case "json": return JSONHandler() case "xml": return XMLHandler() case _: raise ValueError(f"Unknown handler: {handler_type}")

Decorator Pattern

from functools import wraps import time

def timer(func): @wraps(func) def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(f"{func.name} took {end - start:.2f}s") return result return wrapper

@timer def slow_function(): time.sleep(1)

Best Practices

SOLID Principles

Single Responsibility:

Bad: Class does too much

class User: def save(self): pass def send_email(self): pass def generate_report(self): pass

Good: Separate concerns

class User: def save(self): pass

class EmailService: def send_email(self, user): pass

class ReportGenerator: def generate(self, user): pass

Fail Fast

def process_data(data: dict) -> str: # Validate early if not data: raise ValueError("Data cannot be empty") if "required_field" not in data: raise KeyError("Missing required field")

# Process with confidence
return data["required_field"].upper()

Functional Approach

Prefer immutable transformations

def process_items(items: list[int]) -> list[int]: return [item * 2 for item in items] # New list

Over mutations

def process_items_bad(items: list[int]) -> None: for i in range(len(items)): items[i] *= 2 # Mutates input

Project Structure (src layout)

my-project/ ├── pyproject.toml ├── README.md ├── src/ │ └── my_project/ │ ├── init.py │ ├── core.py │ ├── utils.py │ └── models.py └── tests/ ├── conftest.py ├── test_core.py └── test_utils.py

See Also

  • uv-run - Running scripts, temporary dependencies, PEP 723

  • uv-project-management - Project setup and dependency management

  • uv-tool-management - Installing CLI tools globally

  • python-testing - Testing with pytest

  • python-code-quality - Linting and type checking with ruff/ty

  • python-packaging - Building and publishing packages

  • uv-python-versions - Managing Python interpreters

References

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

python-code-quality

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

clippy-advanced

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

python-testing

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

rust-development

No summary provided by upstream source.

Repository SourceNeeds Review