Created
August 3, 2013 08:15
-
-
Save loic/6145691 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py | |
index 0b941df..39700dd 100644 | |
--- a/django/contrib/admin/options.py | |
+++ b/django/contrib/admin/options.py | |
@@ -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 | |
@@ -671,7 +671,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 = [] | |
@@ -692,8 +692,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 | |
]) | |
diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py | |
index f766031..3325747 100644 | |
--- a/django/contrib/admin/views/main.py | |
+++ b/django/contrib/admin/views/main.py | |
@@ -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 | |
diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py | |
index e3f03cc..c5c2db4 100644 | |
--- a/django/contrib/auth/forms.py | |
+++ b/django/contrib/auth/forms.py | |
@@ -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'] | |
]) | |
diff --git a/django/contrib/auth/hashers.py b/django/contrib/auth/hashers.py | |
index 45ebc0f..06aec64 100644 | |
--- a/django/contrib/auth/hashers.py | |
+++ b/django/contrib/auth/hashers.py | |
@@ -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)), | |
diff --git a/django/contrib/formtools/wizard/views.py b/django/contrib/formtools/wizard/views.py | |
index c137f1a..8c3b825 100644 | |
--- a/django/contrib/formtools/wizard/views.py | |
+++ b/django/contrib/formtools/wizard/views.py | |
@@ -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,9 @@ 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] | |
+ key = form_list.keys().index(step) + 1 | |
+ if len(form_list.keys()) > key: | |
+ return form_list.keys()[key] | |
return None | |
def get_prev_step(self, step=None): | |
@@ -512,9 +512,9 @@ class WizardView(TemplateView): | |
if step is None: | |
step = self.steps.current | |
form_list = self.get_form_list() | |
- key = form_list.keyOrder.index(step) - 1 | |
+ key = form_list.keys().index(step) - 1 | |
if key >= 0: | |
- return form_list.keyOrder[key] | |
+ return form_list.keys()[key] | |
return None | |
def get_step_index(self, step=None): | |
@@ -524,7 +524,7 @@ class WizardView(TemplateView): | |
""" | |
if step is None: | |
step = self.steps.current | |
- return self.get_form_list().keyOrder.index(step) | |
+ return self.get_form_list().keys().index(step) | |
def get_context_data(self, form, **kwargs): | |
""" | |
diff --git a/django/contrib/staticfiles/finders.py b/django/contrib/staticfiles/finders.py | |
index 7d266d9..c4afe6f 100644 | |
--- a/django/contrib/staticfiles/finders.py | |
+++ b/django/contrib/staticfiles/finders.py | |
@@ -1,8 +1,9 @@ | |
import os | |
+from collections import OrderedDict | |
+ | |
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: | |
diff --git a/django/contrib/staticfiles/management/commands/collectstatic.py b/django/contrib/staticfiles/management/commands/collectstatic.py | |
index 7c3de80..c1e9fa8 100644 | |
--- a/django/contrib/staticfiles/management/commands/collectstatic.py | |
+++ b/django/contrib/staticfiles/management/commands/collectstatic.py | |
@@ -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 | |
diff --git a/django/contrib/staticfiles/storage.py b/django/contrib/staticfiles/storage.py | |
index f6d0a37..a814533 100644 | |
--- a/django/contrib/staticfiles/storage.py | |
+++ b/django/contrib/staticfiles/storage.py | |
@@ -1,5 +1,6 @@ | |
from __future__ import unicode_literals | |
import hashlib | |
+from collections import OrderedDict | |
from importlib import import_module | |
import os | |
import posixpath | |
@@ -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: | |
diff --git a/django/core/management/commands/dumpdata.py b/django/core/management/commands/dumpdata.py | |
index 100c187..1676081 100644 | |
--- a/django/core/management/commands/dumpdata.py | |
+++ b/django/core/management/commands/dumpdata.py | |
@@ -2,8 +2,8 @@ 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 collections import OrderedDict | |
from optparse import make_option | |
class Command(BaseCommand): | |
@@ -66,11 +66,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('.') | |
diff --git a/django/core/management/commands/inspectdb.py b/django/core/management/commands/inspectdb.py | |
index dc26bb1..2cfea02 100644 | |
--- a/django/core/management/commands/inspectdb.py | |
+++ b/django/core/management/commands/inspectdb.py | |
@@ -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: | |
diff --git a/django/core/management/commands/syncdb.py b/django/core/management/commands/syncdb.py | |
index 7c8d8b5..d51699e 100644 | |
--- a/django/core/management/commands/syncdb.py | |
+++ b/django/core/management/commands/syncdb.py | |
@@ -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 | |
) | |
diff --git a/django/db/models/deletion.py b/django/db/models/deletion.py | |
index e0bfb9d..f4c64f7 100644 | |
--- a/django/db/models/deletion.py | |
+++ b/django/db/models/deletion.py | |
@@ -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): | |
diff --git a/django/db/models/loading.py b/django/db/models/loading.py | |
index 8368203..e1f7b84 100644 | |
--- a/django/db/models/loading.py | |
+++ b/django/db/models/loading.py | |
@@ -1,5 +1,6 @@ | |
"Utilities for loading models and the modules that contain them." | |
+from collections import OrderedDict | |
import imp | |
from importlib import import_module | |
import os | |
@@ -7,7 +8,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 +17,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 +39,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 +252,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 +306,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 | |
diff --git a/django/db/models/options.py b/django/db/models/options.py | |
index d072d67..95cefec 100644 | |
--- a/django/db/models/options.py | |
+++ b/django/db/models/options.py | |
@@ -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(): | |
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py | |
index fa7ae51..de43120 100644 | |
--- a/django/db/models/sql/query.py | |
+++ b/django/db/models/sql/query.py | |
@@ -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 | |
]) | |
diff --git a/django/forms/forms.py b/django/forms/forms.py | |
index 31e51e7..9905eee 100644 | |
--- a/django/forms/forms.py | |
+++ b/django/forms/forms.py | |
@@ -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): | |
""" | |
diff --git a/django/forms/models.py b/django/forms/models.py | |
index 83954b0..a5b82e5 100644 | |
--- a/django/forms/models.py | |
+++ b/django/forms/models.py | |
@@ -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)] | |
) | |
diff --git a/django/middleware/locale.py b/django/middleware/locale.py | |
index 4e0a475..cd5d2cc 100644 | |
--- a/django/middleware/locale.py | |
+++ b/django/middleware/locale.py | |
@@ -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): | |
diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py | |
index 3b16383..41b6501 100644 | |
--- a/django/utils/datastructures.py | |
+++ b/django/utils/datastructures.py | |
@@ -1,6 +1,6 @@ | |
import copy | |
from django.utils import six | |
- | |
+import warnings | |
class MergeDict(object): | |
""" | |
@@ -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) | |
@@ -496,3 +500,4 @@ class DictWrapper(dict): | |
if use_func: | |
return self.func(value) | |
return value | |
+ | |
diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py | |
index 91a73f1..11463d8 100644 | |
--- a/django/utils/translation/trans_real.py | |
+++ b/django/utils/translation/trans_real.py | |
@@ -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) | |
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt | |
index 3d6cd48..53eb8a3 100644 | |
--- a/docs/internals/deprecation.txt | |
+++ b/docs/internals/deprecation.txt | |
@@ -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 the built in | |
+ collections.OrderedDict instead. | |
+ | |
2.0 | |
--- | |
diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt | |
index c47a392..606f640 100644 | |
--- a/docs/releases/1.7.txt | |
+++ b/docs/releases/1.7.txt | |
@@ -164,6 +164,12 @@ 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 OrderedDict was added to the standard library's :mod:`collections` in | |
+Python 2.7, ``django.utils.datastructures.SortedDict`` has been deprecated. | |
+ | |
Custom SQL location for models package | |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
diff --git a/tests/queries/tests.py b/tests/queries/tests.py | |
index 025fcd8..6e03b0d 100644 | |
--- a/tests/queries/tests.py | |
+++ b/tests/queries/tests.py | |
@@ -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') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment