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

时间:2018-04-06 09:43:52

标签: python pip

所以今天我确实发现,pip 10.x.x版本req已更改其目录,现在可以在pip._internal.req下找到。

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

或者在不使用_internal的情况下实际上最佳做法是什么?

5 个答案:

答案 0 :(得分:10)

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

话虽如此...

可以从 setuptools requirements.txt脚本中解析相对简单的setup.py文件,而无需 pip 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,
)

同样,这仅适用于简单的requirements.txt文件。请参阅Requirements parsing in the documentation page for pkg_resources以获取有关处理内容的详细信息。简而言之,每行应为有效的PEP 508 requirementNotations that are really specific to pip未处理。


注释

答案 1 :(得分:7)

solution of 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

答案 2 :(得分:0)

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

REQUIRED_PACKAGES = [
    'boto3==1.7.33'
]

if __name__ == '__main__':
    setup(
        ...
        install_requires=REQUIRED_PACKAGES,
        ...
    )

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

答案 3 :(得分:0)

我不同意接受的答案。如果您有一个依赖项很多的大型项目,那么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.req) for requirement in requriements],
        ...
    )

在项目根目录下的requirements.txt中提出所有要求。

答案 4 :(得分:0)

with open("requirements.txt") as f:
    dependencies = [line for line in f if "==" in line]

setup(
    install_requires=dependencies
)