Metadata-Version: 2.1
Name: lookups
Version: 0.2.0
Summary: DCI lookups in Python (inspired by Netbeans Platform Lookups API)
Home-page: https://github.com/AxelVoitier/lookups
Author: Axel Voitier
Author-email: axel.voitier@gmail.com
License: MPL-2.0
Description: [![PyPI version shields.io](https://img.shields.io/pypi/v/lookups?style=for-the-badge)](https://pypi.python.org/pypi/lookups)
        [![PyPI download shields.io](https://img.shields.io/pypi/dm/lookups?style=for-the-badge)](https://pypi.python.org/pypi/lookups)
        [![PyPI Python version shields.io](https://img.shields.io/pypi/pyversions/lookups?style=for-the-badge)](https://pypi.python.org/pypi/lookups)
        [![GitHub license shields.io](https://img.shields.io/github/license/AxelVoitier/lookups?style=for-the-badge)](https://github.com/AxelVoitier/lookups/blob/master/LICENSE)
        
        [![GitHub commits since shields.io](https://img.shields.io/github/commits-since/AxelVoitier/lookups/0.1.0?style=for-the-badge)](https://github.com/AxelVoitier/lookups/commits/master)
        [![GitHub build shields.io](https://img.shields.io/github/workflow/status/AxelVoitier/lookups/Python%20package?style=for-the-badge)](https://github.com/AxelVoitier/lookups/actions)
        [![Codecov shields.io](https://img.shields.io/codecov/c/gh/AxelVoitier/lookups?style=for-the-badge)](https://codecov.io/gh/AxelVoitier/lookups)
        
        # lookups - Find object instances
        
        [DCI](https://en.wikipedia.org/wiki/Data,_context_and_interaction) lookups for Python (inspired by Netbeans Platform [Lookups API](http://wiki.netbeans.org/DevFaqLookup))
        
        ## Principle
        
        A lookup is like a dict where you can store object instances as values. And the search keys are their type classes.
        
        Simply.
        
        But `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.Item` can provide you with additional info on an instance: display string, persistence ID string, type, and instance itself.
        
        ## `lookups.GenericLookup`
        
        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.InstanceContent` provide write-access to the lookup: add/set/remove instances.
        - `lookups.GenericLookup` provide read-access to search in the lookup.
        
        ```python
        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).
        ```
        
        ## Other lookups
        
        * `lookups.fixed`: Simple unmodifiable lookup. Content is set at creation time.
        * `lookups.singleton`: Unmodifiable lookup that contains just one fixed object.
        * `lookups.EmptyLookup`: A lookup containing nothing.
        
        
        Individual Contributors
        =======================
        
        A list of people who have contributed to Lookups in order of their first
        contribution.
        
        Format: ```Name-or-Well-known-alias <email@domain.tld> (url)```
        
        * Axel Voitier <axel.voitier@gmail.com>
        
        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
        
        
        CHANGELOG
        =========
        
        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.
        
Keywords: lookup lookups dci
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Object Brokering
Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Typing :: Typed
Requires-Python: ~=3.7
Description-Content-Type: text/markdown
