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 copy
-import warnings
 from collections import OrderedDict
 from collections import OrderedDict
 
 
 from django.utils import six
 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):
 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
     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.
     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``
 ``django.utils.dateparse``
 ==========================
 ==========================
 
 

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

@@ -714,12 +714,12 @@ Data structures
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
 ``django.newforms.forms.SortedDictFromList`` was removed.
 ``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.
 a sequence of tuples.
 
 
 To update your code:
 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``.
    using ``django.newforms.forms.SortedDictFromList``.
 
 
 2. Because ``django.utils.datastructures.SortedDict.copy`` doesn't
 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
 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
 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
 :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
 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.
 behave likewise in Python 3.
 
 
 six_ provides compatibility functions to work around this change:
 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 copy
-import pickle
 
 
-from django.test import SimpleTestCase, ignore_warnings
+from django.test import SimpleTestCase
 from django.utils.datastructures import (DictWrapper, ImmutableList,
 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
 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):
 class OrderedSetTests(SimpleTestCase):
 
 
     def test_bool(self):
     def test_bool(self):