对于基于平台的 Python 应用程序,是否有一种方法可以获得一个条件需求.txt 文件?

我有一个 Python 应用程序,我写的兼容 Linux 和 Windows 平台。但是有一个问题... 我需要的一个 Python 软件包与 Linux 不兼容。幸运的是,还有另一个软件包在 Linux 上提供了相同的功能。所有其他依赖项在这两个平台中都是兼容的。

我知道我可以有两个单独的需求文件来分别处理这两个平台的依赖关系。比如 win _ requments.txt 和 linux _ requments.txt,但是这种方法似乎不是最好的方法。

我想知道是否有一种方法我只能有一个 Requments.txt 文件,这样任何用户都可以使用 pip install -r requirements.txt来安装所有的依赖项,而不管它们是什么平台?

比如说? ? :

SOAPpy>=0.12.22
pycrypto>=2.6.1
suds>=0.4
Python-ldap>=2.4.19
paramiko>=1.15.2
nose>=1.3.4
selenium>=2.44.0
bottle>=0.12.8
CherryPy>=3.6.0
pika>=0.9.14
if platform.system() == 'Linux':
wmi-client-wrapper>=0.0.12
else if platform.system() == 'Windows':
WMI>=1.4.9
40567 次浏览

You could create an install.py script and call pip by script.

import pip


_all_ = [
"SOAPpy>=0.12.22",
"pycrypto>=2.6.1",
"suds>=0.4",
"Python-ldap>=2.4.19",
"paramiko>=1.15.2",
"nose>=1.3.4",
"selenium>=2.44.0",
"bottle>=0.12.8",
"CherryPy>=3.6.0",
"pika>=0.9.14",
]


windows = ["wmi-client-wrapper>=0.0.12",]


linux = ["WMI>=1.4.9",]


darwin = []


def install(packages):
for package in packages:
pip.main(['install', package])


if __name__ == '__main__':


from sys import platform


install(_all_)
if platform == 'windows':
install(windows)
if platform.startswith('linux'):
install(linux)
if platform == 'darwin': # MacOS
install(darwin)

Another way to resolve this issue using only requirements files should be using inheritance of requirements

requirements.txt

SOAPpy>=0.12.22
pycrypto>=2.6.1
suds>=0.4
Python-ldap>=2.4.19
paramiko>=1.15.2
nose>=1.3.4
selenium>=2.44.0
bottle>=0.12.8
CherryPy>=3.6.0

windows.txt

-r requirements.txt
WMI>=1.4.9

linux.txt

-r requirements.txt
WMI>=1.4.9

Then you can call just the requirement equivalent to platform.

pip install -r windows.txt
pip install -r linux.txt

You can add certain conditional requirements after a semi-colon. Particularly useful for sys_platform and python_version.

Examples:

atomac==1.1.0; sys_platform == 'darwin'
futures>=3.0.5; python_version < '3.0'
futures>=3.0.5; python_version == '2.6' or python_version=='2.7'

Apparently you can also exclude particular versions of a library:

futures>=3.0,!=3.0.5

They are defined in PEP 508 and PEP 0345 (Environment Markers) but the syntax appears to follow the draft PEP 0496.

You can add additional requirements to any package after a semicolon. You may limit any package with multi-condition by and, or. more conditions: https://www.python.org/dev/peps/pep-0508/#environment-markers

examples:

futures>=3.0.5; python_version < '3.0'
futures>=3.0.5; python_version == '2.6' or python_version=='2.7'
futures>3 ; python_version >= "3.6" and sys_platform == "linux"
futures>3.3 ; python_version >= "3.6" and sys_platform == "darwin"

Use this in the requirements.txt file

uwsgi==2.0.18; platform_system != "Windows"

in this case pip will install uwsgi if not running on Windows

A Complimentary questions though, What if none of the default markers is suitable for our usecase. For example, if I want to install a package when it is run in CI vs when it runs on my machine , Can I set an environment variable and decideds based on its value ?