如何引用setup.py中定义的变量?

How to reference a variable defined in setup.py?

我得到了以下 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 extras 的包。

如果我可以访问 setup.py 中定义的 dependencies 变量,我可以轻松地为这些包编写验证函数。

这个问题的可能答案:

  1. 告诉我如何在 setup.py 中访问 dependencies
  2. 告诉我组织可选依赖项的更好方法。

如果您想从已安装的软件包中访问信息, 那么您不能尝试直接访问 setup.py 源,因为 它实际上并不存在 。一旦您的代码安装到 site-packages,安装程序即 setup.py 文件本身就消失了。您可以从开发源代码树中访问它,例如 git 签出,但当您的包被其他人安装和使用时,情况就不同了。

对于 wheel 安装,.whl 文件中根本就没有 setup.py。它只是一个 zip 文件,解压缩并亲自查看!但是缺少 setup.py 即使在源代码分发安装 (mypkg-1.0.tar.gz) 或从 pip 安装的任何东西(它首先构建一个 wheel 文件然后安装 wheel)的情况下也是如此。

相反,您将需要这样的东西,以从包元数据访问依赖项数据:

# from within your my_module:
from importlib.metadata import requires
reqs = requires(__package__)

结构有点不同,因此您可能需要将其解析回字典,但所有信息都在那里:

>>> 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"')>