python-programming-expert · git:20260808.748cfa2 · 2026-08-08 · sha256 742f915b88f21ffc
python-programming-expert git:20260808.748cfa2A
Immutable. This exact content is served forever at /api/v1/blob/742f915b88f21ffc.
---
name: python-programming-expert
description: "Expert-level skill for Python programming (Python 3.13/3.14+). Covers type safety, generic syntax (PEP 695), async/await TaskGroups, FastAPI 0.115+, Pydantic v2, uv package manager, Ruff, and pytest in English and Indonesian."
author: "Roedy Rustam"
---
# Python Programming Expert (3.14 Edition)
[English](#english) | [Bahasa Indonesia](#bahasa-indonesia)
---
<a name="english"></a>
## English
### Description
Expert-level Python development guidance for **Python 3.13 / 3.14+** covering JIT compilation, free-threaded (no-GIL) mode, modern type safety patterns, async architecture, and the full production stack: **FastAPI 0.115+**, **Pydantic v2**, **SQLAlchemy 2.x / SQLModel**, **uv**, **Ruff**, and **pytest-asyncio**.
### Trigger Conditions
- Writing Python 3.13+ / 3.14+ applications or services.
- Building **FastAPI 0.115+** REST APIs, **Django 5.x**, or **Litestar** web services.
- Managing Python projects with the **`uv`** package manager.
- Implementing async/await patterns with `asyncio.TaskGroup` or structured concurrency.
- Writing type-safe Python with **Pydantic v2** and modern generics (PEP 695/696).
- Setting up **Ruff** for linting + formatting; **pytest** with `pytest-asyncio` for testing.
- Building AI backends integrating with LLM APIs (OpenAI, Anthropic, Google GenAI).
---
### Python Version Matrix (2026)
| Version | Status | Key Feature |
|---|---|---|
| **Python 3.14** | Latest (Oct 2025) | PEP 696 defaults, improved JIT, `@` on types |
| **Python 3.13** | Stable LTS | JIT compiler, free-threaded mode (no GIL) |
| **Python 3.12** | Supported | PEP 695 generics, `type` alias statement |
| **Python 3.11** | Security only | `asyncio.TaskGroup`, `ExceptionGroup` |
---
### Modern Python Toolchain (2026)
#### uv — The Standard Package Manager
Replace `pip`, `pip-tools`, `virtualenv`, `pyenv`, and `poetry` entirely with **uv** (written in Rust — 10-100x faster):
```bash
# Create project
uv init my-api
cd my-api
# Add runtime dependencies
uv add fastapi pydantic httpx sqlalchemy[asyncio]
# Add dev dependencies
uv add --dev pytest pytest-asyncio ruff mypy httpx
# Run scripts (no activation needed)
uv run python main.py
uv run pytest
uv run fastapi dev main.py # Hot reload dev server
# Pin exact Python version
uv python pin 3.13
# Sync all environments
uv sync
```
#### `pyproject.toml` — Single Config File
```toml
[project]
name = "my-api"
version = "0.1.0"
requires-python = ">=3.13"
dependencies = [
"fastapi>=0.115",
"pydantic>=2.9",
"sqlalchemy[asyncio]>=2.0",
"asyncpg>=0.30",
]
[tool.ruff]
line-length = 88
target-version = "py313"
[tool.ruff.lint]
select = ["E", "F", "I", "N", "UP", "B", "SIM", "ANN", "ASYNC"]
[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["ANN"] # No type annotations required in tests
[tool.pytest.ini_options]
asyncio_mode = "auto" # pytest-asyncio auto mode
```
---
### Type Safety — Modern Patterns
#### PEP 695 — Generic Syntax (Python 3.12+)
```python
# Old way (verbose)
from typing import TypeVar, Generic
T = TypeVar('T')
class Stack(Generic[T]):
def push(self, item: T) -> None: ...
# New way (Python 3.12+) — clean, no boilerplate
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()
# Generic functions
def first[T](lst: list[T]) -> T:
return lst[0]
# Type aliases (PEP 695)
type Vector = list[float]
type Matrix[T] = list[list[T]]
```
#### PEP 696 — TypeVar Defaults (Python 3.14+)
```python
# Default generic types — reduces boilerplate in libraries
class Response[T = dict]: # T defaults to dict if not specified
def __init__(self, data: T) -> None:
self.data = data
response = Response({"key": "value"}) # T inferred as dict
```
#### Pydantic v2 — Production Data Validation
```python
from pydantic import BaseModel, Field, field_validator, model_validator
from pydantic import EmailStr, SecretStr
from typing import Annotated
# Annotated types for reusability
PositiveInt = Annotated[int, Field(gt=0)]
TrimmedStr = Annotated[str, Field(min_length=1, strip_whitespace=True)]
class UserCreate(BaseModel):
model_config = {"str_strip_whitespace": True}
name: TrimmedStr = Field(max_length=50)
email: EmailStr
age: PositiveInt
password: SecretStr = Field(min_length=8)
@field_validator('name')
@classmethod
def validate_name(cls, v: str) -> str:
if not v.replace(' ', '').isalpha():
raise ValueError('Name must contain only letters')
return v.title()
@model_validator(mode='after')
def check_adult_email(self) -> 'UserCreate':
if self.age < 18 and 'kids' not in self.email:
raise ValueError('Minors must use a kids account email')
return self
# Usage
user = UserCreate(name="alice smith", email="alice@example.com", age=25, password="securepassword")
user.model_dump() # {'name': 'Alice Smith', 'email': 'alice@example.com', 'age': 25}
user.model_dump(mode='json') # JSON-serializable dict
```
---
### FastAPI 0.115+ — Production Patterns
#### Application Structure
```
my_api/
├── main.py # FastAPI app + lifespan
├── routers/
│ ├── users.py # APIRouter for /users
│ └── posts.py # APIRouter for /posts
├── models/
│ ├── user.py # Pydantic request/response models
│ └── post.py
├── db/
│ ├── database.py # SQLAlchemy engine + session
│ └── models.py # ORM models
├── services/
│ └── user_service.py # Business logic layer
└── core/
├── config.py # Settings with Pydantic BaseSettings
└── security.py # JWT, hashing
```
#### Lifespan — Startup & Shutdown
```python
from contextlib import asynccontextmanager
from fastapi import FastAPI
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker
engine = create_async_engine(settings.DATABASE_URL, echo=False, pool_size=10)
AsyncSessionLocal = async_sessionmaker(engine, expire_on_commit=False)
@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
print("✅ Database connected")
yield
# Shutdown
await engine.dispose()
print("✅ Database disconnected")
app = FastAPI(title="My API", version="1.0.0", lifespan=lifespan)
```
#### Dependency Injection Pattern
```python
from typing import Annotated
from fastapi import Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
async def get_db() -> AsyncSession:
async with AsyncSessionLocal() as session:
yield session
DbDep = Annotated[AsyncSession, Depends(get_db)]
# In routes
@router.get("/users/{user_id}", response_model=UserResponse)
async def get_user(user_id: str, db: DbDep):
user = await db.get(User, user_id)
if not user:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")
return user
```
#### Settings with Pydantic BaseSettings
```python
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8")
DATABASE_URL: str
SECRET_KEY: str
ALGORITHM: str = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES: int = 15
ENVIRONMENT: str = "development"
@property
def is_production(self) -> bool:
return self.ENVIRONMENT == "production"
settings = Settings()
```
#### Structured Error Handling (RFC 9457)
```python
from fastapi import Request
from fastapi.responses import JSONResponse
class AppException(Exception):
def __init__(self, *, type: str, title: str, status: int, detail: str):
self.type = type
self.title = title
self.status = status
self.detail = detail
@app.exception_handler(AppException)
async def app_exception_handler(request: Request, exc: AppException) -> JSONResponse:
return JSONResponse(
status_code=exc.status,
content={
"type": exc.type,
"title": exc.title,
"status": exc.status,
"detail": exc.detail,
}
)
# Usage in routes
raise AppException(
type="https://myapi.com/errors/user-not-found",
title="User Not Found",
status=404,
detail=f"User with id '{user_id}' does not exist",
)
```
---
### Async Patterns
#### asyncio.TaskGroup (Python 3.11+)
```python
import asyncio
async def main():
# Better than asyncio.gather — propagates exceptions immediately
async with asyncio.TaskGroup() as tg:
task_users = tg.create_task(fetch_users())
task_posts = tg.create_task(fetch_posts())
task_stats = tg.create_task(fetch_stats())
# All tasks complete here — exception in any task cancels all others
return task_users.result(), task_posts.result(), task_stats.result()
```
#### Python 3.13 — JIT & Free-Threaded Mode
```bash
# JIT compiler — 10-20% speedup on CPU-bound code
PYTHON_JIT=1 python3.13 compute_heavy.py
# Free-threaded build (no GIL) — true CPU parallelism
uv python install 3.13t # install free-threaded build
python3.13t -X gil=0 parallel_app.py
```
---
### Testing with pytest + pytest-asyncio
```python
# conftest.py
import pytest
from httpx import AsyncClient, ASGITransport
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker
TEST_DATABASE_URL = "sqlite+aiosqlite:///:memory:"
@pytest.fixture
async def db_session():
engine = create_async_engine(TEST_DATABASE_URL)
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
async with async_sessionmaker(engine)() as session:
yield session
await engine.dispose()
@pytest.fixture
async def client(db_session):
app.dependency_overrides[get_db] = lambda: db_session
async with AsyncClient(
transport=ASGITransport(app=app), base_url="http://test"
) as ac:
yield ac
# test_users.py
async def test_create_user(client: AsyncClient):
response = await client.post("/users", json={"name": "Alice", "email": "alice@test.com", "age": 25, "password": "password123"})
assert response.status_code == 201
data = response.json()
assert data["email"] == "alice@test.com"
```
---
<a name="bahasa-indonesia"></a>
## Bahasa Indonesia
### Deskripsi
Panduan pengembangan Python tingkat ahli untuk **Python 3.13/3.14+** mencakup JIT compilation, mode free-threaded (tanpa GIL), pola keamanan tipe modern, arsitektur async, dan stack produksi lengkap: **FastAPI 0.115+**, **Pydantic v2**, **SQLAlchemy 2.x**, **uv**, **Ruff**, dan **pytest-asyncio**.
### Kondisi Pemicu
- Menulis aplikasi atau layanan Python 3.13+/3.14+.
- Membangun REST API FastAPI 0.115+, Django 5.x, atau Litestar.
- Mengelola proyek Python dengan manajer paket `uv`.
- Mengimplementasikan pola async/await dengan `asyncio.TaskGroup`.
- Menulis Python type-safe dengan Pydantic v2 dan generik modern (PEP 695/696).
- Menyiapkan Ruff untuk linting + formatting; pytest-asyncio untuk pengujian.
### Toolchain Modern (2026)
**`uv`** menggantikan `pip`, `pip-tools`, `virtualenv`, `pyenv`, dan `poetry` — ditulis dalam Rust, 10-100x lebih cepat. Gunakan satu file `pyproject.toml` untuk semua konfigurasi.
### Keamanan Tipe — Pola Modern
**PEP 695** (Python 3.12+): Sintaksis generic baru yang bersih tanpa boilerplate `TypeVar`. Gunakan `type` statement untuk alias tipe.
**PEP 696** (Python 3.14+): Default untuk TypeVar — mengurangi boilerplate lebih lanjut pada library dan class generic.
**Pydantic v2**: Gunakan `BaseModel`, `Field`, `@field_validator`, dan `@model_validator` untuk validasi data yang ketat. `model_dump()` dan `model_validate()` menggantikan metode v1.
### FastAPI 0.115+ — Pola Produksi
- **Lifespan**: Gunakan `@asynccontextmanager` dengan `lifespan=` di `FastAPI()` untuk startup/shutdown yang bersih.
- **Dependency Injection**: Gunakan `Depends()` dengan `Annotated` untuk sesi database, autentikasi, dll.
- **BaseSettings**: Gunakan `pydantic-settings` untuk konfigurasi dari environment variables dengan validasi tipe.
- **Error RFC 9457**: Format error yang konsisten dengan `type`, `title`, `status`, `detail`.
### Pola Async
Gunakan `asyncio.TaskGroup` (Python 3.11+) sebagai pengganti `asyncio.gather()` — lebih aman karena propagasi exception langsung dan membatalkan semua task lain saat ada yang gagal.
Python 3.13 JIT: Aktifkan dengan `PYTHON_JIT=1` untuk kode CPU-bound. Free-threaded mode (`python3.13t -X gil=0`) untuk paralelisme CPU sejati.
### Pengujian
Gunakan `pytest-asyncio` dengan `asyncio_mode = "auto"` di `pyproject.toml`. Gunakan `AsyncClient` dari `httpx` dengan `ASGITransport` untuk pengujian endpoint async yang bersih dan terisolasi tanpa perlu menjalankan server.