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 ?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With