From caa0523cb8afc19fbbe193b8488eed810dc35829 Mon Sep 17 00:00:00 2001 From: Malcolm Tredinnick Date: Thu, 29 Nov 2007 20:09:54 +0000 Subject: [PATCH] Fixed #6050 -- Handled edge-case of duplicate keys being passed when initialising SortedDict. Patch from Collin Grady and SmileyChris. git-svn-id: http://code.djangoproject.com/svn/django/trunk@6751 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/utils/datastructures.py | 5 +- tests/regressiontests/utils/datastructures.py | 51 +++++++++++++++++++ tests/regressiontests/utils/tests.py | 13 +++-- tests/regressiontests/utils/timesince.py | 2 +- 4 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 tests/regressiontests/utils/datastructures.py diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py index ffdc73f922..ee156b11d0 100644 --- a/django/utils/datastructures.py +++ b/django/utils/datastructures.py @@ -60,7 +60,10 @@ class SortedDict(dict): if isinstance(data, dict): self.keyOrder = data.keys() else: - self.keyOrder = [key for key, value in data] + self.keyOrder = [] + for key, value in data: + if key not in self.keyOrder: + self.keyOrder.append(key) def __deepcopy__(self, memo): from copy import deepcopy diff --git a/tests/regressiontests/utils/datastructures.py b/tests/regressiontests/utils/datastructures.py new file mode 100644 index 0000000000..52bf81a9e0 --- /dev/null +++ b/tests/regressiontests/utils/datastructures.py @@ -0,0 +1,51 @@ +""" +>>> from django.utils.datastructures import SortedDict + +>>> d = SortedDict() +>>> d[7] = 'seven' +>>> d[1] = 'one' +>>> d[9] = 'nine' +>>> d.keys() +[7, 1, 9] +>>> d.values() +['seven', 'one', 'nine'] +>>> d.items() +[(7, 'seven'), (1, 'one'), (9, 'nine')] + +# Overwriting an item keeps it's place. +>>> d[1] = 'ONE' +>>> d.values() +['seven', 'ONE', 'nine'] + +# New items go to the end. +>>> d[0] = 'nil' +>>> d.keys() +[7, 1, 9, 0] + +# Deleting an item, then inserting the same key again will place it at the end. +>>> del d[7] +>>> d.keys() +[1, 9, 0] +>>> d[7] = 'lucky number 7' +>>> d.keys() +[1, 9, 0, 7] + +# Changing the keys won't do anything, it's only a copy of the keys dict. +>>> k = d.keys() +>>> k.remove(9) +>>> d.keys() +[1, 9, 0, 7] + +# Initialising a SortedDict with two keys will just take the first one. A real +# dict will actually take the second value so we will too, but we'll keep the +# ordering from the first key found. +>>> tuples = ((2, 'two'), (1, 'one'), (2, 'second-two')) +>>> d = SortedDict(tuples) +>>> d.keys() +[2, 1] +>>> real_dict = dict(tuples) +>>> real_dict.values() +['one', 'second-two'] +>>> d.values() +['second-two', 'one'] +""" \ No newline at end of file diff --git a/tests/regressiontests/utils/tests.py b/tests/regressiontests/utils/tests.py index eb3a722888..abcd7212d8 100644 --- a/tests/regressiontests/utils/tests.py +++ b/tests/regressiontests/utils/tests.py @@ -6,7 +6,14 @@ from unittest import TestCase from django.utils import html, checksums -from timesince import timesince_tests +import timesince +import datastructures + +# Extra tests +__test__ = { + 'timesince': timesince, + 'datastructures': datastructures, +} class TestUtilsHtml(TestCase): @@ -142,10 +149,6 @@ class TestUtilsChecksums(TestCase): for value, output in items: self.check_output(f, value, output) -__test__ = { - 'timesince_tests': timesince_tests, -} - if __name__ == "__main__": import doctest doctest.testmod() diff --git a/tests/regressiontests/utils/timesince.py b/tests/regressiontests/utils/timesince.py index 30200be6e9..4f304ec7f7 100644 --- a/tests/regressiontests/utils/timesince.py +++ b/tests/regressiontests/utils/timesince.py @@ -1,4 +1,4 @@ -timesince_tests = """ +""" >>> from datetime import datetime, timedelta >>> from django.utils.timesince import timesince