Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Removed custom python_2_unicode_compatible. Closes #2183
  • Loading branch information
maryokhin committed Dec 4, 2014
commit 09e59f268619927dc22f15fed97c3ceac05ea306
5 changes: 4 additions & 1 deletion rest_framework/authtoken/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import binascii
import os

from django.conf import settings
from django.db import models
from django.utils.encoding import python_2_unicode_compatible


# Prior to Django 1.5, the AUTH_USER_MODEL setting does not exist.
Expand All @@ -11,6 +13,7 @@
AUTH_USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', 'auth.User')


@python_2_unicode_compatible
class Token(models.Model):
"""
The default authorization token model.
Expand All @@ -35,5 +38,5 @@ def save(self, *args, **kwargs):
def generate_key(self):
return binascii.hexlify(os.urandom(20)).decode()

def __unicode__(self):
def __str__(self):
return self.key
42 changes: 12 additions & 30 deletions rest_framework/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
# flake8: noqa
from __future__ import unicode_literals

import inspect

from django.core.exceptions import ImproperlyConfigured
from django.conf import settings
from django.utils import six
import django
import inspect


# Handle django.utils.encoding rename in 1.5 onwards.
Expand Down Expand Up @@ -49,7 +50,6 @@
except ImportError:
django_filters = None


if django.VERSION >= (1, 6):
def clean_manytomany_helptext(text):
return text
Expand Down Expand Up @@ -123,7 +123,6 @@ def _allowed_methods(self):
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
Expand Down Expand Up @@ -187,28 +186,30 @@ def __init__(self, *args, **kwargs):
# 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
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),
'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
Expand Down Expand Up @@ -287,10 +288,12 @@ def check_nonce(request, oauth_request, oauth_nonce, oauth_timestamp):
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
Expand All @@ -301,7 +304,7 @@ def check_nonce(request, oauth_request, oauth_nonce, oauth_timestamp):
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 = (',', ':')
Expand All @@ -316,30 +319,9 @@ def check_nonce(request, oauth_request, oauth_nonce, oauth_timestamp):

if six.PY3:
def is_non_str_iterable(obj):
if (isinstance(obj, str) or
(isinstance(obj, Promise) and obj._delegate_text)):
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
5 changes: 2 additions & 3 deletions rest_framework/utils/mediatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"""
from __future__ import unicode_literals
from django.http.multipartparser import parse_header
from django.utils.encoding import python_2_unicode_compatible
from rest_framework import HTTP_HEADER_ENCODING


Expand Down Expand Up @@ -43,6 +44,7 @@ def order_by_precedence(media_type_lst):
return [media_types for media_types in ret if media_types]


@python_2_unicode_compatible
class _MediaType(object):
def __init__(self, media_type_str):
if media_type_str is None:
Expand Down Expand Up @@ -79,9 +81,6 @@ def precedence(self):
return 3

def __str__(self):
return self.__unicode__().encode('utf-8')

def __unicode__(self):
ret = "%s/%s" % (self.main_type, self.sub_type)
for key, val in self.params.items():
ret += "; %s=%s" % (key, val)
Expand Down
5 changes: 2 additions & 3 deletions tests/test_description.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import unicode_literals
from django.test import TestCase
from django.utils.encoding import python_2_unicode_compatible
from rest_framework.compat import apply_markdown, smart_text
from rest_framework.views import APIView
from .description import ViewWithNonASCIICharactersInDocstring
Expand Down Expand Up @@ -107,16 +108,14 @@ class that can be converted to a string.
"""
# use a mock object instead of gettext_lazy to ensure that we can't end
# up with a test case string in our l10n catalog
@python_2_unicode_compatible
class MockLazyStr(object):
def __init__(self, string):
self.s = string

def __str__(self):
return self.s

def __unicode__(self):
return self.s

class MockView(APIView):
__doc__ = MockLazyStr("a gettext string")

Expand Down
2 changes: 1 addition & 1 deletion tests/test_relations_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from django.contrib.contenttypes.generic import GenericRelation, GenericForeignKey
from django.db import models
from django.test import TestCase
from django.utils.encoding import python_2_unicode_compatible
from rest_framework import serializers
from rest_framework.compat import python_2_unicode_compatible


@python_2_unicode_compatible
Expand Down