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 ?