Skip to content

Add django-upgrade to pre-commit hooks #9683

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
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
10 changes: 10 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,13 @@ repos:
hooks:
- id: pyupgrade
args: ["--py39-plus", "--keep-percent-format"]

- repo: https://github.com/adamchainz/django-upgrade
rev: 1.24.0
hooks:
- id: django-upgrade
args: [
--target-version, "4.2",
# test_urlpatterns.py has re_path related tests
--skip, "django_urls", "tests/test_urlpatterns.py",
]
2 changes: 1 addition & 1 deletion rest_framework/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def get_authorization_header(request):

Hide some test client ickyness where the header can be unicode.
"""
auth = request.META.get('HTTP_AUTHORIZATION', b'')
auth = request.headers.get('authorization', b'')
if isinstance(auth, str):
# Work around django test client oddness
auth = auth.encode(HTTP_HEADER_ENCODING)
Expand Down
4 changes: 1 addition & 3 deletions rest_framework/authtoken/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def url_for_result(self, result):
current_app=self.model_admin.admin_site.name)


@admin.register(TokenProxy)
class TokenAdmin(admin.ModelAdmin):
list_display = ('key', 'user', 'created')
fields = ('user',)
Expand Down Expand Up @@ -49,6 +50,3 @@ def delete_model(self, request, obj):
# Map back to actual Token, since delete() uses pk.
token = Token.objects.get(key=obj.key)
return super().delete_model(request, token)


admin.site.register(TokenProxy, TokenAdmin)
2 changes: 1 addition & 1 deletion rest_framework/negotiation.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,5 @@ def get_accept_list(self, request):
Given the incoming request, return a tokenized list of media
type strings.
"""
header = request.META.get('HTTP_ACCEPT', '*/*')
header = request.headers.get('accept', '*/*')
return [token.strip() for token in header.split(',')]
2 changes: 1 addition & 1 deletion rest_framework/throttling.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def get_ident(self, request):
if present and number of proxies is > 0. If not use all of
HTTP_X_FORWARDED_FOR if it is available, if not use REMOTE_ADDR.
"""
xff = request.META.get('HTTP_X_FORWARDED_FOR')
xff = request.headers.get('x-forwarded-for')
remote_addr = request.META.get('REMOTE_ADDR')
num_proxies = api_settings.NUM_PROXIES

Expand Down
4 changes: 2 additions & 2 deletions tests/test_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from django.http import HttpResponse
from django.test import override_settings
from django.urls import path, re_path
from django.urls import path

from rest_framework.compat import coreapi, coreschema
from rest_framework.parsers import FileUploadParser
Expand Down Expand Up @@ -180,7 +180,7 @@ def get(self, request):
urlpatterns = [
path('', SchemaView.as_view()),
path('example/', ListView.as_view()),
re_path(r'^example/(?P<id>[0-9]+)/$', DetailView.as_view()),
path('example/<int:id>/', DetailView.as_view()),
path('upload/', UploadView.as_view()),
path('download/', DownloadView.as_view()),
path('text/', TextView.as_view()),
Expand Down
2 changes: 1 addition & 1 deletion tests/test_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def test_middleware_can_access_user_when_processing_response(self):
key = 'abcd1234'
Token.objects.create(key=key, user=user)

self.client.get('/auth', HTTP_AUTHORIZATION='Token %s' % key)
self.client.get('/auth', headers={"authorization": 'Token %s' % key})

@override_settings(MIDDLEWARE=('tests.test_middleware.RequestPOSTMiddleware',))
def test_middleware_can_access_request_post_when_processing_response(self):
Expand Down
4 changes: 2 additions & 2 deletions tests/test_relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from _pytest.monkeypatch import MonkeyPatch
from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
from django.test import override_settings
from django.urls import re_path
from django.urls import path
from django.utils.datastructures import MultiValueDict

from rest_framework import relations, serializers
Expand Down Expand Up @@ -152,7 +152,7 @@ def test_pk_representation(self):


urlpatterns = [
re_path(r'^example/(?P<name>.+)/$', lambda: None, name='example'),
path('example/<path:name>/', lambda: None, name='example'),
]


Expand Down
16 changes: 8 additions & 8 deletions tests/test_renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,30 +174,30 @@ def test_head_method_serializes_no_content(self):

def test_default_renderer_serializes_content_on_accept_any(self):
"""If the Accept header is set to */* the default renderer should serialize the response."""
resp = self.client.get('/', HTTP_ACCEPT='*/*')
resp = self.client.get('/', headers={"accept": '*/*'})
self.assertEqual(resp['Content-Type'], RendererA.media_type + '; charset=utf-8')
self.assertEqual(resp.content, RENDERER_A_SERIALIZER(DUMMYCONTENT))
self.assertEqual(resp.status_code, DUMMYSTATUS)

def test_specified_renderer_serializes_content_default_case(self):
"""If the Accept header is set the specified renderer should serialize the response.
(In this case we check that works for the default renderer)"""
resp = self.client.get('/', HTTP_ACCEPT=RendererA.media_type)
resp = self.client.get('/', headers={"accept": RendererA.media_type})
self.assertEqual(resp['Content-Type'], RendererA.media_type + '; charset=utf-8')
self.assertEqual(resp.content, RENDERER_A_SERIALIZER(DUMMYCONTENT))
self.assertEqual(resp.status_code, DUMMYSTATUS)

def test_specified_renderer_serializes_content_non_default_case(self):
"""If the Accept header is set the specified renderer should serialize the response.
(In this case we check that works for a non-default renderer)"""
resp = self.client.get('/', HTTP_ACCEPT=RendererB.media_type)
resp = self.client.get('/', headers={"accept": RendererB.media_type})
self.assertEqual(resp['Content-Type'], RendererB.media_type + '; charset=utf-8')
self.assertEqual(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT))
self.assertEqual(resp.status_code, DUMMYSTATUS)

def test_unsatisfiable_accept_header_on_request_returns_406_status(self):
"""If the Accept header is unsatisfiable we should return a 406 Not Acceptable response."""
resp = self.client.get('/', HTTP_ACCEPT='foo/bar')
resp = self.client.get('/', headers={"accept": 'foo/bar'})
self.assertEqual(resp.status_code, status.HTTP_406_NOT_ACCEPTABLE)

def test_specified_renderer_serializes_content_on_format_query(self):
Expand Down Expand Up @@ -228,14 +228,14 @@ def test_specified_renderer_is_used_on_format_query_with_matching_accept(self):
RendererB.format
)
resp = self.client.get('/' + param,
HTTP_ACCEPT=RendererB.media_type)
headers={"accept": RendererB.media_type})
self.assertEqual(resp['Content-Type'], RendererB.media_type + '; charset=utf-8')
self.assertEqual(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT))
self.assertEqual(resp.status_code, DUMMYSTATUS)

def test_parse_error_renderers_browsable_api(self):
"""Invalid data should still render the browsable API correctly."""
resp = self.client.post('/parseerror', data='foobar', content_type='application/json', HTTP_ACCEPT='text/html')
resp = self.client.post('/parseerror', data='foobar', content_type='application/json', headers={"accept": 'text/html'})
self.assertEqual(resp['Content-Type'], 'text/html; charset=utf-8')
self.assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST)

Expand Down Expand Up @@ -714,13 +714,13 @@ class DummyView:
assert result is None

def test_extra_actions_dropdown(self):
resp = self.client.get('/api/examples/', HTTP_ACCEPT='text/html')
resp = self.client.get('/api/examples/', headers={"accept": 'text/html'})
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()

def test_extra_actions_dropdown_not_authed(self):
resp = self.client.get('/api/unauth-examples/', HTTP_ACCEPT='text/html')
resp = self.client.get('/api/unauth-examples/', headers={"accept": 'text/html'})
assert 'id="extra-actions-menu"' not in resp.content.decode()
assert '/api/examples/list_action/' not in resp.content.decode()
assert '>Extra list action<' not in resp.content.decode()
Expand Down
2 changes: 1 addition & 1 deletion tests/test_requests_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def post(self, request):
}
post = request.POST
json = None
if request.META.get('CONTENT_TYPE') == 'application/json':
if request.headers.get('content-type') == 'application/json':
json = request.data

return Response({
Expand Down
8 changes: 4 additions & 4 deletions tests/test_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,23 +151,23 @@ def test_head_method_serializes_no_content(self):

def test_default_renderer_serializes_content_on_accept_any(self):
"""If the Accept header is set to */* the default renderer should serialize the response."""
resp = self.client.get('/', HTTP_ACCEPT='*/*')
resp = self.client.get('/', headers={"accept": '*/*'})
self.assertEqual(resp['Content-Type'], RendererA.media_type + '; charset=utf-8')
self.assertEqual(resp.content, RENDERER_A_SERIALIZER(DUMMYCONTENT))
self.assertEqual(resp.status_code, DUMMYSTATUS)

def test_specified_renderer_serializes_content_default_case(self):
"""If the Accept header is set the specified renderer should serialize the response.
(In this case we check that works for the default renderer)"""
resp = self.client.get('/', HTTP_ACCEPT=RendererA.media_type)
resp = self.client.get('/', headers={"accept": RendererA.media_type})
self.assertEqual(resp['Content-Type'], RendererA.media_type + '; charset=utf-8')
self.assertEqual(resp.content, RENDERER_A_SERIALIZER(DUMMYCONTENT))
self.assertEqual(resp.status_code, DUMMYSTATUS)

def test_specified_renderer_serializes_content_non_default_case(self):
"""If the Accept header is set the specified renderer should serialize the response.
(In this case we check that works for a non-default renderer)"""
resp = self.client.get('/', HTTP_ACCEPT=RendererB.media_type)
resp = self.client.get('/', headers={"accept": RendererB.media_type})
self.assertEqual(resp['Content-Type'], RendererB.media_type + '; charset=utf-8')
self.assertEqual(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT))
self.assertEqual(resp.status_code, DUMMYSTATUS)
Expand All @@ -192,7 +192,7 @@ def test_specified_renderer_is_used_on_format_query_with_matching_accept(self):
"""If both a 'format' query and a matching Accept header specified,
the renderer with the matching format attribute should serialize the response."""
resp = self.client.get('/?format=%s' % RendererB.format,
HTTP_ACCEPT=RendererB.media_type)
headers={"accept": RendererB.media_type})
self.assertEqual(resp['Content-Type'], RendererB.media_type + '; charset=utf-8')
self.assertEqual(resp.content, RENDERER_B_SERIALIZER(DUMMYCONTENT))
self.assertEqual(resp.status_code, DUMMYSTATUS)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

@api_view(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'])
def view(request):
data = {'auth': request.META.get('HTTP_AUTHORIZATION', b'')}
data = {'auth': request.headers.get('authorization', b'')}
if request.user:
data['user'] = request.user.username
if request.auth:
Expand Down Expand Up @@ -347,7 +347,7 @@ def test_empty_request_content_type(self):
data=None,
content_type='application/json',
)
assert request.META['CONTENT_TYPE'] == 'application/json'
assert request.headers['content-type'] == 'application/json'


class TestUrlPatternTestCase(URLPatternsTestCase):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_urlpatterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def test_format_suffix_django2(self):
def test_format_suffix_django2_args(self):
urlpatterns = [
path('convtest/<int:pk>', dummy_view),
re_path(r'^retest/(?P<pk>[0-9]+)$', dummy_view),
path('retest/<int:pk>', dummy_view),
]
test_paths = [
URLTestPath('/convtest/42', (), {'pk': 42}),
Expand Down
2 changes: 1 addition & 1 deletion tests/test_versioning.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class TestURLReversing(URLPatternsTestCase, APITestCase):
path('v1/', include((included, 'v1'), namespace='v1')),
path('another/', dummy_view, name='another'),
re_path(r'^(?P<version>[v1|v2]+)/another/$', dummy_view, name='another'),
re_path(r'^(?P<foo>.+)/unversioned/$', dummy_view, name='unversioned'),
path('<path:foo>/unversioned/', dummy_view, name='unversioned'),

]

Expand Down
Loading