structures: little bit more general, lower-key-caching version of CaseInsensitiveDict
authorGulácsi Tamás <gt-waterhouse@gthomas.homelinux.org>
Sat, 23 Jul 2011 20:16:12 +0000 (22:16 +0200)
committerGulácsi Tamás <gt-waterhouse@gthomas.homelinux.org>
Sat, 23 Jul 2011 20:16:12 +0000 (22:16 +0200)
requests/structures.py

index bfee7b1..b23b72b 100644 (file)
@@ -9,20 +9,39 @@ Datastructures that power Requests.
 """
 
 class CaseInsensitiveDict(dict):
-    """Case-insensitive Dictionary for :class:`Response <models.Response>` Headers.
+    """Case-insensitive Dictionary
 
     For example, ``headers['content-encoding']`` will return the
     value of a ``'Content-Encoding'`` response header."""
 
-    def _lower_keys(self):
-        return map(str.lower, self.keys())
+    @property
+    def lower_keys(self):
+        if not hasattr(self, '_lower_keys') or not self._lower_keys:
+            self._lower_keys = dict((k.lower(), k) for k in self.iterkeys())
+        return self._lower_keys
 
+    def _clear_lower_keys(self):
+        if hasattr(self, '_lower_keys'):
+            self._lower_keys.clear()
 
-    def __contains__(self, key):
-        return key.lower() in self._lower_keys()
+    def __setitem__(self, key, value):
+        dict.__setitem__(self, key, value)
+        self._clear_lower_keys()
+
+    def __delitem__(self, key):
+        dict.__delitem__(self, key, value)
+        self._lower_keys.clear()
 
+    def __contains__(self, key):
+        return key.lower() in self.lower_keys
 
     def __getitem__(self, key):
         # We allow fall-through here, so values default to None
         if key in self:
-            return self.items()[self._lower_keys().index(key.lower())][1]
+            return dict.__getitem__(self, self.lower_keys[key.lower()])
+
+    def get(self, key, default=None):
+        if key in self:
+            return self[key]
+        else:
+            return default