Python package guidelines (简体中文)
32-bit – CLR – CMake – Cross – DKMS – Eclipse – Electron – Font – Free Pascal – GNOME – Go – Haskell – Java – KDE – Kernel – Lisp – Meson – MinGW – Node.js – Nonfree – OCaml – Perl – PHP – Python – R – Ruby – Rust – VCS – Web – Wine
本文档描述了如何基于标准 PKGBUILDs 来为 Python 程序进行打包.
包命名
Python 3 的包应该使用 python-modulename
进行命名。如果软件包与 Python 某个生态系统(例如 pip 或 tox) 关系密切,请添加相应前缀。对于其他 Python 程序来说, 使用程序名就足够了。无论如何, 包的名字应该完全使用小写。
这同样适用于 Python 2,只需要修改前缀为 python2-
(如果必须)。
带版本的软件包
如果你需要添加一个带版本的软件包,请使用这种格式: python-模块名-版本
, 比如 python-colorama-0.2.5
。这样,Python 的依赖colorama==0.2.5
就会成为名为 python-colorama-0.2.5
的 Arch 软件包。
安装方式
Python 的包通常使用 Python 语言自带的工具来安装, 例如 pip 或者 easy_install[失效链接 2021-05-17 ⓘ], 这些工具就像是能从在线源 (通常是 PyPI, Python 包索引 (Python Package Index) ) 获取源文件的软件包管理器一样,而且还能跟踪相关的文件状态。 (如需这两个工具的详细比较,请参见 pip vs easy_install).
然而,如果要想使用 PKGBUILD 文件来帮助安装 Python 软件包的话,标准化的 distutils 可以说是最方便的了。它会使用已下载源码包里面的 setup.py
接着就能很轻松地将文件安装到 $pkgdir/usr/lib/python<python 版本>/site-packages/$pkgname
这个文件夹下面了。
distutils
这里有一个 distutils PKGBUILD 样本。他遵从下面的格式:
<python 版本> setup.py install --root="$pkgdir/" --optimize=1
其中:
- 根据程序所使用的 Python 版本来使用
python
或者python2
替换 <python 版本> 。 -
--root="$pkgdir/"
选项是为了防止文件直接安装到主系统而不是打包目录中。如果直接安装到主系统中,会产生权限错误。 -
--optimize=1
选项是用来编译生成.pyo
文件,好让 pacman 更好的跟踪优化她们。
setuptools
Python 包装机制已从 distutils 向 setuptools 迁移, 后者目前正处于活跃开发时期并且能直接在 setup.py
文件中替换前者。不过主要的区别在于,setuptools 并没有和 Python 主包打在一起,因此你必须将其指定为 makedepends
。
如果成品包中存在导入 (import) 了 pkg_resources
模块 的二进制, 那么 setuptools 必须在分包函数 package_*()
中另外指定为 depends
; 还有, 如果 PKGBUILD 只安装一个版本的 Python 包的话, setuptools 需要从 makedepends
移至 depends
。
pip
如果你需要使用 pip (由 python-pip 和 python2-pip[损坏的链接:package not found] 提供), 例如 为了安装 wheel[失效链接 2021-05-17 ⓘ] 的Python包, 请记得传入下列参数:
PIP_CONFIG_FILE=/dev/null pip install --isolated --root="$pkgdir" --ignore-installed --no-deps *.whl
-
PIP_CONFIG_FILE=/dev/null
此参数会使 pip 忽略{/etc,~/.config}/pip.conf
因为这个配置文件可能会向 pip 添加一些额外参数。 -
--isolated
此参数会使 pip 忽略环境变量 (以及{/etc,~/.config}/pip/pip.conf
) 否则 pip 又会被添加一些额外参数。 -
--ignore-installed
在 https://github.com/pypa/pip/issues/3063 处提出的问题解决之前,把这个参数加上吧 (不然的话 pip 会在有早期--user
安装痕迹的情况下跳过安装). -
--no-deps
此参数能确保依赖不会跟着一起被打进主包里面去。
pip 不知道如何生成 .pyo
文件 (see https://github.com/pypa/pip/issues/2209). 为了生成 .pyo
文件,在使用 pip 安装后, 运行:
python -O -m compileall "${pkgdir}/path/to/module
注意事项
绝大部分情况下, 你应该设置 arch
为 any
,因为绝大部分 Python 包是平台无关的。
请不要将文件安装到类似于 tests
这样名字的目录中, 因为这很容易与其他 Python 包发生文件冲突 (比方说, /usr/lib/python2.7/site-packages/tests/
).
PyPI 下载 URLs
PyPI 中像是这种格式 https://pypi.python.org/packages/source/${_name:0:1}/${_name}/${_name}-${pkgver}.tar.gz
<footnote> 的 URL 已经在 2016 年静默失效了, 而新的格式需要一种只有从 PyPI 网站才能取得的不可预测的哈希码[1][失效链接 2021-05-17 ⓘ]。
在下游维护者向 PyPI 维护者抱怨了这个问题 [2][失效链接 2021-05-17 ⓘ] 之后, 一种新的稳定的格式出现了 [3][失效链接 2021-05-17 ⓘ]: PKGBUILD#source source=()
数值现在需要使用如下 URL 模板:
请注意,我们使用了自定义的 $_name
而不是 $pkgname
,因为 Python 包通常都命名成这样: python-$_name
。
- 源码包
https://files.pythonhosted.org/packages/source/${_name::1}/${_name}/${_name}-${pkgver}.tar.gz
- 双版本 wheel 包 (Python 2 和 Python 3 都兼容)
https://files.pythonhosted.org/packages/py2.py3/${_name::1}/$_name/$_name-$pkgver-$_name-$pkgver-py2.py3-none-any.whl
- 特定架构的 wheel 包
- 对于特定架构的 wheel 包,可以使用
source_x86_64=('...')
来表示 x86_64 架构的下载地址。与此同时可以使用_py=py36
来避免重复书写 Python 版本: https://files.pythonhosted.org/packages/$_py/${_name::1}/$_name/$_name-$pkgver-$_py-${_py}m-manylinux1_x86_64.whl