From 07c5c968ce8b06c7ebbcc91a070aa492510611b2 Mon Sep 17 00:00:00 2001 From: Charlie Hornsby Date: Mon, 25 Feb 2019 10:17:04 +0200 Subject: [PATCH] Fix DeprecationWarning when accessing collections.abc classes via collections (#6268) * Use compat version of collections.abc.Mapping Since the Mapping class will no longer be available to import directly from the collections module in Python 3.8, we should use the compatibility helper introduced in #6154 in the fields module. * Alias and use compat version of collections.abc.MutableMapping Since the MutableMapping class will no longer be available to import directly from the collections module in Python 3.8, we should create an alias for it in the compat module and use that instead. --- rest_framework/compat.py | 4 ++-- rest_framework/fields.py | 7 +++---- rest_framework/utils/serializer_helpers.py | 5 ++--- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/rest_framework/compat.py b/rest_framework/compat.py index 5a4bcdf66..59217c587 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -12,10 +12,10 @@ from django.views.generic import View try: # Python 3 - from collections.abc import Mapping # noqa + from collections.abc import Mapping, MutableMapping # noqa except ImportError: # Python 2.7 - from collections import Mapping # noqa + from collections import Mapping, MutableMapping # noqa try: from django.urls import ( # noqa diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 2cbfd22bb..1b8387714 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -1,6 +1,5 @@ from __future__ import unicode_literals -import collections import copy import datetime import decimal @@ -33,7 +32,7 @@ from pytz.exceptions import InvalidTimeError from rest_framework import ISO_8601 from rest_framework.compat import ( - MaxLengthValidator, MaxValueValidator, MinLengthValidator, + Mapping, MaxLengthValidator, MaxValueValidator, MinLengthValidator, MinValueValidator, ProhibitNullCharactersValidator, unicode_repr, unicode_to_repr ) @@ -96,7 +95,7 @@ def get_attribute(instance, attrs): """ for attr in attrs: try: - if isinstance(instance, collections.Mapping): + if isinstance(instance, Mapping): instance = instance[attr] else: instance = getattr(instance, attr) @@ -1661,7 +1660,7 @@ class ListField(Field): """ if html.is_html_input(data): data = html.parse_html_list(data, default=[]) - if isinstance(data, type('')) or isinstance(data, collections.Mapping) or not hasattr(data, '__iter__'): + if isinstance(data, type('')) or isinstance(data, Mapping) or not hasattr(data, '__iter__'): self.fail('not_a_list', input_type=type(data).__name__) if not self.allow_empty and len(data) == 0: self.fail('empty') diff --git a/rest_framework/utils/serializer_helpers.py b/rest_framework/utils/serializer_helpers.py index 6b662a66c..c24e51d09 100644 --- a/rest_framework/utils/serializer_helpers.py +++ b/rest_framework/utils/serializer_helpers.py @@ -1,11 +1,10 @@ from __future__ import unicode_literals -import collections from collections import OrderedDict from django.utils.encoding import force_text -from rest_framework.compat import unicode_to_repr +from rest_framework.compat import MutableMapping, unicode_to_repr from rest_framework.utils import json @@ -130,7 +129,7 @@ class NestedBoundField(BoundField): return self.__class__(self._field, values, self.errors, self._prefix) -class BindingDict(collections.MutableMapping): +class BindingDict(MutableMapping): """ This dict-like object is used to store fields on a serializer.