Browse Source

Removed django.utils.datastructures.SortedDict per deprecation timeline.

Tim Graham 10 years ago
parent
commit
c820892eed

+ 0 - 125
django/utils/datastructures.py

@@ -1,132 +1,7 @@
 import copy
-import warnings
 from collections import OrderedDict
 
 from django.utils import six
-from django.utils.deprecation import RemovedInDjango19Warning
-
-
-class SortedDict(dict):
-    """
-    A dictionary that keeps its keys in the order in which they're inserted.
-    """
-    def __new__(cls, *args, **kwargs):
-        instance = super(SortedDict, cls).__new__(cls, *args, **kwargs)
-        instance.keyOrder = []
-        return instance
-
-    def __init__(self, data=None):
-        warnings.warn(
-            "SortedDict is deprecated and will be removed in Django 1.9.",
-            RemovedInDjango19Warning, stacklevel=2
-        )
-        if data is None or isinstance(data, dict):
-            data = data or []
-            super(SortedDict, self).__init__(data)
-            self.keyOrder = list(data) if data else []
-        else:
-            super(SortedDict, self).__init__()
-            super_set = super(SortedDict, self).__setitem__
-            for key, value in data:
-                # Take the ordering from first key
-                if key not in self:
-                    self.keyOrder.append(key)
-                # But override with last value in data (dict() does this)
-                super_set(key, value)
-
-    def __deepcopy__(self, memo):
-        return self.__class__([(key, copy.deepcopy(value, memo))
-                               for key, value in self.items()])
-
-    def __copy__(self):
-        # The Python's default copy implementation will alter the state
-        # of self. The reason for this seems complex but is likely related to
-        # subclassing dict.
-        return self.copy()
-
-    def __setitem__(self, key, value):
-        if key not in self:
-            self.keyOrder.append(key)
-        super(SortedDict, self).__setitem__(key, value)
-
-    def __delitem__(self, key):
-        super(SortedDict, self).__delitem__(key)
-        self.keyOrder.remove(key)
-
-    def __iter__(self):
-        return iter(self.keyOrder)
-
-    def __reversed__(self):
-        return reversed(self.keyOrder)
-
-    def pop(self, k, *args):
-        result = super(SortedDict, self).pop(k, *args)
-        try:
-            self.keyOrder.remove(k)
-        except ValueError:
-            # Key wasn't in the dictionary in the first place. No problem.
-            pass
-        return result
-
-    def popitem(self):
-        result = super(SortedDict, self).popitem()
-        self.keyOrder.remove(result[0])
-        return result
-
-    def _iteritems(self):
-        for key in self.keyOrder:
-            yield key, self[key]
-
-    def _iterkeys(self):
-        for key in self.keyOrder:
-            yield key
-
-    def _itervalues(self):
-        for key in self.keyOrder:
-            yield self[key]
-
-    if six.PY3:
-        items = _iteritems
-        keys = _iterkeys
-        values = _itervalues
-    else:
-        iteritems = _iteritems
-        iterkeys = _iterkeys
-        itervalues = _itervalues
-
-        def items(self):
-            return [(k, self[k]) for k in self.keyOrder]
-
-        def keys(self):
-            return self.keyOrder[:]
-
-        def values(self):
-            return [self[k] for k in self.keyOrder]
-
-    def update(self, dict_):
-        for k, v in six.iteritems(dict_):
-            self[k] = v
-
-    def setdefault(self, key, default):
-        if key not in self:
-            self.keyOrder.append(key)
-        return super(SortedDict, self).setdefault(key, default)
-
-    def copy(self):
-        """Returns a copy of this object."""
-        # This way of initializing the copy means it works for subclasses, too.
-        return self.__class__(self)
-
-    def __repr__(self):
-        """
-        Replaces the normal dict.__repr__ with a version that returns the keys
-        in their sorted order.
-        """
-        return '{%s}' % ', '.join('%r: %r' % (k, v) for k, v in six.iteritems(self))
-
-    def clear(self):
-        super(SortedDict, self).clear()
-        self.keyOrder = []
 
 
 class OrderedSet(object):

+ 0 - 28
docs/ref/utils.txt

@@ -97,34 +97,6 @@ need to distinguish caches by the ``Accept-language`` header.
     cache, this just means that we have to build the response once to get at
     the Vary header and so at the list of headers to use for the cache key.
 
-``django.utils.datastructures``
-===============================
-
-.. module:: django.utils.datastructures
-   :synopsis: Data structures that aren't in Python's standard library.
-
-.. class:: SortedDict
-
-.. deprecated:: 1.7
-    ``SortedDict`` is deprecated and will be removed in Django 1.9. Use
-    :class:`collections.OrderedDict` instead.
-
-    The :class:`django.utils.datastructures.SortedDict` class is a dictionary
-    that keeps its keys in the order in which they're inserted.
-
-Creating a new SortedDict
--------------------------
-
-Creating a new ``SortedDict`` must be done in a way where ordering is
-guaranteed. For example::
-
-    SortedDict({'b': 1, 'a': 2, 'c': 3})
-
-will not work. Passing in a basic Python ``dict`` could produce unreliable
-results. Instead do::
-
-    SortedDict([('b', 1), ('a', 2), ('c', 3)])
-
 ``django.utils.dateparse``
 ==========================
 

+ 2 - 2
docs/releases/1.0-porting-guide.txt

@@ -714,12 +714,12 @@ Data structures
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 ``django.newforms.forms.SortedDictFromList`` was removed.
-:class:`django.utils.datastructures.SortedDict` can now be instantiated with
+``django.utils.datastructures.SortedDict`` can now be instantiated with
 a sequence of tuples.
 
 To update your code:
 
-1. Use :class:`django.utils.datastructures.SortedDict` wherever you were
+1. Use ``django.utils.datastructures.SortedDict`` wherever you were
    using ``django.newforms.forms.SortedDictFromList``.
 
 2. Because ``django.utils.datastructures.SortedDict.copy`` doesn't

+ 1 - 2
docs/releases/1.7.txt

@@ -1511,8 +1511,7 @@ Python versions, this module isn't useful anymore. It has been deprecated. Use
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 As :class:`~collections.OrderedDict` was added to the standard library in
-Python 2.7, :class:`~django.utils.datastructures.SortedDict` is no longer
-needed and has been deprecated.
+Python 2.7, ``SortedDict`` is no longer needed and has been deprecated.
 
 Custom SQL location for models package
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+ 1 - 1
docs/topics/python3.txt

@@ -181,7 +181,7 @@ versions of Python.
 
 :meth:`dict.keys`, :meth:`dict.items` and :meth:`dict.values` return lists in
 Python 2 and iterators in Python 3. :class:`~django.http.QueryDict` and the
-:class:`dict`-like classes defined in :mod:`django.utils.datastructures`
+:class:`dict`-like classes defined in ``django.utils.datastructures``
 behave likewise in Python 3.
 
 six_ provides compatibility functions to work around this change:

+ 2 - 129
tests/utils_tests/test_datastructures.py

@@ -3,140 +3,13 @@ Tests for stuff in django.utils.datastructures.
 """
 
 import copy
-import pickle
 
-from django.test import SimpleTestCase, ignore_warnings
+from django.test import SimpleTestCase
 from django.utils.datastructures import (DictWrapper, ImmutableList,
-    MultiValueDict, MultiValueDictKeyError, OrderedSet, SortedDict)
-from django.utils.deprecation import RemovedInDjango19Warning
+    MultiValueDict, MultiValueDictKeyError, OrderedSet)
 from django.utils import six
 
 
-@ignore_warnings(category=RemovedInDjango19Warning)
-class SortedDictTests(SimpleTestCase):
-    def setUp(self):
-        super(SortedDictTests, self).setUp()
-        self.d1 = SortedDict()
-        self.d1[7] = 'seven'
-        self.d1[1] = 'one'
-        self.d1[9] = 'nine'
-
-        self.d2 = SortedDict()
-        self.d2[1] = 'one'
-        self.d2[9] = 'nine'
-        self.d2[0] = 'nil'
-        self.d2[7] = 'seven'
-
-    def test_basic_methods(self):
-        self.assertEqual(list(six.iterkeys(self.d1)), [7, 1, 9])
-        self.assertEqual(list(six.itervalues(self.d1)), ['seven', 'one', 'nine'])
-        self.assertEqual(list(six.iteritems(self.d1)), [(7, 'seven'), (1, 'one'), (9, 'nine')])
-
-    def test_overwrite_ordering(self):
-        """ Overwriting an item keeps its place. """
-        self.d1[1] = 'ONE'
-        self.assertEqual(list(six.itervalues(self.d1)), ['seven', 'ONE', 'nine'])
-
-    def test_append_items(self):
-        """ New items go to the end. """
-        self.d1[0] = 'nil'
-        self.assertEqual(list(six.iterkeys(self.d1)), [7, 1, 9, 0])
-
-    def test_delete_and_insert(self):
-        """
-        Deleting an item, then inserting the same key again will place it
-        at the end.
-        """
-        del self.d2[7]
-        self.assertEqual(list(six.iterkeys(self.d2)), [1, 9, 0])
-        self.d2[7] = 'lucky number 7'
-        self.assertEqual(list(six.iterkeys(self.d2)), [1, 9, 0, 7])
-
-    if six.PY2:
-        def test_change_keys(self):
-            """
-            Changing the keys won't do anything, it's only a copy of the
-            keys dict.
-
-            This test doesn't make sense under Python 3 because keys is
-            an iterator.
-            """
-            k = self.d2.keys()
-            k.remove(9)
-            self.assertEqual(self.d2.keys(), [1, 9, 0, 7])
-
-    def test_init_keys(self):
-        """
-        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)
-
-        self.assertEqual(list(six.iterkeys(d)), [2, 1])
-
-        real_dict = dict(tuples)
-        self.assertEqual(sorted(six.itervalues(real_dict)), ['one', 'second-two'])
-
-        # Here the order of SortedDict values *is* what we are testing
-        self.assertEqual(list(six.itervalues(d)), ['second-two', 'one'])
-
-    def test_overwrite(self):
-        self.d1[1] = 'not one'
-        self.assertEqual(self.d1[1], 'not one')
-        self.assertEqual(list(six.iterkeys(self.d1)), list(six.iterkeys(self.d1.copy())))
-
-    def test_append(self):
-        self.d1[13] = 'thirteen'
-        self.assertEqual(
-            repr(self.d1),
-            "{7: 'seven', 1: 'one', 9: 'nine', 13: 'thirteen'}"
-        )
-
-    def test_pop(self):
-        self.assertEqual(self.d1.pop(1, 'missing'), 'one')
-        self.assertEqual(self.d1.pop(1, 'missing'), 'missing')
-
-        # We don't know which item will be popped in popitem(), so we'll
-        # just check that the number of keys has decreased.
-        l = len(self.d1)
-        self.d1.popitem()
-        self.assertEqual(l - len(self.d1), 1)
-
-    def test_dict_equality(self):
-        d = SortedDict((i, i) for i in range(3))
-        self.assertEqual(d, {0: 0, 1: 1, 2: 2})
-
-    def test_tuple_init(self):
-        d = SortedDict(((1, "one"), (0, "zero"), (2, "two")))
-        self.assertEqual(repr(d), "{1: 'one', 0: 'zero', 2: 'two'}")
-
-    def test_pickle(self):
-        self.assertEqual(
-            pickle.loads(pickle.dumps(self.d1, 2)),
-            {7: 'seven', 1: 'one', 9: 'nine'}
-        )
-
-    def test_copy(self):
-        orig = SortedDict(((1, "one"), (0, "zero"), (2, "two")))
-        copied = copy.copy(orig)
-        self.assertEqual(list(six.iterkeys(orig)), [1, 0, 2])
-        self.assertEqual(list(six.iterkeys(copied)), [1, 0, 2])
-
-    def test_clear(self):
-        self.d1.clear()
-        self.assertEqual(self.d1, {})
-        self.assertEqual(self.d1.keyOrder, [])
-
-    def test_reversed(self):
-        self.assertEqual(list(self.d1), [7, 1, 9])
-        self.assertEqual(list(self.d2), [1, 9, 0, 7])
-        self.assertEqual(list(reversed(self.d1)), [9, 1, 7])
-        self.assertEqual(list(reversed(self.d2)), [7, 0, 9, 1])
-
-
 class OrderedSetTests(SimpleTestCase):
 
     def test_bool(self):