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

时间:2012-11-24 20:29:20

标签: python setuptools

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

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

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

for entrypoint in pkg_resources.iter_entry_points("myapp.myclasses"):

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

1 个答案:

答案 0 :(得分:11)

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

[myapp.myclasses]
classentry1 = myapp.mymodule:myclassname1
classentry2 = myapp.mymodule:myclassname2

Babel project就是这样做的;在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,
}}

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

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