This commit is contained in:
Asif Saif Uddin 2019-05-02 12:55:27 +06:00
commit b37eb5f2fa
45 changed files with 103 additions and 144 deletions

View File

@ -59,7 +59,7 @@ Changes should broadly follow the [PEP 8][pep-8] style conventions, and we recom
To run the tests, clone the repository, and then:
# Setup the virtual environment
virtualenv env
python3 -m venv env
source env/bin/activate
pip install django
pip install -r requirements.txt
@ -115,7 +115,7 @@ It's also useful to remember that if you have an outstanding pull request then p
GitHub's documentation for working on pull requests is [available here][pull-requests].
Always run the tests before submitting pull requests, and ideally run `tox` in order to check that your modifications are compatible with both Python 2 and Python 3, and that they run properly on all supported versions of Django.
Always run the tests before submitting pull requests, and ideally run `tox` in order to check that your modifications are compatible on all supported versions of Python and Django.
Once you've made a pull request take a look at the Travis build status in the GitHub interface and make sure the tests are running as you'd expect.

View File

@ -354,7 +354,7 @@ The following third party packages are also available.
## Django OAuth Toolkit
The [Django OAuth Toolkit][django-oauth-toolkit] package provides OAuth 2.0 support, and works with Python 2.7 and Python 3.3+. The package is maintained by [Evonove][evonove] and uses the excellent [OAuthLib][oauthlib]. The package is well documented, and well supported and is currently our **recommended package for OAuth 2.0 support**.
The [Django OAuth Toolkit][django-oauth-toolkit] package provides OAuth 2.0 support and works with Python 3.4+. The package is maintained by [Evonove][evonove] and uses the excellent [OAuthLib][oauthlib]. The package is well documented, and well supported and is currently our **recommended package for OAuth 2.0 support**.
#### Installation & configuration

View File

@ -159,7 +159,7 @@ If you want the date field to be entirely hidden from the user, then use `Hidden
---
**Note**: The `UniqueFor<Range>Validation` classes impose an implicit constraint that the fields they are applied to are always treated as required. Fields with `default` values are an exception to this as they always supply a value even when omitted from user input.
**Note**: The `UniqueFor<Range>Validator` classes impose an implicit constraint that the fields they are applied to are always treated as required. Fields with `default` values are an exception to this as they always supply a value even when omitted from user input.
---

View File

@ -65,7 +65,7 @@ Changes should broadly follow the [PEP 8][pep-8] style conventions, and we recom
To run the tests, clone the repository, and then:
# Setup the virtual environment
virtualenv env
python3 -m venv env
source env/bin/activate
pip install django
pip install -r requirements.txt
@ -121,7 +121,7 @@ It's also useful to remember that if you have an outstanding pull request then p
GitHub's documentation for working on pull requests is [available here][pull-requests].
Always run the tests before submitting pull requests, and ideally run `tox` in order to check that your modifications are compatible with both Python 2 and Python 3, and that they run properly on all supported versions of Django.
Always run the tests before submitting pull requests, and ideally run `tox` in order to check that your modifications are compatible on all supported versions of Python and Django.
Once you've made a pull request take a look at the Travis build status in the GitHub interface and make sure the tests are running as you'd expect.

View File

@ -84,7 +84,7 @@ continued development by **[signing up for a paid plan][funding]**.
REST framework requires the following:
* Python (2.7, 3.4, 3.5, 3.6, 3.7)
* Python (3.4, 3.5, 3.6, 3.7)
* Django (1.11, 2.0, 2.1, 2.2)
We **highly recommend** and only officially support the latest patch release of

View File

@ -14,18 +14,18 @@ The tutorial is fairly in-depth, so you should probably get a cookie and a cup o
## Setting up a new environment
Before we do anything else we'll create a new virtual environment, using [virtualenv]. This will make sure our package configuration is kept nicely isolated from any other projects we're working on.
Before we do anything else we'll create a new virtual environment, using [venv]. This will make sure our package configuration is kept nicely isolated from any other projects we're working on.
virtualenv env
python3 -m venv env
source env/bin/activate
Now that we're inside a virtualenv environment, we can install our package requirements.
Now that we're inside a virtual environment, we can install our package requirements.
pip install django
pip install djangorestframework
pip install pygments # We'll be using this for the code highlighting
**Note:** To exit the virtualenv environment at any time, just type `deactivate`. For more information see the [virtualenv documentation][virtualenv].
**Note:** To exit the virtual environment at any time, just type `deactivate`. For more information see the [venv documentation][venv].
## Getting started
@ -372,7 +372,7 @@ We'll see how we can start to improve things in [part 2 of the tutorial][tut-2].
[quickstart]: quickstart.md
[repo]: https://github.com/encode/rest-framework-tutorial
[sandbox]: https://restframework.herokuapp.com/
[virtualenv]: http://www.virtualenv.org/en/latest/index.html
[venv]: https://docs.python.org/3/library/venv.html
[tut-2]: 2-requests-and-responses.md
[httpie]: https://github.com/jakubroztocil/httpie#installation
[curl]: https://curl.haxx.se/

View File

@ -10,11 +10,11 @@ Create a new Django project named `tutorial`, then start a new app called `quick
mkdir tutorial
cd tutorial
# Create a virtualenv to isolate our package dependencies locally
virtualenv env
# Create a virtual environment to isolate our package dependencies locally
python3 -m venv env
source env/bin/activate # On Windows use `env\Scripts\activate`
# Install Django and Django REST framework into the virtualenv
# Install Django and Django REST framework into the virtual environment
pip install django
pip install djangorestframework

View File

@ -6,7 +6,7 @@ import binascii
from django.contrib.auth import authenticate, get_user_model
from django.middleware.csrf import CsrfViewMiddleware
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework import HTTP_HEADER_ENCODING, exceptions

View File

@ -1,5 +1,5 @@
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
class AuthTokenConfig(AppConfig):

View File

@ -3,7 +3,7 @@ import os
from django.conf import settings
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
class Token(models.Model):

View File

@ -1,5 +1,5 @@
from django.contrib.auth import authenticate
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers

View File

@ -3,7 +3,6 @@ The `compat` module provides support for backwards compatibility with older
versions of Django/Python, and compatibility wrappers around optional packages.
"""
import sys
from collections.abc import Mapping, MutableMapping # noqa
from django.conf import settings
from django.core import validators

View File

@ -8,8 +8,8 @@ import math
from django.http import JsonResponse
from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext
from django.utils.translation import gettext_lazy as _
from django.utils.translation import ngettext
from rest_framework import status
from rest_framework.utils.serializer_helpers import ReturnDict, ReturnList
@ -230,7 +230,7 @@ class Throttled(APIException):
wait = math.ceil(wait)
detail = ' '.join((
detail,
force_text(ungettext(self.extra_detail_singular.format(wait=wait),
force_text(ngettext(self.extra_detail_singular.format(wait=wait),
self.extra_detail_plural.format(wait=wait),
wait))))
self.wait = wait

View File

@ -6,6 +6,7 @@ import inspect
import re
import uuid
from collections import OrderedDict
from collections.abc import Mapping
from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
@ -25,12 +26,12 @@ from django.utils.formats import localize_input, sanitize_separators
from django.utils.functional import lazy
from django.utils.ipv6 import clean_ipv6_address
from django.utils.timezone import utc
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from pytz.exceptions import InvalidTimeError
from rest_framework import ISO_8601
from rest_framework.compat import (
Mapping, MaxLengthValidator, MaxValueValidator, MinLengthValidator,
MaxLengthValidator, MaxValueValidator, MinLengthValidator,
MinValueValidator, ProhibitNullCharactersValidator
)
from rest_framework.exceptions import ErrorDetail, ValidationError
@ -1753,7 +1754,7 @@ class JSONField(Field):
try:
if self.binary or getattr(data, 'is_json_string', False):
if isinstance(data, bytes):
data = data.decode('utf-8')
data = data.decode()
return json.loads(data)
else:
json.dumps(data)
@ -1764,10 +1765,7 @@ class JSONField(Field):
def to_representation(self, value):
if self.binary:
value = json.dumps(value)
# On python 2.x the return type for json.dumps() is underspecified.
# On python 3.x json.dumps() returns unicode strings.
if isinstance(value, str):
value = bytes(value.encode('utf-8'))
value = value.encode()
return value

View File

@ -12,7 +12,7 @@ from django.db.models.constants import LOOKUP_SEP
from django.db.models.sql.constants import ORDER_PATTERN
from django.template import loader
from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework import RemovedInDRF310Warning
from rest_framework.compat import (

View File

@ -29,7 +29,7 @@ class Command(BaseCommand):
renderer = self.get_renderer(options['format'])
output = renderer.render(schema, renderer_context={})
self.stdout.write(output.decode('utf-8'))
self.stdout.write(output.decode())
def get_renderer(self, format):
renderer_cls = {

View File

@ -10,7 +10,7 @@ from django.core.paginator import InvalidPage
from django.core.paginator import Paginator as DjangoPaginator
from django.template import loader
from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework.compat import coreapi, coreschema
from rest_framework.exceptions import NotFound

View File

@ -80,8 +80,7 @@ class FormParser(BaseParser):
"""
parser_context = parser_context or {}
encoding = parser_context.get('encoding', settings.DEFAULT_CHARSET)
data = QueryDict(stream.read(), encoding=encoding)
return data
return QueryDict(stream.read(), encoding=encoding)
class MultiPartParser(BaseParser):
@ -202,7 +201,7 @@ class FileUploadParser(BaseParser):
try:
meta = parser_context['request'].META
disposition = parse_header(meta['HTTP_CONTENT_DISPOSITION'].encode('utf-8'))
disposition = parse_header(meta['HTTP_CONTENT_DISPOSITION'].encode())
filename_parm = disposition[1]
if 'filename*' in filename_parm:
return self.get_encoded_filename(filename_parm)

View File

@ -7,7 +7,7 @@ from django.db.models import Manager
from django.db.models.query import QuerySet
from django.urls import NoReverseMatch, Resolver404, get_script_prefix, resolve
from django.utils.encoding import smart_text, uri_to_iri
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework.fields import (
Field, empty, get_attribute, is_simple_callable, iter_options

View File

@ -104,18 +104,11 @@ class JSONRenderer(BaseRenderer):
allow_nan=not self.strict, separators=separators
)
# On python 2.x json.dumps() returns bytestrings if ensure_ascii=True,
# but if ensure_ascii=False, the return type is underspecified,
# and may (or may not) be unicode.
# On python 3.x json.dumps() returns unicode strings.
if isinstance(ret, str):
# We always fully escape \u2028 and \u2029 to ensure we output JSON
# that is a strict javascript subset. If bytes were returned
# by json.dumps() then we don't have these characters in any case.
# that is a strict javascript subset.
# See: http://timelessrepo.com/json-isnt-a-javascript-subset
ret = ret.replace('\u2028', '\\u2028').replace('\u2029', '\\u2029')
return bytes(ret.encode('utf-8'))
return ret
return ret.encode()
class TemplateHTMLRenderer(BaseRenderer):
@ -574,7 +567,7 @@ class BrowsableAPIRenderer(BaseRenderer):
data.pop(name, None)
content = renderer.render(data, accepted, context)
# Renders returns bytes, but CharField expects a str.
content = content.decode('utf-8')
content = content.decode()
else:
content = None
@ -681,7 +674,7 @@ class BrowsableAPIRenderer(BaseRenderer):
csrf_header_name = csrf_header_name[5:]
csrf_header_name = csrf_header_name.replace('_', '-')
context = {
return {
'content': self.get_content(renderer, data, accepted_media_type, renderer_context),
'code_style': pygments_css(self.code_style),
'view': view,
@ -717,7 +710,6 @@ class BrowsableAPIRenderer(BaseRenderer):
'csrf_cookie_name': csrf_cookie_name,
'csrf_header_name': csrf_header_name
}
return context
def render(self, data, accepted_media_type=None, renderer_context=None):
"""
@ -1032,7 +1024,7 @@ class OpenAPIRenderer(_BaseOpenAPIRenderer):
def render(self, data, media_type=None, renderer_context=None):
structure = self.get_structure(data)
return yaml.dump(structure, default_flow_style=False).encode('utf-8')
return yaml.dump(structure, default_flow_style=False).encode()
class JSONOpenAPIRenderer(_BaseOpenAPIRenderer):
@ -1045,4 +1037,4 @@ class JSONOpenAPIRenderer(_BaseOpenAPIRenderer):
def render(self, data, media_type=None, renderer_context=None):
structure = self.get_structure(data)
return json.dumps(structure, indent=4).encode('utf-8')
return json.dumps(structure, indent=4).encode()

View File

@ -184,9 +184,7 @@ class EndpointEnumerator:
)
api_endpoints.extend(nested_endpoints)
api_endpoints = sorted(api_endpoints, key=endpoint_ordering)
return api_endpoints
return sorted(api_endpoints, key=endpoint_ordering)
def get_path_from_regex(self, path_regex):
"""
@ -195,8 +193,7 @@ class EndpointEnumerator:
path = simplify_regex(path_regex)
# Strip Django 2.0 convertors as they are incompatible with uritemplate format
path = re.sub(_PATH_PARAMETER_COMPONENT_RE, r'{\g<parameter>}', path)
return path
return re.sub(_PATH_PARAMETER_COMPONENT_RE, r'{\g<parameter>}', path)
def should_include_endpoint(self, path, callback):
"""

View File

@ -11,7 +11,7 @@ from weakref import WeakKeyDictionary
from django.db import models
from django.utils.encoding import force_text, smart_text
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework import exceptions, serializers
from rest_framework.compat import coreapi, coreschema, uritemplate
@ -435,8 +435,7 @@ class AutoSchema(ViewInspector):
by_name = OrderedDict((f.name, f) for f in fields)
for f in update_with:
by_name[f.name] = f
fields = list(by_name.values())
return fields
return list(by_name.values())
def get_encoding(self, path, method):
"""

View File

@ -14,6 +14,7 @@ import copy
import inspect
import traceback
from collections import OrderedDict
from collections.abc import Mapping
from django.core.exceptions import ImproperlyConfigured
from django.core.exceptions import ValidationError as DjangoValidationError
@ -23,9 +24,9 @@ from django.db.models.fields import Field as DjangoModelField
from django.db.models.fields import FieldDoesNotExist
from django.utils import timezone
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework.compat import Mapping, postgres_fields
from rest_framework.compat import postgres_fields
from rest_framework.exceptions import ErrorDetail, ValidationError
from rest_framework.fields import get_error_detail, set_value
from rest_framework.settings import api_settings

View File

@ -18,10 +18,9 @@ This module provides the `api_setting` object, that is used to access
REST framework settings, checking for user settings first, then falling
back to the defaults.
"""
from importlib import import_module
from django.conf import settings
from django.test.signals import setting_changed
from django.utils.module_loading import import_string
from rest_framework import ISO_8601
@ -175,11 +174,8 @@ def import_from_string(val, setting_name):
Attempt to import a class from a string representation.
"""
try:
# Nod to tastypie's use of importlib.
module_path, class_name = val.rsplit('.', 1)
module = import_module(module_path)
return getattr(module, class_name)
except (ImportError, AttributeError) as e:
return import_string(val)
except ImportError as e:
msg = "Could not import '%s' for API setting '%s'. %s: %s." % (val, setting_name, e.__class__.__name__, e)
raise ImportError(msg)

View File

@ -12,7 +12,7 @@
<div class="modal-body">
{% if user.is_authenticated %}
<h4 class="text-center">You are logged in as {{ user.username }}.</h4>
<h4 class="text-center">You are logged in as {{ user.get_username }}.</h4>
{% else %}
<div class="text-center">

View File

@ -47,7 +47,7 @@ class JSONEncoder(json.JSONEncoder):
return tuple(obj)
elif isinstance(obj, bytes):
# Best-effort for binary blobs. See #4187.
return obj.decode('utf-8')
return obj.decode()
elif hasattr(obj, 'tolist'):
# Numpy arrays and array scalars.
return obj.tolist()

View File

@ -41,9 +41,7 @@ def smart_repr(value):
# <django.core.validators.RegexValidator object at 0x1047af050>
# Should be presented as
# <django.core.validators.RegexValidator object>
value = re.sub(' at 0x[0-9A-Fa-f]{4,32}>', '>', value)
return value
return re.sub(' at 0x[0-9A-Fa-f]{4,32}>', '>', value)
def field_repr(field, force_many=False):

View File

@ -1,8 +1,8 @@
from collections import OrderedDict
from collections.abc import MutableMapping
from django.utils.encoding import force_text
from rest_framework.compat import MutableMapping
from rest_framework.utils import json

View File

@ -7,7 +7,7 @@ object creation, and makes it possible to switch between using the implicit
`ModelSerializer` class and an equivalent explicit `Serializer` class.
"""
from django.db import DataError
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework.exceptions import ValidationError
from rest_framework.utils.representation import smart_repr

View File

@ -1,6 +1,6 @@
import re
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework import exceptions
from rest_framework.compat import unicode_http_header

View File

@ -11,7 +11,7 @@ PYTEST_ARGS = {
FLAKE8_ARGS = ['rest_framework', 'tests']
ISORT_ARGS = ['--recursive', '--check-only', '--diff', '-o' 'uritemplate', '-p', 'tests', 'rest_framework', 'tests']
ISORT_ARGS = ['--recursive', '--check-only', '--diff', 'rest_framework', 'tests']
def exit_on_failure(ret, message=None):

View File

@ -14,8 +14,8 @@ skip=.tox
atomic=true
multi_line_output=5
known_standard_library=types
known_third_party=pytest,_pytest,django,pytz
known_first_party=rest_framework
known_third_party=pytest,_pytest,django,pytz,uritemplate
known_first_party=rest_framework,tests
[coverage:run]
# NOTE: source is ignored with pytest-cov (but uses the same).

View File

@ -183,7 +183,7 @@ class SessionAuthTests(TestCase):
cf. [#1810](https://github.com/encode/django-rest-framework/pull/1810)
"""
response = self.csrf_client.get('/auth/login/')
content = response.content.decode('utf8')
content = response.content.decode()
assert '<label for="id_username">Username:</label>' in content
def test_post_form_session_auth_failing_csrf(self):

View File

@ -24,18 +24,18 @@ class DropdownWithAuthTests(TestCase):
def test_name_shown_when_logged_in(self):
self.client.login(username=self.username, password=self.password)
response = self.client.get('/')
content = response.content.decode('utf8')
content = response.content.decode()
assert 'john' in content
def test_logout_shown_when_logged_in(self):
self.client.login(username=self.username, password=self.password)
response = self.client.get('/')
content = response.content.decode('utf8')
content = response.content.decode()
assert '>Log out<' in content
def test_login_shown_when_logged_out(self):
response = self.client.get('/')
content = response.content.decode('utf8')
content = response.content.decode()
assert '>Log in<' in content
@ -59,16 +59,16 @@ class NoDropdownWithoutAuthTests(TestCase):
def test_name_shown_when_logged_in(self):
self.client.login(username=self.username, password=self.password)
response = self.client.get('/')
content = response.content.decode('utf8')
content = response.content.decode()
assert 'john' in content
def test_dropdown_not_shown_when_logged_in(self):
self.client.login(username=self.username, password=self.password)
response = self.client.get('/')
content = response.content.decode('utf8')
content = response.content.decode()
assert '<li class="dropdown">' not in content
def test_dropdown_not_shown_when_logged_out(self):
response = self.client.get('/')
content = response.content.decode('utf8')
content = response.content.decode()
assert '<li class="dropdown">' not in content

View File

@ -34,7 +34,7 @@ class DropdownWithAuthTests(TestCase):
def test_login(self):
response = self.client.get('/api/')
assert 200 == response.status_code
content = response.content.decode('utf-8')
content = response.content.decode()
assert 'form action="/api/"' in content
assert 'input name="nested.one"' in content
assert 'input name="nested.two"' in content

View File

@ -1,7 +1,7 @@
import uuid
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
class RESTFrameworkModel(models.Model):

View File

@ -202,8 +202,7 @@ class ActionDecoratorTestCase(TestCase):
def method():
raise NotImplementedError
# Python 2.x compatibility - cast __name__ to str
method.__name__ = str(name)
method.__name__ = name
getattr(test_action.mapping, name)(method)
# ensure the mapping returns the correct method name

View File

@ -1,6 +1,6 @@
from django.test import RequestFactory, TestCase
from django.utils import translation
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework.exceptions import (
APIException, ErrorDetail, Throttled, _get_error_details, bad_request,

View File

@ -164,7 +164,7 @@ class TestRootView(TestCase):
request = factory.post('/', data, HTTP_ACCEPT='text/html')
response = self.view(request).render()
expected_error = '<span class="help-block">Ensure this field has no more than 100 characters.</span>'
assert expected_error in response.rendered_content.decode('utf-8')
assert expected_error in response.rendered_content.decode()
EXPECTED_QUERIES_FOR_PUT = 2
@ -311,7 +311,7 @@ class TestInstanceView(TestCase):
request = factory.put('/', data, HTTP_ACCEPT='text/html')
response = self.view(request, pk=1).render()
expected_error = '<span class="help-block">Ensure this field has no more than 100 characters.</span>'
assert expected_error in response.rendered_content.decode('utf-8')
assert expected_error in response.rendered_content.decode()
class TestFKInstanceView(TestCase):
@ -538,7 +538,7 @@ class TestFilterBackendAppliedToViews(TestCase):
view = DynamicSerializerView.as_view()
request = factory.get('/')
response = view(request).render()
content = response.content.decode('utf8')
content = response.content.decode()
assert 'field_b' in content
assert 'field_a' not in content

View File

@ -40,9 +40,7 @@ class TestFileUploadParser(TestCase):
def setUp(self):
class MockRequest:
pass
self.stream = io.BytesIO(
"Test text file".encode('utf-8')
)
self.stream = io.BytesIO(b"Test text file")
request = MockRequest()
request.upload_handlers = (MemoryFileUploadHandler(),)
request.META = {
@ -128,7 +126,7 @@ class TestFileUploadParser(TestCase):
class TestJSONParser(TestCase):
def bytes(self, value):
return io.BytesIO(value.encode('utf-8'))
return io.BytesIO(value.encode())
def test_float_strictness(self):
parser = JSONParser()

View File

@ -1,5 +1,6 @@
import re
from collections import OrderedDict
from collections.abc import MutableMapping
import pytest
from django.conf.urls import include, url
@ -9,10 +10,10 @@ from django.http.request import HttpRequest
from django.template import loader
from django.test import TestCase, override_settings
from django.utils.safestring import SafeText
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework import permissions, serializers, status
from rest_framework.compat import MutableMapping, coreapi
from rest_framework.compat import coreapi
from rest_framework.decorators import action
from rest_framework.renderers import (
AdminRenderer, BaseRenderer, BrowsableAPIRenderer, DocumentationRenderer,
@ -75,8 +76,7 @@ class MockView(APIView):
renderer_classes = (RendererA, RendererB)
def get(self, request, **kwargs):
response = Response(DUMMYCONTENT, status=DUMMYSTATUS)
return response
return Response(DUMMYCONTENT, status=DUMMYSTATUS)
class MockGETView(APIView):
@ -303,14 +303,14 @@ class JSONRendererTests(TestCase):
o = DummyTestModel.objects.create(name='dummy')
qs = DummyTestModel.objects.values('id', 'name')
ret = JSONRenderer().render(qs)
data = json.loads(ret.decode('utf-8'))
data = json.loads(ret.decode())
self.assertEqual(data, [{'id': o.id, 'name': o.name}])
def test_render_queryset_values_list(self):
o = DummyTestModel.objects.create(name='dummy')
qs = DummyTestModel.objects.values_list('id', 'name')
ret = JSONRenderer().render(qs)
data = json.loads(ret.decode('utf-8'))
data = json.loads(ret.decode())
self.assertEqual(data, [[o.id, o.name]])
def test_render_dict_abc_obj(self):
@ -340,7 +340,7 @@ class JSONRendererTests(TestCase):
x['key'] = 'string value'
x[2] = 3
ret = JSONRenderer().render(x)
data = json.loads(ret.decode('utf-8'))
data = json.loads(ret.decode())
self.assertEqual(data, {'key': 'string value', '2': 3})
def test_render_obj_with_getitem(self):
@ -380,7 +380,7 @@ class JSONRendererTests(TestCase):
renderer = JSONRenderer()
content = renderer.render(obj, 'application/json')
# Fix failing test case which depends on version of JSON library.
self.assertEqual(content.decode('utf-8'), _flat_repr)
self.assertEqual(content.decode(), _flat_repr)
def test_with_content_type_args(self):
"""
@ -389,7 +389,7 @@ class JSONRendererTests(TestCase):
obj = {'foo': ['bar', 'baz']}
renderer = JSONRenderer()
content = renderer.render(obj, 'application/json; indent=2')
self.assertEqual(strip_trailing_whitespace(content.decode('utf-8')), _indented_repr)
self.assertEqual(strip_trailing_whitespace(content.decode()), _indented_repr)
class UnicodeJSONRendererTests(TestCase):
@ -400,7 +400,7 @@ class UnicodeJSONRendererTests(TestCase):
obj = {'countries': ['United Kingdom', 'France', 'España']}
renderer = JSONRenderer()
content = renderer.render(obj, 'application/json')
self.assertEqual(content, '{"countries":["United Kingdom","France","España"]}'.encode('utf-8'))
self.assertEqual(content, '{"countries":["United Kingdom","France","España"]}'.encode())
def test_u2028_u2029(self):
# The \u2028 and \u2029 characters should be escaped,
@ -409,7 +409,7 @@ class UnicodeJSONRendererTests(TestCase):
obj = {'should_escape': '\u2028\u2029'}
renderer = JSONRenderer()
content = renderer.render(obj, 'application/json')
self.assertEqual(content, '{"should_escape":"\\u2028\\u2029"}'.encode('utf-8'))
self.assertEqual(content, '{"should_escape":"\\u2028\\u2029"}'.encode())
class AsciiJSONRendererTests(TestCase):
@ -422,7 +422,7 @@ class AsciiJSONRendererTests(TestCase):
obj = {'countries': ['United Kingdom', 'France', 'España']}
renderer = AsciiJSONRenderer()
content = renderer.render(obj, 'application/json')
self.assertEqual(content, '{"countries":["United Kingdom","France","Espa\\u00f1a"]}'.encode('utf-8'))
self.assertEqual(content, '{"countries":["United Kingdom","France","Espa\\u00f1a"]}'.encode())
# Tests for caching issue, #346
@ -653,9 +653,9 @@ class BrowsableAPIRendererTests(URLPatternsTestCase):
def test_extra_actions_dropdown(self):
resp = self.client.get('/api/examples/', HTTP_ACCEPT='text/html')
assert 'id="extra-actions-menu"' in resp.content.decode('utf-8')
assert '/api/examples/list_action/' in resp.content.decode('utf-8')
assert '>Extra list action<' in resp.content.decode('utf-8')
assert 'id="extra-actions-menu"' in resp.content.decode()
assert '/api/examples/list_action/' in resp.content.decode()
assert '>Extra list action<' in resp.content.decode()
class AdminRendererTests(TestCase):

View File

@ -438,13 +438,13 @@ class TestEmptyPrefix(URLPatternsTestCase, TestCase):
def test_empty_prefix_list(self):
response = self.client.get('/empty-prefix/')
assert response.status_code == 200
assert json.loads(response.content.decode('utf-8')) == [{'uuid': '111', 'text': 'First'},
assert json.loads(response.content.decode()) == [{'uuid': '111', 'text': 'First'},
{'uuid': '222', 'text': 'Second'}]
def test_empty_prefix_detail(self):
response = self.client.get('/empty-prefix/1/')
assert response.status_code == 200
assert json.loads(response.content.decode('utf-8')) == {'uuid': '111', 'text': 'First'}
assert json.loads(response.content.decode()) == {'uuid': '111', 'text': 'First'}
class TestRegexUrlPath(URLPatternsTestCase, TestCase):
@ -456,14 +456,14 @@ class TestRegexUrlPath(URLPatternsTestCase, TestCase):
kwarg = '1234'
response = self.client.get('/regex/list/{}/'.format(kwarg))
assert response.status_code == 200
assert json.loads(response.content.decode('utf-8')) == {'kwarg': kwarg}
assert json.loads(response.content.decode()) == {'kwarg': kwarg}
def test_regex_url_path_detail(self):
pk = '1'
kwarg = '1234'
response = self.client.get('/regex/{}/detail/{}/'.format(pk, kwarg))
assert response.status_code == 200
assert json.loads(response.content.decode('utf-8')) == {'pk': pk, 'kwarg': kwarg}
assert json.loads(response.content.decode()) == {'pk': pk, 'kwarg': kwarg}
class TestViewInitkwargs(URLPatternsTestCase, TestCase):

View File

@ -1358,4 +1358,4 @@ def test_schema_handles_exception():
response = schema_view(request)
response.render()
assert response.status_code == 403
assert "You do not have permission to perform this action." in str(response.content)
assert b"You do not have permission to perform this action." in response.content

View File

@ -2,12 +2,12 @@ import inspect
import pickle
import re
from collections import ChainMap
from collections.abc import Mapping
import pytest
from django.db import models
from rest_framework import exceptions, fields, relations, serializers
from rest_framework.compat import Mapping
from rest_framework.fields import Field
from .models import (
@ -386,23 +386,6 @@ class TestIncorrectlyConfigured:
)
class TestUnicodeRepr:
def test_repr(self):
class ExampleSerializer(serializers.Serializer):
example = serializers.CharField()
class ExampleObject:
def __init__(self):
self.example = '한국'
def __repr__(self):
return repr(self.example)
instance = ExampleObject()
serializer = ExampleSerializer(instance)
repr(serializer) # Should not error.
class TestNotRequiredOutput:
def test_not_required_output_for_dict(self):
"""

View File

@ -6,7 +6,7 @@ from django.shortcuts import render
def test_base_template_with_context():
context = {'request': True, 'csrf_token': 'TOKEN'}
result = render({}, 'rest_framework/base.html', context=context)
assert re.search(r'\bcsrfToken: "TOKEN"', result.content.decode('utf-8'))
assert re.search(r'\bcsrfToken: "TOKEN"', result.content.decode())
def test_base_template_with_no_context():
@ -14,4 +14,4 @@ def test_base_template_with_no_context():
# so it can be easily extended.
result = render({}, 'rest_framework/base.html')
# note that this response will not include a valid CSRF token
assert re.search(r'\bcsrfToken: ""', result.content.decode('utf-8'))
assert re.search(r'\bcsrfToken: ""', result.content.decode())