我有以下内容
setup.py
:
import itertools
dependencies = {
'minimal': ['numpy', 'requests'],
'option-a': ['scipy'],
'option-b': ['matplotlib']
}
setup(
install_requires=dependencies['minimal'], # minimal dependencies
extras_require={
'all': list(itertools.chain(*dependencies.values())), # all dependencies included
**{k: v for k, v in dependencies.items() if k != 'minimal'}, # each extra dependency group
},
# other setup parameters omitted
)
我使用变量
dependencies
来避免重复依赖项列表并使其易于维护。这似乎是个好方法。
我想编写一个函数
verify_optional_extras('option-a')
,它将检查是否安装了option-a
附加功能的软件包。
如果我可以访问
dependencies
中定义的 setup.py
变量,我可以轻松地为这些包编写验证函数。
这个问题的可能答案:
dependencies
中访问 setup.py
。如果您想从已安装的软件包中访问信息, 那么你不应该尝试直接访问
setup.py
源,因为 它实际上并不在那里。一旦您的代码安装到站点包中,安装程序(即 setup.py
文件本身)就会消失。您也许可以从开发源代码树中访问它,例如 git checkout,但当您的包被其他人安装和使用时,情况就不同了。
对于轮子安装,
setup.py
文件中根本就没有 .whl
。这只是一个 zip 文件,解压后亲自查看!但是,即使在源代码分发安装 (setup.py
) 或从 pip 安装的任何内容(首先构建轮子文件,然后安装轮子)的情况下,缺失的 mypkg-1.0.tar.gz
也是如此。
相反,您将需要这样的东西,以从包元数据访问依赖项数据:
from importlib.metadata import requires
reqs = requires("mypkg")
结构有点不同,因此您可能需要将其解析回字典,但所有信息都在那里:
>>> requires("mypkg")
['numpy',
'requests',
'numpy; extra == "all"',
'requests; extra == "all"',
'scipy; extra == "all"',
'matplotlib; extra == "all"',
'scipy; extra == "option-a"',
'matplotlib; extra == "option-b"']
这些是需求行,如果您在验证可选 deps 安装时需要一个解析它们的工具,那么您可以使用 packaging 模块:
>>> from packaging.requirements import Requirement
>>> req = Requirement('scipy >= 1.6; extra == "option-a"')
>>> req.name
'scipy'
>>> req.specifier
<SpecifierSet('>=1.6')>
>>> "1.7.3" in req.specifier
True
>>> "1.5" in req.specifier
False
>>> req.marker
<Marker('extra == "option-a"')>