You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by jo...@apache.org on 2012/10/29 21:10:46 UTC

[7/25] git commit: [#5193] Replaced implementation of CaseInsensitiveDict with one based on ABC

[#5193] Replaced implementation of CaseInsensitiveDict with one based on ABC

Signed-off-by: Cory Johns <jo...@geek.net>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/04fb3cb9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/04fb3cb9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/04fb3cb9

Branch: refs/heads/cj/5076
Commit: 04fb3cb9bd93038833ccd10e78e66facdd506787
Parents: c11f794
Author: Cory Johns <jo...@geek.net>
Authored: Mon Oct 29 16:56:09 2012 +0000
Committer: Cory Johns <jo...@geek.net>
Committed: Mon Oct 29 16:56:09 2012 +0000

----------------------------------------------------------------------
 Allura/allura/lib/utils.py        |   56 ++++++++++++++++----------------
 Allura/allura/tests/test_utils.py |    5 +--
 2 files changed, 30 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/04fb3cb9/Allura/allura/lib/utils.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/utils.py b/Allura/allura/lib/utils.py
index 285cbfb..285e7e4 100644
--- a/Allura/allura/lib/utils.py
+++ b/Allura/allura/lib/utils.py
@@ -11,6 +11,7 @@ import mimetypes
 import re
 import magic
 from itertools import groupby
+import collections
 
 import tg
 import pylons
@@ -348,44 +349,43 @@ class TruthyCallable(object):
     def __nonzero__(self):
         return self.callable()
 
-class CaseInsensitiveDict(dict):
+
+class TransformedDict(collections.MutableMapping):
+    """
+    A dictionary which applies an arbitrary
+    key-altering function before accessing the keys.
+
+    From: http://stackoverflow.com/questions/3387691/python-how-to-perfectly-override-a-dict
+    """
 
     def __init__(self, *args, **kwargs):
-        super(CaseInsensitiveDict, self).__init__(*args, **kwargs)
-        self._reindex()
+        self.store = dict()
+        self.update(dict(*args, **kwargs)) # use the free update to set keys
+
+    def __getitem__(self, key):
+        return self.store[self.__keytransform__(key)]
+
+    def __setitem__(self, key, value):
+        self.store[self.__keytransform__(key)] = value
 
-    def _reindex(self):
-        items = self.items()
-        self.clear()
-        self._index = {}
-        for k,v in items:
-            self[k] = v
-        assert len(self) == len(items), 'Duplicate (case-insensitive) key'
+    def __delitem__(self, key):
+        del self.store[self.__keytransform__(key)]
 
-    def __getitem__(self, name):
-        return super(CaseInsensitiveDict, self).__getitem__(name.lower())
+    def __iter__(self):
+        return iter(self.store)
 
-    def __setitem__(self, name, value):
-        lname = name.lower()
-        super(CaseInsensitiveDict, self).__setitem__(lname, value)
-        self._index[lname] = name
+    def __len__(self):
+        return len(self.store)
 
-    def __delitem__(self, name):
-        super(CaseInsensitiveDict, self).__delitem__(name.lower())
+    def __keytransform__(self, key):
+        return key
 
-    def __contains__(self, name):
-        return super(CaseInsensitiveDict, self).__contains__(name.lower())
 
-    def pop(self, k, *args):
-        return super(CaseInsensitiveDict, self).pop(k.lower(), *args)
+class CaseInsensitiveDict(TransformedDict):
 
-    def popitem(self):
-        k,v = super(CaseInsensitiveDict, self).popitem()
-        return self._index[k], v
+    def __keytransform__(self, key):
+        return key.lower()
 
-    def update(self, *args, **kwargs):
-        super(CaseInsensitiveDict, self).update(*args, **kwargs)
-        self._reindex()
 
 def postmortem_hook(etype, value, tb): # pragma no cover
     import sys, pdb, traceback

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/04fb3cb9/Allura/allura/tests/test_utils.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_utils.py b/Allura/allura/tests/test_utils.py
index 69f26c6..62a01b8 100644
--- a/Allura/allura/tests/test_utils.py
+++ b/Allura/allura/tests/test_utils.py
@@ -111,12 +111,11 @@ class TestCaseInsensitiveDict(unittest.TestCase):
         assert d['bar'] == d['Bar'] == 6
         d['bar'] = 7
         assert d['bar'] == d['bAr'] == 7
-        self.assertRaises(AssertionError, utils.CaseInsensitiveDict, foo=1, Foo=2)
         del d['bar']
         assert len(d) == 1, d
-        assert d.popitem() == ('Foo', 5)
-        self.assertRaises(AssertionError, d.update, foo=1, Foo=2)
+        assert d.get('foo') == 5
         d.update(foo=1, Bar=2)
+        assert d.get('FOO') == 1
         assert d == dict(foo=1, bar=2)
         assert d != dict(Foo=1, bar=2)
         assert d == utils.CaseInsensitiveDict(Foo=1, bar=2)