Deprecated SortedDict (replaced with collections.OrderedDict)

Thanks Loic Bistuer for the review.
This commit is contained in:
Curtis Maloney 2013-08-03 15:41:15 +10:00 committed by Tim Graham
parent b278f7478d
commit 07876cf02b
26 changed files with 139 additions and 107 deletions

View File

@ -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.http.response import HttpResponseBase
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 @@ class ModelAdmin(BaseModelAdmin):
# 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 @@ class ModelAdmin(BaseModelAdmin):
# 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
])

View File

@ -1,3 +1,4 @@
from collections import OrderedDict
import sys
import warnings
@ -7,7 +8,6 @@ from django.core.urlresolvers import reverse
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 @@ class ChangeList(six.with_metaclass(RenameChangeListMethods)):
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

View File

@ -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 @@ class PasswordChangeForm(SetPasswordForm):
)
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']
])

View File

@ -2,13 +2,13 @@ from __future__ import unicode_literals
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 @@ class PBKDF2PasswordHasher(BasePasswordHasher):
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 @@ class BCryptSHA256PasswordHasher(BasePasswordHasher):
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 @@ class SHA1PasswordHasher(BasePasswordHasher):
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 @@ class MD5PasswordHasher(BasePasswordHasher):
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 @@ class UnsaltedSHA1PasswordHasher(BasePasswordHasher):
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 @@ class UnsaltedMD5PasswordHasher(BasePasswordHasher):
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 @@ class CryptPasswordHasher(BasePasswordHasher):
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)),

View File

@ -1,3 +1,4 @@
from collections import OrderedDict
import re
from django import forms
@ -5,7 +6,6 @@ from django.shortcuts import redirect
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 @@ class WizardView(TemplateView):
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 @@ class WizardView(TemplateView):
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 @@ class WizardView(TemplateView):
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 @@ class WizardView(TemplateView):
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 @@ class WizardView(TemplateView):
"""
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):
"""

View File

@ -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.utils import six
from django.contrib.staticfiles import utils
from django.contrib.staticfiles.storage import AppStaticStorage
_finders = SortedDict()
_finders = OrderedDict()
class BaseFinder(object):
@ -47,7 +48,7 @@ class FileSystemFinder(BaseFinder):
# 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 @@ class AppDirectoriesFinder(BaseFinder):
# 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:

View File

@ -2,12 +2,12 @@ from __future__ import unicode_literals
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 @@ class Command(NoArgsCommand):
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

View File

@ -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.cache import (get_cache, InvalidCacheBackendError,
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 @@ class CachedFilesMixin(object):
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 @@ class CachedFilesMixin(object):
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:

View File

@ -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 @@ class Command(BaseCommand):
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('.')

View File

@ -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 @@ class Command(NoArgsCommand):
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 @@ class Command(NoArgsCommand):
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:

View File

@ -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.base import NoArgsCommand
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 @@ class Command(NoArgsCommand):
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
)

View File

@ -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 @@ class Collector(object):
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):

View File

@ -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 @@ import sys
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 @@ __all__ = ('get_apps', 'get_app', 'get_models', 'get_model', 'register_models',
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 @@ class AppCache(object):
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 @@ class AppCache(object):
# 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

View File

@ -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.fields.proxy import OrderWrt
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 @@ class Options(object):
# 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 @@ class Options(object):
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 @@ class Options(object):
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 @@ class Options(object):
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():

View File

@ -7,9 +7,9 @@ databases). The abstraction barrier only works one way: this module has to know
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 @@ class Query(object):
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 @@ class Query(object):
# 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 @@ class Query(object):
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 @@ class Query(object):
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 @@ class Query(object):
# 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 @@ class Query(object):
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 @@ class Query(object):
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 @@ class Query(object):
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 @@ class Query(object):
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
])

View File

@ -4,6 +4,7 @@ Form classes
from __future__ import unicode_literals
from collections import OrderedDict
import copy
import warnings
@ -11,7 +12,6 @@ from django.core.exceptions import ValidationError
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):
"""

View File

@ -5,6 +5,7 @@ and database field objects.
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.util import ErrorList
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)]
)

View File

@ -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):

View File

@ -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 @@ class SortedDict(dict):
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)

View File

@ -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 importlib import import_module
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)

View File

@ -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
---

View File

@ -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

View File

@ -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.

View File

@ -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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -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 @@ class ExtraRegressTests(TestCase):
# 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 @@ class ExtraRegressTests(TestCase):
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)]
)

View File

@ -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.where import WhereNode, EverythingNode, NothingNode
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 @@ class Queries1Tests(BaseQuerysetTest):
)
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 @@ class Queries1Tests(BaseQuerysetTest):
# 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 @@ class ValuesQuerysetTests(BaseQuerysetTest):
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')