所以今天我确实发现,pip 10.x.x
版本req
已更改其目录,现在可以在pip._internal.req
下找到。
由于通常的做法是使用parse_requirements
中的setup.py
函数来安装需求文件中的所有依赖项,我现在想知道这种做法是否应该改变,因为它现在位于{{{ 1}}?
或者在不使用_internal
的情况下实际上最佳做法是什么?
答案 0 :(得分:10)
首先,我认为从requirements.txt
内部解析setup.py
并不是一个好主意。相反,应该将install_requires
或setup.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 requirement。 Notations 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
)