summaryrefslogtreecommitdiffstats
path: root/ipalib/plugable.py
diff options
context:
space:
mode:
authorJason Gerard DeRose <jderose@redhat.com>2008-08-15 01:24:51 +0000
committerJason Gerard DeRose <jderose@redhat.com>2008-08-15 01:24:51 +0000
commite43a5c642e1717c9309e8747e5433ab85abf2779 (patch)
tree1adb20f0dcf34ab21c08bc05eb100a0d4122e036 /ipalib/plugable.py
parentf6c2181eebf6e6bd794eaca8b78d3b35ad3be4e4 (diff)
downloadfreeipa-e43a5c642e1717c9309e8747e5433ab85abf2779.tar.gz
freeipa-e43a5c642e1717c9309e8747e5433ab85abf2779.tar.xz
freeipa-e43a5c642e1717c9309e8747e5433ab85abf2779.zip
171: MagicDict now subclasses from DictProxy; updated unit tests
Diffstat (limited to 'ipalib/plugable.py')
-rw-r--r--ipalib/plugable.py88
1 files changed, 31 insertions, 57 deletions
diff --git a/ipalib/plugable.py b/ipalib/plugable.py
index 0d8286a4..ba9b6973 100644
--- a/ipalib/plugable.py
+++ b/ipalib/plugable.py
@@ -123,6 +123,13 @@ def lock(readonly):
class SetProxy(ReadOnly):
+ """
+ A read-only proxy to an underlying set.
+
+ Although the underlying set cannot be changed through the SetProxy,
+ the set can change and is expected to (unless the underlying set is a
+ frozen set).
+ """
def __init__(self, s):
allowed = (set, frozenset, dict)
if type(s) not in allowed:
@@ -142,6 +149,9 @@ class SetProxy(ReadOnly):
class DictProxy(SetProxy):
+ """
+ A read-only proxy to an underlying dict.
+ """
def __init__(self, d):
if type(d) is not dict:
raise TypeError('%r is not %r' % (type(d), dict))
@@ -150,11 +160,31 @@ class DictProxy(SetProxy):
def __getitem__(self, key):
"""
- Returns the value
+ Returns the value corresponding to ``key``.
"""
return self.__d[key]
+class MagicDict(DictProxy):
+ """
+ A read-only dict whose items can also be accessed as attributes.
+
+ Although a MagicDict is read-only, the underlying dict can change (and is
+ assumed to).
+
+ One of these is created for each allowed base in a `Registrar` instance.
+ """
+
+ def __getattr__(self, name):
+ """
+ Returns the value corresponding to ``name``.
+ """
+ try:
+ return self[name]
+ except KeyError:
+ raise AttributeError('no attribute %r' % name)
+
+
class Plugin(ReadOnly):
"""
Base class for all plugins.
@@ -525,63 +555,7 @@ class NameSpace(ReadOnly):
return '%s(<%d members>)' % (self.__class__.__name__, len(self))
-class MagicDict(ReadOnly):
- """
- A read-only dict whose items can also be accessed as attributes.
-
- Although a MagicDict is read-only, the underlying dict can change (and is
- assumed to).
- One of these is created for each allowed base in a `Registrar` instance.
- """
- def __init__(self, d):
- """
- :param d: The ``dict`` instance to proxy.
- """
- assert type(d) is dict, '`d` must be %r, got %r' % (dict, type(d))
- self.__d = d
- lock(self)
-
- def __len__(self):
- """
- Returns number of items in underlying ``dict``.
- """
- return len(self.__d)
-
- def __iter__(self):
- """
- Iterates through keys of underlying ``dict`` in ascending order.
- """
- for name in sorted(self.__d):
- yield name
-
- def __contains__(self, key):
- """
- Returns True if underlying dict contains ``key``, False otherwise.
-
- :param key: The key to query upon.
- """
- return key in self.__d
-
- def __getitem__(self, key):
- """
- Returns value from underlying dict corresponding to ``key``.
-
- :param key: The key of the value to retrieve.
- """
- if key in self.__d:
- return self.__d[key]
- raise KeyError('no item at key %r' % key)
-
- def __getattr__(self, name):
- """
- Returns value from underlying dict corresponding to ``name``.
-
- :param name: The name of the attribute to retrieve.
- """
- if name in self.__d:
- return self.__d[name]
- raise AttributeError('no attribute %r' % name)
class Registrar(ReadOnly):