sophophilix/python-standards

Définit la chaîne d'outils Python partagée, la politique de dépendances, les barrières de qualité, le socle de sécurité, le schéma de journalisation et la propriété de la configuration. À utiliser pour toute tâche de code Python ou lorsqu'une autre compétence Python nécessite une règle centrale. Utilisez « technical-writing » pour toute documentation produite au cours de la tâche.

Qu'est-ce que python-standards ?

Cette compétence est la source de vérité pour les outils Python et les règles transverses aux projets. Elle établit des normes cohérentes de formatage, de linting, de typage, de tests et de sécurité, réduisant ainsi la duplication entre les compétences « architecture », « style », « test » et « révision ». Elle fonctionne aussi bien pour Claude Code que pour tout agent nécessitant une politique Python centralisée. Les règles s'appliquent par ordre de priorité : d'abord les exigences explicites de l'utilisateur ou de l'organisation, puis la configuration du dépôt, puis cette compétence, et enfin PEP 8. Le socle de sécurité ne peut être affaibli silencieusement ; toute exception doit être documentée dans le registre des décisions du projet. La compétence impose l'utilisation de `uv` pour les environnements et les dépendances, Ruff pour le formatage et le linting, mypy en mode strict pour le typage, pytest avec couverture de code, Bandit et Semgrep pour la sécurité, structlog pour la journalisation structurée, et OpenTelemetry pour le tracing. Elle fournit également des commandes canoniques pour la CI, des exemples de configuration `pyproject.toml` et un contrat de journalisation structurée avec des champs obligatoires comme `timestamp`, `level`, `event` et `trace_id`.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/sophophilix/agent-skills/tree/HEAD/plugins/python/skills/python-standards

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Normes Python

Cette compétence est la source de vérité pour les outils Python et les règles transverses aux projets. Les compétences d'architecture, de style, de test et de révision doivent la référencer plutôt que la répéter.

Pour la prose d'un projet, chargez également technical-writing. Elle invoque humanizer et gère l'emplacement des documents, les horodatages, les métadonnées de révision, l'accessibilité et la qualité rédactionnelle.

Ordre de priorité des règles

Appliquer les règles dans cet ordre :

  1. Exigences explicites de l'utilisateur ou de l'organisation
  2. Configuration du dépôt et décisions d'architecture acceptées
  3. Cette compétence et les autres compétences Python
  4. PEP 8 et paramètres par défaut des outils

N'affaiblissez pas le socle de sécurité silencieusement. Enregistrez une exception requise, son périmètre, son risque, son propriétaire (si connu) et sa condition de suppression dans le registre des décisions du projet.

Exécution et disposition

  • Ciblez Python 3.11 ou plus récent. Respectez un dépôt qui cible une version plus récente.
  • Utilisez from __future__ import annotations lorsque cela améliore la compatibilité ascendante ou résout un ordre d'annotation. Ne l'ajoutez pas mécaniquement aux fichiers qui n'en ont pas besoin.
  • Préférez une disposition src/ pour les nouveaux paquets distribuables.
  • Conservez les métadonnées du projet et la configuration des outils pris en charge dans pyproject.toml.
  • Utilisez uv pour les environnements, la résolution des dépendances, le verrouillage et l'exécution des commandes.

Chaîne d'outils prise en charge

ObjectifPar défautUtilisation requise
Formatage et lintingRuffTous les projets maintenus
Vérification de typagemypy strictPaquets de production et API publiques
Tests et couverturepytest, pytest-cov, coverage.pyTous les changements de comportement
Linting de sécuritéRègles S de Ruff et BanditPaquets de production
SASTSemgrep avec règles du dépôtCI pour les produits maintenus
Audit des dépendancespip-auditCI et vérifications de version
Journalisation structuréestructlogApplications et services
TracingOpenTelemetryServices réseau et pipelines tracés
Gestion des paquetsuvTous les projets
Hooks Gitpre-commitDépôts maintenus
Distribution de secretsInfisical par défaut de l'organisationCharges de travail utilisant des secrets

Une décision d'architecture acceptée peut sélectionner un fournisseur équivalent ou omettre un outil opérationnel qui ne convient pas à une petite bibliothèque locale ou à un script. Ruff, le typage, les tests et la gestion sécurisée des dépendances restent la base de référence.

Les outils expérimentaux, y compris les scanners de vulnérabilité basés sur des modèles et les réviseurs IA, sont consultatifs. Ils ne doivent pas constituer des barrières obligatoires tant que l'équipe n'a pas défini une version prise en charge, une commande, une politique d'échec et un propriétaire.

Politique de dépendances et de versions

  • Déclarez des plages d'exécution compatibles dans pyproject.toml.
  • Validez uv.lock pour les applications et les environnements de développement reproductibles. Le fichier de verrouillage possède les versions résolues exactes.
  • Pour les bibliothèques publiées, déclarez des limites inférieures honnêtes, testez les versions Python prises en charge et les limites inférieures importantes, et ne vous fiez pas au fichier de verrouillage comme contrat de consommateur.
  • Placez les outils de qualité et de test dans des groupes de dépendances nommés.
  • Exécutez les commandes de qualité via l'environnement uv verrouillé. Ne maintenez pas un second ensemble de versions d'outils Python dans pre-commit.
  • Mettez à niveau intentionnellement avec uv lock --upgrade-package <nom> ou une actualisation complète du verrouillage révisée.

Audit canonique des dépendances pour un projet uv :

fichier_exigences="$(mktemp)"
trap 'rm -f "$fichier_exigences"' EXIT
uv export \
  --frozen \
  --no-dev \
  --no-emit-project \
  --no-hashes \
  --format requirements.txt \
  --output-file "$fichier_exigences"
uv run --frozen pip-audit \
  --strict \
  --no-deps \
  --requirement "$fichier_exigences"

L'exportation audite les dépendances d'exécution verrouillées exactes sans demander à pip-audit de résoudre un second graphe. La détection actuelle de projet --locked de pip-audit prend en charge pyproject.toml et pylock.*.toml, pas uv.lock, donc n'utilisez pas pip-audit --locked . comme audit uv.

pip-audit doit être présent dans le groupe de dépendances de qualité. Une dérogation de vulnérabilité doit nommer l'avis, le périmètre concerné, le contrôle compensatoire, le propriétaire (si connu) et la date d'expiration ou de révision.

Commandes de qualité canoniques

Adaptez les chemins des paquets au dépôt, mais conservez une seule source de commandes pour une utilisation locale et CI :

uv sync --frozen
uv run --frozen ruff check .
uv run --frozen ruff format --check .
uv run --frozen mypy <racines-des-paquets>
uv run --frozen bandit -c pyproject.toml -r <racines-des-paquets>
uv run --frozen semgrep scan --config .semgrep.yml <racines-des-paquets>
uv run --frozen pytest
# Exécutez l'audit de dépendances verrouillées canonique ci-dessus.

La CI enregistre la commande et le résultat. Un outil ou une configuration manquant est « indisponible », pas un succès.

Propriété de pre-commit

Épinglez les hooks d'hygiène non Python par version. Invoquez les outils Python comme hooks locaux via uv run --frozen, afin que les hooks locaux et la CI utilisent les versions exactes de uv.lock.

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: [<racines-des-paquets>]

Exécutez Bandit, Semgrep, les tests et l'audit de dépendances dans la CI. Ajoutez-les à pre-commit uniquement lorsque leur latence et leurs dépendances conviennent au dépôt.

Décisions minimales de pyproject.toml

Utilisez les noms et racines des paquets du dépôt plutôt que de copier des espaces réservés.

[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 = ["votre_paquet"]

[tool.coverage.report]
fail_under = 80
show_missing = true

[tool.bandit]
exclude_dirs = ["tests"]
skips = ["B101"]

Documentez chaque ignore avec un périmètre restreint et une raison. Préférez les ignores par fichier aux ignores globaux.

Contrat de journalisation structurée

Les applications émettent ces champs. Les bibliothèques peuvent utiliser la façade de journalisation de l'application hôte et ne doivent pas configurer de gestionnaires globaux à l'importation.

ChampExigenceSignification
timestampToujoursISO 8601 UTC
levelToujoursDEBUG, INFO, WARNING, ERROR ou CRITICAL
eventToujoursNom d'événement stable en snake_case
serviceToujours pour les applicationsNom du service ou de l'application
trace_idQuand une trace existeID de trace OpenTelemetry
span_idQuand une span existeID de span OpenTelemetry
errorEn cas d'échecType d'exception sûr et message
duration_msPour les opérations mesuréesMillisecondes écoulées

Les processeurs de niveau de structlog reçoivent généralement des noms de méthode en minuscules. Normalisez après avoir ajouté le niveau :

from typing import Any

import structlog


def mettre_en_majuscule_niveau_log(
    _logger: Any,
    _method_name: str,
    event_dict: dict[str, Any],
) -> dict[str, Any]:
    """Normalise le niveau de journalisation structurée vers le schéma partagé."""
    level = event_dict.get("level")
    if isinstance(level, str):
        event_dict["level"] = level.upper()
    return event_dict


processeurs = [
    structlog.processors.add_log_level,
    mettre_en_majuscule_niveau_log,
    structlog.processors.TimeStamper(fmt="iso", utc=True),
]

Testez l'événement final rendu, pas seulement le processeur isolément.

Socle de sécurité

Ne jamais :

  • valider ou coder en dur des informations d'identification, jetons, clés privées ou valeurs secrètes réelles
  • stocker des secrets réels dans .env ou des fichiers TOML
  • journaliser des secrets, jetons d'accès, données personnelles sensibles ou corps de requête non restreints
  • interpoler des valeurs externes dans du SQL
  • utiliser shell=True avec une entrée externe ou variable
  • désérialiser des données pickle non fiables
  • exécuter une entrée non fiable avec eval, exec ou compile
  • utiliser des arguments par défaut mutables
  • utiliser des importations génériques sauf une ré-exportation publique documentée
  • ignorer silencieusement une valeur de retour ou une exception sensible à la sécurité
  • utiliser un except: nu

Attrapez Exception uniquement à la limite d'un processus, worker, tâche ou framework où le gestionnaire journalise de manière sécurisée puis relance, mappe l'échec à un code de sortie, ou renvoie une erreur de protocole définie. Attrapez des exceptions spécifiques dans la logique applicative.

Stockez les paramètres ordinaires et les références de secrets dans des fichiers de configuration. Livrez les valeurs secrètes au démarrage via l'injection Infisical ou un équivalent approuvé. Validez la configuration requise avant d'accepter du travail.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Skills associés