From bd5861251490758e189d6d657de4683897024c70 Mon Sep 17 00:00:00 2001 From: Aymeric Augustin Date: Thu, 9 Feb 2012 18:41:20 +0000 Subject: [PATCH] Fixed #17634 -- Optimized the performance of MultiValueDict by using append instead of copy and by minimizing the number of dict lookups. Refs #736. git-svn-id: http://code.djangoproject.com/svn/django/trunk@17464 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/utils/datastructures.py | 21 +++++++++++-------- tests/regressiontests/utils/datastructures.py | 6 ++++++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py index 46f705f747..09d37518e0 100644 --- a/django/utils/datastructures.py +++ b/django/utils/datastructures.py @@ -312,9 +312,9 @@ class MultiValueDict(dict): try: return super(MultiValueDict, self).__getitem__(key) except KeyError: - if default is not None: - return default - return [] + if default is None: + return [] + return default def setlist(self, key, list_): super(MultiValueDict, self).__setitem__(key, list_) @@ -322,17 +322,20 @@ class MultiValueDict(dict): def setdefault(self, key, default=None): if key not in self: self[key] = default + return default return self[key] - def setlistdefault(self, key, default_list=()): + def setlistdefault(self, key, default_list=None): if key not in self: + if default_list is None: + default_list = [] self.setlist(key, default_list) + return default_list return self.getlist(key) def appendlist(self, key, value): """Appends an item to the internal list associated with key.""" - self.setlistdefault(key, []) - super(MultiValueDict, self).__setitem__(key, self.getlist(key) + [value]) + self.setlistdefault(key).append(value) def items(self): """ @@ -381,15 +384,15 @@ class MultiValueDict(dict): other_dict = args[0] if isinstance(other_dict, MultiValueDict): for key, value_list in other_dict.lists(): - self.setlistdefault(key, []).extend(value_list) + self.setlistdefault(key).extend(value_list) else: try: for key, value in other_dict.items(): - self.setlistdefault(key, []).append(value) + self.setlistdefault(key).append(value) except TypeError: raise ValueError("MultiValueDict.update() takes either a MultiValueDict or dictionary") for key, value in kwargs.iteritems(): - self.setlistdefault(key, []).append(value) + self.setlistdefault(key).append(value) def dict(self): """ diff --git a/tests/regressiontests/utils/datastructures.py b/tests/regressiontests/utils/datastructures.py index aaac9ba477..d6db991007 100644 --- a/tests/regressiontests/utils/datastructures.py +++ b/tests/regressiontests/utils/datastructures.py @@ -206,6 +206,12 @@ class MultiValueDictTests(SimpleTestCase): self.assertEqual(list(d.itervalues()), ['Developer', 'Simon', 'Willison']) + def test_appendlist(self): + d = MultiValueDict() + d.appendlist('name', 'Adrian') + d.appendlist('name', 'Simon') + self.assertEqual(d.getlist('name'), ['Adrian', 'Simon']) + def test_copy(self): for copy_func in [copy.copy, lambda d: d.copy()]: d1 = MultiValueDict({