Rules
Öne çıkan·v1.0.0·2026-04-22Python Projesi Kuralları
Modern Python (3.12+) projeleri için kural seti — type hints, ruff + mypy strict, async disiplini, FastAPI / SQLAlchemy best practice, pytest + pyproject.toml baseline. CLAUDE.md / .cursorrules için.
pythonfastapimypyruffrulesbackendclaude-md
İçerik
Bu içeriği projenin CLAUDE.md / AGENTS.md / .cursorrules dosyasına yapıştır.
Python Projesi Kuralları
Version & tooling
- Python 3.12+ (3.10 altı yasak — match/case, modern typing, performance).
- Paket yöneticisi:
uv(tercih) veyapoetry.pip installdoğrudan yasak. - Lockfile commit edilir (
uv.lock/poetry.lock). - Virtual env
.venv(klasör isim sabitliği). .python-versiondosyası proje kökünde.
Code style & lint
- Formatter:
ruff format(Black uyumlu). PR öncesi format zorunlu. - Linter:
ruff check— şu rule set'ler aktif:[tool.ruff.lint] select = [ "E", "F", "W", # pycodestyle + pyflakes "I", # isort "B", # flake8-bugbear "C4", # flake8-comprehensions "UP", # pyupgrade "N", # pep8-naming "ANN", # flake8-annotations (type hints) "ASYNC", # async/await best practices "S", # bandit (security) "PL", # pylint subset "RUF" # ruff-specific ] ignore = ["ANN101", "ANN102"] # self/cls annotation gereksiz - Line length: 100 (projeye göre — 88-120 arası seçilir, tutarlı kullanılır).
- Import sıralama: stdlib / third-party / local (ruff halleder).
Type hints zorunlu
- Tüm fonksiyon signature'larında tip var. Public API'de
-> Nonebile explicit. mypy --strictyeşil olmalı. Scope gereği gevşetme inline# type: ignore[code]+ yorum.Anyyasak.Unknown(TypeAlias) ya daobjectveya concrete type.typing.Anyiç kodda görürsen refactor et. Dış boundary'de (untyped lib)cast+ yorum.- Modern typing:
list[int],dict[str, Any],X | None(3.10+).List,Dict,Optionaldeprecated. - Generic'ler:
Sequence,Mapping,Iterable(abstract), concretelist/dictsadece gerçekten list/dict lazımsa. - Pydantic v2 runtime validation için; type hint ayrı katman.
Naming
- Modules:
snake_case.py - Classes:
PascalCase - Functions / variables:
snake_case - Constants:
SCREAMING_SNAKE - Private:
_leading_underscore(gerçekten private'sa) __dunder__sadece Python protokol için
Yapı
- Paket layout:
src/layout. Root'ta__init__.pyyok.project/ src/ myapp/ __init__.py api/ models/ services/ tests/ pyproject.toml - Dosya boyutu: 500 satırı geçerse parçala.
__init__.pybarrel sadece public API için. Wildcard import yasak (from module import *).
Async disiplini
asyncio+async defFastAPI, async DB driver kullananlar için.async deffonksiyonda senkron I/O çağırma (blocks event loop):requests❌ →httpx✅psycopg2❌ →asyncpg/psycopg[async]✅time.sleep()❌ →asyncio.sleep()✅
- CPU-bound iş async fonksiyonda ❌.
asyncio.to_thread()ile thread'e at. asyncio.gather()paralel I/O için —return_exceptions=Truedikkatli.- Context manager
async withconnection/file için.
FastAPI (kullanılıyorsa)
- Route handler ince: input parse → service call → response format. İş mantığı handler'da değil.
- Pydantic model'leri:
- Request:
XxxRequest - Response:
XxxResponse - DB model'i (SQLAlchemy) ≠ API model'i. Çevirme katmanı olur.
- Request:
- Dependency injection (
Depends) DB session, current user, feature flag için. - Exception handler global: domain exception → HTTP mapping.
- Response model explicit —
response_model=XxxResponse(extra field sızıntısını önler). - Path / query / body ayrımı net. Query param:
Query(...); path:Path(...).
DB (SQLAlchemy 2.x)
- Async engine:
create_async_engine. - Session factory:
async_sessionmaker. - Typed mapped classes: SQLAlchemy 2.x
Mapped[]syntax. - Transactions:
async with session.begin():context'i. Otomatik rollback on exception. - N+1 = sorun:
selectinload,joinedloadile eager load. - Migration: Alembic. Auto-generate kabul ama manual review edilir (rename column gibi şeyler auto-detect edilmez).
- Repository pattern: karmaşık projelerde. Küçükte direct SQLAlchemy query kabul.
Error handling
Exceptionyakalama sadece en dış katmanda (FastAPI handler, task runner). İçeride spesifik exception.- Custom exception class'ları:
NotFoundError,ValidationError,AuthErrorgibi domain-specific. try/except/passyasak — ya handle et ya yukarı fırlat.raise ... from econtext zinciri için.- Assert production kodunda mantık için yasak — Python
-Oflag ile assert'leri atlar.if not x: raisekullan.
Logging
loggingmodule ya dastructlog.print()yasak.- Logger instance modül seviyesinde:
logger = logging.getLogger(__name__) - Seviyeler bilinçli:
DEBUG— troubleshoot içinINFO— başarılı operasyonWARNING— beklenmeyen ama toparlanıyorERROR— işlem başarısızCRITICAL— servis etkileniyor
- Structured log:
logger.info("order.created", extra={"order_id": id})
Test (pytest)
- Test dosyası:
tests/ayrı klasör.test_*.pynaming. - Fixture'lar
conftest.py'de. Scope bilinçli (function,module,session). pytest-asyncioasync test için.asyncio_mode = "auto"config.pytest-covcoverage raporu. Hedef kaplama % değil kritik yolun testi.- Parametrize (
@pytest.mark.parametrize) benzer case'ler için. - Mock:
unittest.mockveyapytest-mock. Mock ≠ her yer — boundary'de kullan. - Factories:
factory-boyveya plain fixture functions. - DB test'leri transaction rollback ile izole (sqlalchemy
session.rollbacksonunda).
Performans notları
sum(x for x in lst)✅ generator — büyük veri için. List comprehension sadece gerekirse.dict.get(key, default)vskey in dict: ...— tercih.get.- f-string >>
.format()>>%s(performance + okunur). - Early return nested if'ten iyidir.
functools.lru_cachesaf fonksiyonlar için. Instance method'a dikkat (memory leak).
Secret & config
.envdosyası git-ignored..env.examplecommit'lenir.pydantic-settingstype-safe config.- Hardcoded secret yasak — env, secret manager, vault.
getpass.getpass()scripts için.
Packaging
pyproject.tomlher şey tek yerde (setup.py yok).[tool.ruff],[tool.mypy],[tool.pytest.ini_options]hepsi burada.- Dependencies:
[project.dependencies](runtime),[project.optional-dependencies](dev). - Version
__version__ = ...single source of truth.
Yasak listesi (özet)
from X import *(wildcard)print()prod kodundatyping.Anyiç koddatyping.Optional(useX | None)typing.List/Dict/Tuple(uselist/dict/tuple)except:veyaexcept Exception: passassertbusiness logic içinpip installdoğrudan (paket yöneticisi kullan)requestsasync context'tetime.sleep()async context'teglobalstatement (statefulness gerekliyse class veya dependency)sys.pathmanipülasyonu- Hardcoded secret / API key
Commit
Conventional Commits + "neden". Kapsam prefix'leri: api, db, worker, infra.