如何在我的主项目中添加setuptools entry_point作为示例?

Tho*_*ele 6 python setuptools

我想让我的程序可插拔.我想使用setuptools的方式,使用鸡蛋.

我已经能够制作一个插件来为某些功能提供替代类,我可以使用它.

我想选择在运行时使用的类; 我的核心模块或任何插件中的一个.我想使用pkg_resources查询这些类的方式:

for entrypoint in pkg_resources.iter_entry_points("myapp.myclasses"):
Run Code Online (Sandbox Code Playgroud)

如何在核心中为我的类创建一个EntryPoint对象并注册它,以便iter_entry_points将以与我的.egg插件类相同的方式返回它?

Mar*_*ers 11

pkg_resources.iter_entry_points列出任何蛋中给定名称的任何入口点,包括您自己的包.因此,如果您的entry_points条目setup.py列出以下内容,并且您已经运行setup.py develop以生成元数据,则将包含您自己的入口点:

[myapp.myclasses]
classentry1 = myapp.mymodule:myclassname1
classentry2 = myapp.mymodule:myclassname2
Run Code Online (Sandbox Code Playgroud)

巴贝尔项目正是这样做的; 在它的setup.py它列出切入点既babel.checkersbabel.extractors,这些都是通过查找babel.messages.checkers:_find_checkersbabel.messages.extract:extract分别.

如果您不想拥有一个setup.py文件(这很容易从模板创建和/或生成),那么您将面临改变内部状态的问题pkg_resources.working_set:

  • working_set.entries是一个鸡蛋清单.您必须将项目顶级目录的路径添加到此.
  • working_set.entry_keys是从路径entries到包名列表的映射.将项目添加为`working_set.entry_keys [path] = ['package.name']
  • working_set.by_key是从包名到pkg_resources.Distribution实例的映射.您需要创建一个Distribution实例并将其存储在您的包名称下:working_set.by_key['package.name'] = yourdistribution.

为了您的目的,Distribution实例可能相当稀疏,但我至少包括项目名称.你需要在它上面有一个入口点地图:

yourdistribution = Distribution(project_name='package.name')
yourdistribution._ep_map = {'myapp.myclasses', {
    'classentry1': entrypointinstance_for_classentry1,
    'classentry2': entrypointinstance_for_classentry2,
}}
Run Code Online (Sandbox Code Playgroud)

内部结构_ep_map通常根据egg-info元数据进行解析.

请注意,这完全依赖于可以在不同版本之间更改的未记录的内部数据结构.换句话说,你在这里独自一人.我会生成一个setup.py文件,然后运行python setup.py develop以生成egg元数据.