Replaced OrderedDict with dict

`dict` is now assumed to be ordered in all currently supported versions of Python
This commit is contained in:
David Smith 2020-09-06 08:39:44 +01:00
parent d5461e93fe
commit 2a52d36460
16 changed files with 81 additions and 93 deletions

View File

@ -6,7 +6,6 @@ import inspect
import re
import uuid
import warnings
from collections import OrderedDict
from collections.abc import Mapping
from django.conf import settings
@ -142,7 +141,7 @@ def to_choices_dict(choices):
# choices = [1, 2, 3]
# choices = [(1, 'First'), (2, 'Second'), (3, 'Third')]
# choices = [('Category', ((1, 'First'), (2, 'Second'))), (3, 'Third')]
ret = OrderedDict()
ret = {}
for choice in choices:
if not isinstance(choice, (list, tuple)):
# single choice
@ -165,7 +164,7 @@ def flatten_choices_dict(choices):
flatten_choices_dict({1: '1st', 2: '2nd'}) -> {1: '1st', 2: '2nd'}
flatten_choices_dict({'Group': {1: '1st', 2: '2nd'}}) -> {1: '1st', 2: '2nd'}
"""
ret = OrderedDict()
ret = {}
for key, value in choices.items():
if isinstance(value, dict):
# grouped choices (category, sub choices)
@ -1662,7 +1661,7 @@ class ListField(Field):
def run_child_validation(self, data):
result = []
errors = OrderedDict()
errors = {}
for idx, item in enumerate(data):
try:
@ -1724,7 +1723,7 @@ class DictField(Field):
def run_child_validation(self, data):
result = {}
errors = OrderedDict()
errors = {}
for key, value in data.items():
key = str(key)

View File

@ -6,8 +6,6 @@ some fairly ad-hoc information about the view.
Future implementations might use JSON schema or other definitions in order
to return this information in a more standardized way.
"""
from collections import OrderedDict
from django.core.exceptions import PermissionDenied
from django.http import Http404
from django.utils.encoding import force_str
@ -59,7 +57,7 @@ class SimpleMetadata(BaseMetadata):
})
def determine_metadata(self, request, view):
metadata = OrderedDict()
metadata = {}
metadata['name'] = view.get_view_name()
metadata['description'] = view.get_view_description()
metadata['renders'] = [renderer.media_type for renderer in view.renderer_classes]
@ -106,7 +104,7 @@ class SimpleMetadata(BaseMetadata):
# If this is a `ListSerializer` then we want to examine the
# underlying child serializer instance instead.
serializer = serializer.child
return OrderedDict([
return dict([
(field_name, self.get_field_info(field))
for field_name, field in serializer.fields.items()
if not isinstance(field, serializers.HiddenField)
@ -117,7 +115,7 @@ class SimpleMetadata(BaseMetadata):
Given an instance of a serializer field, return a dictionary
of metadata about it.
"""
field_info = OrderedDict()
field_info = {}
field_info['type'] = self.label_lookup[field]
field_info['required'] = getattr(field, 'required', False)

View File

@ -3,7 +3,7 @@ Pagination serializers determine the structure of the output that should
be used for paginated responses.
"""
from base64 import b64decode, b64encode
from collections import OrderedDict, namedtuple
from collections import namedtuple
from urllib import parse
from django.core.paginator import InvalidPage
@ -218,12 +218,12 @@ class PageNumberPagination(BasePagination):
return list(self.page)
def get_paginated_response(self, data):
return Response(OrderedDict([
('count', self.page.paginator.count),
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('results', data)
]))
return Response({
'count': self.page.paginator.count,
'next': self.get_next_link(),
'previous': self.get_previous_link(),
'results': data,
})
def get_paginated_response_schema(self, schema):
return {
@ -391,12 +391,12 @@ class LimitOffsetPagination(BasePagination):
return list(queryset[self.offset:self.offset + self.limit])
def get_paginated_response(self, data):
return Response(OrderedDict([
('count', self.count),
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('results', data)
]))
return Response({
'count': self.count,
'next': self.get_next_link(),
'previous': self.get_previous_link(),
'results': data,
})
def get_paginated_response_schema(self, schema):
return {
@ -889,11 +889,11 @@ class CursorPagination(BasePagination):
return str(attr)
def get_paginated_response(self, data):
return Response(OrderedDict([
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('results', data)
]))
return Response({
'next': self.get_next_link(),
'previous': self.get_previous_link(),
'results': data,
})
def get_paginated_response_schema(self, schema):
return {

View File

@ -1,5 +1,4 @@
import sys
from collections import OrderedDict
from urllib import parse
from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
@ -199,7 +198,7 @@ class RelatedField(Field):
if cutoff is not None:
queryset = queryset[:cutoff]
return OrderedDict([
return dict([
(
self.to_representation(item),
self.display_value(item)

View File

@ -7,7 +7,6 @@ on the response, such as JSON encoded data or HTML output.
REST framework also provides an HTML renderer that renders the browsable API.
"""
import base64
from collections import OrderedDict
from urllib import parse
from django import forms
@ -657,7 +656,7 @@ class BrowsableAPIRenderer(BaseRenderer):
raw_data_patch_form = self.get_raw_data_form(data, view, 'PATCH', request)
raw_data_put_or_patch_form = raw_data_put_form or raw_data_patch_form
response_headers = OrderedDict(sorted(response.items()))
response_headers = dict(sorted(response.items()))
renderer_content_type = ''
if renderer:
renderer_content_type = '%s' % renderer.media_type

View File

@ -14,7 +14,7 @@ For example, you might have a `urls.py` that looks something like this:
urlpatterns = router.urls
"""
import itertools
from collections import OrderedDict, namedtuple
from collections import namedtuple
from django.core.exceptions import ImproperlyConfigured
from django.urls import NoReverseMatch, re_path
@ -279,7 +279,7 @@ class APIRootView(views.APIView):
def get(self, request, *args, **kwargs):
# Return a plain {"name": "hyperlink"} response.
ret = OrderedDict()
ret = {}
namespace = request.resolver_match.namespace
for key, url_name in self.api_root_dict.items():
if namespace:
@ -323,7 +323,7 @@ class DefaultRouter(SimpleRouter):
"""
Return a basic root view.
"""
api_root_dict = OrderedDict()
api_root_dict = {}
list_name = self.routes[0].name
for prefix, viewset, basename in self.registry:
api_root_dict[prefix] = list_name.format(basename=basename)

View File

@ -1,5 +1,5 @@
import warnings
from collections import Counter, OrderedDict
from collections import Counter
from urllib import parse
from django.db import models
@ -54,7 +54,7 @@ to customise schema structure.
"""
class LinkNode(OrderedDict):
class LinkNode(dict):
def __init__(self):
self.links = []
self.methods_counter = Counter()
@ -264,7 +264,7 @@ def field_to_schema(field):
)
elif isinstance(field, serializers.Serializer):
return coreschema.Object(
properties=OrderedDict([
properties=dict([
(key, field_to_schema(value))
for key, value
in field.fields.items()
@ -545,7 +545,7 @@ class AutoSchema(ViewInspector):
if not update_with:
return fields
by_name = OrderedDict((f.name, f) for f in fields)
by_name = dict((f.name, f) for f in fields)
for f in update_with:
by_name[f.name] = f
fields = list(by_name.values())

View File

@ -1,6 +1,5 @@
import re
import warnings
from collections import OrderedDict
from decimal import Decimal
from operator import attrgetter
from urllib.parse import urljoin
@ -331,7 +330,7 @@ class AutoSchema(ViewInspector):
return paginator.get_schema_operation_parameters(view)
def map_choicefield(self, field):
choices = list(OrderedDict.fromkeys(field.choices)) # preserve order and remove duplicates
choices = list(dict.fromkeys(field.choices)) # preserve order and remove duplicates
if all(isinstance(choice, bool) for choice in choices):
type = 'boolean'
elif all(isinstance(choice, int) for choice in choices):

View File

@ -13,7 +13,7 @@ response content is handled by parsers and renderers.
import copy
import inspect
import traceback
from collections import OrderedDict, defaultdict
from collections import defaultdict
from collections.abc import Mapping
from django.core.exceptions import FieldDoesNotExist, ImproperlyConfigured
@ -302,7 +302,7 @@ class SerializerMetaclass(type):
for name, f in base._declared_fields.items() if name not in known
]
return OrderedDict(base_fields + fields)
return dict(base_fields + fields)
def __new__(cls, name, bases, attrs):
attrs['_declared_fields'] = cls._get_declared_fields(bases, attrs)
@ -387,16 +387,16 @@ class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
if hasattr(self, 'initial_data'):
# initial_data may not be a valid type
if not isinstance(self.initial_data, Mapping):
return OrderedDict()
return {}
return OrderedDict([
return dict([
(field_name, field.get_value(self.initial_data))
for field_name, field in self.fields.items()
if (field.get_value(self.initial_data) is not empty) and
not field.read_only
])
return OrderedDict([
return dict([
(field.field_name, field.get_initial())
for field in self.fields.values()
if not field.read_only
@ -435,7 +435,7 @@ class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
if (field.read_only) and (field.default != empty) and (field.source != '*') and ('.' not in field.source)
]
defaults = OrderedDict()
defaults = {}
for field in fields:
try:
default = field.get_default()
@ -468,8 +468,8 @@ class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
api_settings.NON_FIELD_ERRORS_KEY: [message]
}, code='invalid')
ret = OrderedDict()
errors = OrderedDict()
ret = {}
errors = {}
fields = self._writable_fields
for field in fields:
@ -497,7 +497,7 @@ class Serializer(BaseSerializer, metaclass=SerializerMetaclass):
"""
Object instance -> Dict of primitive datatypes.
"""
ret = OrderedDict()
ret = {}
fields = self._readable_fields
for field in fields:
@ -1040,7 +1040,7 @@ class ModelSerializer(Serializer):
)
# Determine the fields that should be included on the serializer.
fields = OrderedDict()
fields = {}
for field_name in field_names:
# If the field is explicitly declared on the class then use that.
@ -1517,13 +1517,13 @@ class ModelSerializer(Serializer):
# which may map onto a model field. Any dotted field name lookups
# cannot map to a field, and must be a traversal, so we're not
# including those.
field_sources = OrderedDict(
field_sources = dict(
(field.field_name, field.source) for field in self._writable_fields
if (field.source != '*') and ('.' not in field.source)
)
# Special Case: Add read_only fields with defaults.
field_sources.update(OrderedDict(
field_sources.update(dict(
(field.field_name, field.source) for field in self.fields.values()
if (field.read_only) and (field.default != empty) and (field.source != '*') and ('.' not in field.source)
))

View File

@ -1,5 +1,4 @@
import re
from collections import OrderedDict
from django import template
from django.template import loader
@ -49,7 +48,7 @@ def with_location(fields, location):
@register.simple_tag
def form_for_link(link):
import coreschema
properties = OrderedDict([
properties = dict([
(field.name, field.schema or coreschema.String())
for field in link.fields
])
@ -272,7 +271,7 @@ def schema_links(section, sec_key=None):
links.update(new_links)
if sec_key is not None:
new_links = OrderedDict()
new_links = {}
for link_key, link in links.items():
new_key = NESTED_FORMAT % (sec_key, link_key)
new_links.update({new_key: link})

View File

@ -5,7 +5,7 @@ relationships and their associated metadata.
Usage: `get_field_info(model)` returns a `FieldInfo` instance.
"""
from collections import OrderedDict, namedtuple
from collections import namedtuple
FieldInfo = namedtuple('FieldResult', [
'pk', # Model field instance
@ -58,7 +58,7 @@ def _get_pk(opts):
def _get_fields(opts):
fields = OrderedDict()
fields = {}
for field in [field for field in opts.fields if field.serialize and not field.remote_field]:
fields[field.name] = field
@ -71,9 +71,9 @@ def _get_to_field(field):
def _get_forward_relationships(opts):
"""
Returns an `OrderedDict` of field names to `RelationInfo`.
Returns a `Dict` of field names to `RelationInfo`.
"""
forward_relations = OrderedDict()
forward_relations = {}
for field in [field for field in opts.fields if field.serialize and field.remote_field]:
forward_relations[field.name] = RelationInfo(
model_field=field,
@ -103,9 +103,9 @@ def _get_forward_relationships(opts):
def _get_reverse_relationships(opts):
"""
Returns an `OrderedDict` of field names to `RelationInfo`.
Returns a `Dict` of field names to `RelationInfo`.
"""
reverse_relations = OrderedDict()
reverse_relations = {}
all_related_objects = [r for r in opts.related_objects if not r.field.many_to_many]
for relation in all_related_objects:
accessor_name = relation.get_accessor_name()
@ -139,7 +139,7 @@ def _get_reverse_relationships(opts):
def _merge_fields_and_pk(pk, fields):
fields_and_pk = OrderedDict()
fields_and_pk = {}
fields_and_pk['pk'] = pk
fields_and_pk[pk.name] = pk
fields_and_pk.update(fields)
@ -148,7 +148,7 @@ def _merge_fields_and_pk(pk, fields):
def _merge_relationships(forward_relations, reverse_relations):
return OrderedDict(
return dict(
list(forward_relations.items()) +
list(reverse_relations.items())
)

View File

@ -1,4 +1,3 @@
from collections import OrderedDict
from collections.abc import MutableMapping
from django.utils.encoding import force_str
@ -6,7 +5,7 @@ from django.utils.encoding import force_str
from rest_framework.utils import json
class ReturnDict(OrderedDict):
class ReturnDict(dict):
"""
Return object from `serializer.data` for the `Serializer` class.
Includes a backlink to the serializer instance for renderers
@ -138,7 +137,7 @@ class BindingDict(MutableMapping):
def __init__(self, serializer):
self.serializer = serializer
self.fields = OrderedDict()
self.fields = {}
def __setitem__(self, key, field):
self.fields[key] = field

View File

@ -16,7 +16,6 @@ automatically.
router.register(r'users', UserViewSet, 'user')
urlpatterns = router.urls
"""
from collections import OrderedDict
from functools import update_wrapper
from inspect import getmembers
@ -183,7 +182,7 @@ class ViewSetMixin:
This method will noop if `detail` was not provided as a view initkwarg.
"""
action_urls = OrderedDict()
action_urls = {}
# exit early if `detail` has not been provided
if self.detail is None:

View File

@ -10,7 +10,6 @@ import decimal
import json # noqa
import sys
import tempfile
from collections import OrderedDict
import django
import pytest
@ -778,7 +777,7 @@ class TestRelationalFieldDisplayValue(TestCase):
fields = '__all__'
serializer = TestSerializer()
expected = OrderedDict([(1, 'Red Color'), (2, 'Yellow Color'), (3, 'Green Color')])
expected = {1: 'Red Color', 2: 'Yellow Color', 3: 'Green Color'}
self.assertEqual(serializer.fields['color'].choices, expected)
def test_custom_display_value(self):
@ -794,7 +793,7 @@ class TestRelationalFieldDisplayValue(TestCase):
fields = '__all__'
serializer = TestSerializer()
expected = OrderedDict([(1, 'My Red Color'), (2, 'My Yellow Color'), (3, 'My Green Color')])
expected = {1: 'My Red Color', 2: 'My Yellow Color', 3: 'My Green Color'}
self.assertEqual(serializer.fields['color'].choices, expected)

View File

@ -1,5 +1,4 @@
import re
from collections import OrderedDict
from collections.abc import MutableMapping
import pytest
@ -457,12 +456,12 @@ class CacheRenderTest(TestCase):
class TestJSONIndentationStyles:
def test_indented(self):
renderer = JSONRenderer()
data = OrderedDict([('a', 1), ('b', 2)])
data = {'a': 1, 'b': 2}
assert renderer.render(data) == b'{"a":1,"b":2}'
def test_compact(self):
renderer = JSONRenderer()
data = OrderedDict([('a', 1), ('b', 2)])
data = {'a': 1, 'b': 2}
context = {'indent': 4}
assert (
renderer.render(data, renderer_context=context) ==
@ -472,7 +471,7 @@ class TestJSONIndentationStyles:
def test_long_form(self):
renderer = JSONRenderer()
renderer.compact = False
data = OrderedDict([('a', 1), ('b', 2)])
data = {'a': 1, 'b': 2}
assert renderer.render(data) == b'{"a": 1, "b": 2}'

View File

@ -1,4 +1,3 @@
from collections import OrderedDict
from functools import wraps
import pytest
@ -261,11 +260,11 @@ class GetExtraActionUrlMapTests(TestCase):
response = self.client.get('/api/actions/')
view = response.view
expected = OrderedDict([
('Custom list action', 'http://testserver/api/actions/custom_list_action/'),
('List action', 'http://testserver/api/actions/list_action/'),
('Wrapped list action', 'http://testserver/api/actions/wrapped_list_action/'),
])
expected = {
'Custom list action': 'http://testserver/api/actions/custom_list_action/',
'List action': 'http://testserver/api/actions/list_action/',
'Wrapped list action': 'http://testserver/api/actions/wrapped_list_action/',
}
self.assertEqual(view.get_extra_action_url_map(), expected)
@ -273,28 +272,28 @@ class GetExtraActionUrlMapTests(TestCase):
response = self.client.get('/api/actions/1/')
view = response.view
expected = OrderedDict([
('Custom detail action', 'http://testserver/api/actions/1/custom_detail_action/'),
('Detail action', 'http://testserver/api/actions/1/detail_action/'),
('Wrapped detail action', 'http://testserver/api/actions/1/wrapped_detail_action/'),
expected = {
'Custom detail action': 'http://testserver/api/actions/1/custom_detail_action/',
'Detail action': 'http://testserver/api/actions/1/detail_action/',
'Wrapped detail action': 'http://testserver/api/actions/1/wrapped_detail_action/',
# "Unresolvable detail action" excluded, since it's not resolvable
])
}
self.assertEqual(view.get_extra_action_url_map(), expected)
def test_uninitialized_view(self):
self.assertEqual(ActionViewSet().get_extra_action_url_map(), OrderedDict())
self.assertEqual(ActionViewSet().get_extra_action_url_map(), dict())
def test_action_names(self):
# Action 'name' and 'suffix' kwargs should be respected
response = self.client.get('/api/names/1/')
view = response.view
expected = OrderedDict([
('Custom Name', 'http://testserver/api/names/1/named_action/'),
('Action Names Custom Suffix', 'http://testserver/api/names/1/suffixed_action/'),
('Unnamed action', 'http://testserver/api/names/1/unnamed_action/'),
])
expected = {
'Custom Name': 'http://testserver/api/names/1/named_action/',
'Action Names Custom Suffix': 'http://testserver/api/names/1/suffixed_action/',
'Unnamed action': 'http://testserver/api/names/1/unnamed_action/',
}
self.assertEqual(view.get_extra_action_url_map(), expected)