summaryrefslogtreecommitdiffstats
path: root/ipapython
diff options
context:
space:
mode:
authorPetr Viktorin <pviktori@redhat.com>2013-02-05 10:24:46 -0500
committerPetr Viktorin <pviktori@redhat.com>2013-09-25 10:13:56 +0200
commit0226064baced57f09b899370752c63cce8009b61 (patch)
tree89e0cb981f255e4c4c1ca47ff6258742382d1621 /ipapython
parent468e5e40ccc9251cdb6b2d1ad95e32dc588be332 (diff)
downloadfreeipa-0226064baced57f09b899370752c63cce8009b61.tar.gz
freeipa-0226064baced57f09b899370752c63cce8009b61.tar.xz
freeipa-0226064baced57f09b899370752c63cce8009b61.zip
Add missing dict methods to CIDict
Make the CIDict interface match standard dict (except view* methods). Add __contains__, __iter__, clear. Add keyword and iterable support for __init__, update. Also add values() and itervalues(). Previously the dict versions were used; the new ones guarantee that the order matches keys(). Mark view* methods as not implemented. CIDict.copy() now returns a CIDict. Test the above additions, and fromkeys() which worked but wasn't tested.
Diffstat (limited to 'ipapython')
-rw-r--r--ipapython/ipautil.py67
1 files changed, 49 insertions, 18 deletions
diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index 92569c3b4..c5b47f5b4 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -444,10 +444,13 @@ class CIDict(dict):
If you extend UserDict, isinstance(foo, dict) returns false.
"""
- def __init__(self, default=None):
+ def __init__(self, default=None, **kwargs):
super(CIDict, self).__init__()
- self._keys = {}
- self.update(default or {})
+ self._keys = {} # mapping of lowercased keys to proper case
+ if default:
+ self.update(default)
+ if kwargs:
+ self.update(kwargs)
def __getitem__(self, key):
return super(CIDict, self).__getitem__(key.lower())
@@ -460,11 +463,22 @@ class CIDict(dict):
def __delitem__(self, key):
lower_key = key.lower()
del self._keys[lower_key]
- return super(CIDict, self).__delitem__(key.lower())
+ return super(CIDict, self).__delitem__(lower_key)
+
+ def update(self, new=None, **kwargs):
+ if new:
+ try:
+ keys = new.keys
+ except AttributeError:
+ self.update(dict(new))
+ else:
+ for key in keys():
+ self[key] = new[key]
+ for key, value in kwargs.iteritems():
+ self[key] = value
- def update(self, dict):
- for key in dict.keys():
- self[key] = dict[key]
+ def __contains__(self, key):
+ return super(CIDict, self).__contains__(key.lower())
def has_key(self, key):
return super(CIDict, self).has_key(key.lower())
@@ -475,26 +489,30 @@ class CIDict(dict):
except KeyError:
return failobj
+ def __iter__(self):
+ return self._keys.itervalues()
+
def keys(self):
- return self._keys.values()
+ return list(self.iterkeys())
def items(self):
- result = []
- for k in self._keys.values():
- result.append((k, self[k]))
- return result
+ return list(self.iteritems())
+
+ def values(self):
+ return list(self.itervalues())
def copy(self):
- copy = {}
- for k in self._keys.values():
- copy[k] = self[k]
- return copy
+ """Returns a shallow copy of this CIDict"""
+ return CIDict(self.items())
def iteritems(self):
- return self.copy().iteritems()
+ return ((k, self[k]) for k in self._keys.itervalues())
def iterkeys(self):
- return self.copy().iterkeys()
+ return self._keys.itervalues()
+
+ def itervalues(self):
+ return (v for k, v in self.iteritems())
def setdefault(self, key, value=None):
try:
@@ -520,6 +538,19 @@ class CIDict(dict):
return (key, value)
+ def clear(self):
+ self._keys.clear()
+ return super(CIDict, self).clear()
+
+ def viewitems(self):
+ raise NotImplementedError('CIDict.viewitems is not implemented')
+
+ def viewkeys(self):
+ raise NotImplementedError('CIDict.viewkeys is not implemented')
+
+ def viewvvalues(self):
+ raise NotImplementedError('CIDict.viewvvalues is not implemented')
+
class GeneralizedTimeZone(datetime.tzinfo):
"""This class is a basic timezone wrapper for the offset specified