diff options
| -rw-r--r-- | rest_framework/__init__.py | 3 | ||||
| -rw-r--r-- | rest_framework/authentication.py | 19 | ||||
| -rw-r--r-- | rest_framework/relations.py | 2 | ||||
| -rw-r--r-- | rest_framework/serializers.py | 6 | ||||
| -rw-r--r-- | rest_framework/settings.py | 3 | ||||
| -rw-r--r-- | rest_framework/tests/authentication.py | 11 | ||||
| -rw-r--r-- | rest_framework/tests/genericrelations.py | 12 | ||||
| -rw-r--r-- | rest_framework/tests/relations_hyperlink.py | 8 | ||||
| -rw-r--r-- | rest_framework/tests/relations_nested.py | 4 | ||||
| -rw-r--r-- | rest_framework/tests/relations_pk.py | 8 | ||||
| -rw-r--r-- | rest_framework/tests/relations_slug.py | 108 | ||||
| -rw-r--r-- | rest_framework/tests/serializer.py | 14 | ||||
| -rw-r--r-- | rest_framework/tests/utils.py | 4 | ||||
| -rw-r--r-- | rest_framework/tests/validators.py | 2 | ||||
| -rw-r--r-- | tox.ini | 32 | 
15 files changed, 129 insertions, 107 deletions
| diff --git a/rest_framework/__init__.py b/rest_framework/__init__.py index f9882c57..80e2c410 100644 --- a/rest_framework/__init__.py +++ b/rest_framework/__init__.py @@ -1,3 +1,6 @@  __version__ = '2.1.17'  VERSION = __version__  # synonym + +# Header encoding (see RFC5987) +HTTP_HEADER_ENCODING = 'iso-8859-1' diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index 76ee4bd6..c15568db 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -1,10 +1,11 @@  """  Provides a set of pluggable authentication policies.  """ +from __future__ import unicode_literals  from django.contrib.auth import authenticate  from django.utils.encoding import DjangoUnicodeDecodeError -from rest_framework import exceptions +from rest_framework import exceptions, HTTP_HEADER_ENCODING  from rest_framework.compat import CsrfViewMiddleware  from rest_framework.compat import smart_text  from rest_framework.authtoken.models import Token @@ -43,23 +44,25 @@ class BasicAuthentication(BaseAuthentication):          Returns a `User` if a correct username and password have been supplied          using HTTP Basic authentication.  Otherwise returns `None`.          """ -        auth = request.META.get('HTTP_AUTHORIZATION', '').split() +        auth = request.META.get('HTTP_AUTHORIZATION', b'') +        if type(auth) == type(''): +            # Work around django test client oddness +            auth = auth.encode(HTTP_HEADER_ENCODING) +        auth = auth.split() -        if not auth or auth[0].lower() != "basic": +        if not auth or auth[0].lower() != b'basic':              return None          if len(auth) != 2:              raise exceptions.AuthenticationFailed('Invalid basic header') -        encoding = api_settings.HTTP_HEADER_ENCODING          try: -            auth_parts = base64.b64decode(auth[1].encode(encoding)).partition(':') -        except TypeError: +            auth_parts = base64.b64decode(auth[1]).decode(HTTP_HEADER_ENCODING).partition(':') +        except (TypeError, UnicodeDecodeError):              raise exceptions.AuthenticationFailed('Invalid basic header')          try: -            userid = smart_text(auth_parts[0]) -            password = smart_text(auth_parts[2]) +            userid, password = auth_parts[0], auth_parts[2]          except DjangoUnicodeDecodeError:              raise exceptions.AuthenticationFailed('Invalid basic header') diff --git a/rest_framework/relations.py b/rest_framework/relations.py index c4f854ef..dfa80fb7 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -311,7 +311,7 @@ class SlugRelatedField(RelatedField):              return self.queryset.get(**{self.slug_field: data})          except ObjectDoesNotExist:              raise ValidationError(self.error_messages['does_not_exist'] % -                                  (self.slug_field, unicode(data))) +                                  (self.slug_field, smart_text(data)))          except (TypeError, ValueError):              msg = self.error_messages['invalid']              raise ValidationError(msg) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 3d3bcb3c..b154fcad 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -212,7 +212,7 @@ class BaseSerializer(Field):          reverted_data = {}          if data is not None and not isinstance(data, dict): -            self._errors['non_field_errors'] = [u'Invalid data'] +            self._errors['non_field_errors'] = ['Invalid data']              return None          for field_name, field in self.fields.items(): @@ -287,7 +287,7 @@ class BaseSerializer(Field):          """          Deserialize primitives -> objects.          """ -        if hasattr(data, '__iter__') and not isinstance(data, dict): +        if hasattr(data, '__iter__') and not isinstance(data, (dict, six.text_type)):              # TODO: error data when deserializing lists              return [self.from_native(item, None) for item in data] @@ -525,7 +525,7 @@ class ModelSerializer(Serializer):          """          try:              instance.full_clean(exclude=self.get_validation_exclusions()) -        except ValidationError, err: +        except ValidationError as err:              self._errors = err.message_dict              return None          return instance diff --git a/rest_framework/settings.py b/rest_framework/settings.py index 13d03e62..b3ca0134 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -75,9 +75,6 @@ DEFAULTS = {      'URL_FORMAT_OVERRIDE': 'format',      'FORMAT_SUFFIX_KWARG': 'format', - -    # Header encoding (see RFC5987) -    'HTTP_HEADER_ENCODING': 'iso-8859-1',  } diff --git a/rest_framework/tests/authentication.py b/rest_framework/tests/authentication.py index ba2042cb..7dde6d22 100644 --- a/rest_framework/tests/authentication.py +++ b/rest_framework/tests/authentication.py @@ -1,6 +1,9 @@ +from __future__ import unicode_literals +  from django.contrib.auth.models import User  from django.http import HttpResponse  from django.test import Client, TestCase +from rest_framework import HTTP_HEADER_ENCODING  from rest_framework import permissions  from rest_framework.authtoken.models import Token  from rest_framework.authentication import TokenAuthentication, BasicAuthentication, SessionAuthentication @@ -41,13 +44,17 @@ class BasicAuthTests(TestCase):      def test_post_form_passing_basic_auth(self):          """Ensure POSTing json over basic auth with correct credentials passes and does not require CSRF""" -        auth = 'Basic %s' % base64.encodestring('%s:%s' % (self.username, self.password)).encode('iso-8859-1').strip().decode('iso-8859-1') +        credentials = ('%s:%s' % (self.username, self.password)) +        base64_credentials = base64.b64encode(credentials.encode(HTTP_HEADER_ENCODING)).decode(HTTP_HEADER_ENCODING) +        auth = 'Basic %s' % base64_credentials          response = self.csrf_client.post('/basic/', {'example': 'example'}, HTTP_AUTHORIZATION=auth)          self.assertEqual(response.status_code, 200)      def test_post_json_passing_basic_auth(self):          """Ensure POSTing form over basic auth with correct credentials passes and does not require CSRF""" -        auth = 'Basic %s' % base64.encodestring('%s:%s' % (self.username, self.password)).encode('iso-8859-1').strip().decode('iso-8859-1') +        credentials = ('%s:%s' % (self.username, self.password)) +        base64_credentials = base64.b64encode(credentials.encode(HTTP_HEADER_ENCODING)).decode(HTTP_HEADER_ENCODING) +        auth = 'Basic %s' % base64_credentials          response = self.csrf_client.post('/basic/', json.dumps({'example': 'example'}), 'application/json', HTTP_AUTHORIZATION=auth)          self.assertEqual(response.status_code, 200) diff --git a/rest_framework/tests/genericrelations.py b/rest_framework/tests/genericrelations.py index 72070a1a..91a98604 100644 --- a/rest_framework/tests/genericrelations.py +++ b/rest_framework/tests/genericrelations.py @@ -86,16 +86,16 @@ class TestGenericRelations(TestCase):          serializer = TagSerializer(Tag.objects.all())          expected = [          { -            'tag': u'django', -            'tagged_item': u'Bookmark: https://www.djangoproject.com/' +            'tag': 'django', +            'tagged_item': 'Bookmark: https://www.djangoproject.com/'          },          { -            'tag': u'python', -            'tagged_item': u'Bookmark: https://www.djangoproject.com/' +            'tag': 'python', +            'tagged_item': 'Bookmark: https://www.djangoproject.com/'          },          { -            'tag': u'reminder', -            'tagged_item': u'Note: Remember the milk' +            'tag': 'reminder', +            'tagged_item': 'Note: Remember the milk'          }          ]          self.assertEquals(serializer.data, expected) diff --git a/rest_framework/tests/relations_hyperlink.py b/rest_framework/tests/relations_hyperlink.py index b4ad3166..f2957abf 100644 --- a/rest_framework/tests/relations_hyperlink.py +++ b/rest_framework/tests/relations_hyperlink.py @@ -218,11 +218,11 @@ class HyperlinkedForeignKeyTests(TestCase):          self.assertEquals(serializer.data, expected)      def test_foreign_key_update_incorrect_type(self): -        data = {'url': '/foreignkeysource/1/', 'name': u'source-1', 'target': 2} +        data = {'url': '/foreignkeysource/1/', 'name': 'source-1', 'target': 2}          instance = ForeignKeySource.objects.get(pk=1)          serializer = ForeignKeySourceSerializer(instance, data=data)          self.assertFalse(serializer.is_valid()) -        self.assertEquals(serializer.errors, {'target': [u'Incorrect type.  Expected url string, received int.']}) +        self.assertEquals(serializer.errors, {'target': ['Incorrect type.  Expected url string, received int.']})      def test_reverse_foreign_key_update(self):          data = {'url': '/foreignkeytarget/2/', 'name': 'target-2', 'sources': ['/foreignkeysource/1/', '/foreignkeysource/3/']} @@ -439,7 +439,7 @@ class HyperlinkedNullableOneToOneTests(TestCase):          queryset = OneToOneTarget.objects.all()          serializer = NullableOneToOneTargetSerializer(queryset)          expected = [ -            {'url': '/onetoonetarget/1/', 'name': u'target-1', 'nullable_source': '/nullableonetoonesource/1/'}, -            {'url': '/onetoonetarget/2/', 'name': u'target-2', 'nullable_source': None}, +            {'url': '/onetoonetarget/1/', 'name': 'target-1', 'nullable_source': '/nullableonetoonesource/1/'}, +            {'url': '/onetoonetarget/2/', 'name': 'target-2', 'nullable_source': None},          ]          self.assertEquals(serializer.data, expected) diff --git a/rest_framework/tests/relations_nested.py b/rest_framework/tests/relations_nested.py index e81f0e42..e9051e71 100644 --- a/rest_framework/tests/relations_nested.py +++ b/rest_framework/tests/relations_nested.py @@ -109,7 +109,7 @@ class NestedNullableOneToOneTests(TestCase):          queryset = OneToOneTarget.objects.all()          serializer = NullableOneToOneTargetSerializer(queryset)          expected = [ -            {'id': 1, 'name': u'target-1', 'nullable_source': {'id': 1, 'name': u'source-1', 'target': 1}}, -            {'id': 2, 'name': u'target-2', 'nullable_source': None}, +            {'id': 1, 'name': 'target-1', 'nullable_source': {'id': 1, 'name': 'source-1', 'target': 1}}, +            {'id': 2, 'name': 'target-2', 'nullable_source': None},          ]          self.assertEquals(serializer.data, expected) diff --git a/rest_framework/tests/relations_pk.py b/rest_framework/tests/relations_pk.py index 4d00795a..ca7ac17e 100644 --- a/rest_framework/tests/relations_pk.py +++ b/rest_framework/tests/relations_pk.py @@ -198,11 +198,11 @@ class PKForeignKeyTests(TestCase):          self.assertEquals(serializer.data, expected)      def test_foreign_key_update_incorrect_type(self): -        data = {'id': 1, 'name': u'source-1', 'target': 'foo'} +        data = {'id': 1, 'name': 'source-1', 'target': 'foo'}          instance = ForeignKeySource.objects.get(pk=1)          serializer = ForeignKeySourceSerializer(instance, data=data)          self.assertFalse(serializer.is_valid()) -        self.assertEquals(serializer.errors, {'target': [u'Incorrect type.  Expected pk value, received str.']}) +        self.assertEquals(serializer.errors, {'target': ['Incorrect type.  Expected pk value, received str.']})      def test_reverse_foreign_key_update(self):          data = {'id': 2, 'name': 'target-2', 'sources': [1, 3]} @@ -415,7 +415,7 @@ class PKNullableOneToOneTests(TestCase):          queryset = OneToOneTarget.objects.all()          serializer = NullableOneToOneTargetSerializer(queryset)          expected = [ -            {'id': 1, 'name': u'target-1', 'nullable_source': 1}, -            {'id': 2, 'name': u'target-2', 'nullable_source': None}, +            {'id': 1, 'name': 'target-1', 'nullable_source': 1}, +            {'id': 2, 'name': 'target-2', 'nullable_source': None},          ]          self.assertEquals(serializer.data, expected) diff --git a/rest_framework/tests/relations_slug.py b/rest_framework/tests/relations_slug.py index 37ccc75e..b4c2cb5f 100644 --- a/rest_framework/tests/relations_slug.py +++ b/rest_framework/tests/relations_slug.py @@ -39,9 +39,9 @@ class PKForeignKeyTests(TestCase):          queryset = ForeignKeySource.objects.all()          serializer = ForeignKeySourceSerializer(queryset)          expected = [ -            {'id': 1, 'name': u'source-1', 'target': 'target-1'}, -            {'id': 2, 'name': u'source-2', 'target': 'target-1'}, -            {'id': 3, 'name': u'source-3', 'target': 'target-1'} +            {'id': 1, 'name': 'source-1', 'target': 'target-1'}, +            {'id': 2, 'name': 'source-2', 'target': 'target-1'}, +            {'id': 3, 'name': 'source-3', 'target': 'target-1'}          ]          self.assertEquals(serializer.data, expected) @@ -49,13 +49,13 @@ class PKForeignKeyTests(TestCase):          queryset = ForeignKeyTarget.objects.all()          serializer = ForeignKeyTargetSerializer(queryset)          expected = [ -            {'id': 1, 'name': u'target-1', 'sources': ['source-1', 'source-2', 'source-3']}, -            {'id': 2, 'name': u'target-2', 'sources': []}, +            {'id': 1, 'name': 'target-1', 'sources': ['source-1', 'source-2', 'source-3']}, +            {'id': 2, 'name': 'target-2', 'sources': []},          ]          self.assertEquals(serializer.data, expected)      def test_foreign_key_update(self): -        data = {'id': 1, 'name': u'source-1', 'target': 'target-2'} +        data = {'id': 1, 'name': 'source-1', 'target': 'target-2'}          instance = ForeignKeySource.objects.get(pk=1)          serializer = ForeignKeySourceSerializer(instance, data=data)          self.assertTrue(serializer.is_valid()) @@ -66,21 +66,21 @@ class PKForeignKeyTests(TestCase):          queryset = ForeignKeySource.objects.all()          serializer = ForeignKeySourceSerializer(queryset)          expected = [ -            {'id': 1, 'name': u'source-1', 'target': 'target-2'}, -            {'id': 2, 'name': u'source-2', 'target': 'target-1'}, -            {'id': 3, 'name': u'source-3', 'target': 'target-1'} +            {'id': 1, 'name': 'source-1', 'target': 'target-2'}, +            {'id': 2, 'name': 'source-2', 'target': 'target-1'}, +            {'id': 3, 'name': 'source-3', 'target': 'target-1'}          ]          self.assertEquals(serializer.data, expected)      def test_foreign_key_update_incorrect_type(self): -        data = {'id': 1, 'name': u'source-1', 'target': 123} +        data = {'id': 1, 'name': 'source-1', 'target': 123}          instance = ForeignKeySource.objects.get(pk=1)          serializer = ForeignKeySourceSerializer(instance, data=data)          self.assertFalse(serializer.is_valid()) -        self.assertEquals(serializer.errors, {'target': [u'Object with name=123 does not exist.']}) +        self.assertEquals(serializer.errors, {'target': ['Object with name=123 does not exist.']})      def test_reverse_foreign_key_update(self): -        data = {'id': 2, 'name': u'target-2', 'sources': ['source-1', 'source-3']} +        data = {'id': 2, 'name': 'target-2', 'sources': ['source-1', 'source-3']}          instance = ForeignKeyTarget.objects.get(pk=2)          serializer = ForeignKeyTargetSerializer(instance, data=data)          self.assertTrue(serializer.is_valid()) @@ -89,8 +89,8 @@ class PKForeignKeyTests(TestCase):          queryset = ForeignKeyTarget.objects.all()          new_serializer = ForeignKeyTargetSerializer(queryset)          expected = [ -            {'id': 1, 'name': u'target-1', 'sources': ['source-1', 'source-2', 'source-3']}, -            {'id': 2, 'name': u'target-2', 'sources': []}, +            {'id': 1, 'name': 'target-1', 'sources': ['source-1', 'source-2', 'source-3']}, +            {'id': 2, 'name': 'target-2', 'sources': []},          ]          self.assertEquals(new_serializer.data, expected) @@ -101,55 +101,55 @@ class PKForeignKeyTests(TestCase):          queryset = ForeignKeyTarget.objects.all()          serializer = ForeignKeyTargetSerializer(queryset)          expected = [ -            {'id': 1, 'name': u'target-1', 'sources': ['source-2']}, -            {'id': 2, 'name': u'target-2', 'sources': ['source-1', 'source-3']}, +            {'id': 1, 'name': 'target-1', 'sources': ['source-2']}, +            {'id': 2, 'name': 'target-2', 'sources': ['source-1', 'source-3']},          ]          self.assertEquals(serializer.data, expected)      def test_foreign_key_create(self): -        data = {'id': 4, 'name': u'source-4', 'target': 'target-2'} +        data = {'id': 4, 'name': 'source-4', 'target': 'target-2'}          serializer = ForeignKeySourceSerializer(data=data)          serializer.is_valid()          self.assertTrue(serializer.is_valid())          obj = serializer.save()          self.assertEquals(serializer.data, data) -        self.assertEqual(obj.name, u'source-4') +        self.assertEqual(obj.name, 'source-4')          # Ensure source 4 is added, and everything else is as expected          queryset = ForeignKeySource.objects.all()          serializer = ForeignKeySourceSerializer(queryset)          expected = [ -            {'id': 1, 'name': u'source-1', 'target': 'target-1'}, -            {'id': 2, 'name': u'source-2', 'target': 'target-1'}, -            {'id': 3, 'name': u'source-3', 'target': 'target-1'}, -            {'id': 4, 'name': u'source-4', 'target': 'target-2'}, +            {'id': 1, 'name': 'source-1', 'target': 'target-1'}, +            {'id': 2, 'name': 'source-2', 'target': 'target-1'}, +            {'id': 3, 'name': 'source-3', 'target': 'target-1'}, +            {'id': 4, 'name': 'source-4', 'target': 'target-2'},          ]          self.assertEquals(serializer.data, expected)      def test_reverse_foreign_key_create(self): -        data = {'id': 3, 'name': u'target-3', 'sources': ['source-1', 'source-3']} +        data = {'id': 3, 'name': 'target-3', 'sources': ['source-1', 'source-3']}          serializer = ForeignKeyTargetSerializer(data=data)          self.assertTrue(serializer.is_valid())          obj = serializer.save()          self.assertEquals(serializer.data, data) -        self.assertEqual(obj.name, u'target-3') +        self.assertEqual(obj.name, 'target-3')          # Ensure target 3 is added, and everything else is as expected          queryset = ForeignKeyTarget.objects.all()          serializer = ForeignKeyTargetSerializer(queryset)          expected = [ -            {'id': 1, 'name': u'target-1', 'sources': ['source-2']}, -            {'id': 2, 'name': u'target-2', 'sources': []}, -            {'id': 3, 'name': u'target-3', 'sources': ['source-1', 'source-3']}, +            {'id': 1, 'name': 'target-1', 'sources': ['source-2']}, +            {'id': 2, 'name': 'target-2', 'sources': []}, +            {'id': 3, 'name': 'target-3', 'sources': ['source-1', 'source-3']},          ]          self.assertEquals(serializer.data, expected)      def test_foreign_key_update_with_invalid_null(self): -        data = {'id': 1, 'name': u'source-1', 'target': None} +        data = {'id': 1, 'name': 'source-1', 'target': None}          instance = ForeignKeySource.objects.get(pk=1)          serializer = ForeignKeySourceSerializer(instance, data=data)          self.assertFalse(serializer.is_valid()) -        self.assertEquals(serializer.errors, {'target': [u'Value may not be null']}) +        self.assertEquals(serializer.errors, {'target': ['Value may not be null']})  class SlugNullableForeignKeyTests(TestCase): @@ -166,28 +166,28 @@ class SlugNullableForeignKeyTests(TestCase):          queryset = NullableForeignKeySource.objects.all()          serializer = NullableForeignKeySourceSerializer(queryset)          expected = [ -            {'id': 1, 'name': u'source-1', 'target': 'target-1'}, -            {'id': 2, 'name': u'source-2', 'target': 'target-1'}, -            {'id': 3, 'name': u'source-3', 'target': None}, +            {'id': 1, 'name': 'source-1', 'target': 'target-1'}, +            {'id': 2, 'name': 'source-2', 'target': 'target-1'}, +            {'id': 3, 'name': 'source-3', 'target': None},          ]          self.assertEquals(serializer.data, expected)      def test_foreign_key_create_with_valid_null(self): -        data = {'id': 4, 'name': u'source-4', 'target': None} +        data = {'id': 4, 'name': 'source-4', 'target': None}          serializer = NullableForeignKeySourceSerializer(data=data)          self.assertTrue(serializer.is_valid())          obj = serializer.save()          self.assertEquals(serializer.data, data) -        self.assertEqual(obj.name, u'source-4') +        self.assertEqual(obj.name, 'source-4')          # Ensure source 4 is created, and everything else is as expected          queryset = NullableForeignKeySource.objects.all()          serializer = NullableForeignKeySourceSerializer(queryset)          expected = [ -            {'id': 1, 'name': u'source-1', 'target': 'target-1'}, -            {'id': 2, 'name': u'source-2', 'target': 'target-1'}, -            {'id': 3, 'name': u'source-3', 'target': None}, -            {'id': 4, 'name': u'source-4', 'target': None} +            {'id': 1, 'name': 'source-1', 'target': 'target-1'}, +            {'id': 2, 'name': 'source-2', 'target': 'target-1'}, +            {'id': 3, 'name': 'source-3', 'target': None}, +            {'id': 4, 'name': 'source-4', 'target': None}          ]          self.assertEquals(serializer.data, expected) @@ -196,27 +196,27 @@ class SlugNullableForeignKeyTests(TestCase):          The emptystring should be interpreted as null in the context          of relationships.          """ -        data = {'id': 4, 'name': u'source-4', 'target': ''} -        expected_data = {'id': 4, 'name': u'source-4', 'target': None} +        data = {'id': 4, 'name': 'source-4', 'target': ''} +        expected_data = {'id': 4, 'name': 'source-4', 'target': None}          serializer = NullableForeignKeySourceSerializer(data=data)          self.assertTrue(serializer.is_valid())          obj = serializer.save()          self.assertEquals(serializer.data, expected_data) -        self.assertEqual(obj.name, u'source-4') +        self.assertEqual(obj.name, 'source-4')          # Ensure source 4 is created, and everything else is as expected          queryset = NullableForeignKeySource.objects.all()          serializer = NullableForeignKeySourceSerializer(queryset)          expected = [ -            {'id': 1, 'name': u'source-1', 'target': 'target-1'}, -            {'id': 2, 'name': u'source-2', 'target': 'target-1'}, -            {'id': 3, 'name': u'source-3', 'target': None}, -            {'id': 4, 'name': u'source-4', 'target': None} +            {'id': 1, 'name': 'source-1', 'target': 'target-1'}, +            {'id': 2, 'name': 'source-2', 'target': 'target-1'}, +            {'id': 3, 'name': 'source-3', 'target': None}, +            {'id': 4, 'name': 'source-4', 'target': None}          ]          self.assertEquals(serializer.data, expected)      def test_foreign_key_update_with_valid_null(self): -        data = {'id': 1, 'name': u'source-1', 'target': None} +        data = {'id': 1, 'name': 'source-1', 'target': None}          instance = NullableForeignKeySource.objects.get(pk=1)          serializer = NullableForeignKeySourceSerializer(instance, data=data)          self.assertTrue(serializer.is_valid()) @@ -227,9 +227,9 @@ class SlugNullableForeignKeyTests(TestCase):          queryset = NullableForeignKeySource.objects.all()          serializer = NullableForeignKeySourceSerializer(queryset)          expected = [ -            {'id': 1, 'name': u'source-1', 'target': None}, -            {'id': 2, 'name': u'source-2', 'target': 'target-1'}, -            {'id': 3, 'name': u'source-3', 'target': None} +            {'id': 1, 'name': 'source-1', 'target': None}, +            {'id': 2, 'name': 'source-2', 'target': 'target-1'}, +            {'id': 3, 'name': 'source-3', 'target': None}          ]          self.assertEquals(serializer.data, expected) @@ -238,8 +238,8 @@ class SlugNullableForeignKeyTests(TestCase):          The emptystring should be interpreted as null in the context          of relationships.          """ -        data = {'id': 1, 'name': u'source-1', 'target': ''} -        expected_data = {'id': 1, 'name': u'source-1', 'target': None} +        data = {'id': 1, 'name': 'source-1', 'target': ''} +        expected_data = {'id': 1, 'name': 'source-1', 'target': None}          instance = NullableForeignKeySource.objects.get(pk=1)          serializer = NullableForeignKeySourceSerializer(instance, data=data)          self.assertTrue(serializer.is_valid()) @@ -250,8 +250,8 @@ class SlugNullableForeignKeyTests(TestCase):          queryset = NullableForeignKeySource.objects.all()          serializer = NullableForeignKeySourceSerializer(queryset)          expected = [ -            {'id': 1, 'name': u'source-1', 'target': None}, -            {'id': 2, 'name': u'source-2', 'target': 'target-1'}, -            {'id': 3, 'name': u'source-3', 'target': None} +            {'id': 1, 'name': 'source-1', 'target': None}, +            {'id': 2, 'name': 'source-2', 'target': 'target-1'}, +            {'id': 3, 'name': 'source-3', 'target': None}          ]          self.assertEquals(serializer.data, expected) diff --git a/rest_framework/tests/serializer.py b/rest_framework/tests/serializer.py index a00626b5..9697889d 100644 --- a/rest_framework/tests/serializer.py +++ b/rest_framework/tests/serializer.py @@ -236,17 +236,17 @@ class ValidationTests(TestCase):          data = ['i am', 'a', 'list']          serializer = CommentSerializer(self.comment, data=data)          self.assertEquals(serializer.is_valid(), False) -        self.assertEquals(serializer.errors, {'non_field_errors': [u'Invalid data']}) +        self.assertEquals(serializer.errors, {'non_field_errors': ['Invalid data']})          data = 'and i am a string'          serializer = CommentSerializer(self.comment, data=data)          self.assertEquals(serializer.is_valid(), False) -        self.assertEquals(serializer.errors, {'non_field_errors': [u'Invalid data']}) +        self.assertEquals(serializer.errors, {'non_field_errors': ['Invalid data']})          data = 42          serializer = CommentSerializer(self.comment, data=data)          self.assertEquals(serializer.is_valid(), False) -        self.assertEquals(serializer.errors, {'non_field_errors': [u'Invalid data']}) +        self.assertEquals(serializer.errors, {'non_field_errors': ['Invalid data']})      def test_cross_field_validation(self): @@ -300,7 +300,7 @@ class ValidationTests(TestCase):          }          serializer = ActionItemSerializerCustomRestore(data=data)          self.assertEquals(serializer.is_valid(), False) -        self.assertEquals(serializer.errors, {'title': [u'Ensure this value has at most 200 characters (it has 201).']}) +        self.assertEquals(serializer.errors, {'title': ['Ensure this value has at most 200 characters (it has 201).']})      def test_default_modelfield_max_length_exceeded(self):          data = { @@ -340,7 +340,7 @@ class CustomValidationTests(TestCase):          serializer = self.CommentSerializerWithFieldValidator(data=data)          self.assertFalse(serializer.is_valid()) -        self.assertEquals(serializer.errors, {'content': [u'Test not in value']}) +        self.assertEquals(serializer.errors, {'content': ['Test not in value']})      def test_missing_data(self):          """ @@ -352,7 +352,7 @@ class CustomValidationTests(TestCase):          }          serializer = self.CommentSerializerWithFieldValidator(data=incomplete_data)          self.assertFalse(serializer.is_valid()) -        self.assertEquals(serializer.errors, {'content': [u'This field is required.']}) +        self.assertEquals(serializer.errors, {'content': ['This field is required.']})      def test_wrong_data(self):          """ @@ -365,7 +365,7 @@ class CustomValidationTests(TestCase):          }          serializer = self.CommentSerializerWithFieldValidator(data=wrong_data)          self.assertFalse(serializer.is_valid()) -        self.assertEquals(serializer.errors, {'email': [u'Enter a valid e-mail address.']}) +        self.assertEquals(serializer.errors, {'email': ['Enter a valid e-mail address.']})  class PositiveIntegerAsChoiceTests(TestCase): diff --git a/rest_framework/tests/utils.py b/rest_framework/tests/utils.py index 3906adb9..4e6faac4 100644 --- a/rest_framework/tests/utils.py +++ b/rest_framework/tests/utils.py @@ -1,6 +1,6 @@  from django.test.client import RequestFactory, FakePayload  from django.test.client import MULTIPART_CONTENT -from urlparse import urlparse +from rest_framework.compat import urlparse  class RequestFactory(RequestFactory): @@ -14,7 +14,7 @@ class RequestFactory(RequestFactory):          patch_data = self._encode_data(data, content_type) -        parsed = urlparse(path) +        parsed = urlparse.urlparse(path)          r = {              'CONTENT_LENGTH': len(patch_data),              'CONTENT_TYPE':   content_type, diff --git a/rest_framework/tests/validators.py b/rest_framework/tests/validators.py index c032985e..8844cb74 100644 --- a/rest_framework/tests/validators.py +++ b/rest_framework/tests/validators.py @@ -139,7 +139,7 @@  #         raise errors on unexpected request data"""  #         content = {'qwerty': 'uiop', 'extra': 'extra'}  #         validator.allow_unknown_form_fields = True -#         self.assertEqual({'qwerty': u'uiop'}, +#         self.assertEqual({'qwerty': 'uiop'},  #                          validator.validate_request(content, None),  #                          "Resource didn't accept unknown fields.")  #         validator.allow_unknown_form_fields = False @@ -1,28 +1,33 @@  [tox]  downloadcache = {toxworkdir}/cache/ -envlist = py2.7-django1.5,py2.7-django1.4,py2.7-django1.3,py2.6-django1.5,py2.6-django1.4,py2.6-django1.3 +envlist = py3.3-django1.5,py3.2-django1.5,py2.7-django1.5,py2.7-django1.4,py2.7-django1.3,py2.6-django1.5,py2.6-django1.4,py2.6-django1.3  [testenv]  commands = {envpython} rest_framework/runtests/runtests.py -[testenv:py2.7-django1.5] -basepython = python2.7 -deps = https://github.com/django/django/zipball/master +[testenv:py3.3-django1.5] +basepython = python3.3 +deps = https://www.djangoproject.com/download/1.5c1/tarball/         django-filter==0.5.4 -[testenv:py2.7-django1.4] -basepython = python2.7 -deps = django==1.4.3 +[testenv:py3.2-django1.5] +basepython = python3.2 +deps = https://www.djangoproject.com/download/1.5c1/tarball/         django-filter==0.5.4 -[testenv:py2.7-django1.3] +[testenv:py2.7-django1.5]  basepython = python2.7 -deps = django==1.3.5 +deps = https://www.djangoproject.com/download/1.5c1/tarball/         django-filter==0.5.4  [testenv:py2.6-django1.5]  basepython = python2.6 -deps = https://github.com/django/django/zipball/master +deps = https://www.djangoproject.com/download/1.5c1/tarball/ +       django-filter==0.5.4 + +[testenv:py2.7-django1.4] +basepython = python2.7 +deps = django==1.4.3         django-filter==0.5.4  [testenv:py2.6-django1.4] @@ -30,7 +35,14 @@ basepython = python2.6  deps = django==1.4.3         django-filter==0.5.4 +[testenv:py2.7-django1.3] +basepython = python2.7 +deps = django==1.3.5 +       django-filter==0.5.4 +       six +  [testenv:py2.6-django1.3]  basepython = python2.6  deps = django==1.3.5         django-filter==0.5.4 +       six | 
