Fixed #30159 -- Removed unneeded use of OrderedDict.

Dicts preserve order since Python 3.6.
This commit is contained in:
Nick Pope 2019-02-05 11:22:08 +00:00 committed by Tim Graham
parent 21bb71ef0d
commit 24b82cd201
31 changed files with 201 additions and 287 deletions

View File

@ -2,7 +2,7 @@ import functools
import sys
import threading
import warnings
from collections import Counter, OrderedDict, defaultdict
from collections import Counter, defaultdict
from functools import partial
from django.core.exceptions import AppRegistryNotReady, ImproperlyConfigured
@ -31,10 +31,10 @@ class Apps:
# and whether the registry has been populated. Since it isn't possible
# to reimport a module safely (it could reexecute initialization code)
# all_models is never overridden or reset.
self.all_models = defaultdict(OrderedDict)
self.all_models = defaultdict(dict)
# Mapping of labels to AppConfig instances for installed apps.
self.app_configs = OrderedDict()
self.app_configs = {}
# Stack of app_configs. Used to store the current state in
# set_available_apps and set_installed_apps.
@ -316,10 +316,11 @@ class Apps:
)
self.stored_app_configs.append(self.app_configs)
self.app_configs = OrderedDict(
(label, app_config)
self.app_configs = {
label: app_config
for label, app_config in self.app_configs.items()
if app_config.name in available)
if app_config.name in available
}
self.clear_cache()
def unset_available_apps(self):
@ -347,7 +348,7 @@ class Apps:
if not self.ready:
raise AppRegistryNotReady("App registry isn't ready yet.")
self.stored_app_configs.append(self.app_configs)
self.app_configs = OrderedDict()
self.app_configs = {}
self.apps_ready = self.models_ready = self.loading = self.ready = False
self.clear_cache()
self.populate(installed)

View File

@ -2,7 +2,6 @@ import copy
import json
import operator
import re
from collections import OrderedDict
from functools import partial, reduce, update_wrapper
from urllib.parse import quote as urlquote
@ -682,10 +681,7 @@ class ModelAdmin(BaseModelAdmin):
exclude = exclude or None
# Remove declared form fields which are in readonly_fields.
new_attrs = OrderedDict.fromkeys(
f for f in readonly_fields
if f in self.form.declared_fields
)
new_attrs = dict.fromkeys(f for f in readonly_fields if f in self.form.declared_fields)
form = type(self.form.__name__, (self.form,), new_attrs)
defaults = {
@ -886,13 +882,9 @@ class ModelAdmin(BaseModelAdmin):
# If self.actions is set to None that means actions are disabled on
# this page.
if self.actions is None or IS_POPUP_VAR in request.GET:
return OrderedDict()
return {}
actions = self._filter_actions_by_permissions(request, self._get_base_actions())
# Convert the actions into an OrderedDict keyed by name.
return OrderedDict(
(name, (func, name, desc))
for func, name, desc in actions
)
return {name: (func, name, desc) for func, name, desc in actions}
def get_action_choices(self, request, default_choices=BLANK_CHOICE_DASH):
"""

View File

@ -1,4 +1,3 @@
from collections import OrderedDict
from datetime import datetime, timedelta
from django.conf import settings
@ -361,12 +360,12 @@ class ChangeList:
def get_ordering_field_columns(self):
"""
Return an OrderedDict of ordering field column numbers and asc/desc.
Return a dictionary 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 = OrderedDict()
ordering_fields = {}
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

@ -4,7 +4,6 @@ import functools
import hashlib
import importlib
import warnings
from collections import OrderedDict
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
@ -256,12 +255,12 @@ class PBKDF2PasswordHasher(BasePasswordHasher):
def safe_summary(self, encoded):
algorithm, iterations, salt, hash = encoded.split('$', 3)
assert algorithm == self.algorithm
return OrderedDict([
(_('algorithm'), algorithm),
(_('iterations'), iterations),
(_('salt'), mask_hash(salt)),
(_('hash'), mask_hash(hash)),
])
return {
_('algorithm'): algorithm,
_('iterations'): iterations,
_('salt'): mask_hash(salt),
_('hash'): mask_hash(hash),
}
def must_update(self, encoded):
algorithm, iterations, salt, hash = encoded.split('$', 3)
@ -330,16 +329,16 @@ class Argon2PasswordHasher(BasePasswordHasher):
(algorithm, variety, version, time_cost, memory_cost, parallelism,
salt, data) = self._decode(encoded)
assert algorithm == self.algorithm
return OrderedDict([
(_('algorithm'), algorithm),
(_('variety'), variety),
(_('version'), version),
(_('memory cost'), memory_cost),
(_('time cost'), time_cost),
(_('parallelism'), parallelism),
(_('salt'), mask_hash(salt)),
(_('hash'), mask_hash(data)),
])
return {
_('algorithm'): algorithm,
_('variety'): variety,
_('version'): version,
_('memory cost'): memory_cost,
_('time cost'): time_cost,
_('parallelism'): parallelism,
_('salt'): mask_hash(salt),
_('hash'): mask_hash(data),
}
def must_update(self, encoded):
(algorithm, variety, version, time_cost, memory_cost, parallelism,
@ -426,12 +425,12 @@ class BCryptSHA256PasswordHasher(BasePasswordHasher):
algorithm, empty, algostr, work_factor, data = encoded.split('$', 4)
assert algorithm == self.algorithm
salt, checksum = data[:22], data[22:]
return OrderedDict([
(_('algorithm'), algorithm),
(_('work factor'), work_factor),
(_('salt'), mask_hash(salt)),
(_('checksum'), mask_hash(checksum)),
])
return {
_('algorithm'): algorithm,
_('work factor'): work_factor,
_('salt'): mask_hash(salt),
_('checksum'): mask_hash(checksum),
}
def must_update(self, encoded):
algorithm, empty, algostr, rounds, data = encoded.split('$', 4)
@ -486,11 +485,11 @@ class SHA1PasswordHasher(BasePasswordHasher):
def safe_summary(self, encoded):
algorithm, salt, hash = encoded.split('$', 2)
assert algorithm == self.algorithm
return OrderedDict([
(_('algorithm'), algorithm),
(_('salt'), mask_hash(salt, show=2)),
(_('hash'), mask_hash(hash)),
])
return {
_('algorithm'): algorithm,
_('salt'): mask_hash(salt, show=2),
_('hash'): mask_hash(hash),
}
def harden_runtime(self, password, encoded):
pass
@ -517,11 +516,11 @@ class MD5PasswordHasher(BasePasswordHasher):
def safe_summary(self, encoded):
algorithm, salt, hash = encoded.split('$', 2)
assert algorithm == self.algorithm
return OrderedDict([
(_('algorithm'), algorithm),
(_('salt'), mask_hash(salt, show=2)),
(_('hash'), mask_hash(hash)),
])
return {
_('algorithm'): algorithm,
_('salt'): mask_hash(salt, show=2),
_('hash'): mask_hash(hash),
}
def harden_runtime(self, password, encoded):
pass
@ -553,10 +552,10 @@ class UnsaltedSHA1PasswordHasher(BasePasswordHasher):
def safe_summary(self, encoded):
assert encoded.startswith('sha1$$')
hash = encoded[6:]
return OrderedDict([
(_('algorithm'), self.algorithm),
(_('hash'), mask_hash(hash)),
])
return {
_('algorithm'): self.algorithm,
_('hash'): mask_hash(hash),
}
def harden_runtime(self, password, encoded):
pass
@ -589,10 +588,10 @@ class UnsaltedMD5PasswordHasher(BasePasswordHasher):
return constant_time_compare(encoded, encoded_2)
def safe_summary(self, encoded):
return OrderedDict([
(_('algorithm'), self.algorithm),
(_('hash'), mask_hash(encoded, show=3)),
])
return {
_('algorithm'): self.algorithm,
_('hash'): mask_hash(encoded, show=3),
}
def harden_runtime(self, password, encoded):
pass
@ -627,11 +626,11 @@ class CryptPasswordHasher(BasePasswordHasher):
def safe_summary(self, encoded):
algorithm, salt, data = encoded.split('$', 2)
assert algorithm == self.algorithm
return OrderedDict([
(_('algorithm'), algorithm),
(_('salt'), salt),
(_('hash'), mask_hash(data, show=3)),
])
return {
_('algorithm'): algorithm,
_('salt'): salt,
_('hash'): mask_hash(data, show=3),
}
def harden_runtime(self, password, encoded):
pass

View File

@ -1,6 +1,5 @@
import functools
import os
from collections import OrderedDict
from django.apps import apps
from django.conf import settings
@ -54,7 +53,7 @@ class FileSystemFinder(BaseFinder):
# List of locations with static files
self.locations = []
# Maps dir paths to an appropriate storage instance
self.storages = OrderedDict()
self.storages = {}
for root in settings.STATICFILES_DIRS:
if isinstance(root, (list, tuple)):
prefix, root = root
@ -144,7 +143,7 @@ class AppDirectoriesFinder(BaseFinder):
# The list of apps that are handled
self.apps = []
# Mapping of app names to storage instances
self.storages = OrderedDict()
self.storages = {}
app_configs = apps.get_app_configs()
if app_names:
app_names = set(app_names)

View File

@ -1,5 +1,4 @@
import os
from collections import OrderedDict
from django.apps import apps
from django.contrib.staticfiles.finders import get_finders
@ -100,7 +99,7 @@ class Command(BaseCommand):
else:
handler = self.copy_file
found_files = OrderedDict()
found_files = {}
for finder in get_finders():
for path, storage in finder.list(self.ignore_patterns):
# Prefix the relative path if the source storage contains it

View File

@ -4,7 +4,6 @@ import os
import posixpath
import re
import warnings
from collections import OrderedDict
from urllib.parse import unquote, urldefrag, urlsplit, urlunsplit
from django.conf import settings
@ -59,7 +58,7 @@ class HashedFilesMixin:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._patterns = OrderedDict()
self._patterns = {}
self.hashed_files = {}
for extension, patterns in self.patterns:
for pattern in patterns:
@ -208,7 +207,7 @@ class HashedFilesMixin:
def post_process(self, paths, dry_run=False, **options):
"""
Post process the given OrderedDict of files (called from collectstatic).
Post process the given dictionary of files (called from collectstatic).
Processing is actually two separate operations:
@ -225,7 +224,7 @@ class HashedFilesMixin:
return
# where to store the new paths
hashed_files = OrderedDict()
hashed_files = {}
# build a list of adjustable files
adjustable_paths = [
@ -386,20 +385,20 @@ class ManifestFilesMixin(HashedFilesMixin):
def load_manifest(self):
content = self.read_manifest()
if content is None:
return OrderedDict()
return {}
try:
stored = json.loads(content, object_pairs_hook=OrderedDict)
stored = json.loads(content)
except json.JSONDecodeError:
pass
else:
version = stored.get('version')
if version == '1.0':
return stored.get('paths', OrderedDict())
return stored.get('paths', {})
raise ValueError("Couldn't load manifest '%s' (version %s)" %
(self.manifest_name, self.manifest_version))
def post_process(self, *args, **kwargs):
self.hashed_files = OrderedDict()
self.hashed_files = {}
yield from super().post_process(*args, **kwargs)
self.save_manifest()

View File

@ -2,7 +2,7 @@ import functools
import os
import pkgutil
import sys
from collections import OrderedDict, defaultdict
from collections import defaultdict
from difflib import get_close_matches
from importlib import import_module
@ -339,8 +339,8 @@ class ManagementUtility:
# The exception will be raised later in the child process
# started by the autoreloader. Pretend it didn't happen by
# loading an empty list of applications.
apps.all_models = defaultdict(OrderedDict)
apps.app_configs = OrderedDict()
apps.all_models = defaultdict(dict)
apps.app_configs = {}
apps.apps_ready = apps.models_ready = apps.ready = True
# Remove options not compatible with the built-in runserver

View File

@ -1,5 +1,4 @@
import warnings
from collections import OrderedDict
from django.apps import apps
from django.core import serializers
@ -87,14 +86,14 @@ class Command(BaseCommand):
if not app_labels:
if primary_keys:
raise CommandError("You can only use --pks option with one model")
app_list = OrderedDict.fromkeys(
app_list = dict.fromkeys(
app_config for app_config in apps.get_app_configs()
if app_config.models_module is not None and app_config 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 = OrderedDict()
app_list = {}
for label in app_labels:
try:
app_label, model_label = label.split('.')

View File

@ -1,6 +1,5 @@
import keyword
import re
from collections import OrderedDict
from django.core.management.base import BaseCommand, CommandError
from django.db import DEFAULT_DB_ALIAS, connections
@ -98,7 +97,7 @@ class Command(BaseCommand):
column_to_field_name = {} # Maps column names to names of model fields
for row in table_description:
comment_notes = [] # Holds Field notes, to be displayed in a Python comment.
extra_params = OrderedDict() # Holds Field parameters such as 'db_column'.
extra_params = {} # Holds Field parameters such as 'db_column'.
column_name = row.name
is_relation = column_name in relations
@ -232,7 +231,7 @@ class Command(BaseCommand):
description, this routine will return the given field type name, as
well as any additional keyword parameters and notes for the field.
"""
field_params = OrderedDict()
field_params = {}
field_notes = []
try:

View File

@ -1,5 +1,4 @@
import time
from collections import OrderedDict
from importlib import import_module
from django.apps import apps
@ -314,10 +313,10 @@ class Command(BaseCommand):
(opts.auto_created and converter(opts.auto_created._meta.db_table) in tables)
)
manifest = OrderedDict(
(app_name, list(filter(model_installed, model_list)))
manifest = {
app_name: list(filter(model_installed, model_list))
for app_name, model_list in all_models
)
}
# Create the tables for each model
if self.verbosity >= 1:

View File

@ -3,7 +3,6 @@ A Python "serializer". Doesn't do much serializing per se -- just converts to
and from basic Python data types (lists, dicts, strings, etc.). Useful as a basis for
other serializers.
"""
from collections import OrderedDict
from django.apps import apps
from django.core.serializers import base
@ -26,14 +25,14 @@ class Serializer(base.Serializer):
pass
def start_object(self, obj):
self._current = OrderedDict()
self._current = {}
def end_object(self, obj):
self.objects.append(self.get_dump_object(obj))
self._current = None
def get_dump_object(self, obj):
data = OrderedDict([('model', str(obj._meta))])
data = {'model': str(obj._meta)}
if not self.use_natural_primary_keys or not hasattr(obj, 'natural_key'):
data["pk"] = self._value_from_field(obj, obj._meta.pk)
data['fields'] = self._current

View File

@ -34,6 +34,9 @@ class DjangoSafeDumper(SafeDumper):
DjangoSafeDumper.add_representer(decimal.Decimal, DjangoSafeDumper.represent_decimal)
DjangoSafeDumper.add_representer(collections.OrderedDict, DjangoSafeDumper.represent_ordered_dict)
# Workaround to represent dictionaries in insertion order.
# See https://github.com/yaml/pyyaml/pull/143.
DjangoSafeDumper.add_representer(dict, DjangoSafeDumper.represent_ordered_dict)
class Serializer(PythonSerializer):

View File

@ -8,7 +8,6 @@ import math
import re
import types
import uuid
from collections import OrderedDict
from django.conf import SettingsReference
from django.db import models
@ -273,25 +272,26 @@ class UUIDSerializer(BaseSerializer):
class Serializer:
_registry = OrderedDict([
(frozenset, FrozensetSerializer),
(list, SequenceSerializer),
(set, SetSerializer),
(tuple, TupleSerializer),
(dict, DictionarySerializer),
(enum.Enum, EnumSerializer),
(datetime.datetime, DatetimeDatetimeSerializer),
((datetime.date, datetime.timedelta, datetime.time), DateTimeSerializer),
(SettingsReference, SettingsReferenceSerializer),
(float, FloatSerializer),
((bool, int, type(None), bytes, str), BaseSimpleSerializer),
(decimal.Decimal, DecimalSerializer),
((functools.partial, functools.partialmethod), FunctoolsPartialSerializer),
((types.FunctionType, types.BuiltinFunctionType, types.MethodType), FunctionTypeSerializer),
(collections.abc.Iterable, IterableSerializer),
((COMPILED_REGEX_TYPE, RegexObject), RegexSerializer),
(uuid.UUID, UUIDSerializer),
])
_registry = {
# Some of these are order-dependent.
frozenset: FrozensetSerializer,
list: SequenceSerializer,
set: SetSerializer,
tuple: TupleSerializer,
dict: DictionarySerializer,
enum.Enum: EnumSerializer,
datetime.datetime: DatetimeDatetimeSerializer,
(datetime.date, datetime.timedelta, datetime.time): DateTimeSerializer,
SettingsReference: SettingsReferenceSerializer,
float: FloatSerializer,
(bool, int, type(None), bytes, str): BaseSimpleSerializer,
decimal.Decimal: DecimalSerializer,
(functools.partial, functools.partialmethod): FunctoolsPartialSerializer,
(types.FunctionType, types.BuiltinFunctionType, types.MethodType): FunctionTypeSerializer,
collections.abc.Iterable: IterableSerializer,
(COMPILED_REGEX_TYPE, RegexObject): RegexSerializer,
uuid.UUID: UUIDSerializer,
}
@classmethod
def register(cls, type_, serializer):

View File

@ -1,5 +1,4 @@
import copy
from collections import OrderedDict
from contextlib import contextmanager
from django.apps import AppConfig
@ -334,7 +333,7 @@ class StateApps(Apps):
if app_label not in self.app_configs:
self.app_configs[app_label] = AppConfigStub(app_label)
self.app_configs[app_label].apps = self
self.app_configs[app_label].models = OrderedDict()
self.app_configs[app_label].models = {}
self.app_configs[app_label].models[model._meta.model_name] = model
self.do_pending_operations(model)
self.clear_cache()

View File

@ -1,4 +1,4 @@
from collections import Counter, OrderedDict
from collections import Counter
from operator import attrgetter
from django.db import IntegrityError, connections, transaction
@ -64,7 +64,7 @@ class Collector:
def __init__(self, using):
self.using = using
# Initially, {model: {instances}}, later values become lists.
self.data = OrderedDict()
self.data = {}
self.field_updates = {} # {model: {(field, value): {instances}}}
# fast_deletes is a list of queryset-likes that can be deleted without
# fetching the objects into memory.
@ -257,8 +257,7 @@ class Collector:
found = True
if not found:
return
self.data = OrderedDict((model, self.data[model])
for model in sorted_models)
self.data = {model: self.data[model] for model in sorted_models}
def delete(self):
# sort instance collections

View File

@ -1,7 +1,7 @@
import copy
import inspect
from bisect import bisect
from collections import OrderedDict, defaultdict
from collections import defaultdict
from django.apps import apps
from django.conf import settings
@ -117,7 +117,7 @@ class Options:
# concrete models, the concrete_model is always the class itself.
self.concrete_model = None
self.swappable = None
self.parents = OrderedDict()
self.parents = {}
self.auto_created = False
# List of all lookups defined in ForeignKey 'limit_choices_to' options

View File

@ -5,7 +5,7 @@ The main QuerySet implementation. This provides the public API for the ORM.
import copy
import operator
import warnings
from collections import OrderedDict, namedtuple
from collections import namedtuple
from functools import lru_cache
from itertools import chain
@ -725,7 +725,7 @@ class QuerySet:
query = self.query.chain(sql.UpdateQuery)
query.add_update_values(kwargs)
# Clear any annotations so that they won't be present in subqueries.
query._annotations = None
query.annotations = {}
with transaction.mark_for_rollback_on_error(using=self.db):
rows = query.get_compiler(self.db).execute_sql(CURSOR)
self._result_cache = None
@ -744,7 +744,7 @@ class QuerySet:
query = self.query.chain(sql.UpdateQuery)
query.add_update_fields(values)
# Clear any annotations so that they won't be present in subqueries.
query._annotations = None
query.annotations = {}
self._result_cache = None
return query.get_compiler(self.db).execute_sql(CURSOR)
_update.alters_data = True
@ -1014,7 +1014,7 @@ class QuerySet:
with extra data or aggregations.
"""
self._validate_values_are_expressions(args + tuple(kwargs.values()), method_name='annotate')
annotations = OrderedDict() # To preserve ordering of args
annotations = {}
for arg in args:
# The default_alias property may raise a TypeError.
try:

View File

@ -317,7 +317,7 @@ class SQLCompiler:
), False))
continue
if not self.query._extra or col not in self.query._extra:
if not self.query.extra or col not in self.query.extra:
# 'col' is of the form 'field' or 'field1__field2' or
# '-field1__field2__field', etc.
order_by.extend(self.find_ordering_name(
@ -1438,7 +1438,7 @@ class SQLUpdateCompiler(SQLCompiler):
query = self.query.chain(klass=Query)
query.select_related = False
query.clear_ordering(True)
query._extra = {}
query.extra = {}
query.select = []
query.add_fields([query.get_meta().pk.name])
super().pre_sql_setup()

View File

@ -8,7 +8,7 @@ all about the internals of models in order to get the information it needs.
"""
import difflib
import functools
from collections import Counter, OrderedDict, namedtuple
from collections import Counter, namedtuple
from collections.abc import Iterator, Mapping
from itertools import chain, count, product
from string import ascii_uppercase
@ -152,7 +152,7 @@ class Query:
# types they are. The key is the alias of the joined table (possibly
# the table name) and the value is a Join-like object (see
# sql.datastructures.Join for more information).
self.alias_map = OrderedDict()
self.alias_map = {}
# Sometimes the query contains references to aliases in outer queries (as
# a result of split_exclude). Correct alias quoting needs to know these
# aliases too.
@ -199,10 +199,7 @@ class Query:
self.values_select = ()
# SQL annotation-related attributes
# The _annotations will be an OrderedDict when used. Due to the cost
# of creating OrderedDict this attribute is created lazily (in
# self.annotations property).
self._annotations = None # Maps alias -> Annotation Expression
self.annotations = {} # Maps alias -> Annotation Expression
self.annotation_select_mask = None
self._annotation_select_cache = None
@ -213,9 +210,7 @@ class Query:
# These are for extensions. The contents are more or less appended
# verbatim to the appropriate clause.
# The _extra attribute is an OrderedDict, lazily created similarly to
# .annotations
self._extra = None # Maps col_alias -> (col_sql, params).
self.extra = {} # Maps col_alias -> (col_sql, params).
self.extra_select_mask = None
self._extra_select_cache = None
@ -233,18 +228,6 @@ class Query:
self.explain_format = None
self.explain_options = {}
@property
def extra(self):
if self._extra is None:
self._extra = OrderedDict()
return self._extra
@property
def annotations(self):
if self._annotations is None:
self._annotations = OrderedDict()
return self._annotations
@property
def has_select_fields(self):
return bool(self.select or self.annotation_select_mask or self.extra_select_mask)
@ -311,7 +294,7 @@ class Query:
obj.external_aliases = self.external_aliases.copy()
obj.table_map = self.table_map.copy()
obj.where = self.where.clone()
obj._annotations = self._annotations.copy() if self._annotations is not None else None
obj.annotations = self.annotations.copy()
if self.annotation_select_mask is None:
obj.annotation_select_mask = None
else:
@ -322,7 +305,7 @@ class Query:
# It will get re-populated in the cloned queryset the next time it's
# used.
obj._annotation_select_cache = None
obj._extra = self._extra.copy() if self._extra is not None else None
obj.extra = self.extra.copy()
if self.extra_select_mask is None:
obj.extra_select_mask = None
else:
@ -479,7 +462,7 @@ class Query:
outer_query = self
self.select = ()
self.default_cols = False
self._extra = {}
self.extra = {}
outer_query.clear_ordering(True)
outer_query.clear_limits()
@ -613,7 +596,7 @@ class Query:
# It would be nice to be able to handle this, but the queries don't
# really make sense (or return consistent value sets). Not worth
# the extra complexity when you can write a real query instead.
if self._extra and rhs._extra:
if self.extra and rhs.extra:
raise ValueError("When merging querysets using 'or', you cannot have extra(select=…) on both sides.")
self.extra.update(rhs.extra)
extra_select_mask = set()
@ -825,9 +808,9 @@ class Query:
if isinstance(self.group_by, tuple):
self.group_by = tuple([col.relabeled_clone(change_map) for col in self.group_by])
self.select = tuple([col.relabeled_clone(change_map) for col in self.select])
self._annotations = self._annotations and OrderedDict(
(key, col.relabeled_clone(change_map)) for key, col in self._annotations.items()
)
self.annotations = self.annotations and {
key: col.relabeled_clone(change_map) for key, col in self.annotations.items()
}
# 2. Rename the alias in the internal table/alias datastructures.
for old_alias, new_alias in change_map.items():
@ -887,11 +870,10 @@ class Query:
)
self.subq_aliases = self.subq_aliases.union([self.alias_prefix])
outer_query.subq_aliases = outer_query.subq_aliases.union(self.subq_aliases)
change_map = OrderedDict()
for pos, alias in enumerate(self.alias_map):
new_alias = '%s%d' % (self.alias_prefix, pos)
change_map[alias] = new_alias
self.change_aliases(change_map)
self.change_aliases({
alias: '%s%d' % (self.alias_prefix, pos)
for pos, alias in enumerate(self.alias_map)
})
def get_initial_alias(self):
"""
@ -1042,7 +1024,7 @@ class Query:
Solve the lookup type from the lookup (e.g.: 'foobar__id__icontains').
"""
lookup_splitted = lookup.split(LOOKUP_SEP)
if self._annotations:
if self.annotations:
expression, expression_lookups = refs_expression(lookup_splitted, self.annotations)
if expression:
return expression_lookups, (), expression
@ -1867,7 +1849,7 @@ class Query:
# dictionary with their parameters in 'select_params' so that
# subsequent updates to the select dictionary also adjust the
# parameters appropriately.
select_pairs = OrderedDict()
select_pairs = {}
if select_params:
param_iter = iter(select_params)
else:
@ -1881,7 +1863,6 @@ class Query:
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 an OrderedDict.
self.extra.update(select_pairs)
if where or params:
self.where.add(ExtraWhere(where, params), AND)
@ -1998,7 +1979,7 @@ class Query:
field_names = []
extra_names = []
annotation_names = []
if not self._extra and not self._annotations:
if not self.extra and not self.annotations:
# Shortcut - if there are no extra or annotations, then
# the values() clause must be just field names.
field_names = list(fields)
@ -2022,18 +2003,18 @@ class Query:
@property
def annotation_select(self):
"""
Return the OrderedDict of aggregate columns that are not masked and
Return the dictionary of aggregate columns that are not masked and
should be used in the SELECT clause. Cache this result for performance.
"""
if self._annotation_select_cache is not None:
return self._annotation_select_cache
elif not self._annotations:
elif not self.annotations:
return {}
elif self.annotation_select_mask is not None:
self._annotation_select_cache = OrderedDict(
(k, v) for k, v in self.annotations.items()
self._annotation_select_cache = {
k: v for k, v in self.annotations.items()
if k in self.annotation_select_mask
)
}
return self._annotation_select_cache
else:
return self.annotations
@ -2042,13 +2023,13 @@ class Query:
def extra_select(self):
if self._extra_select_cache is not None:
return self._extra_select_cache
if not self._extra:
if not self.extra:
return {}
elif self.extra_select_mask is not None:
self._extra_select_cache = OrderedDict(
(k, v) for k, v in self.extra.items()
self._extra_select_cache = {
k: v for k, v in self.extra.items()
if k in self.extra_select_mask
)
}
return self._extra_select_cache
else:
return self.extra

View File

@ -3,7 +3,6 @@ Form classes
"""
import copy
from collections import OrderedDict
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
# BoundField is imported for backwards compatibility in Django 1.9
@ -31,12 +30,12 @@ class DeclarativeFieldsMetaclass(MediaDefiningClass):
if isinstance(value, Field):
current_fields.append((key, value))
attrs.pop(key)
attrs['declared_fields'] = OrderedDict(current_fields)
attrs['declared_fields'] = dict(current_fields)
new_class = super(DeclarativeFieldsMetaclass, mcs).__new__(mcs, name, bases, attrs)
# Walk through the MRO.
declared_fields = OrderedDict()
declared_fields = {}
for base in reversed(new_class.__mro__):
# Collect fields from base class.
if hasattr(base, 'declared_fields'):
@ -52,11 +51,6 @@ class DeclarativeFieldsMetaclass(MediaDefiningClass):
return new_class
@classmethod
def __prepare__(metacls, name, bases, **kwds):
# Remember the order in which form fields are defined.
return OrderedDict()
@html_safe
class BaseForm:
@ -129,7 +123,7 @@ class BaseForm:
"""
if field_order is None:
return
fields = OrderedDict()
fields = {}
for key in field_order:
try:
fields[key] = self.fields.pop(key)

View File

@ -3,7 +3,6 @@ Helper functions for creating Form classes from Django models
and database field objects.
"""
from collections import OrderedDict
from itertools import chain
from django.core.exceptions import (
@ -105,7 +104,7 @@ def fields_for_model(model, fields=None, exclude=None, widgets=None,
labels=None, help_texts=None, error_messages=None,
field_classes=None, *, apply_limit_choices_to=True):
"""
Return an ``OrderedDict`` containing form fields for the given model.
Return a dictionary containing form fields for the given model.
``fields`` is an optional list of field names. If provided, return only the
named fields.
@ -134,7 +133,7 @@ def fields_for_model(model, fields=None, exclude=None, widgets=None,
``apply_limit_choices_to`` is a boolean indicating if limit_choices_to
should be applied to a field's queryset.
"""
field_list = []
field_dict = {}
ignored = []
opts = model._meta
# Avoid circular import
@ -178,15 +177,14 @@ def fields_for_model(model, fields=None, exclude=None, widgets=None,
if formfield:
if apply_limit_choices_to:
apply_limit_choices_to_to_formfield(formfield)
field_list.append((f.name, formfield))
field_dict[f.name] = formfield
else:
ignored.append(f.name)
field_dict = OrderedDict(field_list)
if fields:
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)]
)
field_dict = {
f: field_dict.get(f) for f in fields
if (not exclude or f not in exclude) and f not in ignored
}
return field_dict

View File

@ -1,5 +1,5 @@
import functools
from collections import Counter, OrderedDict
from collections import Counter
from pathlib import Path
from django.apps import apps
@ -27,7 +27,7 @@ class EngineHandler:
if self._templates is None:
self._templates = settings.TEMPLATES
templates = OrderedDict()
templates = {}
backend_names = []
for tpl in self._templates:
try:

View File

@ -1,4 +1,3 @@
import collections
import logging
import re
import sys
@ -280,8 +279,7 @@ def get_unique_databases_and_mirrors(aliases=None):
if alias != DEFAULT_DB_ALIAS and connection.creation.test_db_signature() != default_sig:
dependencies[alias] = test_settings.get('DEPENDENCIES', [DEFAULT_DB_ALIAS])
test_databases = dependency_ordered(test_databases.items(), dependencies)
test_databases = collections.OrderedDict(test_databases)
test_databases = dict(dependency_ordered(test_databases.items(), dependencies))
return test_databases, mirrored_aliases

View File

@ -1,16 +1,14 @@
import copy
from collections import OrderedDict
from collections.abc import Mapping
class OrderedSet:
"""
A set which keeps the ordering of the inserted items.
Currently backs onto OrderedDict.
"""
def __init__(self, iterable=None):
self.dict = OrderedDict.fromkeys(iterable or ())
self.dict = dict.fromkeys(iterable or ())
def add(self, item):
self.dict[item] = None

View File

@ -5,7 +5,6 @@ import os
import re
import sys
import warnings
from collections import OrderedDict
from threading import local
from django.apps import apps
@ -385,9 +384,9 @@ def check_for_language(lang_code):
@functools.lru_cache()
def get_languages():
"""
Cache of settings.LANGUAGES in an OrderedDict for easy lookups by key.
Cache of settings.LANGUAGES in a dictionary for easy lookups by key.
"""
return OrderedDict(settings.LANGUAGES)
return dict(settings.LANGUAGES)
@functools.lru_cache(maxsize=1000)

View File

@ -3,7 +3,6 @@ Utilities for XML generation/parsing.
"""
import re
from collections import OrderedDict
from xml.sax.saxutils import XMLGenerator
@ -30,5 +29,5 @@ class SimplerXMLGenerator(XMLGenerator):
def startElement(self, name, attrs):
# Sort attrs for a deterministic output.
sorted_attrs = OrderedDict(sorted(attrs.items())) if attrs else attrs
sorted_attrs = dict(sorted(attrs.items())) if attrs else attrs
super().startElement(name, sorted_attrs)

View File

@ -1363,17 +1363,14 @@ of the arguments is required, but you should use at least one of them.
In some rare cases, you might wish to pass parameters to the SQL
fragments in ``extra(select=...)``. For this purpose, use the
``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:`collections.OrderedDict` for
the ``select`` value, not just a normal Python dictionary.
``select_params`` parameter.
This will work, for example::
Blog.objects.extra(
select=OrderedDict([('a', '%s'), ('b', '%s')]),
select_params=('one', 'two'))
select={'a': '%s', 'b': '%s'},
select_params=('one', 'two'),
)
If you need to use a literal ``%s`` inside your select string, use
the sequence ``%%s``.

View File

@ -1,5 +1,4 @@
import datetime
from collections import OrderedDict
from django.contrib.auth.models import User
from django.test import TestCase
@ -73,10 +72,7 @@ class ExtraRegressTests(TestCase):
# Extra select parameters should stay tied to their corresponding
# select portions. Applies when portions are updated or otherwise
# moved around.
qs = User.objects.extra(
select=OrderedDict((("alpha", "%s"), ("beta", "2"), ("gamma", "%s"))),
select_params=(1, 3)
)
qs = User.objects.extra(select={'alpha': '%s', 'beta': "2", 'gamma': '%s'}, select_params=(1, 3))
qs = qs.extra(select={"beta": 4})
qs = qs.extra(select={"alpha": "%s"}, select_params=[5])
self.assertEqual(
@ -184,7 +180,7 @@ class ExtraRegressTests(TestCase):
self.assertEqual(
list(
TestObject.objects
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
.values()
),
[{
@ -198,7 +194,7 @@ class ExtraRegressTests(TestCase):
list(
TestObject.objects
.values()
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
),
[{
'bar': 'second', 'third': 'third', 'second': 'second', 'whiz': 'third', 'foo': 'first',
@ -210,7 +206,7 @@ class ExtraRegressTests(TestCase):
self.assertEqual(
list(
TestObject.objects
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
.values('first', 'second')
),
[{'second': 'second', 'first': 'first'}]
@ -221,7 +217,7 @@ class ExtraRegressTests(TestCase):
list(
TestObject.objects
.values('first', 'second')
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
),
[{'second': 'second', 'first': 'first'}]
)
@ -230,7 +226,7 @@ class ExtraRegressTests(TestCase):
self.assertEqual(
list(
TestObject.objects
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
.values('first', 'second', 'foo')
),
[{'second': 'second', 'foo': 'first', 'first': 'first'}]
@ -240,7 +236,7 @@ class ExtraRegressTests(TestCase):
self.assertEqual(
list(
TestObject.objects
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
.values('foo', 'whiz')
),
[{'foo': 'first', 'whiz': 'third'}]
@ -251,7 +247,7 @@ class ExtraRegressTests(TestCase):
self.assertEqual(
list(
TestObject.objects
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
.values_list()
),
[('first', 'second', 'third', obj.pk, 'first', 'second', 'third')]
@ -262,7 +258,7 @@ class ExtraRegressTests(TestCase):
list(
TestObject.objects
.values_list()
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
),
[('first', 'second', 'third', obj.pk, 'first', 'second', 'third')]
)
@ -271,7 +267,7 @@ class ExtraRegressTests(TestCase):
self.assertEqual(
list(
TestObject.objects
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
.values_list('first', 'second')
),
[('first', 'second')]
@ -282,7 +278,7 @@ class ExtraRegressTests(TestCase):
list(
TestObject.objects
.values_list('first', 'second')
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
),
[('first', 'second')]
)
@ -290,7 +286,7 @@ class ExtraRegressTests(TestCase):
self.assertEqual(
list(
TestObject.objects
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
.values_list('second', flat=True)
),
['second']
@ -300,7 +296,7 @@ class ExtraRegressTests(TestCase):
self.assertEqual(
list(
TestObject.objects
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
.values_list('first', 'second', 'whiz')
),
[('first', 'second', 'third')]
@ -310,7 +306,7 @@ class ExtraRegressTests(TestCase):
self.assertEqual(
list(
TestObject.objects
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
.values_list('foo', 'whiz')
),
[('first', 'third')]
@ -319,7 +315,7 @@ class ExtraRegressTests(TestCase):
self.assertEqual(
list(
TestObject.objects
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
.values_list('whiz', flat=True)
),
['third']
@ -329,7 +325,7 @@ class ExtraRegressTests(TestCase):
self.assertEqual(
list(
TestObject.objects
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
.values_list('whiz', 'foo')
),
[('third', 'first')]
@ -338,7 +334,7 @@ class ExtraRegressTests(TestCase):
self.assertEqual(
list(
TestObject.objects
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
.values_list('first', 'id')
),
[('first', obj.pk)]
@ -347,7 +343,7 @@ class ExtraRegressTests(TestCase):
self.assertEqual(
list(
TestObject.objects
.extra(select=OrderedDict((('foo', 'first'), ('bar', 'second'), ('whiz', 'third'))))
.extra(select={'foo': 'first', 'bar': 'second', 'whiz': 'third'})
.values_list('whiz', 'first', 'bar', 'id')
),
[('third', 'first', 'second', obj.pk)]

View File

@ -1,7 +1,6 @@
import datetime
import pickle
import unittest
from collections import OrderedDict
from operator import attrgetter
from django.core.exceptions import EmptyResultSet, FieldError
@ -543,31 +542,6 @@ class Queries1Tests(TestCase):
# ...or use the field name.
self.assertSequenceEqual(ExtraInfo.objects.values('note'), [{'note': 1}, {'note': 2}])
def test_ticket2902(self):
# 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
# normal. A normal dict would thus fail.)
s = [('a', '%s'), ('b', '%s')]
params = ['one', 'two']
if list({'a': 1, 'b': 2}) == ['a', 'b']:
s.reverse()
params.reverse()
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.
qs = (
Item.objects
.extra(select={
'count': 'select count(*) from queries_item_tags where queries_item_tags.item_id = queries_item.id'
})
.order_by('-count')
)
self.assertEqual([o.count for o in qs], [2, 2, 1, 0])
def test_ticket6154(self):
# Multiple filter statements are joined using "AND" all the time.
@ -2249,9 +2223,7 @@ class ValuesQuerysetTests(TestCase):
def test_extra_values(self):
# testing for ticket 14930 issues
qs = Number.objects.extra(select=OrderedDict([('value_plus_x', 'num+%s'),
('value_minus_x', 'num-%s')]),
select_params=(1, 2))
qs = Number.objects.extra(select={'value_plus_x': 'num+%s', 'value_minus_x': 'num-%s'}, select_params=(1, 2))
qs = qs.order_by('value_minus_x')
qs = qs.values('num')
self.assertSequenceEqual(qs, [{'num': 72}])
@ -2295,9 +2267,7 @@ class ValuesQuerysetTests(TestCase):
def test_extra_multiple_select_params_values_order_by(self):
# testing for 23259 issue
qs = Number.objects.extra(select=OrderedDict([('value_plus_x', 'num+%s'),
('value_minus_x', 'num-%s')]),
select_params=(72, 72))
qs = Number.objects.extra(select={'value_plus_x': 'num+%s', 'value_minus_x': 'num-%s'}, select_params=(72, 72))
qs = qs.order_by('value_minus_x')
qs = qs.filter(num=1)
qs = qs.values('num')

View File

@ -1,4 +1,3 @@
from collections import OrderedDict
from datetime import date, datetime
from django.conf.urls.i18n import i18n_patterns
@ -102,27 +101,27 @@ fixed_lastmod__mixed_sitemaps = {
'fixed-lastmod-mixed': FixedLastmodMixedSitemap,
}
sitemaps_lastmod_mixed_ascending = OrderedDict([
('no-lastmod', EmptySitemap),
('lastmod', FixedLastmodSitemap),
])
sitemaps_lastmod_mixed_ascending = {
'no-lastmod': EmptySitemap,
'lastmod': FixedLastmodSitemap,
}
sitemaps_lastmod_mixed_descending = OrderedDict([
('lastmod', FixedLastmodSitemap),
('no-lastmod', EmptySitemap),
])
sitemaps_lastmod_mixed_descending = {
'lastmod': FixedLastmodSitemap,
'no-lastmod': EmptySitemap,
}
sitemaps_lastmod_ascending = OrderedDict([
('date', DateSiteMap),
('datetime', FixedLastmodSitemap),
('datetime-newer', FixedNewerLastmodSitemap),
])
sitemaps_lastmod_ascending = {
'date': DateSiteMap,
'datetime': FixedLastmodSitemap,
'datetime-newer': FixedNewerLastmodSitemap,
}
sitemaps_lastmod_descending = OrderedDict([
('datetime-newer', FixedNewerLastmodSitemap),
('datetime', FixedLastmodSitemap),
('date', DateSiteMap),
])
sitemaps_lastmod_descending = {
'datetime-newer': FixedNewerLastmodSitemap,
'datetime': FixedLastmodSitemap,
'date': DateSiteMap,
}
generic_sitemaps = {
'generic': GenericSitemap({'queryset': TestModel.objects.order_by('pk').all()}),