Package logilab :: Package common :: Module registry :: Class RegistryStore

[frames] | no frames]

# Class RegistryStore

source code

    object --+
             |
          dict --+
                 |
                RegistryStore

    This class is responsible for loading objects and storing them
    in their registry which is created on the fly as needed.

    It handles dynamic registration of objects and provides a
    convenient api to access them. To be recognized as an object that
    should be stored into one of the store's registry
    (:class:`Registry`), an object must provide the following
    attributes, used control how they interact with the registry:

    :attr:`__registries__`
      list of registry names (string like 'views', 'templates'...) into which
      the object should be registered

    :attr:`__regid__`
      object identifier in the registry (string like 'main',
      'primary', 'folder_box')

    :attr:`__select__`
      the object predicate selectors

    Moreover, the :attr:`__abstract__` attribute may be set to `True`
    to indicate that an object is abstract and should not be registered
    (such inherited attributes not considered).

    .. Note::

      When using the store to load objects dynamically, you *always* have
      to use **super()** to get the methods and attributes of the
      superclasses, and not use the class identifier. If not, you'll get into
      trouble at reload time.

      For example, instead of writing::

          class Thing(Parent):
              __regid__ = 'athing'
              __select__ = yes()

              def f(self, arg1):
                  Parent.f(self, arg1)

      You must write::

          class Thing(Parent):
              __regid__ = 'athing'
              __select__ = yes()

              def f(self, arg1):
                  super(Thing, self).f(arg1)

    Controlling object registration
    -------------------------------

    Dynamic loading is triggered by calling the :meth:`register_modnames`
    method, given a list of modules names to inspect.

    .. automethod:: register_modnames

    For each module, by default, all compatible objects are registered
    automatically. However if some objects come as replacement of
    other objects, or have to be included only if some condition is
    met, you'll have to define a `registration_callback(vreg)`
    function in the module and explicitly register **all objects** in
    this module, using the api defined below.

    .. automethod:: RegistryStore.register_all
    .. automethod:: RegistryStore.register_and_replace
    .. automethod:: RegistryStore.register
    .. automethod:: RegistryStore.unregister

    .. Note::
        Once the function `registration_callback(vreg)` is implemented in a
        module, all the objects from this module have to be explicitly
        registered as it disables the automatic object registration.

    Examples:

    .. sourcecode:: python

       def registration_callback(store):
          # register everything in the module except BabarClass
          store.register_all(globals().values(), __name__, (BabarClass,))

          # conditionally register BabarClass
          if 'babar_relation' in store.schema:
              store.register(BabarClass)

    In this example, we register all application object classes defined in the module
    except `BabarClass`. This class is then registered only if the 'babar_relation'
    relation type is defined in the instance schema.

    .. sourcecode:: python

       def registration_callback(store):
          store.register(Elephant)
          # replace Babar by Celeste
          store.register_and_replace(Celeste, Babar)

    In this example, we explicitly register classes one by one:

    * the `Elephant` class
    * the `Celeste` to replace `Babar`

    If at some point we register a new appobject class in this module, it won't be
    registered at all without modification to the `registration_callback`
    implementation. The first example will register it though, thanks to the call
    to the `register_all` method.

    Controlling registry instantiation
    ----------------------------------

    The `REGISTRY_FACTORY` class dictionary allows to specify which class should
    be instantiated for a given registry name. The class associated to `None`
    key will be the class used when there is no specific class for a name.

Instance Methods

    new empty dictionary

__init__(self, debugmode=False) x.__init__(...) initializes x; see help(type(x)) for signature | source code

reset(self) clear all registries managed by this store | source code

__getitem__(self, name) return the registry (dictionary of class objects) associated to... | source code

registry_class(self, regid) return existing registry named regid or use factory to create one and... | source code

D.get(k,d), also set D[k]=d if k not in D

setdefault(self, regid) | source code

register_all(self, objects, modname, butclasses=()) register registrable objects into `objects`. | source code

register(self, obj, registryname=None, oid=None, clear=False) register `obj` implementation into `registryname` or `obj.__registries__` if not specified, with identifier `oid` or `obj.__regid__` if not specified. | source code

unregister(self, obj, registryname=None) unregister `obj` object from the registry `registryname` or `obj.__registries__` if not specified. | source code

register_and_replace(self, obj, replaced, registryname=None) register `obj` object into `registryname` or `obj.__registries__` if not specified. | source code

init_registration(self, path, extrapath=None) reset registry and walk down path to return list of (path, name)... | source code

register_objects(self, path, extrapath=None) register all objects found walking down <path> | source code

register_modnames(self, modnames) register all objects found in <modnames> | source code

initialization_completed(self) call initialization_completed() on all known registries | source code

is_reload_needed(self, path) return True if something module changed and the registry should be... | source code

load_file(self, filepath, modname) load registrable objects (if any) from a python file | source code

load_module(self, module) Automatically handle module objects registration. | source code

Inherited from `dict`: `__cmp__`, `__contains__`, `__delitem__`, `__eq__`, `__ge__`, `__getattribute__`, `__gt__`, `__iter__`, `__le__`, `__len__`, `__lt__`, `__ne__`, `__new__`, `__repr__`, `__setitem__`, `__sizeof__`, `clear`, `copy`, `fromkeys`, `get`, `has_key`, `items`, `iteritems`, `iterkeys`, `itervalues`, `keys`, `pop`, `popitem`, `update`, `values`, `viewitems`, `viewkeys`, `viewvalues`

Inherited from `object`: `__delattr__`, `__format__`, `__reduce__`, `__reduce_ex__`, `__setattr__`, `__str__`, `__subclasshook__`

Class Methods

is_registrable(cls, obj) ensure `obj` should be registered | source code

Class Variables
| REGISTRY_FACTORY = `{None: Registry}`
| debug = `lambda msg,* a,** kw:`
| exception = `lambda msg,* a,** kw:`
| critical = `lambda msg,* a,** kw:`
| error = `lambda msg,* a,** kw:`
| warning = `lambda msg,* a,** kw:`
| info = `lambda msg,* a,** kw:`
Inherited from `dict`: `__hash__`

Properties
Inherited from `object`: `__class__`

Method Details

### __init__(self, debugmode=False)
(Constructor)

source code

x.__init__(...) initializes x; see help(type(x)) for signature

Returns:

    new empty dictionary

Overrides: object.__init__
  (inherited documentation)

### __getitem__(self, name)
(Indexing operator)

source code

    return the registry (dictionary of class objects) associated to
    this name

Overrides: dict.__getitem__

### registry_class(self, regid)

source code

    return existing registry named regid or use factory to create one and
    return it

### setdefault(self, regid)

source code

Returns: D.get(k,d), also set D[k]=d if k not in D
Overrides: dict.setdefault
  (inherited documentation)

### register_all(self, objects, modname, butclasses=())

source code

    register registrable objects into `objects`.

    Registrable objects are properly configured subclasses of
    :class:`RegistrableObject`.  Objects which are not defined in the module
    `modname` or which are in `butclasses` won't be registered.

    Typical usage is:

    .. sourcecode:: python

        store.register_all(globals().values(), __name__, (ClassIWantToRegisterExplicitly,))

    So you get partially automatic registration, keeping manual registration
    for some object (to use
    :meth:`~logilab.common.registry.RegistryStore.register_and_replace` for
    instance).

### register(self, obj, registryname=None, oid=None, clear=False)

source code

    register `obj` implementation into `registryname` or
    `obj.__registries__` if not specified, with identifier `oid` or
    `obj.__regid__` if not specified.

    If `clear` is true, all objects with the same identifier will be
    previously unregistered.

### register_and_replace(self, obj, replaced, registryname=None)

source code

    register `obj` object into `registryname` or
    `obj.__registries__` if not specified. If found, the `replaced` object
    will be unregistered first (else a warning will be issued as it is
    generally unexpected).

### init_registration(self, path, extrapath=None)

source code

    reset registry and walk down path to return list of (path, name)
    file modules to be loaded

### register_objects(self, path, extrapath=None)

source code

    register all objects found walking down <path>

Decorators:
  - `@deprecated('use register_modnames() instead')`

### is_reload_needed(self, path)

source code

    return True if something module changed and the registry should be
    reloaded

### load_module(self, module)

source code

    Automatically handle module objects registration.

    Instances are registered as soon as they are hashable and have the
    following attributes:

    * __regid__ (a string)
    * __select__ (a callable)
    * __registries__ (a tuple/list of string)

    For classes this is a bit more complicated :

    - first ensure parent classes are already registered

    - class with __abstract__ == True in their local dictionary are skipped

    - object class needs to have registries and identifier properly set to a
      non empty string to be registered.

### is_registrable(cls, obj)
Class Method

source code

    ensure `obj` should be registered

    as arbitrary stuff may be registered, do a lot of check and warn about
    weird cases (think to dumb proxy objects)