我打算将我的Python项目作为带有固定依赖关系版本的bdist轮子分发,这样对上游依赖关系的更改就不会破坏我的代码。然而,当有人安装我项目的开发版本时,例如通过pip install -e
,我希望引入依赖关系的最新版本,这样我就可以不断地针对它们测试我的代码。
依赖项列在setup.py
:中
from setuptools import setup
setup(
...
install_requires=["numpy", "scipy", "matplotlib"],
)
我使用从项目根(包含setup.py
的根(创建轮子
pip wheel . --no-deps
创建的轮子在安装时,也将安装Numpy、Scipy和Matplotlib的最新版本。解压缩的轮子的METADATA
文件(pip在安装项目时使用该文件来确定项目的依赖关系(显示了这种情况:
...other metadata...
Requires-Dist: numpy
Requires-Dist: scipy
Requires-Dist: matplotlib
如果我在setup.py
中更改install_requires
以设置依赖项的显式版本(例如,使用install_requires=["numpy==1.20.0", ...etc...]
(,则创建的轮子的METADATA
会列出:
...other metadata...
Requires-Dist: numpy (==1.20.0)
...other dependencies...
此操作会告诉最终用户机器上的pip
抓取Numpy 1.20.0。这就是我想要的轮子,但每当有人运行pip install -e .
时,他们也会得到这些固定版本。
有没有一种方法可以指定";开发";依赖性,而不是"依赖性";"轮子";依赖程序?还是我一直在告诉人们手动运行pip install -r unpinned-requirements.txt
和pip install -e . --no-deps
?
更新:
所以基本上,你想做的是把需求固定在轮子上,而不是在开发环境中。
确定setup.py
中的要求:
import sys
import subprocess
from packaging.requirements import InvalidRequirement, Requirement
if 'bdist_wheel' in sys.argv: # building the wheel
if your_environment_is_clean: # e.g. in a build pipeline
# get requirements from pip freeze
# NOTE: this also pins all sub-requirements
res = subprocess.run([sys.executable, "-m", "pip", "freeze"], check=True, capture_output=True, text=True)
requirements = res.stdout.split('n')
elif you_want_to_pin_your_requirements_here:
requirements = [
"numpy==1.20.0", # pinned versions for wheel
# ...
]
else:
# load pinned requirements from file
with open("requirements.txt") as file:
lines = file.readlines()
requirements = []
for line in lines:
try:
# check if lines are valid requirements
req = Requirement(line)
requirements.append(str(req))
except InvalidRequirement:
pass
else:
# not building a wheel
requirements = [
"numpy", # unpinned versions for development
# ...
]
setuptools.setup(
install_requires=requirements,
# ...
)
构建后手动调整轮子:
您只能将版本固定在控制盘中。我不知道是否有任何工具可以做到这一点,但你可以手动完成:
[pip install wheel]
pip wheel --no-deps [-e] .
wheel unpack <package>-<spec>.whl
在package-<version>/<package>-<spec>/METADATA
中固定版本并重新包装轮子:
wheel pack <package>
然后展开车轮。