Source code for jwst.associations.lib.keyvalue_registry

"""Key/Value Registry."""

from collections import UserDict

__all__ = [
    "KeyValueRegistry",
    "KeyValueRegistryError",
    "KeyValueRegistryNoKeyFoundError",
    "KeyValueRegistryNotSingleItemError",
]


[docs] class KeyValueRegistry(UserDict): """ Provide a dict-like registry. Differences from just a `dict`: - Can be given single item or a 2-tuple. If an item, attempts to read the ``__name__`` attribute and use that as the key. - If None is given as a key, a default key can be specified. - Instances can be used as decorators. Parameters ---------- items : object or (str, object) or dict Initializing items. default : str or object The default to use when key is `None`. """ def __init__(self, items=None, default=None): super_args = () if items is not None: super_args = (make_dict(items),) super(KeyValueRegistry, self).__init__(*super_args) self.default = None if default is not None: default_dict = make_dict(default) if len(default_dict) > 1: raise KeyValueRegistryNotSingleItemError default_dict = make_dict(default) self.update(default_dict) self.default = next(iter(default_dict.keys())) self.update({None: default_dict[self.default]})
[docs] def update(self, item): """Add item to registry.""" item_dict = make_dict(item) super(KeyValueRegistry, self).update(item_dict)
[docs] def __call__(self, item): """ Add item by calling instance. This allows an instance to be used as a decorator. Parameters ---------- item : object or (str, object) or dict Item used for decoration. Returns ------- item : object or (str, object) or dict The item used to update self. """ self.update(item) return item
# Errors
[docs] class KeyValueRegistryError(Exception): """Exception class for key value in registry.""" def __init__(self, *args): if len(args) == 0: args = (self.msg,) super(KeyValueRegistryError, self).__init__(*args)
[docs] class KeyValueRegistryNotSingleItemError(KeyValueRegistryError): """Exception class for when passed item is a list and not a single item.""" msg = "Item cannot be a list"
[docs] class KeyValueRegistryNoKeyFoundError(KeyValueRegistryError): """Exception class for no key in registry.""" msg = "Cannot deduce key from given value"
# Utilities def make_dict(item): """ Create a dict from an item. Items may be a dict, a 2-tuple or an object. Objects are most often a file format class from `~jwst.associations.association_io` - JSON or YAML. Parameters ---------- item : object or (name, object) or dict If dict, just return dict. If 2-tuple, return dict with the key/value pair If just object, use ``__name__`` as key Returns ------- dict The dictionary created from the item. """ try: item_dict = dict(item) except (TypeError, ValueError): try: key, value = item except (TypeError, ValueError): try: key = item.__name__ except (AttributeError, SyntaxError) as err: raise KeyValueRegistryNoKeyFoundError from err else: value = item # At they point we have a key/value pair item_dict = {key: value} return item_dict