Python Core Knowledge
Full Reference: See advanced.md for production patterns: Result types, custom exceptions, structured logging, Pydantic validation, testing patterns, performance optimization, and dependency injection.
Deep Knowledge: Use mcp__documentation__fetch_docs with technology: python for comprehensive documentation.
Python Version Support
| Version |
Status |
Key Features |
| 3.14 |
Current |
Type defaults, JIT improvements |
| 3.13 |
Stable |
Free-threading (experimental), JIT |
| 3.12 |
Stable |
PEP 695 type syntax, f-string improvements |
| 3.11 |
Stable |
Exception groups, 10-60% faster |
| 3.10 |
Security |
Pattern matching, | union |
Type Hints (Modern Syntax)
# Python 3.10+ - Use | instead of Union
def greet(name: str | None = None) -> str:
return f"Hello, {name or 'World'}"
# Python 3.9+ - Use built-in generics
def process(items: list[str]) -> dict[str, int]:
return {item: len(item) for item in items}
# Python 3.12+ - PEP 695 Type Parameter Syntax
def first[T](items: list[T]) -> T | None:
return items[0] if items else None
class Stack[T]:
def __init__(self) -> None:
self._items: list[T] = []
def push(self, item: T) -> None:
self._items.append(item)
def pop(self) -> T:
return self._items.pop()
# Type aliases (Python 3.12+)
type Point = tuple[float, float]
type Vector[T] = list[T]
type Handler[T] = Callable[[T], None]
# Callable
def apply(fn: Callable[[int], int], value: int) -> int:
return fn(value)
Dataclasses
from dataclasses import dataclass, field
from datetime import datetime
@dataclass
class User:
id: int
name: str
email: str
created_at: datetime = field(default_factory=datetime.now)
is_active: bool = True
def __post_init__(self):
self.email = self.email.lower()
# Frozen (immutable)
@dataclass(frozen=True)
class Point:
x: float
y: float
# Slots for memory efficiency (Python 3.10+)
@dataclass(slots=True)
class Optimized:
value: int
Async/Await
import asyncio
import aiohttp
async def fetch_user(id: int) -> dict:
async with aiohttp.ClientSession() as session:
async with session.get(f'/api/users/{id}') as response:
return await response.json()
async def fetch_all_users(ids: List[int]) -> List[dict]:
tasks = [fetch_user(id) for id in ids]
return await asyncio.gather(*tasks)
# Run
asyncio.run(fetch_all_users([1, 2, 3]))
Context Managers
from contextlib import contextmanager, asynccontextmanager
@contextmanager
def timer():
start = time.time()
yield
print(f"Elapsed: {time.time() - start:.2f}s")
with timer():
process_data()
@asynccontextmanager
async def get_db():
db = await create_connection()
try:
yield db
finally:
await db.close()
Modern Patterns
# Match (3.10+)
match status:
case "active":
handle_active()
case "inactive" | "pending":
handle_pending()
case {"type": "user", "name": name}: # Dict pattern
handle_user(name)
case [first, *rest]: # Sequence pattern
handle_sequence(first, rest)
case _:
handle_default()
# Walrus operator
if (n := len(items)) > 10:
print(f"Too many: {n}")
# Exception groups (3.11+)
try:
async with asyncio.TaskGroup() as tg:
tg.create_task(task1())
tg.create_task(task2())
except* ValueError as eg:
for exc in eg.exceptions:
print(f"ValueError: {exc}")
except* TypeError as eg:
for exc in eg.exceptions:
print(f"TypeError: {exc}")
Static Analysis & Linting
Official Rules References
Style Guides
Ruff Configuration
# pyproject.toml
[tool.ruff]
line-length = 88
target-version = "py312"
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # Pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
"S", # flake8-bandit (security)
]
ignore = ["E501"] # line too long (handled by formatter)
[tool.ruff.lint.per-file-ignores]
"tests/*" = ["S101"] # allow assert in tests
Full configuration guide: See python-quality skill
Key Rules Categories
| Category |
Rule Example |
Tool |
| Security |
Hardcoded passwords |
Ruff S105, SonarPython S2068 |
| Bug |
Mutable default arg |
Ruff B006 |
| Type Safety |
Missing return type |
Mypy |
| Style |
Unused imports |
Ruff F401 |
| Complexity |
Too complex |
Ruff C901 |
When NOT to Use This Skill
| Scenario |
Use Instead |
| FastAPI-specific features |
backend-fastapi skill |
| Django framework |
Django-specific skill |
| Testing frameworks |
testing-pytest skill |
| Data science/ML |
Data science skills |
| SQLAlchemy ORM |
orm-sqlalchemy skill |
Anti-Patterns
| Anti-Pattern |
Why It's Bad |
Correct Approach |
| Mutable default arguments |
Shared state across calls |
Use None, create in function |
Bare except: clauses |
Catches system exits |
Catch specific exceptions |
Using eval() or exec() |
Security risk, code injection |
Use safer alternatives |
| Not using context managers |
Resource leaks |
Use with statement |
| Global variables everywhere |
Hard to test, maintain |
Pass as parameters |
| Mixing sync and async code |
Deadlocks, blocking |
Use proper async patterns |
| Not using type hints |
Hard to maintain |
Add type annotations |
| String concatenation in loops |
O(n²) complexity |
Use join() or f-strings |
Quick Troubleshooting
| Issue |
Cause |
Solution |
| "NameError: name 'X' is not defined" |
Variable not declared |
Check spelling, imports |
| "AttributeError: object has no attribute" |
Wrong type or missing attr |
Check type, use hasattr() |
| "TypeError: X() takes N positional arguments" |
Wrong arg count |
Check function signature |
| "ModuleNotFoundError: No module named" |
Missing dependency |
Install with pip |
| "IndentationError" |
Mixed tabs/spaces |
Use consistent indentation |
| "RuntimeError: Event loop is closed" |
Async misuse |
Use asyncio.run() properly |
| "RecursionError: maximum recursion depth" |
Infinite recursion |
Add base case, use iteration |
| Memory leak with async |
Tasks not awaited |
Await all tasks or use gather |
Reference Documentation
- Typing - Type hints, generics, PEP 695
- Async - asyncio, TaskGroup, patterns
- CLI - Typer, Click, Rich
- Packaging - uv, poetry, pyproject.toml
1---2name: python3description: Python language (3.10-3.14). Covers typing, async, and modern patterns. Use when writing Python applications. USE WHEN: user mentions "python", "type hints", "dataclasses", "async/await", asks about "asyncio", "context managers", "match statement", "walrus operator", "PEP 695", "type parameter", "generic" DO NOT USE FOR: FastAPI framework - use `backend-fastapi` skill instead DO NOT USE FOR: Django framework - use Django-specific skill DO NOT USE FOR: Package management - use `python-packaging` skill DO NOT USE FOR: Linting/type checking config - use `python-quality` skill4---5# Python Core Knowledge67> **Full Reference**: See [advanced.md](advanced.md) for production patterns: Result types, custom exceptions, structured logging, Pydantic validation, testing patterns, performance optimization, and dependency injection.89> **Deep Knowledge**: Use `mcp__documentation__fetch_docs` with technology: `python` for comprehensive documentation.1011## Python Version Support1213| Version | Status | Key Features |14|---------|--------|--------------|15| 3.14 | Current | Type defaults, JIT improvements |16| 3.13 | Stable | Free-threading (experimental), JIT |17| 3.12 | Stable | **PEP 695** type syntax, f-string improvements |18| 3.11 | Stable | Exception groups, 10-60% faster |19| 3.10 | Security | Pattern matching, `\|` union |2021## Type Hints (Modern Syntax)2223```python24# Python 3.10+ - Use | instead of Union25def greet(name: str | None = None) -> str:26 return f"Hello, {name or 'World'}"2728# Python 3.9+ - Use built-in generics29def process(items: list[str]) -> dict[str, int]:30 return {item: len(item) for item in items}3132# Python 3.12+ - PEP 695 Type Parameter Syntax33def first[T](items: list[T]) -> T | None:34 return items[0] if items else None3536class Stack[T]:37 def __init__(self) -> None:38 self._items: list[T] = []3940 def push(self, item: T) -> None:41 self._items.append(item)4243 def pop(self) -> T:44 return self._items.pop()4546# Type aliases (Python 3.12+)47type Point = tuple[float, float]48type Vector[T] = list[T]49type Handler[T] = Callable[[T], None]5051# Callable52def apply(fn: Callable[[int], int], value: int) -> int:53 return fn(value)54```5556## Dataclasses5758```python59from dataclasses import dataclass, field60from datetime import datetime6162@dataclass63class User:64 id: int65 name: str66 email: str67 created_at: datetime = field(default_factory=datetime.now)68 is_active: bool = True6970 def __post_init__(self):71 self.email = self.email.lower()7273# Frozen (immutable)74@dataclass(frozen=True)75class Point:76 x: float77 y: float7879# Slots for memory efficiency (Python 3.10+)80@dataclass(slots=True)81class Optimized:82 value: int83```8485## Async/Await8687```python88import asyncio89import aiohttp9091async def fetch_user(id: int) -> dict:92 async with aiohttp.ClientSession() as session:93 async with session.get(f'/api/users/{id}') as response:94 return await response.json()9596async def fetch_all_users(ids: List[int]) -> List[dict]:97 tasks = [fetch_user(id) for id in ids]98 return await asyncio.gather(*tasks)99100# Run101asyncio.run(fetch_all_users([1, 2, 3]))102```103104## Context Managers105106```python107from contextlib import contextmanager, asynccontextmanager108109@contextmanager110def timer():111 start = time.time()112 yield113 print(f"Elapsed: {time.time() - start:.2f}s")114115with timer():116 process_data()117118@asynccontextmanager119async def get_db():120 db = await create_connection()121 try:122 yield db123 finally:124 await db.close()125```126127## Modern Patterns128129```python130# Match (3.10+)131match status:132 case "active":133 handle_active()134 case "inactive" | "pending":135 handle_pending()136 case {"type": "user", "name": name}: # Dict pattern137 handle_user(name)138 case [first, *rest]: # Sequence pattern139 handle_sequence(first, rest)140 case _:141 handle_default()142143# Walrus operator144if (n := len(items)) > 10:145 print(f"Too many: {n}")146147# Exception groups (3.11+)148try:149 async with asyncio.TaskGroup() as tg:150 tg.create_task(task1())151 tg.create_task(task2())152except* ValueError as eg:153 for exc in eg.exceptions:154 print(f"ValueError: {exc}")155except* TypeError as eg:156 for exc in eg.exceptions:157 print(f"TypeError: {exc}")158```159160## Static Analysis & Linting161162### Official Rules References163164| Tool | Rules Count | Documentation |165|------|-------------|---------------|166| **Ruff** | 800+ | https://docs.astral.sh/ruff/rules/ |167| **SonarPython** | 300+ | https://rules.sonarsource.com/python/ |168| **Pylint** | 200+ | https://pylint.readthedocs.io/en/latest/user_guide/messages/messages_overview.html |169| **Mypy** | Type checker | https://mypy.readthedocs.io/en/stable/error_codes.html |170171### Style Guides172173| Guide | Link |174|-------|------|175| **PEP 8** | https://peps.python.org/pep-0008/ |176| **PEP 20 (Zen)** | https://peps.python.org/pep-0020/ |177| **Google Python Style** | https://google.github.io/styleguide/pyguide.html |178179### Ruff Configuration180181```toml182# pyproject.toml183[tool.ruff]184line-length = 88185target-version = "py312"186187[tool.ruff.lint]188select = [189 "E", # pycodestyle errors190 "W", # pycodestyle warnings191 "F", # Pyflakes192 "I", # isort193 "B", # flake8-bugbear194 "C4", # flake8-comprehensions195 "UP", # pyupgrade196 "S", # flake8-bandit (security)197]198ignore = ["E501"] # line too long (handled by formatter)199200[tool.ruff.lint.per-file-ignores]201"tests/*" = ["S101"] # allow assert in tests202```203204> **Full configuration guide**: See [python-quality skill](../../best-practices/python-quality/SKILL.md)205206### Key Rules Categories207208| Category | Rule Example | Tool |209|----------|--------------|------|210| Security | Hardcoded passwords | Ruff S105, SonarPython S2068 |211| Bug | Mutable default arg | Ruff B006 |212| Type Safety | Missing return type | Mypy |213| Style | Unused imports | Ruff F401 |214| Complexity | Too complex | Ruff C901 |215216## When NOT to Use This Skill217218| Scenario | Use Instead |219|----------|-------------|220| FastAPI-specific features | `backend-fastapi` skill |221| Django framework | Django-specific skill |222| Testing frameworks | `testing-pytest` skill |223| Data science/ML | Data science skills |224| SQLAlchemy ORM | `orm-sqlalchemy` skill |225226## Anti-Patterns227228| Anti-Pattern | Why It's Bad | Correct Approach |229|--------------|--------------|------------------|230| Mutable default arguments | Shared state across calls | Use None, create in function |231| Bare `except:` clauses | Catches system exits | Catch specific exceptions |232| Using `eval()` or `exec()` | Security risk, code injection | Use safer alternatives |233| Not using context managers | Resource leaks | Use `with` statement |234| Global variables everywhere | Hard to test, maintain | Pass as parameters |235| Mixing sync and async code | Deadlocks, blocking | Use proper async patterns |236| Not using type hints | Hard to maintain | Add type annotations |237| String concatenation in loops | O(n²) complexity | Use join() or f-strings |238239## Quick Troubleshooting240241| Issue | Cause | Solution |242|-------|-------|----------|243| "NameError: name 'X' is not defined" | Variable not declared | Check spelling, imports |244| "AttributeError: object has no attribute" | Wrong type or missing attr | Check type, use hasattr() |245| "TypeError: X() takes N positional arguments" | Wrong arg count | Check function signature |246| "ModuleNotFoundError: No module named" | Missing dependency | Install with pip |247| "IndentationError" | Mixed tabs/spaces | Use consistent indentation |248| "RuntimeError: Event loop is closed" | Async misuse | Use asyncio.run() properly |249| "RecursionError: maximum recursion depth" | Infinite recursion | Add base case, use iteration |250| Memory leak with async | Tasks not awaited | Await all tasks or use gather |251252## Reference Documentation253- [Typing](quick-ref/typing.md) - Type hints, generics, PEP 695254- [Async](quick-ref/async.md) - asyncio, TaskGroup, patterns255- [CLI](quick-ref/cli.md) - Typer, Click, Rich256- [Packaging](quick-ref/packaging.md) - uv, poetry, pyproject.toml