DCI lookups in Python (inspired by Netbeans Platform Lookups API)
lookups - Find object instances
A lookup is like a dict where you can store object instances as values. And the search keys are their type classes.
lookups implements a bit more than that:
- You can also lookup by parent class and not just the most subclasses of an instance.
- You can get hold of a
lookups.Result, which allows you to register a listener for a given class search. You will be notified when an instance of that class is added/removed from the lookup.
- Deferred instanciation with
lookups.Convertor. That is, an 'instance' can appear in a lookup but not be instanciated until it is actually used (ie. looked up). Useful for heavy objects or plugins.
lookups.Itemcan provide you with additional info on an instance: display string, persistence ID string, type, and instance itself.
This is the most basic but versatile and dynamic lookup. (HINT: For Java folks, it corresponds to your AbstractLookup ;-) ).
It comes in two main parts:
lookups.InstanceContentprovide write-access to the lookup: add/set/remove instances.
lookups.GenericLookupprovide read-access to search in the lookup.
from lookups import InstanceContent, GenericLookup my_content = InstanceContent() my_lookup = GenericLookup(my_content) # Adds some objects class ParentClass: pass class ChildClass(ParentClass): pass parent = ParentClass() my_content.add(parent) child1 = ChildClass() my_content.add(child1) child2 = ChildClass() my_content.add(child2) ... # lookup(cls): get first matching instance # a_match will be any of parent, child1 or child2 a_parent_match = my_lookup.lookup(ParentClass) # lookup_all(cls): get all matching instances # all_parent_matches is an immutable sequence # of parent, child1 and child2 all_parent_matches = my_lookup.lookup_all(ParentClass) # all_children_matches is an immutable sequence # of child1 and child2 all_children_matches = my_lookup.lookup_all(ChildClass) # lookup_result(cls): get a Result object for the searched class parent_result = my_lookup.lookup_result(ParentClass) # all_instances(): all instances corresponding to the searched # class (ie. similar to plain lookup_all()) parent_result.all_instances() # all_classes(): Immutable set of all types in the result. # Here it would be set(ParentClass, ChildClass) parent_result.all_classes() # Lookup result listener def call_me_back(result): print('Result changed. Instances are now', result.all_instances()) parent_result.add_lookup_listener(call_me_back) ... my_content.remove(child1) # -> This will invoke call_me_back() # You can also provide a `concurrent.futures.Executor` when # creating the content to control how the listeners are called: # InstanceContent(notify_in: Executor = None).
lookups.Lookup.get_default(): The default lookup in a system.
lookups.ProxyLookup: A lookup that merge results from several lookups.
lookups.DelegatedLookup: A lookup that redirects to another (dynamic) lookup, through a LookupProvider.
lookups.EntryPointLookup: A lookup loading its instances from a setuptools entry point group (ie. provided by any installed package).
lookups.fixed: Simple unmodifiable lookup. Content is set at creation time. Will be one of:
lookup.SimpleLookup: A basic lookup with a static content.
lookups.singleton: Unmodifiable lookup that contains just one fixed object.
lookups.EmptyLookup: A lookup containing nothing.
A list of people who have contributed to Lookups in order of their first contribution.
Name-or-Well-known-alias <email@example.com> (url)
- Axel Voitier firstname.lastname@example.org
Please, add yourself when you contribute!
Original Netbeans authors of Lookup API
- Jaroslav Tulach - Lookup API, AbstractLookup, InstanceContent, ArrayStorage
- Marian Petras - Singleton lookup
- David Strupl - Common lookup implementations
0.3.0 - XX XXXXXXXX 2021
- Adds a EntryPointLookup.
- Adds a DelegatedLookup.
- Adds a ProxyLookup.
- Adds a proper resolution for system default lookup Lookup.get_default().
- Fixes issue with listeners registration disappearing immediately when using object-bound methods.
- Content of a GenericLookup can now behave like a Container (ie. you can do things like "obj in content").
- When an instance is not hashable, provides an alternative using id() of the object in order to be able to store it in a hash-based storage (set, dictionary).
- New syntactic sugar: call directly a lookup object as shortcut for the lookup method. Ie., instead of writing "lookup.lookup(...)" you can now write "lookup(...)".
- Missing declared dependency in typing_extensions.
- Abstract methods now raise NotImplementedError
0.2.0 - 06 February 2020
- Provides GenericLookup and InstanceContent, based on SetStorage. These are the first dynamic lookups. They are based on Netbeans' AbstractLookup, InstanceContent and ArrayStorage.
- Lookup listeners are just simple callables now.
- Follows PEP 561 for packages providing typing information.
- Improved quality assurance process (using Github Workflow as CI).
- First (proto-)documentation.
0.1.0 - 18 May 2019
- Initial dump of code.
- Defines the public API for lookups.
- Provides fixed lookup: members are defined at instantiation time and never change.
- Provides singleton lookup: only one member defined at instantiation time and never change.
- Provides empty lookup: a special lookup with nothing in it.
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.