diff options
author | Jason Gerard DeRose <jderose@redhat.com> | 2008-08-01 06:44:30 +0000 |
---|---|---|
committer | Jason Gerard DeRose <jderose@redhat.com> | 2008-08-01 06:44:30 +0000 |
commit | 8881e4a543e9f1f1edda2d1cc935c020950214e6 (patch) | |
tree | 2c2fa9a4d9e5ca18728ea75a87fafcb10ab85b2a /ipalib/plugable.py | |
parent | 5eac2ea15fbef4fcd2f0a182e41bd4f6f5725d2a (diff) | |
download | freeipa.git-8881e4a543e9f1f1edda2d1cc935c020950214e6.tar.gz freeipa.git-8881e4a543e9f1f1edda2d1cc935c020950214e6.tar.xz freeipa.git-8881e4a543e9f1f1edda2d1cc935c020950214e6.zip |
38: dict interface of Registrar now works with both classes and strings as the key
Diffstat (limited to 'ipalib/plugable.py')
-rw-r--r-- | ipalib/plugable.py | 102 |
1 files changed, 97 insertions, 5 deletions
diff --git a/ipalib/plugable.py b/ipalib/plugable.py index e74809cd..9e94e96b 100644 --- a/ipalib/plugable.py +++ b/ipalib/plugable.py @@ -124,6 +124,83 @@ class Proxy(ReadOnly): return to_cli(self.name) +class NameSpace(ReadOnly): + """ + A read-only namespace of (key, value) pairs that can be accessed + both as instance attributes and as dictionary items. + """ + + def __init__(self, kw): + """ + The `kw` argument is a dict of the (key, value) pairs to be in this + NameSpace instance. The optional `order` keyword argument specifies + the order of the keys in this namespace; if omitted, the default is + to sort the keys in ascending order. + """ + assert isinstance(kw, dict) + self.__kw = dict(kw) + for (key, value) in self.__kw.items(): + assert not key.startswith('_') + setattr(self, key, value) + if order is None: + self.__keys = sorted(self.__kw) + else: + self.__keys = list(order) + assert set(self.__keys) == set(self.__kw) + self.__locked = True + + def __setattr__(self, name, value): + """ + Raises an exception if trying to set an attribute after the + NameSpace has been locked; otherwise calls object.__setattr__(). + """ + if self.__locked: + raise errors.SetError(name) + super(NameSpace, self).__setattr__(name, value) + + def __getitem__(self, key): + """ + Returns item from namespace named `key`. + """ + return self.__kw[key] + + def __hasitem__(self, key): + """ + Returns True if namespace has an item named `key`. + """ + return bool(key in self.__kw) + + def __iter__(self): + """ + Yields the names in this NameSpace in ascending order, or in the + the order specified in `order` kw arg. + + For example: + + >>> ns = NameSpace(dict(attr_b='world', attr_a='hello')) + >>> list(ns) + ['attr_a', 'attr_b'] + >>> [ns[k] for k in ns] + ['hello', 'world'] + """ + for key in self.__keys: + yield key + + def __call__(self): + """ + Iterates through the values in this NameSpace in the same order as + the keys. + """ + for key in self.__keys: + yield self.__kw[key] + + def __len__(self): + """ + Returns number of items in this NameSpace. + """ + return len(self.__keys) + + class Registrar(object): def __init__(self, *allowed): """ @@ -179,15 +256,30 @@ class Registrar(object): self.__registered.add(cls) sub_d[cls.__name__] = cls - def __getitem__(self, name): + def __getitem__(self, item): """ Returns a copy of the namespace dict of the base class named `name`. """ - return dict(self.__d[name]) + if inspect.isclass(item): + if item not in self.__allowed: + raise KeyError(repr(item)) + key = item.__name__ + else: + key = item + return dict(self.__d[key]) + + def __contains__(self, item): + """ + Returns True if a base class named `name` is in this Registrar. + """ + if inspect.isclass(item): + return item in self.__allowed + return item in self.__d def __iter__(self): """ - Iterates through the names of the allowed base classes. + Iterates through a (base, registered_plugins) tuple for each allowed + base. """ - for key in self.__d: - yield key + for base in self.__allowed: + yield (base, self.__d[base.__name__].values()) |