summaryrefslogtreecommitdiffstats
path: root/ipalib
diff options
context:
space:
mode:
authorJason Gerard DeRose <jderose@redhat.com>2008-09-18 20:35:23 +0000
committerJason Gerard DeRose <jderose@redhat.com>2008-09-18 20:35:23 +0000
commit84a721d408c307add34440b7a68a9c7a858c52e3 (patch)
tree3f3589ddf4d3daa20e9c1c584086538b9d4776a7 /ipalib
parentf78f3ed0ddd409d8cf5fcfe28fe9062ab610b432 (diff)
downloadfreeipa-84a721d408c307add34440b7a68a9c7a858c52e3.tar.gz
freeipa-84a721d408c307add34440b7a68a9c7a858c52e3.tar.xz
freeipa-84a721d408c307add34440b7a68a9c7a858c52e3.zip
294: NameSpace no longer subclasses from DictProxy; NameSpace.__getitem__() now works with int and slice objects
Diffstat (limited to 'ipalib')
-rw-r--r--ipalib/plugable.py65
-rw-r--r--ipalib/tests/test_plugable.py2
2 files changed, 50 insertions, 17 deletions
diff --git a/ipalib/plugable.py b/ipalib/plugable.py
index 66e5fada..88b60a2b 100644
--- a/ipalib/plugable.py
+++ b/ipalib/plugable.py
@@ -473,7 +473,7 @@ def check_name(name):
return name
-class NameSpace(DictProxy):
+class NameSpace(ReadOnly):
"""
A read-only namespace with handy container behaviours.
@@ -523,36 +523,69 @@ class NameSpace(DictProxy):
:param members: An iterable providing the members.
:param sort: Whether to sort the members by member name.
"""
- self.__members = tuple(members)
self.__sort = check_type(sort, bool, 'sort')
- names = (m.name for m in self.__members)
if self.__sort:
- self.__names = tuple(sorted(names))
+ self.__members = tuple(sorted(members, key=lambda m: m.name))
else:
- self.__names = tuple(names)
- super(NameSpace, self).__init__(
- dict(self.__member_iter())
- )
-
- def __member_iter(self):
- """
- Helper method called only from `NameSpace.__init__()`.
- """
+ self.__members = tuple(members)
+ self.__names = tuple(m.name for m in self.__members)
+ self.__map = dict()
for member in self.__members:
name = check_name(member.name)
+ assert name not in self.__map, 'already has key %r' % name
+ self.__map[name] = member
assert not hasattr(self, name), 'already has attribute %r' % name
setattr(self, name, member)
- yield (name, member)
+ lock(self)
+
+ def __len__(self):
+ """
+ Returns the number of members.
+ """
+ return len(self.__members)
def __iter__(self):
"""
- Iterates through member names.
+ Iterates through the member names.
- In this instance was created with ``sort=True``,
+ If this instance was created with ``sort=True``, the names will be in
+ alphabetical order; otherwise the names will be in the same order as
+ the members were passed to the constructor.
"""
for name in self.__names:
yield name
+ def __call__(self):
+ """
+ Iterates through the members.
+
+ If this instance was created with ``sort=True``, the members will be
+ in alphabetical order by name; otherwise the members will be in the
+ same order as they were passed to the constructor.
+ """
+ for member in self.__members:
+ yield member
+
+ def __contains__(self, name):
+ """
+ Returns True if namespace has a member named ``name``.
+ """
+ return name in self.__map
+
+ def __getitem__(self, spec):
+ """
+ Returns a member by name or index, or returns a slice of members.
+
+ :param spec: The name or index of a member, or a slice object.
+ """
+ if type(spec) is str:
+ return self.__map[spec]
+ if type(spec) in (int, slice):
+ return self.__members[spec]
+ raise TypeError(
+ 'spec: must be %r, %r, or %r; got %r' % (str, int, slice, spec)
+ )
+
def __repr__(self):
"""
Returns a pseudo-valid expression that could create this instance.
diff --git a/ipalib/tests/test_plugable.py b/ipalib/tests/test_plugable.py
index 62a78e36..b4461dee 100644
--- a/ipalib/tests/test_plugable.py
+++ b/ipalib/tests/test_plugable.py
@@ -569,7 +569,7 @@ class test_NameSpace(ClassChecker):
_cls = plugable.NameSpace
def test_class(self):
- assert self.cls.__bases__ == (plugable.DictProxy,)
+ assert self.cls.__bases__ == (plugable.ReadOnly,)
def test_init(self):
"""