docs: Coding Standards nach externem Review korrigiert (6 Fixes)
This commit is contained in:
+37
-31
@@ -191,22 +191,20 @@ def get_game_by_id(game_id):
|
||||
|
||||
| Regel | Richtig | Falsch |
|
||||
|---|---|---|
|
||||
| `Optional` statt `X \| None` (Konsistenz) | `Optional[str]` | `str \| None` |
|
||||
| `X \| None` (PEP 604, idiomatisch für 3.13+) | `str \| None` | `Optional[str]` |
|
||||
| `list`/`dict` statt `List`/`Dict` (Python 3.9+) | `list[str]` | `List[str]` |
|
||||
| `Any` nur in Ausnahmefällen | `dict[str, Any]` (API-Response) | `Any` als Rückgabetyp |
|
||||
| Generics immer parametrisieren | `dict[str, Any]` | `dict` (implizites `dict[Any, Any]`) |
|
||||
| `-> None` bei Funktionen ohne Return | `def log(msg: str) -> None:` | `def log(msg: str):` |
|
||||
|
||||
```python
|
||||
from typing import Optional, Any
|
||||
|
||||
# ✅ Richtig
|
||||
def find_user(email: str) -> Optional[dict[str, Any]]:
|
||||
def find_user(email: str) -> dict[str, object] | None:
|
||||
"""Sucht einen User per E-Mail. Gibt None zurück, wenn nicht gefunden."""
|
||||
...
|
||||
|
||||
# ✅ Richtig — Flask-Route
|
||||
@app.route("/api/games/<int:game_id>")
|
||||
def get_game(game_id: int) -> tuple[dict, int]:
|
||||
def get_game(game_id: int) -> tuple[dict[str, object], int]:
|
||||
"""Gibt ein einzelnes Spiel zurück."""
|
||||
...
|
||||
```
|
||||
@@ -269,8 +267,8 @@ def berechne_durchschnitt(werteliste: list[float]) -> float:
|
||||
def komplexe_funktion(
|
||||
name: str,
|
||||
werte: list[int],
|
||||
optional: Optional[str] = None,
|
||||
) -> dict[str, Any]:
|
||||
optional: str | None = None,
|
||||
) -> dict[str, object]:
|
||||
"""Kurzbeschreibung (eine Zeile).
|
||||
|
||||
Ausführliche Beschreibung. Kann mehrere Sätze umfassen.
|
||||
@@ -446,9 +444,9 @@ def search_games():
|
||||
|
||||
### 8.1 Grundregeln
|
||||
|
||||
1. **Jede neue Funktion → Test** (TDD: erst Test, dann Code)
|
||||
2. **80% Code Coverage** als Minimum
|
||||
3. **pytest** als Test-Framework
|
||||
1. **Jede neue Funktion → Test** (Empfehlung: TDD — erst Test, dann Code)
|
||||
2. **80% Code Coverage** als harter Floor — unterschreiten blockiert den Commit
|
||||
3. **pytest** als einziges Test-Framework
|
||||
4. **Tests in `tests/`**, spiegelt die Projektstruktur
|
||||
|
||||
### 8.2 Test-Struktur
|
||||
@@ -584,7 +582,7 @@ Jeder Commit folgt dem **Conventional Commits**-Standard:
|
||||
feat(games): Spiele-Suche mit Volltext-Filter
|
||||
fix(auth): Login bricht bei leeren Feldern nicht mehr ab
|
||||
docs: CODING_STANDARDS.md hinzugefügt
|
||||
chore(deps): Ruff auf 0.11.3 aktualisiert
|
||||
chore(deps): Ruff auf 0.15.18 aktualisiert
|
||||
```
|
||||
|
||||
### 10.2 Commit-Frequenz
|
||||
@@ -608,17 +606,16 @@ pytest # Tests müssen grün sein
|
||||
|
||||
| Tool | Zweck | Konfiguration |
|
||||
|---|---|---|
|
||||
| **[Ruff](https://docs.astral.sh/ruff/)** | Linting + Formatierung | `pyproject.toml` → `[tool.ruff]` |
|
||||
| **[Ruff](https://docs.astral.sh/ruff/)** | Linting + Formatierung + Sicherheit | `pyproject.toml` → `[tool.ruff]` |
|
||||
| **[mypy](https://mypy-lang.org/)** | Statische Typ-Prüfung | `pyproject.toml` → `[tool.mypy]` |
|
||||
| **[pre-commit](https://pre-commit.com/)** | Git-Hooks zur Durchsetzung | `.pre-commit-config.yaml` |
|
||||
| **[pytest](https://pytest.org/)** | Testing | `pyproject.toml` → `[tool.pytest.ini_options]` |
|
||||
| **[Bandit](https://bandit.readthedocs.io/)** | Sicherheits-Scans | `pyproject.toml` → `[tool.bandit]` |
|
||||
| **[pytest](https://pytest.org/)** | Testing + Coverage | `pyproject.toml` → `[tool.pytest.ini_options]` |
|
||||
|
||||
### 11.2 Quick-Start (neues Projekt)
|
||||
|
||||
```bash
|
||||
# 1. Tools installieren
|
||||
pip install ruff mypy pre-commit pytest bandit
|
||||
pip install ruff mypy pre-commit pytest
|
||||
|
||||
# 2. Pre-commit-Hooks aktivieren
|
||||
pre-commit install
|
||||
@@ -627,26 +624,24 @@ pre-commit install
|
||||
ruff check . --fix
|
||||
ruff format .
|
||||
mypy .
|
||||
pytest
|
||||
pytest --cov --cov-fail-under=80
|
||||
|
||||
# 4. Vor jedem Commit automatisch
|
||||
# 4. Vor jedem Commit automatisch (Ruff Lint + Format + Basic Checks)
|
||||
git commit -m "feat: ..."
|
||||
# → Ruff prüft + formatiert automatisch
|
||||
# → mypy prüft die Typen
|
||||
# → Bandit scannt auf Sicherheitslücken
|
||||
# → Merge-Konflikte, Whitespace, Debug-Statements werden geprüft
|
||||
# → mypy läuft nicht in pre-commit (isoliertes venv-Drift) — separat ausführen!
|
||||
```
|
||||
|
||||
### 11.3 CI-Setup (später)
|
||||
|
||||
```yaml
|
||||
# .github/workflows/quality.yml
|
||||
- name: Lint
|
||||
- name: Lint + Security
|
||||
run: ruff check .
|
||||
- name: Type Check
|
||||
- name: Type Check (im echten venv!)
|
||||
run: mypy .
|
||||
- name: Security Scan
|
||||
run: bandit -r src/ -c pyproject.toml
|
||||
- name: Tests
|
||||
- name: Tests + Coverage
|
||||
run: pytest --cov --cov-fail-under=80
|
||||
```
|
||||
|
||||
@@ -654,14 +649,17 @@ git commit -m "feat: ..."
|
||||
|
||||
## Anhang A: Checkliste für Code Reviews
|
||||
|
||||
- [ ] PEP 8 eingehalten? (Ruff-Check bestanden)
|
||||
Bei jedem Code-Review durchgehen. 🤖 = automatisch von pre-commit erzwungen.
|
||||
|
||||
- [ ] 🤖 PEP 8 eingehalten? (Ruff-Check bestanden)
|
||||
- [ ] Alle Funktionen haben Typ-Annotationen? (mypy bestanden)
|
||||
- [ ] Docstrings auf Deutsch für alle öffentlichen Funktionen?
|
||||
- [ ] Keine Secrets im Code?
|
||||
- [ ] User-Input validiert?
|
||||
- [ ] Tests geschrieben und grün?
|
||||
- [ ] Keine God-Files (>500 Zeilen)?
|
||||
- [ ] Keine God-Funktionen (>50 Zeilen)?
|
||||
- [ ] Tests geschrieben und grün? Coverage ≥ 80%?
|
||||
- [ ] Keine God-Files (>500 Zeilen)? (manuell)
|
||||
- [ ] Keine God-Funktionen (>50 Statements)? (🤖 Ruff PLR0915)
|
||||
- [ ] McCabe-Komplexität ≤ 10? (🤖 Ruff C901)
|
||||
- [ ] Route enthält keine Business-Logik?
|
||||
- [ ] Commit folgt Conventional Commits?
|
||||
|
||||
@@ -683,5 +681,13 @@ Jede Regel ist **automatisiert durchsetzbar**. Das bedeutet: Du musst sie nicht
|
||||
|
||||
---
|
||||
|
||||
> **Letzte Aktualisierung:** 21. Juni 2026
|
||||
> **Nächste Überprüfung:** Bei Projektstart oder nach 6 Monaten
|
||||
> **Letzte Aktualisierung:** 21. Juni 2026 (extern reviewed ✅ — 6 Fixes eingearbeitet)
|
||||
> **Nächste Überprüfung:** Bei Projektstart oder Dezember 2026
|
||||
>
|
||||
> **Review-Fixes v1.0:**
|
||||
> 1. Optional[X] → X | None (PEP 604, kein Ruff-Konflikt mehr)
|
||||
> 2. B101 global entfernt — asserts nur in tests/ erlaubt
|
||||
> 3. Bandit-Hook gestrichen — Ruffs S-Regeln reichen
|
||||
> 4. C901 + PLR-Regeln aktiviert — God-Funktionen jetzt automatisch geprüft
|
||||
> 5. mypy aus pre-commit entfernt (isoliertes venv-Drift)
|
||||
> 6. TDD → Empfehlung, Typ-Fixes, Ruff 0.15.18, mypy 2.1.0
|
||||
|
||||
Reference in New Issue
Block a user