如何编程检测requirements.txt中固定版本包是否为最新?
问题描述
假设您有如下requirements.txt文件:
pydantic==1.10.7 mypy==1.2.0 pylint>=2.17.3
安装这些依赖时,pydantic和mypy会安装指定的固定版本,而pylint因运算符约束会安装2.17.4而非2.17.3。目前mypy已有新版本1.3.0,如何仅通过requirements.txt,以编程方式检测其中固定版本包是否存在更新?
已尝试的方法
pip list --outdated:功能接近但会显示所有已安装的过时包,而非仅requirements.txt中的包- 编写解析器处理
requirements.txt并解析版本:需深入pip._internals实现,还要支持--extra-index-url、私有仓库等场景,过于繁琐 - piprot:功能符合需求但已过时,已被
pip list --outdated替代
预期输出示例
pydantic==1.10.7 Up to date mypy==1.2.0 Out of date. New version is: 1.3.0 pylint>=2.17.3 Will install version 2.17.4 and is Up to date
注:核心需求是获取检测信息,输出格式可灵活调整。
解决方案
方法1:利用pip install --dry-run模拟升级(原生无依赖)
通过pip的模拟升级命令获取版本对比信息,无需额外工具,且能复用pip的所有配置(包括私有仓库、额外索引):
- 执行模拟升级命令:
pip install --dry-run --upgrade -r requirements.txt
- 解析输出内容:
- 对于固定版本包(
==指定):若输出包含Would install <package>-<new_version>,说明存在更新;若显示Requirement already satisfied且版本与指定一致,则为最新。 - 对于非固定版本包(如
>=指定):搭配pip index versions <package>获取仓库中符合约束的最高可用版本,判断该版本是否为当前仓库的最新版,即可得到类似预期的信息。
- 对于固定版本包(
方法2:使用pip-api简化编程实现
如果允许安装辅助库,pip-api封装了pip的内部逻辑,能快速解析requirements并获取版本数据:
- 安装
pip-api:
pip install pip-api
- 编写检测脚本:
import pip_api from pip_api.models import Requirement # 解析requirements.txt文件 with open('requirements.txt', 'r') as f: reqs = [Requirement(line.strip()) for line in f if line.strip() and not line.startswith('#')] for req in reqs: # 获取包的所有可用版本(按升序排列) all_versions = pip_api.package_versions(req.name) latest_full_version = all_versions[-1] spec = req.specifier # 处理固定版本约束(==) if '==' in spec: specified_version = next(v for op, v in req.specs if op == '==') if specified_version == latest_full_version: print(f"{req.name}=={specified_version} Up to date") else: print(f"{req.name}=={specified_version} Out of date. New version is: {latest_full_version}") # 处理非固定版本约束(如>=) else: # 筛选符合约束的版本 compatible_versions = [v for v in all_versions if spec.contains(v, prereleases=False)] if compatible_versions: latest_compatible = compatible_versions[-1] if latest_compatible == latest_full_version: print(f"{req.name}{spec} Will install version {latest_compatible} and is Up to date") else: print(f"{req.name}{spec} Will install version {latest_compatible}, but newer version {latest_full_version} exists (not compatible with constraint)") else: print(f"{req.name}{spec} No compatible versions found")
该脚本自动处理版本约束,支持私有仓库等场景,直接输出所需检测信息。
方法3:过滤pip list --outdated结果
先提取requirements.txt中的包名,再过滤过时包列表:
- 提取包名(需适配带额外依赖的包名,如
package[extra]):
grep -E '^[^#]+' requirements.txt | sed -E 's/([a-zA-Z0-9_-]+).*/\1/' > req_packages.txt
- 过滤过时包:
pip list --outdated | grep -F -f req_packages.txt
这种方法简单快捷,但需根据实际需求调整包名提取的正则规则。
内容的提问来源于stack exchange,提问作者Keegan Cowle
相关产品推荐
相关产品推荐

