python-pypi-package-builder

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Python PyPI Package Builder Skill

Python PyPI 包构建技能

A complete, battle-tested guide for building, testing, linting, versioning, typing, and publishing a production-grade Python library to PyPI — from first commit to community-ready release.
AI Agent Instruction: Read this entire file before writing a single line of code or creating any file. Every decision — layout, backend, versioning strategy, patterns, CI — has a decision rule here. Follow the decision trees in order. This skill applies to any Python package type (utility, SDK, CLI, plugin, data library). Do not skip sections.

这是一份经过实战验证的完整指南,可指导你完成生产级Python库从首次提交到可面向社区发布的全流程:构建、测试、代码检查、版本管理、类型标注、发布到PyPI。
AI Agent 提示: 在编写任何代码或创建文件前请通读全文。所有决策——项目布局、构建后端、版本管理策略、开发模式、CI配置——都有对应的决策规则,请按顺序遵循决策树。本技能适用于所有Python包类型(工具库、SDK、CLI、插件、数据库),请勿跳过任何章节。

Quick Navigation

快速导航

Section in this fileWhat it covers
1. Skill TriggerWhen to load this skill
2. Package Type DecisionIdentify what you are building
3. Folder Structure Decisionsrc/ vs flat vs monorepo
4. Build Backend Decisionsetuptools / hatchling / flit / poetry
5. PyPA Packaging FlowThe canonical publish pipeline
6. Project Structure TemplatesFull layouts for every option
7. Versioning StrategyPEP 440, semver, dynamic vs static
Reference fileWhat it covers
references/pyproject-toml.md
All four backend templates,
setuptools_scm
,
py.typed
, tool configs
references/library-patterns.md
OOP/SOLID, type hints, core class design, factory, protocols, CLI
references/testing-quality.md
conftest.py
, unit/backend/async tests, ruff/mypy/pre-commit
references/ci-publishing.md
ci.yml
,
publish.yml
, Trusted Publishing, TestPyPI, CHANGELOG, release checklist
references/community-docs.md
README, docstrings, CONTRIBUTING, SECURITY, anti-patterns, master checklist
references/architecture-patterns.md
Backend system (plugin/strategy), config layer, transport layer, CLI, backend injection
references/versioning-strategy.md
PEP 440, SemVer, pre-release, setuptools_scm deep-dive, flit static, decision engine
references/release-governance.md
Branch strategy, branch protection, OIDC, tag author validation, prevent invalid tags
references/tooling-ruff.md
Ruff-only setup (replaces black/isort), mypy config, pre-commit, asyncio_mode=auto
Scaffold script: run
python skills/python-pypi-package-builder/scripts/scaffold.py --name your-package-name
to generate the entire directory layout, stub files, and
pyproject.toml
in one command.

本文章节涵盖内容
1. 技能触发场景何时加载本技能
2. 包类型判定明确你要开发的包类型
3. 文件夹结构选择src/布局 vs 扁平化布局 vs 单仓多包布局
4. 构建后端选择setuptools / hatchling / flit / poetry
5. PyPA 标准打包流程官方发布流水线规范
6. 项目结构模板适配所有选项的完整项目布局
7. 版本管理策略PEP 440、语义化版本、动态版本 vs 静态版本
参考文件涵盖内容
references/pyproject-toml.md
四种构建后端模板、
setuptools_scm
配置、
py.typed
配置、工具链配置
references/library-patterns.md
OOP/SOLID设计、类型提示、核心类设计、工厂函数、协议、CLI实现
references/testing-quality.md
conftest.py
配置、单元/后端/异步测试、ruff/mypy/pre-commit配置
references/ci-publishing.md
ci.yml
publish.yml
配置、可信发布、TestPyPI使用、CHANGELOG规范、发布检查清单
references/community-docs.md
README编写、文档字符串规范、贡献指南、安全说明、反模式、总检查清单
references/architecture-patterns.md
后端系统(插件/策略模式)、配置层、传输层、CLI、后端注入规则
references/versioning-strategy.md
PEP 440、语义化版本、预发布标识、setuptools_scm深入讲解、flit静态版本、决策引擎
references/release-governance.md
分支策略、分支保护规则、OIDC配置、标签作者校验、无效标签拦截
references/tooling-ruff.md
仅用Ruff的配置方案(替代black/isort)、mypy配置、pre-commit钩子、asyncio_mode=auto配置
脚手架脚本: 执行
python skills/python-pypi-package-builder/scripts/scaffold.py --name your-package-name
命令即可一键生成完整目录结构、存根文件和
pyproject.toml

1. Skill Trigger

1. 技能触发场景

Load this skill whenever the user wants to:
  • Create, scaffold, or publish a Python package or library to PyPI
  • Build a pip-installable SDK, utility, CLI tool, or framework extension
  • Set up
    pyproject.toml
    , linting, mypy, pre-commit, or GitHub Actions for a Python project
  • Understand versioning (
    setuptools_scm
    , PEP 440, semver, static versioning)
  • Understand PyPA specs:
    py.typed
    ,
    MANIFEST.in
    ,
    RECORD
    , classifiers
  • Publish to PyPI using Trusted Publishing (OIDC) or API tokens
  • Refactor an existing package to follow modern Python packaging standards
  • Add type hints, protocols, ABCs, or dataclasses to a Python library
  • Apply OOP/SOLID design patterns to a Python package
  • Choose between build backends (setuptools, hatchling, flit, poetry)
Also trigger for phrases like: "build a Python SDK", "publish my library", "set up PyPI CI", "create a pip package", "how do I publish to PyPI", "pyproject.toml help", "PEP 561 typed", "setuptools_scm version", "semver Python", "PEP 440", "git tag release", "Trusted Publishing".

当用户有以下需求时加载本技能:
  • 创建、初始化或发布Python包/库到PyPI
  • 开发可通过pip安装的SDK、工具库、CLI工具或框架扩展
  • 为Python项目配置
    pyproject.toml
    、代码检查、mypy、pre-commit或GitHub Actions
  • 了解版本管理相关内容(
    setuptools_scm
    、PEP 440、语义化版本、静态版本管理)
  • 了解PyPA规范:
    py.typed
    MANIFEST.in
    RECORD
    、分类器
  • 使用可信发布(OIDC)或API令牌发布包到PyPI
  • 重构现有包以符合现代Python打包标准
  • 为Python库添加类型提示、协议、抽象基类或数据类
  • 为Python包应用OOP/SOLID设计模式
  • 在不同构建后端(setuptools、hatchling、flit、poetry)之间做选择
触发关键词: "构建Python SDK"、"发布我的库"、"配置PyPI CI"、"创建pip包"、"如何发布到PyPI"、"pyproject.toml帮助"、"PEP 561类型标注"、"setuptools_scm版本管理"、"Python语义化版本"、"PEP 440"、"git tag发布"、"可信发布"。

2. Package Type Decision

2. 包类型判定

Identify what the user is building before writing any code. Each type has distinct patterns.
在编写任何代码前先明确用户要开发的包类型,不同类型有不同的开发模式。

Decision Table

判定表

TypeCore PatternEntry PointKey DepsExample Packages
Utility libraryModule of pure functions + helpersImport API onlyMinimal
arrow
,
humanize
,
boltons
,
more-itertools
API client / SDKClass with methods, auth, retry logicImport API only
httpx
or
requests
boto3
,
stripe-python
,
openai
CLI toolCommand functions + argument parser
[project.scripts]
or
[project.entry-points]
click
or
typer
black
,
ruff
,
httpie
,
rich
Framework pluginPlugin class, hook registration
[project.entry-points."framework.plugin"]
Framework dep
pytest-*
,
django-*
,
flask-*
Data processing libraryClasses + functional pipelineImport API onlyOptional:
numpy
,
pandas
pydantic
,
marshmallow
,
cerberus
Mixed / genericCombination of aboveVariesVariesMany real-world packages
Decision Rule: Ask the user if unclear. A package can combine types (e.g., SDK with a CLI entry point) — use the primary type for structural decisions and add secondary type patterns on top.
For implementation patterns of each type, see
references/library-patterns.md
.
类型核心模式入口点核心依赖示例包
工具库纯函数+辅助方法模块仅导入API最少依赖
arrow
humanize
boltons
more-itertools
API客户端/SDK封装方法、鉴权、重试逻辑的类仅导入API
httpx
requests
boto3
stripe-python
openai
CLI工具命令函数+参数解析器
[project.scripts]
[project.entry-points]
click
typer
black
ruff
httpie
rich
框架插件插件类、钩子注册
[project.entry-points."framework.plugin"]
对应框架依赖
pytest-*
django-*
flask-*
数据处理库类+函数式处理流水线仅导入API可选:
numpy
pandas
pydantic
marshmallow
cerberus
混合/通用类型以上类型的组合按需设置按需引入多数实际项目中的包
判定规则: 不明确时询问用户。一个包可以组合多种类型(比如同时是SDK和CLI工具)——基于主类型做结构决策,叠加次要类型的开发模式即可。
各类包的实现模式可参考
references/library-patterns.md

Package Naming Rules

包命名规则

  • PyPI name: all lowercase, hyphens —
    my-python-library
  • Python import name: underscores —
    my_python_library
  • Check availability: https://pypi.org/search/ before starting
  • Avoid shadowing popular packages (verify
    pip install <name>
    fails first)

  • PyPI名称:全小写、用连字符分隔 ——
    my-python-library
  • Python导入名称:用下划线分隔 ——
    my_python_library
  • 开发前先检查可用性:https://pypi.org/search/
  • 避免与热门包重名(先验证
    pip install <name>
    会失败再使用)

3. Folder Structure Decision

3. 文件夹结构选择

Decision Tree

决策树

Does the package have 5+ internal modules OR multiple contributors OR complex sub-packages?
├── YES → Use src/ layout
│         Reason: prevents accidental import of uninstalled code during development;
│         separates source from project root files; PyPA-recommended for large projects.
├── NO → Is it a single-module, focused package (e.g., one file + helpers)?
│         ├── YES → Use flat layout
│         └── NO (medium complexity) → Use flat layout, migrate to src/ if it grows
└── Is it multiple related packages under one namespace (e.g., myorg.http, myorg.db)?
          └── YES → Use namespace/monorepo layout
Does the package have 5+ internal modules OR multiple contributors OR complex sub-packages?
├── YES → Use src/ layout
│         Reason: prevents accidental import of uninstalled code during development;
│         separates source from project root files; PyPA-recommended for large projects.
├── NO → Is it a single-module, focused package (e.g., one file + helpers)?
│         ├── YES → Use flat layout
│         └── NO (medium complexity) → Use flat layout, migrate to src/ if it grows
└── Is it multiple related packages under one namespace (e.g., myorg.http, myorg.db)?
          └── YES → Use namespace/monorepo layout

Quick Rule Summary

规则速览

SituationUse
New project, unknown future size
src/
layout (safest default)
Single-purpose, 1–4 modulesFlat layout
Large library, many contributors
src/
layout
Multiple packages in one repoNamespace / monorepo
Migrating old flat projectKeep flat; migrate to
src/
at next major version

场景推荐布局
新项目,未来规模不确定
src/
布局(最安全的默认选项)
单一功能,仅1-4个模块扁平化布局
大型库,多位贡献者
src/
布局
单个仓库下有多个关联包命名空间/单仓多包布局
迁移旧的扁平化项目保留扁平化布局,下个大版本再迁移到
src/

4. Build Backend Decision

4. 构建后端选择

Decision Tree

决策树

Does the user need version derived automatically from git tags?
├── YES → Use setuptools + setuptools_scm
│         (git tag v1.0.0 → that IS your release workflow)
└── NO → Does the user want an all-in-one tool (deps + build + publish)?
          ├── YES → Use poetry (v2+ supports standard [project] table)
          └── NO → Is the package pure Python with no C extensions?
                    ├── YES, minimal config preferred → Use flit
                    │   (zero config, auto-discovers version from __version__)
                    └── YES, modern & fast preferred → Use hatchling
                        (zero-config, plugin system, no setup.py needed)

Does the package have C/Cython/Fortran extensions?
└── YES → MUST use setuptools (only backend with full native extension support)
Does the user need version derived automatically from git tags?
├── YES → Use setuptools + setuptools_scm
│         (git tag v1.0.0 → that IS your release workflow)
└── NO → Does the user want an all-in-one tool (deps + build + publish)?
          ├── YES → Use poetry (v2+ supports standard [project] table)
          └── NO → Is the package pure Python with no C extensions?
                    ├── YES, minimal config preferred → Use flit
                    │   (zero config, auto-discovers version from __version__)
                    └── YES, modern & fast preferred → Use hatchling
                        (zero-config, plugin system, no setup.py needed)

Does the package have C/Cython/Fortran extensions?
└── YES → MUST use setuptools (only backend with full native extension support)

Backend Comparison

后端对比

BackendVersion sourceConfigC extensionsBest for
setuptools
+
setuptools_scm
git tags (automatic)
pyproject.toml
+ optional
setup.py
shim
YesProjects with git-tag releases; any complexity
hatchling
manual or plugin
pyproject.toml
only
NoNew pure-Python projects; fast, modern
flit
__version__
in
__init__.py
pyproject.toml
only
NoVery simple, single-module packages
poetry
pyproject.toml
field
pyproject.toml
only
NoTeams wanting integrated dep management
For all four complete
pyproject.toml
templates, see
references/pyproject-toml.md
.

后端版本来源配置文件支持C扩展适用场景
setuptools
+
setuptools_scm
git标签(自动生成)
pyproject.toml
+ 可选
setup.py
垫片
基于git标签发布的项目;任意复杂度的项目
hatchling
手动配置或插件生成仅需
pyproject.toml
新的纯Python项目;追求现代、高效的开发体验
flit
__init__.py
中的
__version__
仅需
pyproject.toml
非常简单的单模块包
poetry
pyproject.toml
中的字段
仅需
pyproject.toml
需要依赖管理、构建、发布一体化工具的团队
四种构建后端对应的完整
pyproject.toml
模板可参考
references/pyproject-toml.md

5. PyPA Packaging Flow

5. PyPA 标准打包流程

This is the canonical end-to-end flow from source code to user install. Every step must be understood before publishing.
1. SOURCE TREE
   Your code in version control (git)
   └── pyproject.toml describes metadata + build system

2. BUILD
   python -m build
   └── Produces two artifacts in dist/:
       ├── *.tar.gz   → source distribution (sdist)
       └── *.whl      → built distribution (wheel) — preferred by pip

3. VALIDATE
   twine check dist/*
   └── Checks metadata, README rendering, and PyPI compatibility

4. TEST PUBLISH (first release only)
   twine upload --repository testpypi dist/*
   └── Verify: pip install --index-url https://test.pypi.org/simple/ your-package

5. PUBLISH
   twine upload dist/*          ← manual fallback
   OR GitHub Actions publish.yml  ← recommended (Trusted Publishing / OIDC)

6. USER INSTALL
   pip install your-package
   pip install "your-package[extra]"
这是从源代码到用户安装的官方端到端流程,发布前务必理解每一步。
1. SOURCE TREE
   Your code in version control (git)
   └── pyproject.toml describes metadata + build system

2. BUILD
   python -m build
   └── Produces two artifacts in dist/:
       ├── *.tar.gz   → source distribution (sdist)
       └── *.whl      → built distribution (wheel) — preferred by pip

3. VALIDATE
   twine check dist/*
   └── Checks metadata, README rendering, and PyPI compatibility

4. TEST PUBLISH (first release only)
   twine upload --repository testpypi dist/*
   └── Verify: pip install --index-url https://test.pypi.org/simple/ your-package

5. PUBLISH
   twine upload dist/*          ← manual fallback
   OR GitHub Actions publish.yml  ← recommended (Trusted Publishing / OIDC)

6. USER INSTALL
   pip install your-package
   pip install "your-package[extra]"

Key PyPA Concepts

核心PyPA概念

ConceptWhat it means
sdistSource distribution — your source + metadata; used when no wheel is available
wheel (.whl)Pre-built binary — pip extracts directly into site-packages; no build step
PEP 517/518Standard build system interface via
pyproject.toml [build-system]
table
PEP 621Standard
[project]
table in
pyproject.toml
; all modern backends support it
PEP 639
license
key as SPDX string (e.g.,
"MIT"
,
"Apache-2.0"
) — not
{text = "MIT"}
PEP 561
py.typed
empty marker file — tells mypy/IDEs this package ships type information
For complete CI workflow and publishing setup, see
references/ci-publishing.md
.

概念含义
sdist源码分发包——包含你的源码和元数据;无可用wheel包时使用
wheel (.whl)预构建二进制包——pip可直接解压到site-packages,无需构建步骤
PEP 517/518通过
pyproject.toml
[build-system]
表定义标准构建系统接口
PEP 621
pyproject.toml
中的标准
[project]
配置表,所有现代构建后端都支持
PEP 639用SPDX字符串表示
license
字段(比如
"MIT"
"Apache-2.0"
),而非
{text = "MIT"}
PEP 561空标记文件
py.typed
——告诉mypy/IDE本包自带类型信息
完整CI工作流和发布配置可参考
references/ci-publishing.md

6. Project Structure Templates

6. 项目结构模板

A. src/ Layout (Recommended default for new projects)

A. src/布局(新项目推荐默认使用)

your-package/
├── src/
│   └── your_package/
│       ├── __init__.py           # Public API: __all__, __version__
│       ├── py.typed              # PEP 561 marker — EMPTY FILE
│       ├── core.py               # Primary implementation
│       ├── client.py             # (API client type) or remove
│       ├── cli.py                # (CLI type) click/typer commands, or remove
│       ├── config.py             # Settings / configuration dataclass
│       ├── exceptions.py         # Custom exception hierarchy
│       ├── models.py             # Data classes, Pydantic models, TypedDicts
│       ├── utils.py              # Internal helpers (prefix _utils if private)
│       ├── types.py              # Shared type aliases and TypeVars
│       └── backends/             # (Plugin pattern) — remove if not needed
│           ├── __init__.py       # Protocol / ABC interface definition
│           ├── memory.py         # Default zero-dep implementation
│           └── redis.py          # Optional heavy implementation
├── tests/
│   ├── __init__.py
│   ├── conftest.py               # Shared fixtures
│   ├── unit/
│   │   ├── __init__.py
│   │   ├── test_core.py
│   │   ├── test_config.py
│   │   └── test_models.py
│   ├── integration/
│   │   ├── __init__.py
│   │   └── test_backends.py
│   └── e2e/                      # Optional: end-to-end tests
│       └── __init__.py
├── docs/                         # Optional: mkdocs or sphinx
├── scripts/
│   └── scaffold.py
├── .github/
│   ├── workflows/
│   │   ├── ci.yml
│   │   └── publish.yml
│   └── ISSUE_TEMPLATE/
│       ├── bug_report.md
│       └── feature_request.md
├── .pre-commit-config.yaml
├── pyproject.toml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── SECURITY.md
├── LICENSE
├── README.md
└── .gitignore
your-package/
├── src/
│   └── your_package/
│       ├── __init__.py           # Public API: __all__, __version__
│       ├── py.typed              # PEP 561 marker — EMPTY FILE
│       ├── core.py               # Primary implementation
│       ├── client.py             # (API client type) or remove
│       ├── cli.py                # (CLI type) click/typer commands, or remove
│       ├── config.py             # Settings / configuration dataclass
│       ├── exceptions.py         # Custom exception hierarchy
│       ├── models.py             # Data classes, Pydantic models, TypedDicts
│       ├── utils.py              # Internal helpers (prefix _utils if private)
│       ├── types.py              # Shared type aliases and TypeVars
│       └── backends/             # (Plugin pattern) — remove if not needed
│           ├── __init__.py       # Protocol / ABC interface definition
│           ├── memory.py         # Default zero-dep implementation
│           └── redis.py          # Optional heavy implementation
├── tests/
│   ├── __init__.py
│   ├── conftest.py               # Shared fixtures
│   ├── unit/
│   │   ├── __init__.py
│   │   ├── test_core.py
│   │   ├── test_config.py
│   │   └── test_models.py
│   ├── integration/
│   │   ├── __init__.py
│   │   └── test_backends.py
│   └── e2e/                      # Optional: end-to-end tests
│       └── __init__.py
├── docs/                         # Optional: mkdocs or sphinx
├── scripts/
│   └── scaffold.py
├── .github/
│   ├── workflows/
│   │   ├── ci.yml
│   │   └── publish.yml
│   └── ISSUE_TEMPLATE/
│       ├── bug_report.md
│       └── feature_request.md
├── .pre-commit-config.yaml
├── pyproject.toml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── SECURITY.md
├── LICENSE
├── README.md
└── .gitignore

B. Flat Layout (Small / focused packages)

B. 扁平化布局(小型/功能聚焦的包适用)

your-package/
├── your_package/         # ← at root, not inside src/
│   ├── __init__.py
│   ├── py.typed
│   └── ... (same internal structure)
├── tests/
└── ... (same top-level files)
your-package/
├── your_package/         # ← at root, not inside src/
│   ├── __init__.py
│   ├── py.typed
│   └── ... (same internal structure)
├── tests/
└── ... (same top-level files)

C. Namespace / Monorepo Layout (Multiple related packages)

C. 命名空间/单仓多包布局(多个关联包适用)

your-org/
├── packages/
│   ├── your-org-core/
│   │   ├── src/your_org/core/
│   │   └── pyproject.toml
│   ├── your-org-http/
│   │   ├── src/your_org/http/
│   │   └── pyproject.toml
│   └── your-org-cli/
│       ├── src/your_org/cli/
│       └── pyproject.toml
├── .github/workflows/
└── README.md
Each sub-package has its own
pyproject.toml
. They share the
your_org
namespace via PEP 420 implicit namespace packages (no
__init__.py
in the namespace root).
your-org/
├── packages/
│   ├── your-org-core/
│   │   ├── src/your_org/core/
│   │   └── pyproject.toml
│   ├── your-org-http/
│   │   ├── src/your_org/http/
│   │   └── pyproject.toml
│   └── your-org-cli/
│       ├── src/your_org/cli/
│       └── pyproject.toml
├── .github/workflows/
└── README.md
每个子包都有独立的
pyproject.toml
,通过PEP 420隐式命名空间包共享
your_org
命名空间(命名空间根目录无需
__init__.py
)。

Internal Module Guidelines

内部模块规范

FilePurposeWhen to include
__init__.py
Public API surface; re-exports;
__version__
Always
py.typed
PEP 561 typed-package marker (empty)Always
core.py
Primary class / main logicAlways
config.py
Settings dataclass or Pydantic modelWhen configurable
exceptions.py
Exception hierarchy (
YourBaseError
→ specifics)
Always
models.py
Data models / DTOs / TypedDictsWhen data-heavy
utils.py
Internal helpers (not part of public API)As needed
types.py
Shared
TypeVar
,
TypeAlias
,
Protocol
definitions
When complex typing
cli.py
CLI entry points (click/typer)CLI type only
backends/
Plugin/strategy patternWhen swappable implementations
_compat.py
Python version compatibility shimsWhen 3.9–3.13 compat needed

文件用途何时引入
__init__.py
公共API面、导出声明、
__version__
定义
始终需要
py.typed
PEP 561类型包标记(空文件)始终需要
core.py
核心类/主要逻辑始终需要
config.py
配置数据类或Pydantic模型可配置的项目需要
exceptions.py
异常层级(
YourBaseError
→ 具体异常)
始终需要
models.py
数据模型/DTO/TypedDict数据密集型项目需要
utils.py
内部辅助方法(不属于公共API)按需引入
types.py
共享的
TypeVar
TypeAlias
Protocol
定义
类型逻辑复杂的项目需要
cli.py
CLI入口点(click/typer实现)仅CLI类型包需要
backends/
插件/策略模式实现需要可切换实现的项目需要
_compat.py
Python版本兼容垫片需要兼容3.9–3.13版本的项目需要

7. Versioning Strategy

7. 版本管理策略

PEP 440 — The Standard

PEP 440 标准格式

Canonical form:  N[.N]+[{a|b|rc}N][.postN][.devN]

Examples:
  1.0.0          Stable release
  1.0.0a1        Alpha (pre-release)
  1.0.0b2        Beta
  1.0.0rc1       Release candidate
  1.0.0.post1    Post-release (e.g., packaging fix only)
  1.0.0.dev1     Development snapshot (not for PyPI)
Canonical form:  N[.N]+[{a|b|rc}N][.postN][.devN]

Examples:
  1.0.0          Stable release
  1.0.0a1        Alpha (pre-release)
  1.0.0b2        Beta
  1.0.0rc1       Release candidate
  1.0.0.post1    Post-release (e.g., packaging fix only)
  1.0.0.dev1     Development snapshot (not for PyPI)

Semantic Versioning (recommended)

语义化版本(推荐使用)

MAJOR.MINOR.PATCH

MAJOR: Breaking API change (remove/rename public function/class/arg)
MINOR: New feature, fully backward-compatible
PATCH: Bug fix, no API change
MAJOR.MINOR.PATCH

MAJOR: 破坏性API变更(删除/重命名公共函数/类/参数)
MINOR: 新增功能,完全向后兼容
PATCH: 修复bug,无API变更

Dynamic versioning with setuptools_scm (recommended for git-tag workflows)

基于setuptools_scm的动态版本管理(推荐git标签工作流使用)

bash
undefined
bash
undefined

How it works:

工作原理:

git tag v1.0.0 → installed version = 1.0.0 git tag v1.1.0 → installed version = 1.1.0 (commits after tag) → version = 1.1.0.post1 (suffix stripped for PyPI)
git tag v1.0.0 → installed version = 1.0.0 git tag v1.1.0 → installed version = 1.1.0 (commits after tag) → version = 1.1.0.post1 (suffix stripped for PyPI)

In code — NEVER hardcode when using setuptools_scm:

代码中使用——使用setuptools_scm时永远不要硬编码版本号:

from importlib.metadata import version, PackageNotFoundError try: version = version("your-package") except PackageNotFoundError: version = "0.0.0-dev" # Fallback for uninstalled dev checkouts

Required `pyproject.toml` config:
```toml
[tool.setuptools_scm]
version_scheme = "post-release"
local_scheme   = "no-local-version"   # Prevents +g<hash> from breaking PyPI uploads
Critical: always set
fetch-depth: 0
in every CI checkout step. Without full git history,
setuptools_scm
cannot find tags and the build version silently falls back to
0.0.0+dev
.
from importlib.metadata import version, PackageNotFoundError try: version = version("your-package") except PackageNotFoundError: version = "0.0.0-dev" # 未安装的开发环境下的兜底版本

所需`pyproject.toml`配置:
```toml
[tool.setuptools_scm]
version_scheme = "post-release"
local_scheme   = "no-local-version"   # 避免+g<hash>后缀导致PyPI上传失败
关键注意点: 所有CI的拉取代码步骤都要设置
fetch-depth: 0
,如果没有完整的git历史,
setuptools_scm
无法找到标签,构建版本会静默回退到
0.0.0+dev

Static versioning (flit, hatchling manual, poetry)

静态版本管理(flit、hatchling手动配置、poetry适用)

python
undefined
python
undefined

your_package/init.py

your_package/init.py

version = "1.0.0" # Update this before every release
undefined
version = "1.0.0" # 每次发布前更新这个值
undefined

Version specifier best practices for dependencies

依赖版本声明最佳实践

toml
undefined
toml
undefined

In [project] dependencies:

在[project]的dependencies中配置:

"httpx>=0.24" # Minimum version — PREFERRED for libraries "httpx>=0.24,<1.0" # Upper bound only when a known breaking change exists "httpx==0.27.0" # Pin exactly ONLY in applications, NOT libraries
"httpx>=0.24" # 指定最低版本——库项目优先选择这种方式 "httpx>=0.24,<1.0" # 仅当已知有破坏性变更时才加上限 "httpx==0.27.0" # 仅应用项目可以精确锁版本,库项目不要这么做

NEVER do this in a library — it breaks dependency resolution for users:

库项目永远不要这么写,会破坏用户的依赖解析:

"httpx~=0.24.0" # Too tight

"httpx~=0.24.0" # 限制太严格

"httpx==0.27.*" # Fragile

"httpx==0.27.*" # 易出问题

undefined
undefined

Version bump → release flow

版本升级→发布流程

bash
undefined
bash
undefined

1. Update CHANGELOG.md — move [Unreleased] entries to [x.y.z] - YYYY-MM-DD

1. 更新CHANGELOG.md —— 将[Unreleased]下的内容移动到[x.y.z] - YYYY-MM-DD下

2. Commit the changelog

2. 提交更新日志

git add CHANGELOG.md git commit -m "chore: prepare release vX.Y.Z"
git add CHANGELOG.md git commit -m "chore: prepare release vX.Y.Z"

3. Tag and push — this triggers publish.yml automatically

3. 打标签并推送——会自动触发publish.yml

git tag vX.Y.Z git push origin main --tags
git tag vX.Y.Z git push origin main --tags

4. Monitor GitHub Actions → verify on https://pypi.org/project/your-package/

4. 监控GitHub Actions运行状态 → 在https://pypi.org/project/your-package/验证发布结果


For complete pyproject.toml templates for all four backends, see `references/pyproject-toml.md`.

---

四种构建后端对应的完整`pyproject.toml`模板可参考`references/pyproject-toml.md`。

---

Where to Go Next

后续指引

After understanding decisions and structure:
  1. Set up
    pyproject.toml
    references/pyproject-toml.md
    All four backend templates (setuptools+scm, hatchling, flit, poetry), full tool configs,
    py.typed
    setup, versioning config.
  2. Write your library code
    references/library-patterns.md
    OOP/SOLID principles, type hints (PEP 484/526/544/561), core class design, factory functions,
    __init__.py
    , plugin/backend pattern, CLI entry point.
  3. Add tests and code quality
    references/testing-quality.md
    conftest.py
    , unit/backend/async tests, parametrize, ruff/mypy/pre-commit setup.
  4. Set up CI/CD and publish
    references/ci-publishing.md
    ci.yml
    ,
    publish.yml
    with Trusted Publishing (OIDC, no API tokens), CHANGELOG format, release checklist.
  5. Polish for community/OSS
    references/community-docs.md
    README sections, docstring format, CONTRIBUTING, SECURITY, issue templates, anti-patterns table, and master release checklist.
  6. Design backends, config, transport, CLI
    references/architecture-patterns.md
    Backend system (plugin/strategy pattern), Settings dataclass, HTTP transport layer, CLI with click/typer, backend injection rules.
  7. Choose and implement a versioning strategy
    references/versioning-strategy.md
    PEP 440 canonical forms, SemVer rules, pre-release identifiers, setuptools_scm deep-dive, flit static versioning, decision engine (DEFAULT/BEGINNER/MINIMAL).
  8. Govern releases and secure the publish pipeline
    references/release-governance.md
    Branch strategy, branch protection rules, OIDC Trusted Publishing setup, tag author validation in CI, tag format enforcement, full governed
    publish.yml
    .
  9. Simplify tooling with Ruff
    references/tooling-ruff.md
    Ruff-only setup replacing black/isort/flake8, mypy config, pre-commit hooks, asyncio_mode=auto (remove @pytest.mark.asyncio), migration guide.
理解决策规则和结构后,可以按以下步骤继续:
  1. 配置
    pyproject.toml
    → 参考
    references/pyproject-toml.md
    包含四种构建后端模板(setuptools+scm、hatchling、flit、poetry)、完整工具链配置、
    py.typed
    设置、版本管理配置。
  2. 编写库代码 → 参考
    references/library-patterns.md
    OOP/SOLID原则、类型提示(PEP 484/526/544/561)、核心类设计、工厂函数、
    __init__.py
    编写、插件/后端模式、CLI入口点实现。
  3. 添加测试和代码质量配置 → 参考
    references/testing-quality.md
    conftest.py
    配置、单元/后端/异步测试、参数化测试、ruff/mypy/pre-commit配置。
  4. 配置CI/CD和发布流程 → 参考
    references/ci-publishing.md
    ci.yml
    、基于可信发布(OIDC,无需API令牌)的
    publish.yml
    配置、CHANGELOG格式、发布检查清单。
  5. 完善社区/开源相关内容 → 参考
    references/community-docs.md
    README结构、文档字符串规范、贡献指南、安全说明、issue模板、反模式表、总发布检查清单。
  6. 设计后端、配置、传输层、CLI → 参考
    references/architecture-patterns.md
    后端系统(插件/策略模式)、配置数据类、HTTP传输层、基于click/typer的CLI、后端注入规则。
  7. 选择并实现版本管理策略 → 参考
    references/versioning-strategy.md
    PEP 440标准格式、语义化版本规则、预发布标识、setuptools_scm深入讲解、flit静态版本管理、决策引擎(默认/新手/极简模式)。
  8. 管控发布流程、保障发布链路安全 → 参考
    references/release-governance.md
    分支策略、分支保护规则、OIDC可信发布配置、CI中标签作者校验、标签格式校验、全管控
    publish.yml
  9. 使用Ruff简化工具链 → 参考
    references/tooling-ruff.md
    仅用Ruff的配置方案(替代black/isort/flake8)、mypy配置、pre-commit钩子、asyncio_mode=auto配置(无需再写@pytest.mark.asyncio)、迁移指南。