[新教程] pip打包指南
背景
开发了一个项目,需要打成pip包。
重要概念
pyproject.toml 就是“告诉 Python:这个项目叫什么、依赖什么、怎么打包、打完后生成什么”的配置文件。
步骤
1、目录结构
myproj/
mypkg/
__init__.py2、准备project.toml
[project]
name = "mypkg"
version = "0.1.0"
description = "My package"
requires-python = ">=3.11"
dependencies = []
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["mypkg"]3、准备构建工具。
python3 -m venv .pkgbuild
./.pkgbuild/bin/python -m ensurepip --upgrade
./.pkgbuild/bin/python -m pip install -U pip build hatchling -i https://pypi.tuna.tsinghua.edu.cn/simple4、在项目根目录构建包
这里的“项目根目录”就是有 pyproject.toml 的目录
./.pkgbuild/bin/python -m build --no-isolation最简模板
- 纯库包模板
适合:别人 import mypkg,但没有命令行入口。
假设目录是:
myproj/
pyproject.toml
README.md
mypkg/
__init__.py模板:
[project]
name = "mypkg"
version = "0.1.0"
description = "My Python package"
readme = "README.md"
requires-python = ">=3.11"
license = { text = "MIT" }
authors = [
{ name = "your name" }
]
dependencies = []
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["mypkg"]- 带 CLI 的包模板
适合:安装后能直接运行命令,比如mytool。
假设目录是:
myproj/
pyproject.toml
README.md
mypkg/
__init__.py
cli.py如果 cli.py 里有一个可调用入口,例如:
def main():
print("hello")那模板可以写成:
[project]
name = "mypkg"
version = "0.1.0"
description = "My command line tool"
readme = "README.md"
requires-python = ">=3.11"
license = { text = "MIT" }
authors = [
{ name = "your name" }
]
dependencies = []
[project.scripts]
mypkg = "mypkg.cli:main"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["mypkg"]这里最关键的是这句:
[project.scripts]
mypkg = "mypkg.cli:main"意思是安装后可以直接运行 mypkg 命令,它会调用 mypkg/cli.py 里的 main()。
- 带资源文件的包模板
适合:除了 Python 代码,还要把脚本、配置、jar、模板等文件一起打进包里。这个最接近你现在的。
假设目录是:
myproj/
pyproject.toml
README.md
bridge/
package.json
softwares/
tool.jar
mypkg/
__init__.py
cli.py
resources/
config.json
skills/
demo/
SKILL.md
scripts/
run.sh
helper.py模板:
[project]
name = "mypkg"
version = "0.1.0"
description = "My package with bundled resources"
readme = "README.md"
requires-python = ">=3.11"
license = { text = "MIT" }
authors = [
{ name = "your name" }
]
dependencies = []
[project.scripts]
mypkg = "mypkg.cli:main"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["mypkg"]
[tool.hatch.build]
include = [
"mypkg/**/*.py",
"mypkg/**/*.md",
"mypkg/**/*.sh",
"mypkg/**/*.json",
]
[tool.hatch.build.targets.sdist]
include = [
"mypkg/",
"bridge/",
"README.md",
]
artifacts = [
"softwares/**",
]
[tool.hatch.build.targets.wheel.force-include]
"bridge" = "mypkg/bridge"
"softwares" = "mypkg/softwares"这里最值得你记住的是:
include:选进正常资源sdist.include:源码包里带什么artifacts:专门处理像 softwares/ 这种可能被 .gitignore 忽略、但仍然要打包的内容force-include:把包目录外的目录塞进最终 wheel
评论已关闭