在安装时检测 Python 传递依赖性问题?
Detect Python transitive dependency issues at install time?
我最近以任何理智的方式了解到 pip
does not resolve transitive dependencies。这意味着在安装一个包之后,它的某些依赖项的依赖项可能实际上并没有得到满足。
有没有办法以编程方式检查所有已安装包的依赖项是否在安装后得到实际满足?
具体来说,我希望能够创建一个 virtualenv,将一些包安装到其中,然后验证所有安装的包是否确实具有所需的依赖项。
编辑:这里有一个例子可以更好地说明问题。假设包 A
依赖于包 B
和 C
,它们都依赖于包 D
,可能具有不同的版本范围。安装A
时,pip会任意选择D
指定的版本范围之一来满足。例如,可能会满足 B
对 D
的依赖,但可能不会满足 C
对 D
的要求版本。我想检测是否存在这样的问题
This answer shows how to get all locally installed packages. This one 展示了一种验证给定包是否已安装的方法,它还递归地检查包的依赖项。结合这些:
import pip
import pkg_resources
pkg_resources.require(str(dep.as_requirement())
for dep in pip.get_installed_distributions())
如果任何已安装的包有不满足的要求,这将引发 ResolutionError
。
旁白:这似乎是新的pip check
command is intended to do, but it doesn't catch some dependency issues that the above script catches, such as extras-related issues。
更新: pip
的最新版本不提供 get_installed_distributions()
功能。 Per https://github.com/pypa/pip/issues/5243, pkg_resources.working_set
可用于获取依赖列表:
import pkg_resources
pkg_resources.require(str(dep.as_requirement())
for dep in pkg_resources.working_set)
我最近以任何理智的方式了解到 pip
does not resolve transitive dependencies。这意味着在安装一个包之后,它的某些依赖项的依赖项可能实际上并没有得到满足。
有没有办法以编程方式检查所有已安装包的依赖项是否在安装后得到实际满足?
具体来说,我希望能够创建一个 virtualenv,将一些包安装到其中,然后验证所有安装的包是否确实具有所需的依赖项。
编辑:这里有一个例子可以更好地说明问题。假设包 A
依赖于包 B
和 C
,它们都依赖于包 D
,可能具有不同的版本范围。安装A
时,pip会任意选择D
指定的版本范围之一来满足。例如,可能会满足 B
对 D
的依赖,但可能不会满足 C
对 D
的要求版本。我想检测是否存在这样的问题
This answer shows how to get all locally installed packages. This one 展示了一种验证给定包是否已安装的方法,它还递归地检查包的依赖项。结合这些:
import pip
import pkg_resources
pkg_resources.require(str(dep.as_requirement())
for dep in pip.get_installed_distributions())
如果任何已安装的包有不满足的要求,这将引发 ResolutionError
。
旁白:这似乎是新的pip check
command is intended to do, but it doesn't catch some dependency issues that the above script catches, such as extras-related issues。
更新: pip
的最新版本不提供 get_installed_distributions()
功能。 Per https://github.com/pypa/pip/issues/5243, pkg_resources.working_set
可用于获取依赖列表:
import pkg_resources
pkg_resources.require(str(dep.as_requirement())
for dep in pkg_resources.working_set)