如何在 Pipfile 中指定特定于平台的附加功能或版本?

leo*_*loy 5 python pip pipenv pipenv-install

文档“的Pipenv高级用法”,在“指定基本上什么”一节中,介绍了如何包括包装的要求,有条件的操作系统平台,在Pipfile,如:

pywinusb = {version = "*", sys_platform = "== 'win32'"}
Run Code Online (Sandbox Code Playgroud)

根据平台的不同,当想要为包指定不同的版本或选项时,不清楚该怎么做。

具体来说,我有这个要求:

faust = {version=">=1.10.1", extras=["aiodns", "ciso8601", "cython"]}
Run Code Online (Sandbox Code Playgroud)

我想排除ciso8601Windows 中的可选附加项。

如果我写

faust = {version=">=1.10.1", extras=["aiodns", "ciso8601", "cython"], platform_system = "!= 'Windows'"}
faust = {version=">=1.10.1", extras=["aiodns", "cython"], platform_system = "== 'Windows'"}
Run Code Online (Sandbox Code Playgroud)

我收到错误: tomlkit.exceptions.KeyAlreadyPresent: Key "faust " already exists.

另外,我想在setup.py(install_requires部分) 中做同样的事情。

Lif*_*lex 6

工作答案 - 06-30-2021 @15:43 UTC

我检讨浮士德库很多次,发现aiodns用Cythonciso8601不依赖本身,而是束,其安装与PIP根据自述是这样的:

pip install "faust[aiodns, ciso8601, cython]"
Run Code Online (Sandbox Code Playgroud)

我根据您的要求创建了一个 setup.py。我能够安装浮士德与束aiodnsciso8601用Cython非Windows系统上。我没有 Windows 系统来测试该安装,但我确实翻转了系统平台参数,这很有效。

import setuptools

setuptools.setup(

    name="faust_pip_test", # change for your package
    version="1.0.0", # change for your package
    python_requires='>=3.6',
    install_requires=["faust[aiodns, ciso8601,cython]>=1.10.1;sys_platform != 'win32'",
                  "faust[aiodns, cython]>=1.10.1;sys_platform == 'win32'",]

)
Run Code Online (Sandbox Code Playgroud)

这里是faust_pip_test安装与包浮士德和附加软件包aiodnsciso8601用Cython我的MacBook。

在此处输入图片说明

在查看了 PipeEnv 文档后,这并不直观,您似乎可以在 pipfile 中执行以下操作。我查看的每个参考资料都要求您为辅助键指定一个文件路径,在这个原因中是faust_win。在faust_win中调用的文件来自faust PyPi 下载

[packages]
faust = {version = ">=1.10.1",extras = ["aiodns", "ciso8601", "cython"],sys_platform = "!='windows'"}
faust_win = {file = 'https://files.pythonhosted.org/packages/79/f8/3fec4f5c3e5bf1ce8bb557ae507525253fa30a5cfc5984f342b931143f75/faust-1.10.4-py2.py3-none-any.whl',version = ">=1.10.1",extras = ["aiodns", "cython"],sys_platform = "=='windows'"}

Run Code Online (Sandbox Code Playgroud)

我在我的开发环境中使用 PyCharm。如果我__init__.py在我的项目faust_pipenv_test 中创建一个,它会自动触发我的项目的依赖项安装。安装了Faust 标准依赖项要求以及附加包aiodnsciso8601cython。

在此处输入图片说明

我还收到一条消息,说未安装faust_win要求,因为它不符合此要求sys_platform =='win32'

在此处输入图片说明

更新 06-28-2021 @12:23 UTC

当我看着的源代码浮士德我注意到包 aiodns用Cythonciso8601都在依赖浮士德的 setup.py文件。

所以,根据你的问题看来你不想安装 浮士德的默认依赖ciso8601非Windows系统上。根据附加列表,您似乎还试图限制其他依赖项。

这是你想要完成的吗?

Python的开发者指南指出,“额外”参数是用来安装额外的依赖,这是除了经常依赖Python的安装包。

参考:PEP 426 -- Python 软件包 2.0 的元数据

下面的代码来自 PipeEnv Python 包,它显示“extras”参数与包的核心依赖项相结合。

def dependencies(self):
        # type: () -> Tuple[Dict[S, PackagingRequirement], List[Union[S, PackagingRequirement]], List[S]]
        build_deps = []  # type: List[Union[S, PackagingRequirement]]
        setup_deps = []  # type: List[S]
        deps = {}  # type: Dict[S, PackagingRequirement]
        if self.setup_info:
            setup_info = self.setup_info.as_dict()
            deps.update(setup_info.get("requires", {}))
            setup_deps.extend(setup_info.get("setup_requires", []))
            build_deps.extend(setup_info.get("build_requires", []))
            if self.extras and self.setup_info.extras:
                for dep in self.extras:
                    if dep not in self.setup_info.extras:
                        continue
                    extras_list = self.setup_info.extras.get(dep, [])  # type: ignore
                    for req_instance in extras_list:  # type: ignore
                        deps[req_instance.key] = req_instance
        if self.pyproject_requires:
            build_deps.extend(list(self.pyproject_requires))
        setup_deps = list(set(setup_deps))
        build_deps = list(set(build_deps))
        return deps, setup_deps, build_deps
Run Code Online (Sandbox Code Playgroud)

所以下面的例子需要测试,因为在Pipenv高级用法文档中并没有明确是否可以覆盖第三方 Python 包的依赖项要求。

[packages]
faust = {version= ">=1.10.1", extras=["aiodns", "cython"]}
ciso8601 = {version = ">=2.1.0", sys_platform = "!= 'Windows'", index="pypi"}

or 

[packages]
faust = {version=">=1.10.1", extras=["aiodns", "ciso8601", "cython"], sys_platform= "!= 'Windows'"}
"faust_win" = {version=">=1.10.1", extras=["aiodns", "cython"], sys_platform = "== 'Windows'"}

Run Code Online (Sandbox Code Playgroud)

原帖 06-26-2021


TOML 文档中不允许出现重复的键。

例如这个:

faust = {version=">=1.10.1", extras=["aiodns", "ciso8601", "cython"], platform_system = "!= 'Windows'"}

faust = {version=">=1.10.1", extras=["aiodns", "cython"], platform_system = "== 'Windows'"}
Run Code Online (Sandbox Code Playgroud)

参考pipenv的源码

# file: /pipenv/vendor/tomlkit/exceptions.py
# which is referenced from here /pipenv/vendor/tomlkit/container.py

class KeyAlreadyPresent(TOMLKitError):
    """
    An already present key was used.
    """

    def __init__(self, key):
        message = 'Key "{}" already exists.'.format(key)

        super(KeyAlreadyPresent, self).__init__(message)

Run Code Online (Sandbox Code Playgroud)

此外,已在TOML Github 存储库上讨论了重复密钥问题。