diff options
Diffstat (limited to 'rest_framework/compat.py')
| -rw-r--r-- | rest_framework/compat.py | 107 |
1 files changed, 14 insertions, 93 deletions
diff --git a/rest_framework/compat.py b/rest_framework/compat.py index 5bd85e74..71520b92 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -6,24 +6,14 @@ versions of django/python, and compatibility wrappers around optional packages. # flake8: noqa from __future__ import unicode_literals +import inspect + from django.core.exceptions import ImproperlyConfigured +from django.utils.encoding import force_text +from django.utils.six.moves.urllib import parse as urlparse from django.conf import settings from django.utils import six import django -import inspect - - -# Handle django.utils.encoding rename in 1.5 onwards. -# smart_unicode -> smart_text -# force_unicode -> force_text -try: - from django.utils.encoding import smart_text -except ImportError: - from django.utils.encoding import smart_unicode as smart_text -try: - from django.utils.encoding import force_text -except ImportError: - from django.utils.encoding import force_unicode as force_text # OrderedDict only available in Python 2.7. @@ -32,7 +22,7 @@ except ImportError: # For Django <= 1.6 and Python 2.6 fall back to OrderedDict. try: from collections import OrderedDict -except: +except ImportError: from django.utils.datastructures import SortedDict as OrderedDict @@ -49,7 +39,6 @@ try: except ImportError: django_filters = None - if django.VERSION >= (1, 6): def clean_manytomany_helptext(text): return text @@ -72,30 +61,6 @@ if 'guardian' in settings.INSTALLED_APPS: pass -# cStringIO only if it's available, otherwise StringIO -try: - import cStringIO.StringIO as StringIO -except ImportError: - StringIO = six.StringIO - -BytesIO = six.BytesIO - - -# urlparse compat import (Required because it changed in python 3.x) -try: - from urllib import parse as urlparse -except ImportError: - import urlparse - -# UserDict moves in Python 3 -try: - from UserDict import UserDict - from UserDict import DictMixin -except ImportError: - from collections import UserDict - from collections import MutableMapping as DictMixin - - def get_model_name(model_cls): try: return model_cls._meta.model_name @@ -104,14 +69,6 @@ def get_model_name(model_cls): return model_cls._meta.module_name -def get_concrete_model(model_cls): - try: - return model_cls._meta.concrete_model - except AttributeError: - # 1.3 does not include concrete model - return model_cls - - # View._allowed_methods only present from 1.5 onwards if django.VERSION >= (1, 5): from django.views.generic import View @@ -123,7 +80,6 @@ else: return [m.upper() for m in self.http_method_names if hasattr(self, m)] - # MinValueValidator, MaxValueValidator et al. only accept `message` in 1.8+ if django.VERSION >= (1, 8): from django.core.validators import MinValueValidator, MaxValueValidator @@ -187,6 +143,7 @@ if 'patch' not in View.http_method_names: # RequestFactory only provides `generic` from 1.5 onwards from django.test.client import RequestFactory as DjangoRequestFactory from django.test.client import FakePayload + try: # In 1.5 the test client uses force_bytes from django.utils.encoding import force_bytes as force_bytes_or_smart_bytes @@ -194,26 +151,22 @@ except ImportError: # In 1.4 the test client just uses smart_str from django.utils.encoding import smart_str as force_bytes_or_smart_bytes + class RequestFactory(DjangoRequestFactory): def generic(self, method, path, data='', content_type='application/octet-stream', **extra): parsed = urlparse.urlparse(path) data = force_bytes_or_smart_bytes(data, settings.DEFAULT_CHARSET) r = { - 'PATH_INFO': self._get_path(parsed), - 'QUERY_STRING': force_text(parsed[4]), + 'PATH_INFO': self._get_path(parsed), + 'QUERY_STRING': force_text(parsed[4]), 'REQUEST_METHOD': six.text_type(method), } if data: r.update({ 'CONTENT_LENGTH': len(data), - 'CONTENT_TYPE': six.text_type(content_type), - 'wsgi.input': FakePayload(data), - }) - elif django.VERSION <= (1, 4): - # For 1.3 we need an empty WSGI payload - r.update({ - 'wsgi.input': FakePayload('') + 'CONTENT_TYPE': six.text_type(content_type), + 'wsgi.input': FakePayload(data), }) r.update(extra) return self.request(**r) @@ -287,10 +240,12 @@ try: import provider as oauth2_provider from provider import scope as oauth2_provider_scope from provider import constants as oauth2_constants + if oauth2_provider.__version__ in ('0.2.3', '0.2.4'): # 0.2.3 and 0.2.4 are supported version that do not support # timezone aware datetimes import datetime + provider_now = datetime.datetime.now else: # Any other supported version does use timezone aware datetimes @@ -301,7 +256,7 @@ except ImportError: oauth2_constants = None provider_now = None -# `seperators` argument to `json.dumps()` differs between 2.x and 3.x +# `separators` argument to `json.dumps()` differs between 2.x and 3.x # See: http://bugs.python.org/issue22767 if six.PY3: SHORT_SEPARATORS = (',', ':') @@ -309,37 +264,3 @@ if six.PY3: else: SHORT_SEPARATORS = (b',', b':') LONG_SEPARATORS = (b', ', b': ') - - -# Handle lazy strings across Py2/Py3 -from django.utils.functional import Promise - -if six.PY3: - def is_non_str_iterable(obj): - if (isinstance(obj, str) or - (isinstance(obj, Promise) and obj._delegate_text)): - return False - return hasattr(obj, '__iter__') -else: - def is_non_str_iterable(obj): - return hasattr(obj, '__iter__') - - -try: - from django.utils.encoding import python_2_unicode_compatible -except ImportError: - def python_2_unicode_compatible(klass): - """ - A decorator that defines __unicode__ and __str__ methods under Python 2. - Under Python 3 it does nothing. - - To support Python 2 and 3 with a single code base, define a __str__ method - returning text and apply this decorator to the class. - """ - if '__str__' not in klass.__dict__: - raise ValueError("@python_2_unicode_compatible cannot be applied " - "to %s because it doesn't define __str__()." % - klass.__name__) - klass.__unicode__ = klass.__str__ - klass.__str__ = lambda self: self.__unicode__().encode('utf-8') - return klass |
