Community编程与开发github.com

Python 标准规范

定义共享的 Python 工具链、依赖策略、质量门禁、安全基线、日志模式和配置归属。用于任何 Python 代码任务,或当其它 Python 技能需要中心规则时使用。对于任务中产生的文档,请使用 technical-writing。

Python 标准规范 是什么?

该技能是 Python 工具链和跨项目规则的权威来源。它规定了 Python 版本要求(3.11+)、项目布局(优先 src/ 布局)、依赖管理(使用 uv)以及完整的工具链选择,包括 Ruff(格式化和 lint)、mypy strict(类型检查)、pytest(测试)、Bandit 和 Semgrep(安全扫描)。技能强调了规则优先级:显式需求 > 仓库配置 > 本技能 > PEP 8 和工具默认值,并明确要求安全基线不可被静默削弱。此外,它还规范了结构化日志字段(timestamp、level、event、trace_id 等),定义了禁止的安全操作(如硬编码凭证、日志敏感数据、SQL 注入、解包不可信 pickle),并提供了 pyproject.toml 的最小决策模板、pre-commit 钩子配置以及规范的质量命令和依赖审计脚本。该技能适用于任何需要开发或审查 Python 代码的 AI 代理,支持 Claude Code、Cursor 等平台。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/sophophilix/agent-skills/tree/HEAD/plugins/python/skills/python-standards

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Python 标准规范 是做什么的?

本技能是 Python 工具链和跨项目规则的权威来源。架构、样式、测试和审查技能应引用本技能,而非重复其内容。

对于项目中的自然语言文档,请同时加载 technical-writing。它会调用 humanizer,并负责文档位置、时间戳、审查元数据、可访问性和写作质量。

规则优先级

按以下顺序应用规则:

  1. 用户或组织的显式要求
  2. 仓库配置和已接受的架构决策
  3. 本技能和其它 Python 技能
  4. PEP 8 和工具默认值

不要静默削弱安全基线。如需例外,须在项目的决策记录中记录其类型、范围、风险、已知负责人和移除条件。

运行时与布局

  • 目标 Python 3.11 或更新版本。如果仓库定位的是更新版本,则尊重该版本。
  • 当 from __future__ import annotations 能提升前向兼容性或解决注解顺序问题时使用它。不要机械地将其添加到不需要的文件中。
  • 对于新的可分发包,优先使用 src/ 布局。
  • 将项目元数据和受支持工具配置保存在 pyproject.toml 中。
  • 使用 uv 管理环境、依赖解析、锁定和命令执行。

受支持的工具链

用途默认工具是否必需
格式化和 lintRuff所有受维护的项目
类型检查mypy strict生产包和公共 API
测试和覆盖率pytest、pytest-cov、coverage.py所有行为变更
安全 lintRuff S 规则和 Bandit生产包
SAST带仓库规则的 Semgrep受维护产品的 CI
依赖审计pip-auditCI 和发布检查
结构化日志structlog应用和服务
追踪OpenTelemetry网络化服务和有追踪的流水线
包管理uv所有项目
Git 钩子pre-commit受维护的仓库
机密交付按组织默认为 Infisical使用机密的工作负载

已接受的架构决策可以选择等效的供应商,或为小型本地库或脚本省略某个运营工具。Ruff、类型检查、测试和安全依赖处理仍然是基线。

实验性工具(包括基于模型的漏洞扫描器和 AI 审查者)仅作为建议,不得成为强制门禁,除非团队定义了受支持的版本、命令、失败策略和负责人。

依赖与版本策略

  • 在 pyproject.toml 中声明兼容的运行时范围。
  • 对于应用和可重现的开发环境,提交 uv.lock 文件。锁定文件拥有确切的解析版本。
  • 对于发布的库,声明诚实的下限,测试支持的 Python 版本和重要的下限,并且不要依赖锁定文件作为消费者契约。
  • 将质量和测试工具放入命名的依赖组中。
  • 通过锁定的 uv 环境运行质量命令。不要在 pre-commit 中维护第二套 Python 工具版本。
  • 使用 uv lock --upgrade-package <name> 或有审查的完整锁刷新进行有意升级。

uv 项目的规范依赖审计:

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"

导出审计仅审计锁定的运行时依赖,无需 pip-audit 解析第二个图。当前 pip-audit --locked 项目发现支持 pyproject.toml 和 pylock.*.toml,但不支持 uv.lock,因此不要将 pip-audit --locked . 用于 uv 审计。

pip-audit 必须存在于质量依赖组中。漏洞豁免必须指明公告、受影响范围、补偿性控制、已知负责人以及到期或审查日期。

规范的质量命令

调整包路径以适配仓库,但保留一个命令源供本地使用和 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
# 运行上面规范的导出锁定依赖审计。

CI 记录命令及其结果。缺少工具或配置为 unavailable,而非通过。

Pre-commit 所有权

按版本固定非 Python 的 hygiene 挂钩。将 Python 质量工具作为本地挂钩通过 uv run --frozen 调用,使本地挂钩和 CI 使用 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: [<package-roots>]

在 CI 中运行 Bandit、Semgrep、测试和依赖审计。仅在其延迟和依赖适合仓库时,才将其添加到 pre-commit。

最低 pyproject.toml 决策

使用仓库的包名和根目录,而非复制占位符。

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

为每个忽略项记录其狭窄范围和原因。优先使用基于文件的忽略而非全局忽略。

结构化日志契约

应用发出以下字段。库可以使用宿主应用的日志门面,并且不得在导入时配置全局处理器。

字段要求含义
timestamp始终ISO 8601 UTC
level始终DEBUG、INFO、WARNING、ERROR 或 CRITICAL
event始终稳定的蛇形命名事件名称
service应用始终服务或应用名称
trace_id存在追踪时OpenTelemetry 追踪 ID
span_id存在跨度时OpenTelemetry 跨度 ID
error失败时安全的异常类型和消息
duration_ms测量操作时经过的毫秒数

Structlog 的级别处理器通常接收小写的方法名。添加级别后将其标准化:

from typing import Any

import structlog


def uppercase_log_level(
    _logger: Any,
    _method_name: str,
    event_dict: dict[str, Any],
) -> dict[str, Any]:
    """Normalize the structured log level to the shared 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),
]

测试最终渲染的事件,而不仅仅测试处理器本身。

安全基线

绝对禁止:

  • 提交或硬编码凭据、令牌、私钥或真实的秘密值
  • 将真实秘密存储在 .env 或 TOML 文件中
  • 记录秘密、访问令牌、敏感个人数据或未限制的请求体
  • 将外部值插入 SQL
  • 对外部或可变输入使用 shell=True
  • 反序列化不受信任的 pickle 数据
  • 对不受信任的输入使用 eval、exec 或 compile
  • 使用可变默认参数
  • 使用通配符导入,除非是文档化的公共重新导出
  • 静默丢弃安全敏感的返回值或异常
  • 使用裸的 except:

仅在进程、工作器、任务或框架边界捕获 Exception,此时处理器安全地记录日志然后重新抛出、将失败映射到退出状态或返回已定义协议错误。在应用逻辑内捕获特定异常。

将普通设置和秘密引用存储在配置文件中。在启动时通过 Infisical 注入或批准的等效方式交付秘密值。在接受工作前验证必需的配置。

Individual skills in this repo

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

相关技能