pip升级到pip 10.xx后解析需求文件的正确方法?

mut*_*han 7 python pip

所以今天我也发现,与释放pip 10.x.xreq包改变了它的目录,现在可以下找到pip._internal.req.

由于通常的做法是使用parse_requirements你的函数setup.py来安装需求文件中的所有依赖项,我现在想知道这种做法是否应该改变,因为它现在位于_internal

或者什么是不使用的最佳实践parse_requirements

sin*_*roc 16

首先,我认为requirements.txt从内部解析setup.py不是一个好主意。它应该是相反的,install_requiressetup.pysetup.cfg应该被视为某种真实来源,并且requirements.txt应该从那里生成诸如此类的文件。但是每个人都有不同的需求,这导致了不同的工作流程。

所以说...

可以在没有pip 的情况下requirements.txtsetuptools setup.py脚本解析一个相对简单的文件。该setuptools的项目已经包含在其必要的工具顶级包。pkg_resources

它或多或少看起来像这样:

#!/usr/bin/env python3

import pathlib

import pkg_resources
import setuptools

with pathlib.Path('requirements.txt').open() as requirements_txt:
    install_requires = [
        str(requirement)
        for requirement
        in pkg_resources.parse_requirements(requirements_txt)
    ]

setuptools.setup(
    install_requires=install_requires,
)
Run Code Online (Sandbox Code Playgroud)

同样,这仅适用于简单requirements.txt文件。请参阅文档页面中的需求解析pkg_resources以获取有关处理内容的详细信息。简而言之,每一行都应该是一个有效的PEP 508要求。不处理真正特定于pip 的符号


注意事项

  • 这不处理像“-r extra_req.txt”这样的复杂条目。从 pip 导入的选项确实解决了这些情况,但它们还有其他问题。 (2认同)

sh0*_*uit 8

Scrotch解决方案只适用pip 19.0.3于 ,pip >= 20在 PipSession 模块被重构的版本中。这是适用于所有pip版本的导入的解决方案:

try:
    # pip >=20
    from pip._internal.network.session import PipSession
    from pip._internal.req import parse_requirements
except ImportError:
    try:
        # 10.0.0 <= pip <= 19.3.1
        from pip._internal.download import PipSession
        from pip._internal.req import parse_requirements
    except ImportError:
        # pip <= 9.0.3
        from pip.download import PipSession
        from pip.req import parse_requirements
Run Code Online (Sandbox Code Playgroud)

  • @sinoroc 的解决方案很干净。但是,如果使用“pip-tools”等工具创建“requirements.txt”文件,则“requirements.txt”文件中可能会引入“--trusted-host”等项目,导致“pkg_resources”包失败来解析。 (2认同)

mut*_*han 7

我想出的正确方法是在 setup.py 中添加依赖项,例如:

REQUIRED_PACKAGES = [
    'boto3==1.7.33'
]

if __name__ == '__main__':
    setup(
        ...
        install_requires=REQUIRED_PACKAGES,
        ...
    )
Run Code Online (Sandbox Code Playgroud)

.在您的requirements.txt. setup.py如果您从文件安装,它将自动安装所有软件包。


Scr*_*tch 5

我不同意接受的答案。setup.py如果您有一个包含大量依赖项的大型项目,该文件可能会很快变得丑陋。将您的需求保存在单独的.txt文件中始终是一个好习惯。我会做这样的事情 -

try:  # for pip >= 10
    from pip._internal.req import parse_requirements
    from pip._internal.download import PipSession
except ImportError:  # for pip <= 9.0.3
    from pip.req import parse_requirements
    from pip.download import PipSession

requirements = parse_requirements(os.path.join(os.path.dirname(__file__), 'requirements.txt'), session=PipSession())

if __name__ == '__main__':
    setup(
        ...
        install_requires=[str(requirement.requirement) for requirement in requirements],
        ...
    )
Run Code Online (Sandbox Code Playgroud)

将您的所有需求放入requirements.txt项目根目录下。

  • 我的意思是如何将包列表加载到 setup.py 中是一个完全不同的主题。您可以从其他地方的另一个文件导入它。但我仍然认为在自己的应用程序中依赖 pip 库是错误的。如果您不想将包列表放在 setup.py 中,请将其放入任何其他文件中,将其放入常量并将其导入到 setup.py 中 (3认同)