Mercurial > moin > 2.0
view MoinMoin/util/registry.py @ 1613:bc8a2546468b
Clean up registry code.
Quite some boilerplate codes were removed. The signature of several `_factory`
and `Entry.__call__` were changed a bit as well to make things a bit more
uniform.
author | Cheer Xiao <xiaqqaix@gmail.com> |
---|---|
date | Wed, 01 Aug 2012 00:21:03 +0800 |
parents | 4ac437141bbe |
children | ee404f81afe9 |
line wrap: on
line source
# Copyright: 2008-2010 MoinMoin:BastianBlank # License: GNU GPL v2 (or any later version), see LICENSE.txt for details. """ MoinMoin - Module registry Every module registers a factory for itself at the registry with a given priority. During the lookup each factory is called with the given arguments and can return a callable to consider itself as a match. """ from collections import namedtuple class RegistryBase(object): PRIORITY_REALLY_FIRST = -20 PRIORITY_FIRST = -10 PRIORITY_MIDDLE = 0 PRIORITY_LAST = 10 PRIORITY_REALLY_LAST = 20 class Entry(namedtuple('Entry', 'factory priority')): def __call__(self, *args, **kw): return self.factory(*args, **kw) def __lt__(self, other): if isinstance(other, self.__class__): return self.priority < other.priority return NotImplemented def __init__(self): self._entries = [] def __repr__(self): return '<{0}: {1!r}>'.format(self.__class__.__name__, self._entries) def get(self, *args, **kw): """ Lookup a matching module Each registered factory is called with the given arguments and the first matching wins. """ for entry in self._entries: conv = entry(*args, **kw) if conv is not None: return conv def _register(self, entry): if entry not in self._entries: entries = self._entries[:] for i in xrange(len(entries)): if entry < entries[i]: entries.insert(i, entry) break else: entries.append(entry) self._entries = entries def unregister(self, factory): """ Unregister a factory :param factory: Factory to unregister """ old_entries = self._entries entries = [i for i in old_entries if not i.factory is factory] if len(old_entries) == len(entries): # TODO: Is this necessary? raise ValueError self._entries = entries class Registry(RegistryBase): def register(self, factory, priority=RegistryBase.PRIORITY_MIDDLE): """ Register a factory :param factory: Factory to register. Callable, have to return a class """ return self._register(self.Entry(factory, priority))