【问题标题】:Conditional setuptools entry_points条件设置工具 entry_points
【发布时间】:2016-03-15 08:24:35
【问题描述】:

是否可以在 setup.py 中定义条件入口点?我注意到可以使用extras标记一个入口点,但即使安装包时没有该额外功能,该入口点仍然可用。

setup(name='my.package',
      ...
      extras_require={
          'special': [
              'dependency1',
              'dependency2',
          ],
      },
      ...
      entry_points="""
      [custom_entrypoint]
      handlername = my.package.special:feature [special]
      """,
  )

看起来custom_entrypoint 可用,即使在没有special 功能(pip install my.package[special]) 的情况下安装软件包。有没有一种简单的方法可以让这样的东西正常工作?

【问题讨论】:

    标签: python setuptools entry-point


    【解决方案1】:

    入口点被写入package.dist-info/entry_points.txt。我建议在setup.py 中查看系统上安装了哪些软件包,但在这里可能无济于事,因为dist-info 可能会在pip 安装其他软件包之前处理;稍后,即使您安装了其他软件包,这些入口点也不会神奇地出现,除非您使用正确的参数运行 setup.py for my.package

    我建议您进行重构,以便有一个名为 my.package 的包和另一个名为 my.package.special 的可安装包;后者将my.packagedependency1dependency2 作为依赖项和入口点。现在,如果您想安装my.package,它会在没有特价商品的情况下安装; pip install my.package.special 以获得最重要的特殊功能。

    【讨论】:

    • 我得到了类似的结果。我没有将功能移动到新包中,而是保持不变。我不想将几个包中的功能移到新的特殊包中,因为我将它用作experimental 功能切换。相反,我创建了一个名为 app.experimental 的特殊包,并将其作为 extras_require 包含在其他包中。在执行 iter_entry_points 循环时,我检查了入口点是否满足了他们的要求,如果没有被忽略(entrypoint.require() 将引发 pkg_resources.DistributionNotFound)。
    • @Torkel 然后请发布您的解决方案作为替代答案和accept it:D
    • 创建整个 Python 包以满足“元依赖”需求是愚蠢的,而这正是 extras_require 的用途。
    【解决方案2】:

    在您的“插件加载器”中(无论是通过名称还是通过枚举给定命名空间的完整可用入口点来找到入口点),您需要执行以下操作:

    import pkg_resources
    
    # Get a reference to an EntryPoint, somehow.
    plug = pkg_resources.get_entry_info('pip', 'console_scripts', 'pip')
    
    # This is sub-optimal because it raises on the first failure.
    # Can't capture a full list of failed dependencies.
    # plug.require()
    
    # Instead, we find the individual dependencies.
    
    failed = []
    
    for extra in sorted(plug.extras):
        if extra not in plug.dist._dep_map:
            continue  # Not actually a valid extras_require dependency?
    
        for requirement in i.dist._dep_map[extra]:
            try:
                pkg_resources.require(str(requirement))
            except pkg_resources.DistributionNotFound:
                failed.append((plug.name, extra, str(requirement)))
    

    然后我们开始了;对于给定的插件,您将获得失败的依赖项列表(如果成功,则为 not failed)列出 entry_point 插件名称、[foo] 额外标签和特定的未满足的包要求。

    这方面的一个例子来自web.command 包的web versions --namespace 子命令。注意waitress extras_require 是如何满足的,其中gevent 明确指定gevent 包丢失:

    不幸的是,我实际上没有方便展示的多重依赖 entry_point 示例,重要的是要注意列为“缺失”的包可能并不总是与 extras_require 的名称匹配。

    【讨论】:

      猜你喜欢
      • 2012-02-14
      • 1970-01-01
      • 2018-09-06
      • 1970-01-01
      • 2022-06-22
      • 2012-06-28
      • 1970-01-01
      • 2013-01-13
      • 2017-07-20
      相关资源
      最近更新 更多