有没有办法告诉setuptools或distribute在特定平台上需要一个包?
在我的情况下,我正在使用readline
,它作为Unix系统标准库的一部分提供,但在Windows上,我需要pyreadline
模块来替换该功能(参见这个问题)。如果我只是将其放入要求中,它也会安装在完全无用的Unix系统上。
有没有办法告诉setuptools或distribute在特定平台上需要一个包?
在我的情况下,我正在使用readline
,它作为Unix系统标准库的一部分提供,但在Windows上,我需要pyreadline
模块来替换该功能(参见这个问题)。如果我只是将其放入要求中,它也会安装在完全无用的Unix系统上。
尽管Martijn Pieters在当时给出的答案是完全有效的,但自那时以来Python打包方式已经发生了很多变化。
分发软件包的首选格式是使用wheel*。使用wheel无法在安装过程中运行Python代码。
Wheel使用在PEP 0427中规定的元数据版本二。环境标记可用于指定特定平台的依赖项。
Setuptools允许将这些环境标记指定为extras_require
键。以下示例脚本依赖于Windows系统上的pyreadline
和Linux发行版上的pyxdg
。
#!/usr/bin/env python
from setuptools import setup
setup(
name='spam',
version='0.0.1',
extras_require={
':sys_platform == "win32"': [
'pyreadline'
],
':"linux" in sys_platform': [
'pyxdg'
]
})
同时也要发布sdist,这样那些无法使用wheel的平台仍然可以安装你的软件包。
setup_requires
中放置环境标记。setup_requires = [
'foo',
'bar',
'pyreadline; sys_platform == "win32"',
]
setup(
# ...
setup_requires=setup_requires,
)
setuptools
20.6.8发布以来的支持,即2016年5月(支持在version 20.5中引入,但在其中间版本中曾短暂禁用)。easy_install
安装这些要求,这很难配置,因为使用pip
安装项目时需要进行配置。pyproject.toml
文件。 使用具有构建时依赖项的PEP 518构建系统意味着创建一个类似于此的pyproject.toml
文件:[build-system]
requires = [
"setuptools",
"wheel",
"foo",
"bar",
"pyreadline; sys_platform == "win32",
]
setup_requires
相同的列表,但添加了setuptools
和wheel
。此语法由pip
支持,截至版本10.0.0,于2018年3月发布。setup.py
只是一个Python脚本。您可以在该脚本中创建动态依赖项:
import sys
setup_requires = ['foo', 'bar']
if sys.platform() == 'win32':
setup_requires.append('pyreadline')
setup(
# ...
setup_requires=setup_requires,
)
其他答案也是正确的,如果需要支持旧版 setuptools
,那么这些答案可能更方便,但是有一些进展:
最近版本的 setuptools 接受 PEP 508 样式的依赖项规范:
setup(
# ...
install_requires=[
'pyreadline; platform_system == "Windows"',
],
)
选择正确的参数:
install_requires
: 当前分发需要哪些其他分发才能正常工作extras_require
: 将可选功能的名称映射到其要求列表的字典setup_requires
: 其他必须存在的分发,以便设置脚本可以正确运行
注意:列在setup_requires
中的项目不会自动安装。如果它们还没有本地可用,则它们将仅下载到./.eggs目录中。还有一种通过setup.cfg
文件提供这些参数的替代方法。请参阅文档以获取更多信息。
PEP 518引入了一种新的、更强大的方式,可以在pyproject.toml
文件中指定setup_requires
:
[build-system]
# Minimum requirements for the build system to execute.
requires = ['setuptools>"38.3.0"', 'wheel'] # PEP 508 specifications.
from setuptools import setup
setup(
install_requires=(['pymsgbox', 'PyTweening>=1.0.1', 'Pillow', 'pyscreeze']
+ ["python3-xlib; sys_platform == linux"]
+ ["python-xlib; sys_platform == linux2"]
+ ["pyobjc-core; sys_platform == darwin"]
+ ["pyobjc; sys_platform == darwing"]
),
)
这将根据所使用的系统类型(linux2
适用于使用 python2
的 Linux 系统,linux
适用于使用 python3
的 Linux 系统,darwin
适用于 MacOS 系统),安装特定版本的库。
':sys_platform == "win32"'
,不如使用更易读和直观的方式'platform_system=="Windows"'
。而且,与':"linux" in sys_platform'
相比,你可以使用'platform_system=="Linux"'
来代替。这将包括linux
和linux2
。对于其他平台也是一样的,例如mac可以用'platform_system=="Darwin"'
等等。参考资料:PEP 508
,以及EasyBuilders。 - smac89install_requires
和extras_require
都有处理特定平台的依赖项的机制,想知道哪个更建议使用?例如,在Pipenv
中,仍存在一个问题需要支持在Pipfile
中使用extras_require
。 - Drake Guaninstall_requires
应该是需要与包一起存在,为包的生命周期和功能提供必要支持的包列表。这些包(install_requires
)是补充所需包并为请求的包提供必要功能的。extras_require
仅在用户请求额外功能时自行安装。setup_requires
是设置脚本继续运行所必需的包(如果您正在重载安装命令,则需要此关键字)。 - user6767685