diff options
Diffstat (limited to 'paste/util/multidict.py')
-rw-r--r-- | paste/util/multidict.py | 68 |
1 files changed, 50 insertions, 18 deletions
diff --git a/paste/util/multidict.py b/paste/util/multidict.py index d3eb1e9..701d1ac 100644 --- a/paste/util/multidict.py +++ b/paste/util/multidict.py @@ -2,8 +2,15 @@ # Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php import cgi import copy +import six import sys -from UserDict import DictMixin + +try: + # Python 3 + from collections import MutableMapping as DictMixin +except ImportError: + # Python 2 + from UserDict import DictMixin class MultiDict(DictMixin): @@ -19,15 +26,15 @@ class MultiDict(DictMixin): "MultiDict can only be called with one positional argument") if args: if hasattr(args[0], 'iteritems'): - items = list(args[0].iteritems()) + items = args[0].iteritems() elif hasattr(args[0], 'items'): items = args[0].items() else: - items = list(args[0]) - self._items = items + items = args[0] + self._items = list(items) else: self._items = [] - self._items.extend(kw.iteritems()) + self._items.extend(six.iteritems(kw)) def __getitem__(self, key): for k, v in self._items: @@ -54,7 +61,7 @@ class MultiDict(DictMixin): """ result = [] for k, v in self._items: - if key == k: + if type(key) == type(k) and key == k: result.append(v) return result @@ -110,7 +117,7 @@ class MultiDict(DictMixin): items = self._items found = False for i in range(len(items)-1, -1, -1): - if items[i][0] == key: + if type(items[i][0]) == type(key) and items[i][0] == key: del items[i] found = True if not found: @@ -118,7 +125,7 @@ class MultiDict(DictMixin): def __contains__(self, key): for k, v in self._items: - if k == key: + if type(k) == type(key) and k == key: return True return False @@ -139,10 +146,10 @@ class MultiDict(DictMixin): def pop(self, key, *args): if len(args) > 1: - raise TypeError, "pop expected at most 2 arguments, got "\ - + repr(1 + len(args)) + raise TypeError("pop expected at most 2 arguments, got " + + repr(1 + len(args))) for i in range(len(self._items)): - if self._items[i][0] == key: + if type(self._items[i][0]) == type(key) and self._items[i][0] == key: v = self._items[i][1] del self._items[i] return v @@ -226,6 +233,20 @@ class UnicodeMultiDict(DictMixin): self.encoding = encoding self.errors = errors self.decode_keys = decode_keys + if self.decode_keys: + items = self.multi._items + for index, item in enumerate(items): + key, value = item + key = self._encode_key(key) + items[index] = (key, value) + + def _encode_key(self, key): + if self.decode_keys: + try: + key = key.encode(self.encoding, self.errors) + except AttributeError: + pass + return key def _decode_key(self, key): if self.decode_keys: @@ -245,9 +266,10 @@ class UnicodeMultiDict(DictMixin): if isinstance(value, cgi.FieldStorage): # decode FieldStorage's field name and filename value = copy.copy(value) - if self.decode_keys: + if self.decode_keys and isinstance(value.name, six.binary_type): value.name = value.name.decode(self.encoding, self.errors) - value.filename = value.filename.decode(self.encoding, self.errors) + if six.PY2: + value.filename = value.filename.decode(self.encoding, self.errors) else: try: value = value.decode(self.encoding, self.errors) @@ -256,21 +278,25 @@ class UnicodeMultiDict(DictMixin): return value def __getitem__(self, key): + key = self._encode_key(key) return self._decode_value(self.multi.__getitem__(key)) def __setitem__(self, key, value): + key = self._encode_key(key) self.multi.__setitem__(key, value) def add(self, key, value): """ Add the key and value, not overwriting any previous value. """ + key = self._encode_key(key) self.multi.add(key, value) def getall(self, key): """ Return a list of all values matching the key (may be an empty list) """ + key = self._encode_key(key) return [self._decode_value(v) for v in self.multi.getall(key)] def getone(self, key): @@ -278,6 +304,7 @@ class UnicodeMultiDict(DictMixin): Get one value matching the key, raising a KeyError if multiple values were found. """ + key = self._encode_key(key) return self._decode_value(self.multi.getone(key)) def mixed(self): @@ -289,7 +316,7 @@ class UnicodeMultiDict(DictMixin): request. """ unicode_mixed = {} - for key, value in self.multi.mixed().iteritems(): + for key, value in six.iteritems(self.multi.mixed()): if isinstance(value, list): value = [self._decode_value(value) for value in value] else: @@ -303,15 +330,17 @@ class UnicodeMultiDict(DictMixin): list of values. """ unicode_dict = {} - for key, value in self.multi.dict_of_lists().iteritems(): + for key, value in six.iteritems(self.multi.dict_of_lists()): value = [self._decode_value(value) for value in value] unicode_dict[self._decode_key(key)] = value return unicode_dict def __delitem__(self, key): + key = self._encode_key(key) self.multi.__delitem__(key) def __contains__(self, key): + key = self._encode_key(key) return self.multi.__contains__(key) has_key = __contains__ @@ -320,12 +349,15 @@ class UnicodeMultiDict(DictMixin): self.multi.clear() def copy(self): - return UnicodeMultiDict(self.multi.copy(), self.encoding, self.errors) + return UnicodeMultiDict(self.multi.copy(), self.encoding, self.errors, + decode_keys=self.decode_keys) def setdefault(self, key, default=None): + key = self._encode_key(key) return self._decode_value(self.multi.setdefault(key, default)) def pop(self, key, *args): + key = self._encode_key(key) return self._decode_value(self.multi.pop(key, *args)) def popitem(self): @@ -354,10 +386,10 @@ class UnicodeMultiDict(DictMixin): def items(self): return [(self._decode_key(k), self._decode_value(v)) for \ - k, v in self.multi.iteritems()] + k, v in six.iteritems(self.multi)] def iteritems(self): - for k, v in self.multi.iteritems(): + for k, v in six.iteritems(self.multi): yield (self._decode_key(k), self._decode_value(v)) def values(self): |