kkpack 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kkpack-0.1.0/CHANGELOG.md +175 -0
- kkpack-0.1.0/LICENSE +21 -0
- kkpack-0.1.0/MANIFEST.in +19 -0
- kkpack-0.1.0/PKG-INFO +756 -0
- kkpack-0.1.0/README.md +724 -0
- kkpack-0.1.0/pyproject.toml +64 -0
- kkpack-0.1.0/setup.cfg +4 -0
- kkpack-0.1.0/src/kkpack/__init__.py +21 -0
- kkpack-0.1.0/src/kkpack/__main__.py +6 -0
- kkpack-0.1.0/src/kkpack/analyze.py +232 -0
- kkpack-0.1.0/src/kkpack/backends.py +396 -0
- kkpack-0.1.0/src/kkpack/bootgen.py +249 -0
- kkpack-0.1.0/src/kkpack/builder.py +655 -0
- kkpack-0.1.0/src/kkpack/cli.py +341 -0
- kkpack-0.1.0/src/kkpack/config.py +270 -0
- kkpack-0.1.0/src/kkpack/deps.py +694 -0
- kkpack-0.1.0/src/kkpack/peinfo.py +218 -0
- kkpack-0.1.0/src/kkpack/runtime.py +1360 -0
- kkpack-0.1.0/src/kkpack/signing.py +249 -0
- kkpack-0.1.0/src/kkpack.egg-info/PKG-INFO +756 -0
- kkpack-0.1.0/src/kkpack.egg-info/SOURCES.txt +36 -0
- kkpack-0.1.0/src/kkpack.egg-info/dependency_links.txt +1 -0
- kkpack-0.1.0/src/kkpack.egg-info/entry_points.txt +2 -0
- kkpack-0.1.0/src/kkpack.egg-info/requires.txt +7 -0
- kkpack-0.1.0/src/kkpack.egg-info/top_level.txt +1 -0
- kkpack-0.1.0/tests/__init__.py +6 -0
- kkpack-0.1.0/tests/_helpers.py +92 -0
- kkpack-0.1.0/tests/test_analyze.py +292 -0
- kkpack-0.1.0/tests/test_backends.py +473 -0
- kkpack-0.1.0/tests/test_bootgen.py +437 -0
- kkpack-0.1.0/tests/test_builder.py +417 -0
- kkpack-0.1.0/tests/test_cli.py +342 -0
- kkpack-0.1.0/tests/test_config.py +361 -0
- kkpack-0.1.0/tests/test_deps.py +728 -0
- kkpack-0.1.0/tests/test_packaging.py +237 -0
- kkpack-0.1.0/tests/test_peinfo.py +288 -0
- kkpack-0.1.0/tests/test_runtime.py +1319 -0
- kkpack-0.1.0/tests/test_signing.py +415 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# 更新日志
|
|
2
|
+
|
|
3
|
+
本文件记录每个版本的 **对外可见** 变化。格式参考
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),
|
|
5
|
+
版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
|
6
|
+
|
|
7
|
+
## [0.1.0] - 2026-09-23
|
|
8
|
+
|
|
9
|
+
首个公开发布,范围明确收敛为 **Windows 上的 exe 打包**。
|
|
10
|
+
首次发布之前的全部改动都并入本版(此前没有对外发过任何版本)。
|
|
11
|
+
项目改名:`kkbuild` 这个名字在 PyPI 上已被另一个无关项目占用(2023 年后未再更新),
|
|
12
|
+
故自本版起改名 `kkpack` —— 发行名、导入包名、命令名、工作目录全部统一。
|
|
13
|
+
|
|
14
|
+
### 新增
|
|
15
|
+
- 一条命令打包:`kkpack main.py`,无配置文件也能跑。
|
|
16
|
+
- 两种后端:Nuitka(编译成 C,启动快)与 PyInstaller(不需要 C 编译器)。
|
|
17
|
+
- 三种依赖分发模式:
|
|
18
|
+
- `runtime` —— 首次运行从镜像源安装到 exe 同级的 `_deps`
|
|
19
|
+
- `offline` —— wheel 随包分发,目标机完全离线也能装
|
|
20
|
+
- `all` —— 构建期全部编译进 exe
|
|
21
|
+
- **目标机不需要 Python,也不需要 pip。**
|
|
22
|
+
- 配置项 `[tool] exe_name`(产物名,不用写 `.exe`)与 `[tool] icon`(`.ico` 图标)。
|
|
23
|
+
产物名与模块名解耦:入口文件固定用安全 ASCII 模块名,编译完成后再改名,
|
|
24
|
+
所以 `My-App`、`我的工具` 这类名字都能用。
|
|
25
|
+
- 子命令:`kkpack init`(生成带注释的配置样板)、`kkpack doctor`(体检打包环境)。
|
|
26
|
+
- 标准库补全策略 `--stdlib`:`full`(默认,含 tkinter)/`precise`(只补真正用到的)/`none`。
|
|
27
|
+
- 内建进度窗口:GUI 模式(`--windowed`)下没有控制台,安装进度靠它显示。
|
|
28
|
+
- 多语言进度文案:`[progress]` 段可整段替换。
|
|
29
|
+
|
|
30
|
+
- **`runtime` 模式构建期不再下载 wheel**(依赖树解析改成只取元数据)。这一步原本
|
|
31
|
+
整个交给 `pip download` —— "下载"是它唯一能展开间接依赖的方式,于是为了拿到依赖
|
|
32
|
+
清单,几百 MB 的 wheel 被顺带落到 `.kkpack/wheels/`。现在改用
|
|
33
|
+
`pip install --dry-run --report`:只取每个包 KB 级的 `.metadata`(PEP 658),
|
|
34
|
+
直链与 sha256 由 pip 的 report 给出,再按文件名从配置的镜像页补一份镜像直链。
|
|
35
|
+
实测一个真实 PySide6 工程(PySide6 + pyqtgraph + pyserial + pika + pygame,
|
|
36
|
+
展开后 9 个包)**15.9 秒解析完、0 个 wheel 落盘**。
|
|
37
|
+
两个前提 kkpack 自己兜住:pip ≥ 22.2、源支持 PEP 658 元数据(阿里云、清华目前
|
|
38
|
+
都还没支持)。注意 `[bundle] include` 里要求编译进 exe 的包仍然必须下载 ——
|
|
39
|
+
它们要解压出来编译进 exe,这部分任何模式都省不掉;`include_mode = "precise"`
|
|
40
|
+
同理(要扫 wheel 里的 import 才知道该补哪些标准库模块),构建日志会写明原因。
|
|
41
|
+
- 配置项 `[index] upgrade_pip`(默认 `true`):构建环境的 pip 低于 22.2 时,另装一份
|
|
42
|
+
够新的到 `.kkpack/pipenv` 供解析使用。配置项 `[index] pypi_fallback`(默认 `true`):
|
|
43
|
+
元数据与直链解析用官方 PyPI 兜底(**下载依赖仍优先走配置的镜像**),生成的清单
|
|
44
|
+
`INDEXES` 也会带上它 —— 万一镜像上没有该版本,目标机还有一条退路。
|
|
45
|
+
两个开关都能关掉,关掉后 pip 太老 / 源不支持时退回"把 wheel 下载到本地"。
|
|
46
|
+
- **requirements.txt 可以不锁版本,构建期会给出推荐锁定行**。三种写法都收,行为
|
|
47
|
+
差别只在解析时可选的版本集合:`pyserial`(没写版本 → 取当时的最新版)、
|
|
48
|
+
`pyserial>=3.4`(范围 → 取满足约束的最新版)、`pyserial==3.5`(锁定 → 就用这一版)。
|
|
49
|
+
三者最终都会被解析成一个 **具体版本** 并冻结进产物(`dist/*.dist/requirements.txt`
|
|
50
|
+
与运行期清单 `REQUIREMENTS` 里都是 `name==version`),所以目标机装到的依赖始终
|
|
51
|
+
一致 —— 差别只在 **下一次构建会不会拿到另一个版本**。构建期因此逐条报告解析结果,
|
|
52
|
+
并直接给出可粘贴的锁定行:
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
没写版本,按最新解析:pyserial==3.5
|
|
56
|
+
推荐锁定(写回 requirements.txt 即可让每次构建结果一致):pyserial==3.5 pika==1.3.2
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
把那串锁定行写回 `requirements.txt`,同一份代码每次构建的依赖就完全一致。
|
|
60
|
+
新增 `deps.read_requirement_specs()`(保留原始操作符与约束)与
|
|
61
|
+
`deps.lock_advice()`(把写法与实际解析结果对照分类)。
|
|
62
|
+
- **首次运行的下载进度窗口也会用 `[tool] icon` 设置的图标**。tkinter 的
|
|
63
|
+
`wm iconbitmap` 只接受一个 `.ico` **文件路径** —— exe 的图标在 PE 资源段里,
|
|
64
|
+
tkinter 拿不到,所以构建时会把图标 **再复制一份到 exe 同级**,文件名写进清单的
|
|
65
|
+
`ICON`,运行期据此设置窗口图标(原先只能顶着 Tk 默认的羽毛图标)。
|
|
66
|
+
为什么复制而不是用 `--add-data` 打进 exe:`runtime._candidates()` 会主动排除
|
|
67
|
+
onefile 的临时解压目录(`_MEIxxxx` / `onefile_*`),打进 exe 反而找不到;
|
|
68
|
+
exe 同级是目录 / 单文件三种产物形态都成立的位置。图标缺失或损坏一律静默降级
|
|
69
|
+
(`runtime.apply_icon` 吞掉全部异常)—— 外观问题绝不该影响依赖安装。
|
|
70
|
+
- **依赖安装窗口可以取消了(关窗 = 取消,直接停进程)**。以前 `WM_DELETE_WINDOW` 是被
|
|
71
|
+
显式忽略的(本意是"别让依赖停在半装状态"),实际结果是下大 wheel 时窗口关不掉、
|
|
72
|
+
进程也停不下来,只能去任务管理器杀。现在窗口右下角有 **取消** 按钮,点它和点右上角
|
|
73
|
+
的 **X** 是同一个动作:工作线程看到取消后立刻停(下载线程、每个源的轮询、解压循环
|
|
74
|
+
逐处检查),主线程最多再等 1 秒就 `os._exit(130)` 结束进程。
|
|
75
|
+
之所以不指望 `sys.exit`:取消那一刻下载线程多半正卡在 socket 的 `recv` 上,
|
|
76
|
+
而 `concurrent.futures` 注册了 atexit,解释器正常退出时会去 join 这些线程 ——
|
|
77
|
+
实测能一直拖到下载超时(几十秒),那就不叫"关闭"了。
|
|
78
|
+
中断不留坏状态:`_installed.json` 只记录 **整包解压完** 的条目,半途中断的包下次启动
|
|
79
|
+
重新解压(解压可重复);已装好的包继续有效。没有窗口时(`progress = false` /
|
|
80
|
+
`KK_PROGRESS=0`)按 **Ctrl-C** 走同一条退出路径,退出码同样是 130。
|
|
81
|
+
文案可改:`[progress] cancel` / `cancelling` / `cancelled`。
|
|
82
|
+
- **`[version]` / `[sign]`:PE 版本信息资源 + 构建末尾自动签名**(对付杀软误报的两件
|
|
83
|
+
治本手段)。`[version]` 把公司名 / 产品名 / 描述 / 版本 / 版权写进 exe 的 PE
|
|
84
|
+
`VS_VERSION_INFO` 资源 —— 这是 Windows 和安全软件唯一能机器读取的"这东西谁做的"。
|
|
85
|
+
Nuitka 走 `--windows-company-name` 等参数,PyInstaller 走 `--version-file`
|
|
86
|
+
(kkpack 生成该文件,纯 ASCII,中文按 `\uXXXX` 转义)。版本号超过 4 段、含非数字、
|
|
87
|
+
单段 > 65535 都在构建开始就明确报错并给出改法 —— 这三种情况下 Nuitka 自己的报错
|
|
88
|
+
完全看不出和版本号有关。`[sign]` 在 **装箱改名之后** 调用 `signtool`,证书支持
|
|
89
|
+
`.pfx` / `.p12`、40 位指纹、`CN=` 主题三种写法;默认带 RFC 3161 时间戳(不签时间戳
|
|
90
|
+
的话,证书一到期、之前签过的版本全部变成"签名不受信任");`signtool.exe` 找不到时
|
|
91
|
+
会去 Windows SDK 目录里找(按版本号 **数值** 排序,字符串排序会选错)。
|
|
92
|
+
配了证书但签名失败会让 **构建失败**,不会静默产出一个没签名的 exe。
|
|
93
|
+
|
|
94
|
+
### 修复
|
|
95
|
+
- **requirements.txt 的行尾注释会污染版本号**。`pyserial==3.5 # 串口` 这样的行,
|
|
96
|
+
解析出的版本号是 `'3.5 # 串口'` 这个脏字符串(注释没剥),会一路流进构建日志与
|
|
97
|
+
"推荐锁定"的提示里,看起来就像 kkpack 把版本号解析错了。现在与配置文件同一套
|
|
98
|
+
规则剥行尾注释(引号内的 `#` 保留 —— URL 片段里会出现)。
|
|
99
|
+
- **`>=` / `~=` 等范围约束的信息被整个丢掉**,一律被当成"没写版本、版本未知"。
|
|
100
|
+
构建日志因此无法区分"你没锁版本"与"你锁的是一个范围"这两件完全不同的事,
|
|
101
|
+
提示也就没法说清"这个范围本次解析到了哪一版"。现在约束原样保留
|
|
102
|
+
(`read_requirement_specs` 返回 `(name, operator, version)`),日志按三类分别报告。
|
|
103
|
+
- **不要就地升级构建环境的 pip**(`pip install --upgrade pip`)。Windows 上 pip
|
|
104
|
+
自升级要"先卸掉自己、再装新的",而正在运行的 pip 自己的文件正处于占用状态,
|
|
105
|
+
实测把环境的 pip 装成半个:`pip-26.0.1.dist-info` 更新了,
|
|
106
|
+
`pip/__main__.py`、`pip/_internal/__init__.py` 等却不在磁盘上,
|
|
107
|
+
`python -m pip` 直接报
|
|
108
|
+
`No module named pip.__main__; 'pip' is a package and cannot be directly executed`,
|
|
109
|
+
site-packages 里还留下一堆 `~ip-20.3.4.dist-info` 这样的删除残骸
|
|
110
|
+
(pip 对占用文件的"改名后延后删除"机制),后续 `pip` 安装都会附带
|
|
111
|
+
`WARNING: Ignoring invalid distribution`。
|
|
112
|
+
现在改成 `pip install --target .kkpack/pipenv "pip>=22.2"`(带 `--no-deps`,
|
|
113
|
+
不涉及卸载自己),解析时用 `PYTHONPATH` 把它顶到 `site-packages` 之前生效,
|
|
114
|
+
**构建环境一个文件都不动**。老 pip(本机实测 21.2.4)能正常装出 26.0.1,
|
|
115
|
+
端到端解析成功;环境自己的 pip 版本保持不变。
|
|
116
|
+
- **PySide6 项目打包必崩**。PySide6 官方 wheel 的 `top_level.txt` 里写的是路径而不是模块名
|
|
117
|
+
(PySide6-Addons 写 `PySide6/Qt3DCore`、PySide6 元包写 `PySide6/QtCore`),原样传给
|
|
118
|
+
Nuitka 会直接 `FATAL: Error, '--nofollow-import-to' takes only module names or patterns,
|
|
119
|
+
not directory path`。现在统一把斜杠规范成点号(`PySide6.Qt3DCore`),不是合法模块名的
|
|
120
|
+
条目丢弃、重复的合并。
|
|
121
|
+
- **产物缺 `python3.dll`,abi3 轮子在目标机加载失败**。PySide6 / shiboken6 这类
|
|
122
|
+
`cp39-abi3` 轮子的扩展链接的是 **`python3.dll`**(CPython 的稳定 ABI 转发层),而不是
|
|
123
|
+
`python39.dll`。它们被 `--nofollow-import-to` 排除在编译之外、改成运行时安装,后端
|
|
124
|
+
因此看不到这些 DLL 依赖,自然也不会把 `python3.dll` 收进产物 —— 目标机上更没有 Python
|
|
125
|
+
会提供它。实测症状(`kkpack` 打 PySide6 6.7.2 项目,Nuitka 2.3.2):
|
|
126
|
+
`ImportError: DLL load failed while importing Shiboken: 找不到指定的模块。`
|
|
127
|
+
读 PE 导入表可确认 `shiboken6/Shiboken.pyd` 与 `shiboken6.abi3.dll` 的导入表里都写着
|
|
128
|
+
`python3.dll`;把它补到 exe 同级后窗口立刻正常显示。
|
|
129
|
+
现在后端命令里统一带上它 —— Nuitka 用 `--include-data-files=<python3.dll>=python3.dll`,
|
|
130
|
+
PyInstaller 用 `--add-data=<python3.dll>;.`,单文件与目录形式都覆盖。
|
|
131
|
+
- **中文(非 ASCII)项目路径下 Nuitka 编译成功后却报错**。ccache 是原生程序,日志按
|
|
132
|
+
系统 ANSI 代码页写(中文 Windows 就是 GBK),而 Nuitka 2.3.2 用 UTF-8 读它
|
|
133
|
+
(`build/SconsCaching._getCcacheStatistics`),于是 **编译其实已经成功**、在收尾统计时崩:
|
|
134
|
+
`UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd7 in position 2071`。
|
|
135
|
+
实测 `D:\桌面文件夹\...` 必现(ccache 日志里原样写着该路径的 GBK 字节)。
|
|
136
|
+
现在构建路径含非 ASCII 时会自动加 `--disable-ccache` —— Nuitka 只在启用 ccache 时才
|
|
137
|
+
`setEnvironmentVariable("CCACHE_LOGFILE", ...)`,关掉后那段统计整块跳过;ASCII 路径不受影响
|
|
138
|
+
(ccache 继续用于加速重复编译)。
|
|
139
|
+
- **`--clean` 会把刚下载的 wheel 一起删掉**。清理动作发生在「下载依赖」之后,于是
|
|
140
|
+
`mode = "offline"` 打包到装箱阶段报 `FileNotFoundError`(`mode = "all"` 或配了
|
|
141
|
+
`include` 时更早,在解压待编译的包时崩),整轮编译白费。现在 `--clean` 只清自动
|
|
142
|
+
生成物,保留 `.kkpack/wheels/`(下载缓存)与 `.kkpack/venv/`(隔离构建环境)。
|
|
143
|
+
- **旧版 Nuitka(< 2.7)上整包构建崩溃:`--include-module` 里混进了 built-in / frozen
|
|
144
|
+
模块**。`stdlib_names()` 用 `sys.builtin_module_names` 起头,于是 `_abc` / `_winapi` /
|
|
145
|
+
`sys` / `time` / `zlib` 这类由解释器本体提供、压根没有可 include 文件的模块也被发成了
|
|
146
|
+
`--include-module=...`。Nuitka 2.3.2 解析 include 列表时对它们的 `module_filename`
|
|
147
|
+
取到 `None` 就崩(`Recursion.checkPluginSinglePath` → `os.path.abspath(None)` →
|
|
148
|
+
`TypeError: path should be string, bytes or os.PathLike, not NoneType`),2.7.13 起
|
|
149
|
+
才改成只警告 `module ... is built-in`。现在 `split_mods_pkgs()` 会先把这批摘掉
|
|
150
|
+
(full 模式 237 → 169 个模块,产物不变 —— 它们本来就编在解释器里),新旧 Nuitka 都能打包。
|
|
151
|
+
|
|
152
|
+
判定用的是与 Nuitka 同源的 `is_builtin_or_frozen()`:
|
|
153
|
+
`_imp.is_builtin(name) or _imp.is_frozen(name)`。**光看"Lib 里有没有 `<name>.py`"
|
|
154
|
+
是不够的** —— CPython 3.9 上 `zipimport` 是 frozen 模块,`Lib/zipimport.py` 确实在
|
|
155
|
+
磁盘上,但解释器用的是冻结版,Nuitka 同样判它是 built-in、同样会崩,所以 frozen
|
|
156
|
+
必须一起摘(3.9 上是 67 个 built-in + `zipimport` = 68 个,与 Nuitka 自己报的数字一致)。
|
|
157
|
+
- **单文件(`onefile = true`)的"产物体积"报成了整个 `output_dir/dist` 目录**,把编译
|
|
158
|
+
中间产物和上一轮的旧产物一起算了进去。实测用户工程(Nuitka + onefile,
|
|
159
|
+
`output_dir = "dist"`):exe 本体 **10.1 MB**,而同一个目录里还躺着
|
|
160
|
+
`Main.build` 44.7 MB、`Main.onefile-build` 10.2 MB、上一轮目录形式的
|
|
161
|
+
`Main.dist` 34.3 MB —— 于是"产物体积"报成 **99.4 MB**,看起来像单文件版打错了。
|
|
162
|
+
现在 `builder.artifact_size()` 按形态区分:**单文件只算那一个 exe**,目录形式才算
|
|
163
|
+
整个产物目录;单文件模式下另外提示 `*.build` / `*.onefile-build` 可以直接删除。
|
|
164
|
+
|
|
165
|
+
### 设计约束
|
|
166
|
+
- **零第三方依赖**。kkpack 的运行期组件要能被干净地编译进用户的 exe,
|
|
167
|
+
自己再带依赖会把这套方案搞脏;作为工具安装它也不该拖累别人。
|
|
168
|
+
- 只面向 Windows。其它平台不做承诺,也不做兜底。
|
|
169
|
+
|
|
170
|
+
### 已验证
|
|
171
|
+
真机跑过 8 组构建组合(`verify/run_matrix.py`):Nuitka/PyInstaller × 单文件/目录、
|
|
172
|
+
断网索引、中文路径、无控制台(PE 子系统为 GUI)、失败路径、进度窗口。
|
|
173
|
+
产物分别为 41.8 MB(Nuitka 目录形式)与 61.9 MB(Nuitka 单文件)。
|
|
174
|
+
进度窗口的取消流程另有两次端到端实测:真 Tk 窗口点按钮(1.45 s 退出)、
|
|
175
|
+
真实 exe 发 `WM_CLOSE`(2.54 s 退出),退出码均为 130。
|
kkpack-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Python卡皮巴拉
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
kkpack-0.1.0/MANIFEST.in
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# sdist(源码包)里放什么。
|
|
2
|
+
# wheel 的内容由 pyproject.toml 的 [tool.setuptools] 决定,与本文件无关。
|
|
3
|
+
# 只写"额外要什么"和"明确不要什么":__pycache__ / *.pyc / *.egg-info
|
|
4
|
+
# 由 setuptools 自己排除,重复写只会让构建日志刷一堆
|
|
5
|
+
# "no previously-included files matching ..." 的噪音。
|
|
6
|
+
|
|
7
|
+
include LICENSE
|
|
8
|
+
include CHANGELOG.md
|
|
9
|
+
include README.md
|
|
10
|
+
include pyproject.toml
|
|
11
|
+
|
|
12
|
+
# 单测随源码包一起发:下载 sdist 的人能自己验一遍
|
|
13
|
+
recursive-include tests *.py
|
|
14
|
+
|
|
15
|
+
# 真机验证用的构建矩阵属于开发工具:
|
|
16
|
+
# * 里面有中文目录名(sdist 的编码风险)和本机绝对路径
|
|
17
|
+
# * 完整跑一轮要 1 小时以上,且需要 Nuitka/PyInstaller/C 编译器
|
|
18
|
+
# 所以不进发行包;想复现请直接看仓库里的这个目录。
|
|
19
|
+
prune verify
|