Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Deprecated SortedDict (replaced with collections.OrderedDict)

Thanks Loic Bistuer for the review.
  • Loading branch information...
commit 07876cf02b6db453ca0397c29c225668872fa96d 1 parent b278f74
Curtis Maloney funkybob authored timgraham committed
Showing with 139 additions and 107 deletions.
  1. +4 −4 django/contrib/admin/options.py
  2. +3 −3 django/contrib/admin/views/main.py
  3. +3 −2 django/contrib/auth/forms.py
  4. +8 −8 django/contrib/auth/hashers.py
  5. +11 −9 django/contrib/formtools/wizard/views.py
  6. +5 −4 django/contrib/staticfiles/finders.py
  7. +2 −2 django/contrib/staticfiles/management/commands/collectstatic.py
  8. +3 −3 django/contrib/staticfiles/storage.py
  9. +5 −4 django/core/management/commands/dumpdata.py
  10. +3 −3 django/core/management/commands/inspectdb.py
  11. +2 −2 django/core/management/commands/syncdb.py
  12. +2 −2 django/db/models/deletion.py
  13. +15 −6 django/db/models/loading.py
  14. +5 −5 django/db/models/options.py
  15. +10 −10 django/db/models/sql/query.py
  16. +2 −2 django/forms/forms.py
  17. +4 −4 django/forms/models.py
  18. +3 −2 django/middleware/locale.py
  19. +5 −1 django/utils/datastructures.py
  20. +4 −4 django/utils/translation/trans_real.py
  21. +3 −0  docs/internals/deprecation.txt
  22. +3 −4 docs/ref/models/querysets.txt
  23. +4 −0 docs/ref/utils.txt
  24. +7 −0 docs/releases/1.7.txt
  25. +19 −19 tests/extra_regress/tests.py
  26. +4 −4 tests/queries/tests.py
8 django/contrib/admin/options.py
View
@@ -1,3 +1,4 @@
+from collections import OrderedDict
import copy
import operator
from functools import partial, reduce, update_wrapper
@@ -29,7 +30,6 @@
from django.shortcuts import get_object_or_404
from django.template.response import SimpleTemplateResponse, TemplateResponse
from django.utils.decorators import method_decorator
-from django.utils.datastructures import SortedDict
from django.utils.html import escape, escapejs
from django.utils.safestring import mark_safe
from django.utils import six
@@ -672,7 +672,7 @@ def get_actions(self, request):
# want *any* actions enabled on this page.
from django.contrib.admin.views.main import _is_changelist_popup
if self.actions is None or _is_changelist_popup(request):
- return SortedDict()
+ return OrderedDict()
actions = []
@@ -693,8 +693,8 @@ def get_actions(self, request):
# get_action might have returned None, so filter any of those out.
actions = filter(None, actions)
- # Convert the actions into a SortedDict keyed by name.
- actions = SortedDict([
+ # Convert the actions into an OrderedDict keyed by name.
+ actions = OrderedDict([
(name, (func, name, desc))
for func, name, desc in actions
])
6 django/contrib/admin/views/main.py
View
@@ -1,3 +1,4 @@
+from collections import OrderedDict
import sys
import warnings
@@ -7,7 +8,6 @@
from django.db import models
from django.db.models.fields import FieldDoesNotExist
from django.utils import six
-from django.utils.datastructures import SortedDict
from django.utils.deprecation import RenameMethodsBase
from django.utils.encoding import force_str, force_text
from django.utils.translation import ugettext, ugettext_lazy
@@ -319,13 +319,13 @@ def get_ordering(self, request, queryset):
def get_ordering_field_columns(self):
"""
- Returns a SortedDict of ordering field column numbers and asc/desc
+ Returns an OrderedDict of ordering field column numbers and asc/desc
"""
# We must cope with more than one column having the same underlying sort
# field, so we base things on column numbers.
ordering = self._get_default_ordering()
- ordering_fields = SortedDict()
+ ordering_fields = OrderedDict()
if ORDER_VAR not in self.params:
# for ordering specified on ModelAdmin or model Meta, we don't know
# the right column numbers absolutely, because there might be more
5 django/contrib/auth/forms.py
View
@@ -1,9 +1,10 @@
from __future__ import unicode_literals
+from collections import OrderedDict
+
from django import forms
from django.forms.util import flatatt
from django.template import loader
-from django.utils.datastructures import SortedDict
from django.utils.encoding import force_bytes
from django.utils.html import format_html, format_html_join
from django.utils.http import urlsafe_base64_encode
@@ -324,7 +325,7 @@ def clean_old_password(self):
)
return old_password
-PasswordChangeForm.base_fields = SortedDict([
+PasswordChangeForm.base_fields = OrderedDict([
(k, PasswordChangeForm.base_fields[k])
for k in ['old_password', 'new_password1', 'new_password2']
])
16 django/contrib/auth/hashers.py
View
@@ -2,13 +2,13 @@
import base64
import binascii
+from collections import OrderedDict
import hashlib
import importlib
from django.dispatch import receiver
from django.conf import settings
from django.test.signals import setting_changed
-from django.utils.datastructures import SortedDict
from django.utils.encoding import force_bytes, force_str, force_text
from django.core.exceptions import ImproperlyConfigured
from django.utils.crypto import (
@@ -243,7 +243,7 @@ def verify(self, password, encoded):
def safe_summary(self, encoded):
algorithm, iterations, salt, hash = encoded.split('$', 3)
assert algorithm == self.algorithm
- return SortedDict([
+ return OrderedDict([
(_('algorithm'), algorithm),
(_('iterations'), iterations),
(_('salt'), mask_hash(salt)),
@@ -320,7 +320,7 @@ def safe_summary(self, encoded):
algorithm, empty, algostr, work_factor, data = encoded.split('$', 4)
assert algorithm == self.algorithm
salt, checksum = data[:22], data[22:]
- return SortedDict([
+ return OrderedDict([
(_('algorithm'), algorithm),
(_('work factor'), work_factor),
(_('salt'), mask_hash(salt)),
@@ -368,7 +368,7 @@ def verify(self, password, encoded):
def safe_summary(self, encoded):
algorithm, salt, hash = encoded.split('$', 2)
assert algorithm == self.algorithm
- return SortedDict([
+ return OrderedDict([
(_('algorithm'), algorithm),
(_('salt'), mask_hash(salt, show=2)),
(_('hash'), mask_hash(hash)),
@@ -396,7 +396,7 @@ def verify(self, password, encoded):
def safe_summary(self, encoded):
algorithm, salt, hash = encoded.split('$', 2)
assert algorithm == self.algorithm
- return SortedDict([
+ return OrderedDict([
(_('algorithm'), algorithm),
(_('salt'), mask_hash(salt, show=2)),
(_('hash'), mask_hash(hash)),
@@ -429,7 +429,7 @@ def verify(self, password, encoded):
def safe_summary(self, encoded):
assert encoded.startswith('sha1$$')
hash = encoded[6:]
- return SortedDict([
+ return OrderedDict([
(_('algorithm'), self.algorithm),
(_('hash'), mask_hash(hash)),
])
@@ -462,7 +462,7 @@ def verify(self, password, encoded):
return constant_time_compare(encoded, encoded_2)
def safe_summary(self, encoded):
- return SortedDict([
+ return OrderedDict([
(_('algorithm'), self.algorithm),
(_('hash'), mask_hash(encoded, show=3)),
])
@@ -496,7 +496,7 @@ def verify(self, password, encoded):
def safe_summary(self, encoded):
algorithm, salt, data = encoded.split('$', 2)
assert algorithm == self.algorithm
- return SortedDict([
+ return OrderedDict([
(_('algorithm'), algorithm),
(_('salt'), salt),
(_('hash'), mask_hash(data, show=3)),
20 django/contrib/formtools/wizard/views.py
View
@@ -1,3 +1,4 @@
+from collections import OrderedDict
import re
from django import forms
@@ -5,7 +6,6 @@
from django.core.urlresolvers import reverse
from django.forms import formsets, ValidationError
from django.views.generic import TemplateView
-from django.utils.datastructures import SortedDict
from django.utils.decorators import classonlymethod
from django.utils.translation import ugettext as _
from django.utils import six
@@ -158,7 +158,7 @@ def get_initkwargs(cls, form_list=None, initial_dict=None,
form_list = form_list or kwargs.pop('form_list',
getattr(cls, 'form_list', None)) or []
- computed_form_list = SortedDict()
+ computed_form_list = OrderedDict()
assert len(form_list) > 0, 'at least one form is needed'
@@ -206,7 +206,7 @@ def get_form_list(self):
The form_list is always generated on the fly because condition methods
could use data from other (maybe previous forms).
"""
- form_list = SortedDict()
+ form_list = OrderedDict()
for form_key, form_class in six.iteritems(self.form_list):
# try to fetch the value from condition list, by default, the form
# gets passed to the new list.
@@ -498,9 +498,10 @@ def get_next_step(self, step=None):
if step is None:
step = self.steps.current
form_list = self.get_form_list()
- key = form_list.keyOrder.index(step) + 1
- if len(form_list.keyOrder) > key:
- return form_list.keyOrder[key]
+ keys = list(form_list.keys())
+ key = keys.index(step) + 1
+ if len(keys) > key:
+ return keys[key]
return None
def get_prev_step(self, step=None):
@@ -512,9 +513,10 @@ def get_prev_step(self, step=None):
if step is None:
step = self.steps.current
form_list = self.get_form_list()
- key = form_list.keyOrder.index(step) - 1
+ keys = list(form_list.keys())
+ key = keys.index(step) - 1
if key >= 0:
- return form_list.keyOrder[key]
+ return keys[key]
return None
def get_step_index(self, step=None):
@@ -524,7 +526,7 @@ def get_step_index(self, step=None):
"""
if step is None:
step = self.steps.current
- return self.get_form_list().keyOrder.index(step)
+ return list(self.get_form_list().keys()).index(step)
def get_context_data(self, form, **kwargs):
"""
9 django/contrib/staticfiles/finders.py
View
@@ -1,8 +1,9 @@
+from collections import OrderedDict
import os
+
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.core.files.storage import default_storage, Storage, FileSystemStorage
-from django.utils.datastructures import SortedDict
from django.utils.functional import empty, memoize, LazyObject
from django.utils.module_loading import import_by_path
from django.utils._os import safe_join
@@ -11,7 +12,7 @@
from django.contrib.staticfiles import utils
from django.contrib.staticfiles.storage import AppStaticStorage
-_finders = SortedDict()
+_finders = OrderedDict()
class BaseFinder(object):
@@ -47,7 +48,7 @@ def __init__(self, apps=None, *args, **kwargs):
# List of locations with static files
self.locations = []
# Maps dir paths to an appropriate storage instance
- self.storages = SortedDict()
+ self.storages = OrderedDict()
if not isinstance(settings.STATICFILES_DIRS, (list, tuple)):
raise ImproperlyConfigured(
"Your STATICFILES_DIRS setting is not a tuple or list; "
@@ -118,7 +119,7 @@ def __init__(self, apps=None, *args, **kwargs):
# The list of apps that are handled
self.apps = []
# Mapping of app module paths to storage instances
- self.storages = SortedDict()
+ self.storages = OrderedDict()
if apps is None:
apps = settings.INSTALLED_APPS
for app in apps:
4 django/contrib/staticfiles/management/commands/collectstatic.py
View
@@ -2,12 +2,12 @@
import os
import sys
+from collections import OrderedDict
from optparse import make_option
from django.core.files.storage import FileSystemStorage
from django.core.management.base import CommandError, NoArgsCommand
from django.utils.encoding import smart_text
-from django.utils.datastructures import SortedDict
from django.utils.six.moves import input
from django.contrib.staticfiles import finders, storage
@@ -97,7 +97,7 @@ def collect(self):
else:
handler = self.copy_file
- found_files = SortedDict()
+ found_files = OrderedDict()
for finder in finders.get_finders():
for path, storage in finder.list(self.ignore_patterns):
# Prefix the relative path if the source storage contains it
6 django/contrib/staticfiles/storage.py
View
@@ -1,4 +1,5 @@
from __future__ import unicode_literals
+from collections import OrderedDict
import hashlib
from importlib import import_module
import os
@@ -16,7 +17,6 @@
from django.core.exceptions import ImproperlyConfigured
from django.core.files.base import ContentFile
from django.core.files.storage import FileSystemStorage, get_storage_class
-from django.utils.datastructures import SortedDict
from django.utils.encoding import force_bytes, force_text
from django.utils.functional import LazyObject
from django.utils._os import upath
@@ -64,7 +64,7 @@ def __init__(self, *args, **kwargs):
except InvalidCacheBackendError:
# Use the default backend
self.cache = default_cache
- self._patterns = SortedDict()
+ self._patterns = OrderedDict()
for extension, patterns in self.patterns:
for pattern in patterns:
if isinstance(pattern, (tuple, list)):
@@ -202,7 +202,7 @@ def converter(matchobj):
def post_process(self, paths, dry_run=False, **options):
"""
- Post process the given SortedDict of files (called from collectstatic).
+ Post process the given OrderedDict of files (called from collectstatic).
Processing is actually two separate operations:
9 django/core/management/commands/dumpdata.py
View
@@ -1,10 +1,11 @@
+from collections import OrderedDict
+from optparse import make_option
+
from django.core.exceptions import ImproperlyConfigured
from django.core.management.base import BaseCommand, CommandError
from django.core import serializers
from django.db import router, DEFAULT_DB_ALIAS
-from django.utils.datastructures import SortedDict
-from optparse import make_option
class Command(BaseCommand):
option_list = BaseCommand.option_list + (
@@ -66,11 +67,11 @@ def handle(self, *app_labels, **options):
if len(app_labels) == 0:
if primary_keys:
raise CommandError("You can only use --pks option with one model")
- app_list = SortedDict((app, None) for app in get_apps() if app not in excluded_apps)
+ app_list = OrderedDict((app, None) for app in get_apps() if app not in excluded_apps)
else:
if len(app_labels) > 1 and primary_keys:
raise CommandError("You can only use --pks option with one model")
- app_list = SortedDict()
+ app_list = OrderedDict()
for label in app_labels:
try:
app_label, model_label = label.split('.')
6 django/core/management/commands/inspectdb.py
View
@@ -1,12 +1,12 @@
from __future__ import unicode_literals
+from collections import OrderedDict
import keyword
import re
from optparse import make_option
from django.core.management.base import NoArgsCommand, CommandError
from django.db import connections, DEFAULT_DB_ALIAS
-from django.utils.datastructures import SortedDict
class Command(NoArgsCommand):
@@ -69,7 +69,7 @@ def handle_inspection(self, options):
used_column_names = [] # Holds column names used in the table so far
for i, row in enumerate(connection.introspection.get_table_description(cursor, table_name)):
comment_notes = [] # Holds Field notes, to be displayed in a Python comment.
- extra_params = SortedDict() # Holds Field parameters such as 'db_column'.
+ extra_params = OrderedDict() # Holds Field parameters such as 'db_column'.
column_name = row[0]
is_relation = i in relations
@@ -193,7 +193,7 @@ def get_field_type(self, connection, table_name, row):
description, this routine will return the given field type name, as
well as any additional keyword parameters and notes for the field.
"""
- field_params = SortedDict()
+ field_params = OrderedDict()
field_notes = []
try:
4 django/core/management/commands/syncdb.py
View
@@ -1,3 +1,4 @@
+from collections import OrderedDict
from importlib import import_module
from optparse import make_option
import itertools
@@ -9,7 +10,6 @@
from django.core.management.color import no_style
from django.core.management.sql import custom_sql_for_model, emit_post_sync_signal, emit_pre_sync_signal
from django.db import connections, router, transaction, models, DEFAULT_DB_ALIAS
-from django.utils.datastructures import SortedDict
class Command(NoArgsCommand):
@@ -76,7 +76,7 @@ def model_installed(model):
return not ((converter(opts.db_table) in tables) or
(opts.auto_created and converter(opts.auto_created._meta.db_table) in tables))
- manifest = SortedDict(
+ manifest = OrderedDict(
(app_name, list(filter(model_installed, model_list)))
for app_name, model_list in all_models
)
4 django/db/models/deletion.py
View
@@ -1,8 +1,8 @@
+from collections import OrderedDict
from operator import attrgetter
from django.db import connections, transaction, IntegrityError
from django.db.models import signals, sql
-from django.utils.datastructures import SortedDict
from django.utils import six
@@ -234,7 +234,7 @@ def sort(self):
found = True
if not found:
return
- self.data = SortedDict([(model, self.data[model])
+ self.data = OrderedDict([(model, self.data[model])
for model in sorted_models])
def delete(self):
21 django/db/models/loading.py
View
@@ -1,5 +1,7 @@
"Utilities for loading models and the modules that contain them."
+from collections import OrderedDict
+import copy
import imp
from importlib import import_module
import os
@@ -7,7 +9,6 @@
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
-from django.utils.datastructures import SortedDict
from django.utils.module_loading import module_has_submodule
from django.utils._os import upath
from django.utils import six
@@ -17,6 +18,14 @@
MODELS_MODULE_NAME = 'models'
+class ModelDict(OrderedDict):
+ """
+ We need to special-case the deepcopy for this, as the keys are modules,
+ which can't be deep copied.
+ """
+ def __deepcopy__(self, memo):
+ return self.__class__([(key, copy.deepcopy(value, memo))
+ for key, value in self.items()])
class UnavailableApp(Exception):
pass
@@ -31,14 +40,14 @@ class AppCache(object):
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66531.
__shared_state = dict(
# Keys of app_store are the model modules for each application.
- app_store=SortedDict(),
+ app_store=ModelDict(),
# Mapping of installed app_labels to model modules for that app.
app_labels={},
# Mapping of app_labels to a dictionary of model names to model code.
# May contain apps that are not installed.
- app_models=SortedDict(),
+ app_models=ModelDict(),
# Mapping of app_labels to errors raised when trying to import the app.
app_errors={},
@@ -244,12 +253,12 @@ def get_models(self, app_mod=None,
if app_mod:
if app_mod in self.app_store:
app_list = [self.app_models.get(self._label_for(app_mod),
- SortedDict())]
+ ModelDict())]
else:
app_list = []
else:
if only_installed:
- app_list = [self.app_models.get(app_label, SortedDict())
+ app_list = [self.app_models.get(app_label, ModelDict())
for app_label in six.iterkeys(self.app_labels)]
else:
app_list = six.itervalues(self.app_models)
@@ -298,7 +307,7 @@ def register_models(self, app_label, *models):
# Store as 'name: model' pair in a dictionary
# in the app_models dictionary
model_name = model._meta.model_name
- model_dict = self.app_models.setdefault(app_label, SortedDict())
+ model_dict = self.app_models.setdefault(app_label, ModelDict())
if model_name in model_dict:
# The same model may be imported via different paths (e.g.
# appname.models and project.appname.models). We use the source
10 django/db/models/options.py
View
@@ -1,5 +1,6 @@
from __future__ import unicode_literals
+from collections import OrderedDict
import re
from bisect import bisect
import warnings
@@ -11,7 +12,6 @@
from django.db.models.loading import get_models, app_cache_ready
from django.utils import six
from django.utils.functional import cached_property
-from django.utils.datastructures import SortedDict
from django.utils.encoding import force_text, smart_text, python_2_unicode_compatible
from django.utils.translation import activate, deactivate_all, get_language, string_concat
@@ -58,7 +58,7 @@ def __init__(self, meta, app_label=None):
# concrete models, the concrete_model is always the class itself.
self.concrete_model = None
self.swappable = None
- self.parents = SortedDict()
+ self.parents = OrderedDict()
self.auto_created = False
# To handle various inheritance situations, we need to track where
@@ -332,7 +332,7 @@ def get_m2m_with_model(self):
return list(six.iteritems(self._m2m_cache))
def _fill_m2m_cache(self):
- cache = SortedDict()
+ cache = OrderedDict()
for parent in self.parents:
for field, model in parent._meta.get_m2m_with_model():
if model:
@@ -474,7 +474,7 @@ def get_all_related_objects_with_model(self, local_only=False,
return [t for t in cache.items() if all(p(*t) for p in predicates)]
def _fill_related_objects_cache(self):
- cache = SortedDict()
+ cache = OrderedDict()
parent_list = self.get_parent_list()
for parent in self.parents:
for obj, model in parent._meta.get_all_related_objects_with_model(include_hidden=True):
@@ -519,7 +519,7 @@ def get_all_related_m2m_objects_with_model(self):
return list(six.iteritems(cache))
def _fill_related_many_to_many_cache(self):
- cache = SortedDict()
+ cache = OrderedDict()
parent_list = self.get_parent_list()
for parent in self.parents:
for obj, model in parent._meta.get_all_related_m2m_objects_with_model():
20 django/db/models/sql/query.py
View
@@ -7,9 +7,9 @@
all about the internals of models in order to get the information it needs.
"""
+from collections import OrderedDict
import copy
-from django.utils.datastructures import SortedDict
from django.utils.encoding import force_text
from django.utils.tree import Node
from django.utils import six
@@ -142,7 +142,7 @@ def __init__(self, model, where=WhereNode):
self.select_related = False
# SQL aggregate-related attributes
- self.aggregates = SortedDict() # Maps alias -> SQL aggregate function
+ self.aggregates = OrderedDict() # Maps alias -> SQL aggregate function
self.aggregate_select_mask = None
self._aggregate_select_cache = None
@@ -152,7 +152,7 @@ def __init__(self, model, where=WhereNode):
# These are for extensions. The contents are more or less appended
# verbatim to the appropriate clause.
- self.extra = SortedDict() # Maps col_alias -> (col_sql, params).
+ self.extra = OrderedDict() # Maps col_alias -> (col_sql, params).
self.extra_select_mask = None
self._extra_select_cache = None
@@ -741,7 +741,7 @@ def relabel_column(col):
self.group_by = [relabel_column(col) for col in self.group_by]
self.select = [SelectInfo(relabel_column(s.col), s.field)
for s in self.select]
- self.aggregates = SortedDict(
+ self.aggregates = OrderedDict(
(key, relabel_column(col)) for key, col in self.aggregates.items())
# 2. Rename the alias in the internal table/alias datastructures.
@@ -795,7 +795,7 @@ def bump_prefix(self, exceptions=()):
assert current < ord('Z')
prefix = chr(current + 1)
self.alias_prefix = prefix
- change_map = SortedDict()
+ change_map = OrderedDict()
for pos, alias in enumerate(self.tables):
if alias in exceptions:
continue
@@ -1638,7 +1638,7 @@ def add_extra(self, select, select_params, where, params, tables, order_by):
# dictionary with their parameters in 'select_params' so that
# subsequent updates to the select dictionary also adjust the
# parameters appropriately.
- select_pairs = SortedDict()
+ select_pairs = OrderedDict()
if select_params:
param_iter = iter(select_params)
else:
@@ -1651,7 +1651,7 @@ def add_extra(self, select, select_params, where, params, tables, order_by):
entry_params.append(next(param_iter))
pos = entry.find("%s", pos + 2)
select_pairs[name] = (entry, entry_params)
- # This is order preserving, since self.extra_select is a SortedDict.
+ # This is order preserving, since self.extra_select is an OrderedDict.
self.extra.update(select_pairs)
if where or params:
self.where.add(ExtraWhere(where, params), AND)
@@ -1760,7 +1760,7 @@ def set_extra_mask(self, names):
self._extra_select_cache = None
def _aggregate_select(self):
- """The SortedDict of aggregate columns that are not masked, and should
+ """The OrderedDict of aggregate columns that are not masked, and should
be used in the SELECT clause.
This result is cached for optimization purposes.
@@ -1768,7 +1768,7 @@ def _aggregate_select(self):
if self._aggregate_select_cache is not None:
return self._aggregate_select_cache
elif self.aggregate_select_mask is not None:
- self._aggregate_select_cache = SortedDict([
+ self._aggregate_select_cache = OrderedDict([
(k, v) for k, v in self.aggregates.items()
if k in self.aggregate_select_mask
])
@@ -1781,7 +1781,7 @@ def _extra_select(self):
if self._extra_select_cache is not None:
return self._extra_select_cache
elif self.extra_select_mask is not None:
- self._extra_select_cache = SortedDict([
+ self._extra_select_cache = OrderedDict([
(k, v) for k, v in self.extra.items()
if k in self.extra_select_mask
])
4 django/forms/forms.py
View
@@ -4,6 +4,7 @@
from __future__ import unicode_literals
+from collections import OrderedDict
import copy
import warnings
@@ -11,7 +12,6 @@
from django.forms.fields import Field, FileField
from django.forms.util import flatatt, ErrorDict, ErrorList
from django.forms.widgets import Media, media_property, TextInput, Textarea
-from django.utils.datastructures import SortedDict
from django.utils.html import conditional_escape, format_html
from django.utils.encoding import smart_text, force_text, python_2_unicode_compatible
from django.utils.safestring import mark_safe
@@ -55,7 +55,7 @@ def get_declared_fields(bases, attrs, with_base_fields=True):
if hasattr(base, 'declared_fields'):
fields = list(six.iteritems(base.declared_fields)) + fields
- return SortedDict(fields)
+ return OrderedDict(fields)
class DeclarativeFieldsMetaclass(type):
"""
8 django/forms/models.py
View
@@ -5,6 +5,7 @@
from __future__ import unicode_literals
+from collections import OrderedDict
import warnings
from django.core.exceptions import ValidationError, NON_FIELD_ERRORS, FieldError
@@ -15,7 +16,6 @@
from django.forms.widgets import (SelectMultiple, HiddenInput,
MultipleHiddenInput, media_property, CheckboxSelectMultiple)
from django.utils.encoding import smart_text, force_text
-from django.utils.datastructures import SortedDict
from django.utils import six
from django.utils.text import get_text_list, capfirst
from django.utils.translation import ugettext_lazy as _, ugettext, string_concat
@@ -142,7 +142,7 @@ def fields_for_model(model, fields=None, exclude=None, widgets=None,
formfield_callback=None, localized_fields=None,
labels=None, help_texts=None, error_messages=None):
"""
- Returns a ``SortedDict`` containing form fields for the given model.
+ Returns a ``OrderedDict`` containing form fields for the given model.
``fields`` is an optional list of field names. If provided, only the named
fields will be included in the returned fields.
@@ -199,9 +199,9 @@ def fields_for_model(model, fields=None, exclude=None, widgets=None,
field_list.append((f.name, formfield))
else:
ignored.append(f.name)
- field_dict = SortedDict(field_list)
+ field_dict = OrderedDict(field_list)
if fields:
- field_dict = SortedDict(
+ field_dict = OrderedDict(
[(f, field_dict.get(f)) for f in fields
if ((not exclude) or (exclude and f not in exclude)) and (f not in ignored)]
)
5 django/middleware/locale.py
View
@@ -1,12 +1,13 @@
"This is the locale selecting middleware that will look at accept headers"
+from collections import OrderedDict
+
from django.conf import settings
from django.core.urlresolvers import (is_valid_path, get_resolver,
LocaleRegexURLResolver)
from django.http import HttpResponseRedirect
from django.utils.cache import patch_vary_headers
from django.utils import translation
-from django.utils.datastructures import SortedDict
class LocaleMiddleware(object):
@@ -19,7 +20,7 @@ class LocaleMiddleware(object):
"""
def __init__(self):
- self._supported_languages = SortedDict(settings.LANGUAGES)
+ self._supported_languages = OrderedDict(settings.LANGUAGES)
self._is_language_prefix_patterns_used = False
for url_pattern in get_resolver(None).url_patterns:
if isinstance(url_pattern, LocaleRegexURLResolver):
6 django/utils/datastructures.py
View
@@ -1,7 +1,7 @@
import copy
+import warnings
from django.utils import six
-
class MergeDict(object):
"""
A simple class for creating new "virtual" dictionaries that actually look
@@ -124,6 +124,10 @@ def __new__(cls, *args, **kwargs):
return instance
def __init__(self, data=None):
+ warnings.warn(
+ "SortedDict is deprecated and will be removed in Django 1.9.",
+ PendingDeprecationWarning, stacklevel=2
+ )
if data is None or isinstance(data, dict):
data = data or []
super(SortedDict, self).__init__(data)
8 django/utils/translation/trans_real.py
View
@@ -1,6 +1,7 @@
"""Translation helper functions."""
from __future__ import unicode_literals
+from collections import OrderedDict
import locale
import os
import re
@@ -10,7 +11,6 @@
from threading import local
import warnings
-from django.utils.datastructures import SortedDict
from django.utils.encoding import force_str, force_text
from django.utils.functional import memoize
from django.utils._os import upath
@@ -369,7 +369,7 @@ def get_supported_language_variant(lang_code, supported=None, strict=False):
"""
if supported is None:
from django.conf import settings
- supported = SortedDict(settings.LANGUAGES)
+ supported = OrderedDict(settings.LANGUAGES)
if lang_code:
# if fr-CA is not supported, try fr-ca; if that fails, fallback to fr.
generic_lang_code = lang_code.split('-')[0]
@@ -396,7 +396,7 @@ def get_language_from_path(path, supported=None, strict=False):
"""
if supported is None:
from django.conf import settings
- supported = SortedDict(settings.LANGUAGES)
+ supported = OrderedDict(settings.LANGUAGES)
regex_match = language_code_prefix_re.match(path)
if not regex_match:
return None
@@ -418,7 +418,7 @@ def get_language_from_request(request, check_path=False):
"""
global _accepted
from django.conf import settings
- supported = SortedDict(settings.LANGUAGES)
+ supported = OrderedDict(settings.LANGUAGES)
if check_path:
lang_code = get_language_from_path(request.path_info, supported)
3  docs/internals/deprecation.txt
View
@@ -423,6 +423,9 @@ these changes.
* FastCGI support via the ``runfcgi`` management command will be
removed. Please deploy your project using WSGI.
+* ``django.utils.datastructures.SortedDict`` will be removed. Use
+ :class:`collections.OrderedDict` from the Python standard library instead.
+
2.0
---
7 docs/ref/models/querysets.txt
View
@@ -977,14 +977,13 @@ of the arguments is required, but you should use at least one of them.
``select_params`` parameter. Since ``select_params`` is a sequence and
the ``select`` attribute is a dictionary, some care is required so that
the parameters are matched up correctly with the extra select pieces.
- In this situation, you should use a
- :class:`django.utils.datastructures.SortedDict` for the ``select``
- value, not just a normal Python dictionary.
+ In this situation, you should use a :class:`collections.OrderedDict` for
+ the ``select`` value, not just a normal Python dictionary.
This will work, for example::
Blog.objects.extra(
- select=SortedDict([('a', '%s'), ('b', '%s')]),
+ select=OrderedDict([('a', '%s'), ('b', '%s')]),
select_params=('one', 'two'))
The only thing to be careful about when using select parameters in
4 docs/ref/utils.txt
View
@@ -105,6 +105,10 @@ to distinguish caches by the ``Accept-language`` header.
.. 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.
7 docs/releases/1.7.txt
View
@@ -167,6 +167,13 @@ on all Python versions. Since ``unittest2`` became the standard library's
Python versions, this module isn't useful anymore. It has been deprecated. Use
:mod:`unittest` instead.
+``django.utils.datastructures.SortedDict``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+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.
+
Custom SQL location for models package
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
38 tests/extra_regress/tests.py
View
@@ -1,10 +1,10 @@
from __future__ import unicode_literals
+from collections import OrderedDict
import datetime
from django.contrib.auth.models import User
from django.test import TestCase
-from django.utils.datastructures import SortedDict
from .models import TestObject, Order, RevisionableModel
@@ -74,7 +74,7 @@ def test_extra_stay_tied(self):
# select portions. Applies when portions are updated or otherwise
# moved around.
qs = User.objects.extra(
- select=SortedDict((("alpha", "%s"), ("beta", "2"), ("gamma", "%s"))),
+ select=OrderedDict((("alpha", "%s"), ("beta", "2"), ("gamma", "%s"))),
select_params=(1, 3)
)
qs = qs.extra(select={"beta": 4})
@@ -180,100 +180,100 @@ def test_values_with_extra(self):
obj.save()
self.assertEqual(
- list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values()),
+ list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values()),
[{'bar': 'second', 'third': 'third', 'second': 'second', 'whiz': 'third', 'foo': 'first', 'id': obj.pk, 'first': 'first'}]
)
# Extra clauses after an empty values clause are still included
self.assertEqual(
- list(TestObject.objects.values().extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third'))))),
+ list(TestObject.objects.values().extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third'))))),
[{'bar': 'second', 'third': 'third', 'second': 'second', 'whiz': 'third', 'foo': 'first', 'id': obj.pk, 'first': 'first'}]
)
# Extra columns are ignored if not mentioned in the values() clause
self.assertEqual(
- list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('first', 'second')),
+ list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('first', 'second')),
[{'second': 'second', 'first': 'first'}]
)
# Extra columns after a non-empty values() clause are ignored
self.assertEqual(
- list(TestObject.objects.values('first', 'second').extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third'))))),
+ list(TestObject.objects.values('first', 'second').extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third'))))),
[{'second': 'second', 'first': 'first'}]
)
# Extra columns can be partially returned
self.assertEqual(
- list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('first', 'second', 'foo')),
+ list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('first', 'second', 'foo')),
[{'second': 'second', 'foo': 'first', 'first': 'first'}]
)
# Also works if only extra columns are included
self.assertEqual(
- list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('foo', 'whiz')),
+ list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values('foo', 'whiz')),
[{'foo': 'first', 'whiz': 'third'}]
)
# Values list works the same way
# All columns are returned for an empty values_list()
self.assertEqual(
- list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list()),
+ list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list()),
[('first', 'second', 'third', obj.pk, 'first', 'second', 'third')]
)
# Extra columns after an empty values_list() are still included
self.assertEqual(
- list(TestObject.objects.values_list().extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third'))))),
+ list(TestObject.objects.values_list().extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third'))))),
[('first', 'second', 'third', obj.pk, 'first', 'second', 'third')]
)
# Extra columns ignored completely if not mentioned in values_list()
self.assertEqual(
- list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first', 'second')),
+ list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first', 'second')),
[('first', 'second')]
)
# Extra columns after a non-empty values_list() clause are ignored completely
self.assertEqual(
- list(TestObject.objects.values_list('first', 'second').extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third'))))),
+ list(TestObject.objects.values_list('first', 'second').extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third'))))),
[('first', 'second')]
)
self.assertEqual(
- list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('second', flat=True)),
+ list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('second', flat=True)),
['second']
)
# Only the extra columns specified in the values_list() are returned
self.assertEqual(
- list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first', 'second', 'whiz')),
+ list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first', 'second', 'whiz')),
[('first', 'second', 'third')]
)
# ...also works if only extra columns are included
self.assertEqual(
- list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('foo','whiz')),
+ list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('foo','whiz')),
[('first', 'third')]
)
self.assertEqual(
- list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz', flat=True)),
+ list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz', flat=True)),
['third']
)
# ... and values are returned in the order they are specified
self.assertEqual(
- list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz','foo')),
+ list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz','foo')),
[('third', 'first')]
)
self.assertEqual(
- list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first','id')),
+ list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('first','id')),
[('first', obj.pk)]
)
self.assertEqual(
- list(TestObject.objects.extra(select=SortedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz', 'first', 'bar', 'id')),
+ list(TestObject.objects.extra(select=OrderedDict((('foo','first'), ('bar','second'), ('whiz','third')))).values_list('whiz', 'first', 'bar', 'id')),
[('third', 'first', 'second', obj.pk)]
)
8 tests/queries/tests.py
View
@@ -1,5 +1,6 @@
from __future__ import unicode_literals
+from collections import OrderedDict
import datetime
from operator import attrgetter
import pickle
@@ -14,7 +15,6 @@
from django.db.models.sql.datastructures import EmptyResultSet
from django.test import TestCase, skipUnlessDBFeature
from django.test.utils import str_prefix
-from django.utils.datastructures import SortedDict
from .models import (
Annotation, Article, Author, Celebrity, Child, Cover, Detail, DumbCategory,
@@ -499,7 +499,7 @@ def test_ticket4358(self):
)
def test_ticket2902(self):
- # Parameters can be given to extra_select, *if* you use a SortedDict.
+ # Parameters can be given to extra_select, *if* you use an OrderedDict.
# (First we need to know which order the keys fall in "naturally" on
# your system, so we can put things in the wrong way around from
@@ -513,7 +513,7 @@ def test_ticket2902(self):
# This slightly odd comparison works around the fact that PostgreSQL will
# return 'one' and 'two' as strings, not Unicode objects. It's a side-effect of
# using constants here and not a real concern.
- d = Item.objects.extra(select=SortedDict(s), select_params=params).values('a', 'b')[0]
+ d = Item.objects.extra(select=OrderedDict(s), select_params=params).values('a', 'b')[0]
self.assertEqual(d, {'a': 'one', 'b': 'two'})
# Order by the number of tags attached to an item.
@@ -1987,7 +1987,7 @@ def test_flat_values_list(self):
def test_extra_values(self):
# testing for ticket 14930 issues
- qs = Number.objects.extra(select=SortedDict([('value_plus_x', 'num+%s'),
+ qs = Number.objects.extra(select=OrderedDict([('value_plus_x', 'num+%s'),
('value_minus_x', 'num-%s')]),
select_params=(1, 2))
qs = qs.order_by('value_minus_x')
Please sign in to comment.
Something went wrong with that request. Please try again.