How do I add a setuptools entry_point as an example in my main project?

python, setuptools

Solution

`pkg_resources.iter_entry_points` lists any entry points by the given name in any egg, including your own package. Thus, if your `entry_points` entry in `setup.py` lists the following, and you've run `setup.py develop` to generate the metadata, your own entry point will be included:

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

The Babel project does exactly this; in it's `setup.py` it lists entry points for both `babel.checkers` and `babel.extractors`, and these are looked up by `babel.messages.checkers:_find_checkers` and `babel.messages.extract:extract`, respectively.

If you do not want to have a `setup.py` file (which is easy enough to create and/or generate from a template), then you are facing having to alter the internal state of `pkg_resources.working_set` instead:

- `working_set.entries` is a list of eggs. You'll have to add the path of your project's top-level directory to this.

- `working_set.entry_keys` is a mapping from paths in `entries` to a list of package names. Add your project as `working_set.entry_keys[path] = ['package.name']

- `working_set.by_key` is a mapping from package name to a `pkg_resources.Distribution` instances. You'll need to create a `Distribution` instance and store it under your package name: `working_set.by_key['package.name'] = yourdistribution`.

For your purposes the `Distribution` instance can be fairly sparse, but I'd include at least the project name. You'll need to have a entry-point map on it though:

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

The internal structure `_ep_map` is normally parsed on demand from the egg-info metadata.

Please note that this is relying entirely on undocumented internal data structures that can change between versions. In other words, you are on your own here. I'd generate a `setup.py` file instead, and run `python setup.py develop` to generate the egg metadata instead.

Problem

I want to make my program pluggable. I'd like to use the setuptools way of doing so, using eggs. I've been able to make a plugin to provide an alternate class for some functionality, and I can use it. I would like to select the class to use at runtime; either the one in my core module or in any of the plugins. I'd like to use the pkg_resources way of querying for these classes: ``` for entrypoint in pkg_resources.iter_entry_points("myapp.myclasses"): ``` How can I create an EntryPoint object for my class in core, and register it, so that iter_entry_points will return it the same way as for my .egg plugin class ?

Original source