Was macht python-standards?
Diese Fähigkeit ist die Quelle der Wahrheit für Python-Werkzeuge und projektübergreifende Regeln. Die Architektur-, Stil-, Test- und Überprüfungsfähigkeiten sollten darauf verweisen, anstatt sie zu wiederholen.
Für Projektprosa laden Sie auch technical-writing. Es ruft humanizer auf und ist für den Dokumentenstandort, Zeitstempel, Überprüfungsmetadaten, Barrierefreiheit und Schreibqualität verantwortlich.
Regelpriorität
Wenden Sie Regeln in dieser Reihenfolge an:
- Explizite Benutzer- oder Organisationsanforderungen
- Repository-Konfiguration und akzeptierte Architekturentscheidungen
- Diese Fähigkeit und die anderen Python-Fähigkeiten
- PEP 8 und Tool-Standards
Schwächen Sie die Sicherheitsbasis nicht stillschweigend. Erfassen Sie eine erforderliche Ausnahme, ihren Umfang, ihr Risiko, ihren Besitzer (falls bekannt) und die Bedingung für ihre Entfernung im Entscheidungsprotokoll des Projekts.
Laufzeit und Layout
- Ziel ist Python 3.11 oder neuer. Respektieren Sie ein Repository, das eine neuere Version anstrebt.
- Verwenden Sie
from __future__ import annotations, wenn es die Vorwärtskompatibilität verbessert oder die Annotationsreihenfolge auflöst. Fügen Sie es nicht mechanisch zu Dateien hinzu, die es nicht benötigen. - Bevorzugen Sie ein
src/-Layout für neue verteilbare Pakete. - Halten Sie Projektmetadaten und unterstützte Toolkonfiguration in
pyproject.toml. - Verwenden Sie
uvfür Umgebungen, Abhängigkeitsauflösung, Sperren und Befehlsausführung.
Unterstützte Toolkette
| Zweck | Standard | Erforderliche Verwendung |
|---|---|---|
| Formatieren und Linten | Ruff | Alle gepflegten Projekte |
| Typprüfung | mypy strict | Produktionspakete und öffentliche APIs |
| Tests und Abdeckung | pytest, pytest-cov, coverage.py | Alle Verhaltensänderungen |
| Sicherheits-Lint | Ruff S-Regeln und Bandit | Produktionspakete |
| SAST | Semgrep mit Repository-Regeln | CI für gepflegte Produkte |
| Abhängigkeitsaudit | pip-audit | CI und Release-Checks |
| Strukturierte Protokollierung | structlog | Anwendungen und Dienste |
| Tracing | OpenTelemetry | Netzwerkdienste und getracete Pipelines |
| Paketverwaltung | uv | Alle Projekte |
| Git-Hooks | pre-commit | Gepflegte Repositories |
| Geheimnisauslieferung | Infisical als Organisationsstandard | Workloads, die Geheimnisse verwenden |
Eine akzeptierte Architekturentscheidung kann einen gleichwertigen Anbieter auswählen oder ein operationelles Tool auslassen, das nicht zu einer kleinen lokalen Bibliothek oder einem Skript passt. Ruff, Typprüfung, Tests und sichere Abhängigkeitsverwaltung bleiben die Basis.
Experimentelle Tools, einschließlich modellbasierter Schwachstellenscanner und KI-Reviewer, sind beratend. Sie dürfen keine obligatorischen Tore sein, bis das Team eine unterstützte Version, einen Befehl, eine Fehlerbehandlungsrichtlinie und einen Besitzer definiert hat.
Abhängigkeits- und Versionsrichtlinie
- Deklarieren Sie kompatible Laufzeitbereiche in
pyproject.toml. - Committen Sie
uv.lockfür Anwendungen und reproduzierbare Entwicklungsumgebungen. Die Sperrdatei besitzt die exakten aufgelösten Versionen. - Geben Sie für veröffentlichte Bibliotheken ehrliche untere Grenzen an, testen Sie unterstützte Python-Versionen und wichtige untere Grenzen und verlassen Sie sich nicht auf die Sperrdatei als Verbrauchervertrag.
- Platzieren Sie Qualitäts- und Testtools in benannten Abhängigkeitsgruppen.
- Führen Sie Qualitätsbefehle über die gesperrte uv-Umgebung aus. Pflegen Sie keinen zweiten Satz von Python-Tool-Versionen in pre-commit.
- Aktualisieren Sie absichtlich mit
uv lock --upgrade-package <name>oder einem überprüften vollständigen Sperr-Refresh.
Kanonisches Abhängigkeitsaudit für ein uv-Projekt:
requirements_file="$(mktemp)"
trap 'rm -f "$requirements_file"' EXIT
uv export \
--frozen \
--no-dev \
--no-emit-project \
--no-hashes \
--format requirements.txt \
--output-file "$requirements_file"
uv run --frozen pip-audit \
--strict \
--no-deps \
--requirement "$requirements_file"
Der Export prüft exakte gesperrte Laufzeitabhängigkeiten, ohne pip-audit zu bitten, einen zweiten Graphen aufzulösen. Die aktuelle --locked-Projekterkennung von pip-audit unterstützt pyproject.toml und pylock.*.toml, nicht uv.lock. Verwenden Sie daher nicht pip-audit --locked . als uv-Audit.
pip-audit muss in der Qualitätsabhängigkeitsgruppe vorhanden sein. Ein Schwachstellenverzicht muss die Beratung, den betroffenen Bereich, die kompensierende Kontrolle, den Besitzer (falls bekannt) und das Ablauf- oder Überprüfungsdatum nennen.
Kanonische Qualitätsbefehle
Passen Sie Paketpfade an das Repository an, behalten Sie jedoch eine Befehlsquelle für die lokale Verwendung und CI:
uv sync --frozen
uv run --frozen ruff check .
uv run --frozen ruff format --check .
uv run --frozen mypy <package-roots>
uv run --frozen bandit -c pyproject.toml -r <package-roots>
uv run --frozen semgrep scan --config .semgrep.yml <package-roots>
uv run --frozen pytest
# Führen Sie das kanonische exportierte Sperr-Abhängigkeitsaudit oben durch.
CI zeichnet den Befehl und das Ergebnis auf. Ein fehlendes Tool oder eine fehlende Konfiguration ist unavailable, kein Bestehen.
Pre-Commit-Besitz
Pinnen Sie nicht-Python-Hygiene-Hooks nach Release. Rufen Sie Python-Qualitätstools als lokale Hooks über uv run --frozen auf, sodass lokale Hooks und CI die exakten Versionen in uv.lock verwenden.
repos:
- repo: local
hooks:
- id: ruff-check
name: ruff check
entry: uv run --frozen ruff check --fix
language: system
types_or: [python, pyi]
- id: ruff-format
name: ruff format
entry: uv run --frozen ruff format
language: system
types_or: [python, pyi]
- id: mypy
name: mypy
entry: uv run --frozen mypy
language: system
pass_filenames: false
args: [<package-roots>]
Führen Sie Bandit, Semgrep, Tests und Abhängigkeitsaudit in CI durch. Fügen Sie sie pre-commit nur hinzu, wenn ihre Latenz und Abhängigkeiten zum Repository passen.
Minimale pyproject.toml-Entscheidungen
Verwenden Sie Repository-Paketnamen und -Stämme, anstatt Platzhalter zu kopieren.
[tool.ruff]
line-length = 88
target-version = "py311"
[tool.ruff.lint]
select = ["E", "F", "I", "N", "W", "B", "S", "UP", "C4", "SIM", "RUF", "D"]
ignore = ["E501"]
[tool.ruff.lint.pydocstyle]
convention = "google"
[tool.mypy]
python_version = "3.11"
strict = true
warn_return_any = true
warn_unused_configs = true
ignore_missing_imports = false
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-ra --strict-markers --tb=short --import-mode=importlib"
[tool.coverage.run]
branch = true
source_pkgs = ["your_package"]
[tool.coverage.report]
fail_under = 80
show_missing = true
[tool.bandit]
exclude_dirs = ["tests"]
skips = ["B101"]
Dokumentieren Sie jede Ignorierung mit einem engen Gültigkeitsbereich und Grund. Bevorzugen Sie dateispezifisches Ignorieren gegenüber globalen Ignorierungen.
Strukturiertes Protokoll-Schema
Anwendungen senden diese Felder. Bibliotheken können die Protokollierungsfassade der Host-Anwendung verwenden und dürfen keine globalen Handler beim Import konfigurieren.
| Feld | Anforderung | Bedeutung |
|---|---|---|
timestamp | Immer | ISO 8601 UTC |
level | Immer | DEBUG, INFO, WARNING, ERROR oder CRITICAL |
event | Immer | Stabiles snake_case-Event-Name |
service | Immer für Anwendungen | Dienst- oder Anwendungsname |
trace_id | Wenn ein Trace existiert | OpenTelemetry Trace-ID |
span_id | Wenn ein Span existiert | OpenTelemetry Span-ID |
error | Bei Fehlern | Sicherer Ausnahmetyp und -meldung |
duration_ms | Bei gemessenen Vorgängen | Verstrichene Millisekunden |
Structlog-Level-Prozessoren erhalten üblicherweise Methodennamen in Kleinbuchstaben. Normalisieren Sie nach dem Hinzufügen des Levels:
from typing import Any
import structlog
def uppercase_log_level(
_logger: Any,
_method_name: str,
event_dict: dict[str, Any],
) -> dict[str, Any]:
"Normalisiere das strukturierte Protokoll-Level auf das gemeinsame Schema."
level = event_dict.get("level")
if isinstance(level, str):
event_dict["level"] = level.upper()
return event_dict
processors = [
structlog.processors.add_log_level,
uppercase_log_level,
structlog.processors.TimeStamper(fmt="iso", utc=True),
]
Testen Sie das endgültig gerenderte Ereignis, nicht nur den Prozessor isoliert.
Sicherheitsbasis
Niemals:
- Anmeldeinformationen, Tokens, private Schlüssel oder echte geheime Werte committen oder hartcodieren
- Echte Geheimnisse in
.env- oder TOML-Dateien speichern - Geheimnisse, Zugriffstokens, sensible personenbezogene Daten oder uneingeschränkte Anforderungskörper protokollieren
- Externe Werte in SQL interpolieren
shell=Truemit externen oder variablen Eingaben verwenden- Nicht vertrauenswürdige Pickle-Daten deserialisieren
- Nicht vertrauenswürdige Eingaben mit
eval,execodercompileausführen - Veränderbare Standardargumente verwenden
- Wildcard-Importe verwenden, außer einem dokumentierten öffentlichen Re-Export
- Still einen sicherheitskritischen Rückgabewert oder eine Ausnahme verwerfen
- Ein bloßes
except:verwenden
Fangen Sie Exception nur an einer Prozess-, Worker-, Task- oder Framework-Grenze, wo der Handler sicher protokolliert und dann erneut auslöst, den Fehler auf einen Exit-Status abbildet oder einen definierten Protokollfehler zurückgibt. Fangen Sie spezifische Ausnahmen innerhalb der Anwendungslogik.
Speichern Sie gewöhnliche Einstellungen und geheime Referenzen in Konfigurationsdateien. Liefern Sie geheime Werte beim Start durch Infisical-Injektion oder ein genehmigtes Äquivalent aus. Validieren Sie die erforderliche Konfiguration, bevor Sie Arbeit annehmen.