From 5ce273bbce1c76c390cb12d4b9f51fe144490fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Clgen=20Sar=C4=B1kavak?= Date: Wed, 9 Apr 2025 10:14:21 +0300 Subject: [PATCH] Add django-upgrade to pre-commit hooks --- .pre-commit-config.yaml | 10 ++++++++++ rest_framework/authentication.py | 2 +- rest_framework/authtoken/admin.py | 4 +--- rest_framework/negotiation.py | 2 +- rest_framework/throttling.py | 2 +- tests/test_api_client.py | 4 ++-- tests/test_middleware.py | 2 +- tests/test_relations.py | 4 ++-- tests/test_renderers.py | 16 ++++++++-------- tests/test_requests_client.py | 2 +- tests/test_response.py | 8 ++++---- tests/test_testing.py | 4 ++-- tests/test_urlpatterns.py | 2 +- tests/test_versioning.py | 2 +- 14 files changed, 36 insertions(+), 28 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 27bbcb7634..a9c053fcb9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -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", + ] diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index 3f3bd2227c..58ef9d2e10 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -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) diff --git a/rest_framework/authtoken/admin.py b/rest_framework/authtoken/admin.py index eabb8fca8b..0c98c6a0d2 100644 --- a/rest_framework/authtoken/admin.py +++ b/rest_framework/authtoken/admin.py @@ -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',) @@ -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) diff --git a/rest_framework/negotiation.py b/rest_framework/negotiation.py index 23012f71fd..d0b43ccd85 100644 --- a/rest_framework/negotiation.py +++ b/rest_framework/negotiation.py @@ -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(',')] diff --git a/rest_framework/throttling.py b/rest_framework/throttling.py index c0d6cf42fe..90ce01c428 100644 --- a/rest_framework/throttling.py +++ b/rest_framework/throttling.py @@ -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 diff --git a/tests/test_api_client.py b/tests/test_api_client.py index 976f10ed1d..b2d322de28 100644 --- a/tests/test_api_client.py +++ b/tests/test_api_client.py @@ -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 @@ -180,7 +180,7 @@ def get(self, request): urlpatterns = [ path('', SchemaView.as_view()), path('example/', ListView.as_view()), - re_path(r'^example/(?P[0-9]+)/$', DetailView.as_view()), + path('example//', DetailView.as_view()), path('upload/', UploadView.as_view()), path('download/', DownloadView.as_view()), path('text/', TextView.as_view()), diff --git a/tests/test_middleware.py b/tests/test_middleware.py index 11d4bc01eb..bcd076cde7 100644 --- a/tests/test_middleware.py +++ b/tests/test_middleware.py @@ -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): diff --git a/tests/test_relations.py b/tests/test_relations.py index b9ab157896..28f8e9d668 100644 --- a/tests/test_relations.py +++ b/tests/test_relations.py @@ -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 @@ -152,7 +152,7 @@ def test_pk_representation(self): urlpatterns = [ - re_path(r'^example/(?P.+)/$', lambda: None, name='example'), + path('example//', lambda: None, name='example'), ] diff --git a/tests/test_renderers.py b/tests/test_renderers.py index 1b396575d4..b5b28c17f3 100644 --- a/tests/test_renderers.py +++ b/tests/test_renderers.py @@ -174,7 +174,7 @@ 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) @@ -182,7 +182,7 @@ def test_default_renderer_serializes_content_on_accept_any(self): 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) @@ -190,14 +190,14 @@ def test_specified_renderer_serializes_content_default_case(self): 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): @@ -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) @@ -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() diff --git a/tests/test_requests_client.py b/tests/test_requests_client.py index c8e7be6ee3..9b4f4795fb 100644 --- a/tests/test_requests_client.py +++ b/tests/test_requests_client.py @@ -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({ diff --git a/tests/test_response.py b/tests/test_response.py index 83f8a67172..781478b7a3 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -151,7 +151,7 @@ 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) @@ -159,7 +159,7 @@ def test_default_renderer_serializes_content_on_accept_any(self): 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) @@ -167,7 +167,7 @@ def test_specified_renderer_serializes_content_default_case(self): 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) @@ -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) diff --git a/tests/test_testing.py b/tests/test_testing.py index 26a6e8ffb9..db886d20a9 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -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: @@ -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): diff --git a/tests/test_urlpatterns.py b/tests/test_urlpatterns.py index adcd0a7427..3da548aeeb 100644 --- a/tests/test_urlpatterns.py +++ b/tests/test_urlpatterns.py @@ -93,7 +93,7 @@ def test_format_suffix_django2(self): def test_format_suffix_django2_args(self): urlpatterns = [ path('convtest/', dummy_view), - re_path(r'^retest/(?P[0-9]+)$', dummy_view), + path('retest/', dummy_view), ] test_paths = [ URLTestPath('/convtest/42', (), {'pk': 42}), diff --git a/tests/test_versioning.py b/tests/test_versioning.py index b216461840..2c3535c3a4 100644 --- a/tests/test_versioning.py +++ b/tests/test_versioning.py @@ -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[v1|v2]+)/another/$', dummy_view, name='another'), - re_path(r'^(?P.+)/unversioned/$', dummy_view, name='unversioned'), + path('/unversioned/', dummy_view, name='unversioned'), ] pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy