Keep dict key order for Python 3.7

master
Cristi Vîjdea 2019-01-14 14:25:07 +02:00 committed by Cristi Vijdea
parent 0e62fd6f2b
commit 762467285c
2 changed files with 18 additions and 6 deletions

View File

@ -10,7 +10,7 @@ from django.urls import get_script_prefix
from django.utils.functional import Promise from django.utils.functional import Promise
from inflection import camelize from inflection import camelize
from .utils import filter_none, force_real_str from .utils import dict_has_ordered_keys, filter_none, force_real_str
try: try:
from collections import abc as collections_abc from collections import abc as collections_abc
@ -145,7 +145,7 @@ class SwaggerDict(OrderedDict):
result = OrderedDict() result = OrderedDict()
memo[id(obj)] = result memo[id(obj)] = result
items = obj.items() items = obj.items()
if not isinstance(obj, OrderedDict): if not dict_has_ordered_keys(obj):
items = sorted(items) items = sorted(items)
for attr, val in items: for attr, val in items:
result[attr] = SwaggerDict._as_odict(val, memo) result[attr] = SwaggerDict._as_odict(val, memo)

View File

@ -1,5 +1,6 @@
import inspect import inspect
import logging import logging
import sys
from collections import OrderedDict from collections import OrderedDict
from django.db import models from django.db import models
@ -389,8 +390,7 @@ def get_produces(renderer_classes):
def decimal_as_float(field): def decimal_as_float(field):
""" """Returns true if ``field`` is a django-rest-framework DecimalField and its ``coerce_to_string`` attribute or the
Returns true if ``field`` is a django-rest-framework DecimalField and its ``coerce_to_string`` attribute or the
``COERCE_DECIMAL_TO_STRING`` setting is set to ``False``. ``COERCE_DECIMAL_TO_STRING`` setting is set to ``False``.
:rtype: bool :rtype: bool
@ -401,8 +401,7 @@ def decimal_as_float(field):
def get_serializer_ref_name(serializer): def get_serializer_ref_name(serializer):
""" """Get serializer's ref_name (or None for ModelSerializer if it is named 'NestedSerializer')
Get serializer's ref_name (or None for ModelSerializer if it is named 'NestedSerializer')
:param serializer: Serializer instance :param serializer: Serializer instance
:return: Serializer's ``ref_name`` or ``None`` for inline serializer :return: Serializer's ``ref_name`` or ``None`` for inline serializer
@ -469,3 +468,16 @@ def get_field_default(field):
default = serializers.empty default = serializers.empty
return default return default
def dict_has_ordered_keys(obj):
"""Check if a given object is a dict that maintains insertion order.
:param obj: the dict object to check
:rtype: bool
"""
if sys.version_info >= (3, 7):
# the Python 3.7 language spec says that dict must maintain insertion order.
return isinstance(obj, dict)
return isinstance(obj, OrderedDict)