From 3ff5b993d361b4a0c8903022d7e894b99696657d Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Tue, 28 Mar 2006 17:31:04 +0000 Subject: [PATCH] Fixed #1539 in trunk git-svn-id: http://code.djangoproject.com/svn/django/trunk@2578 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/utils/datastructures.py | 21 +++++++++++++-------- django/utils/httpwrappers.py | 29 ++++++++++++++++++----------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py index 8716c9cc3f..20aa30bcff 100644 --- a/django/utils/datastructures.py +++ b/django/utils/datastructures.py @@ -80,9 +80,19 @@ class MultiValueDict(dict): except IndexError: return [] - def _setitem_list(self, key, value): + def __setitem__(self, key, value): dict.__setitem__(self, key, [value]) - __setitem__ = _setitem_list + + def __copy__(self): + return self.__class__(dict.items(self)) + + def __deepcopy__(self, memo={}): + import copy + result = self.__class__() + memo[id(self)] = result + for key, value in dict.items(self): + dict.__setitem__(result, copy.deepcopy(key, memo), copy.deepcopy(value, memo)) + return result def get(self, key, default=None): "Returns the default value if the requested data doesn't exist" @@ -136,12 +146,7 @@ class MultiValueDict(dict): def copy(self): "Returns a copy of this object." - import copy - # Our custom __setitem__ must be disabled for copying machinery. - MultiValueDict.__setitem__ = dict.__setitem__ - cp = copy.deepcopy(self) - MultiValueDict.__setitem__ = MultiValueDict._setitem_list - return cp + return self.__deepcopy__() def update(self, other_dict): "update() extends rather than replaces existing key lists." diff --git a/django/utils/httpwrappers.py b/django/utils/httpwrappers.py index 6fda8ad570..8716505f2e 100644 --- a/django/utils/httpwrappers.py +++ b/django/utils/httpwrappers.py @@ -66,21 +66,34 @@ def parse_file_upload(header_dict, post_data): class QueryDict(MultiValueDict): """A specialized MultiValueDict that takes a query string when initialized. This is immutable unless you create a copy of it.""" - def __init__(self, query_string): + def __init__(self, query_string, mutable=False): MultiValueDict.__init__(self) self._mutable = True for key, value in parse_qsl((query_string or ''), True): # keep_blank_values=True self.appendlist(key, value) - self._mutable = False + self._mutable = mutable def _assert_mutable(self): if not self._mutable: raise AttributeError, "This QueryDict instance is immutable" - def _setitem_if_mutable(self, key, value): + def __setitem__(self, key, value): self._assert_mutable() MultiValueDict.__setitem__(self, key, value) - __setitem__ = _setitem_if_mutable + + def __copy__(self): + result = self.__class__('', mutable=True) + for key, value in dict.items(self): + dict.__setitem__(result, key, value) + return result + + def __deepcopy__(self, memo={}): + import copy + result = self.__class__('', mutable=True) + memo[id(self)] = result + for key, value in dict.items(self): + dict.__setitem__(result, copy.deepcopy(key, memo), copy.deepcopy(value, memo)) + return result def setlist(self, key, list_): self._assert_mutable() @@ -112,13 +125,7 @@ class QueryDict(MultiValueDict): def copy(self): "Returns a mutable copy of this object." - import copy - # Our custom __setitem__ must be disabled for copying machinery. - QueryDict.__setitem__ = dict.__setitem__ - cp = copy.deepcopy(self) - QueryDict.__setitem__ = QueryDict._setitem_if_mutable - cp._mutable = True - return cp + return self.__deepcopy__() def urlencode(self): output = []