diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8939dd3db6..27bbcb7634 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,3 +31,9 @@ repos: hooks: - id: codespell exclude: locale|kickstarter-announcement.md|coreapi-0.1.1.js + +- repo: https://github.com/asottile/pyupgrade + rev: v3.19.1 + hooks: + - id: pyupgrade + args: ["--py39-plus", "--keep-percent-format"] diff --git a/rest_framework/authtoken/management/commands/drf_create_token.py b/rest_framework/authtoken/management/commands/drf_create_token.py index 3d65392442..3f4521fe42 100644 --- a/rest_framework/authtoken/management/commands/drf_create_token.py +++ b/rest_framework/authtoken/management/commands/drf_create_token.py @@ -42,4 +42,4 @@ def handle(self, *args, **options): username) ) self.stdout.write( - 'Generated token {} for user {}'.format(token.key, username)) + f'Generated token {token.key} for user {username}') diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 6989edc0a8..89c0a714c6 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -111,7 +111,7 @@ def get_attribute(instance, attrs): # If we raised an Attribute or KeyError here it'd get treated # as an omitted field in `Field.get_attribute()`. Instead we # raise a ValueError to ensure the exception is not masked. - raise ValueError('Exception raised in callable attribute "{}"; original exception was: {}'.format(attr, exc)) + raise ValueError(f'Exception raised in callable attribute "{attr}"; original exception was: {exc}') return instance @@ -1103,7 +1103,7 @@ def to_representation(self, value): if self.localize: return localize_input(quantized) - return '{:f}'.format(quantized) + return f'{quantized:f}' def quantize(self, value): """ @@ -1861,7 +1861,7 @@ def __init__(self, method_name=None, **kwargs): def bind(self, field_name, parent): # The method name defaults to `get_{field_name}`. if self.method_name is None: - self.method_name = 'get_{field_name}'.format(field_name=field_name) + self.method_name = f'get_{field_name}' super().bind(field_name, parent) diff --git a/rest_framework/negotiation.py b/rest_framework/negotiation.py index b4bbfa1f54..23012f71fd 100644 --- a/rest_framework/negotiation.py +++ b/rest_framework/negotiation.py @@ -65,7 +65,7 @@ def select_renderer(self, request, renderers, format_suffix=None): full_media_type = ';'.join( (renderer.media_type,) + tuple( - '{}={}'.format(key, value) + f'{key}={value}' for key, value in media_type_wrapper.params.items() ) ) diff --git a/rest_framework/permissions.py b/rest_framework/permissions.py index 7c15eca589..768f6cb957 100644 --- a/rest_framework/permissions.py +++ b/rest_framework/permissions.py @@ -225,7 +225,7 @@ def _queryset(self, view): if hasattr(view, 'get_queryset'): queryset = view.get_queryset() assert queryset is not None, ( - '{}.get_queryset() returned None'.format(view.__class__.__name__) + f'{view.__class__.__name__}.get_queryset() returned None' ) return queryset return view.queryset diff --git a/rest_framework/response.py b/rest_framework/response.py index 6e756544c6..507ea595f6 100644 --- a/rest_framework/response.py +++ b/rest_framework/response.py @@ -66,7 +66,7 @@ def rendered_content(self): content_type = self.content_type if content_type is None and charset is not None: - content_type = "{}; charset={}".format(media_type, charset) + content_type = f"{media_type}; charset={charset}" elif content_type is None: content_type = media_type self['Content-Type'] = content_type diff --git a/rest_framework/schemas/coreapi.py b/rest_framework/schemas/coreapi.py index 582aba196e..657178304a 100644 --- a/rest_framework/schemas/coreapi.py +++ b/rest_framework/schemas/coreapi.py @@ -68,7 +68,7 @@ def get_available_key(self, preferred_key): current_val = self.methods_counter[preferred_key] self.methods_counter[preferred_key] += 1 - key = '{}_{}'.format(preferred_key, current_val) + key = f'{preferred_key}_{current_val}' if key not in self: return key diff --git a/rest_framework/schemas/openapi.py b/rest_framework/schemas/openapi.py index 019eeb33e1..eb7dc909d9 100644 --- a/rest_framework/schemas/openapi.py +++ b/rest_framework/schemas/openapi.py @@ -82,7 +82,7 @@ def get_schema(self, request=None, public=False): continue if components_schemas[k] == components[k]: continue - warnings.warn('Schema component "{}" has been overridden with a different value.'.format(k)) + warnings.warn(f'Schema component "{k}" has been overridden with a different value.') components_schemas.update(components) @@ -644,7 +644,7 @@ def get_response_serializer(self, path, method): return self.get_serializer(path, method) def get_reference(self, serializer): - return {'$ref': '#/components/schemas/{}'.format(self.get_component_name(serializer))} + return {'$ref': f'#/components/schemas/{self.get_component_name(serializer)}'} def get_request_body(self, path, method): if method not in ('PUT', 'PATCH', 'POST'): diff --git a/rest_framework/utils/field_mapping.py b/rest_framework/utils/field_mapping.py index fc63f96fe0..15c4b91055 100644 --- a/rest_framework/utils/field_mapping.py +++ b/rest_framework/utils/field_mapping.py @@ -66,7 +66,7 @@ def get_unique_validators(field_name, model_field): """ Returns a list of UniqueValidators that should be applied to the field. """ - field_set = set([field_name]) + field_set = {field_name} conditions = { c.condition for c in model_field.model._meta.constraints diff --git a/tests/schemas/test_coreapi.py b/tests/schemas/test_coreapi.py index 171f086469..a97b02fe1f 100644 --- a/tests/schemas/test_coreapi.py +++ b/tests/schemas/test_coreapi.py @@ -1234,7 +1234,7 @@ def _verify_cbv_links(self, loc, url, methods=None, suffixes=None): for method, suffix in zip(methods, suffixes): if suffix is not None: - key = '{}_{}'.format(method, suffix) + key = f'{method}_{suffix}' else: key = method assert loc[key].url == url diff --git a/tests/schemas/test_managementcommand.py b/tests/schemas/test_managementcommand.py index c0713f43ce..fa1b75fbf1 100644 --- a/tests/schemas/test_managementcommand.py +++ b/tests/schemas/test_managementcommand.py @@ -70,7 +70,7 @@ def test_renders_openapi_json_schema(self): def test_accepts_custom_schema_generator(self): call_command('generateschema', - '--generator_class={}.{}'.format(__name__, CustomSchemaGenerator.__name__), + f'--generator_class={__name__}.{CustomSchemaGenerator.__name__}', stdout=self.out) out_json = yaml.safe_load(self.out.getvalue()) assert out_json == CustomSchemaGenerator.SCHEMA @@ -78,7 +78,7 @@ def test_accepts_custom_schema_generator(self): def test_writes_schema_to_file_on_parameter(self): fd, path = tempfile.mkstemp() try: - call_command('generateschema', '--file={}'.format(path), stdout=self.out) + call_command('generateschema', f'--file={path}', stdout=self.out) # nothing on stdout assert not self.out.getvalue() diff --git a/tests/test_exceptions.py b/tests/test_exceptions.py index 9516bfec97..67be5cfbd9 100644 --- a/tests/test_exceptions.py +++ b/tests/test_exceptions.py @@ -43,12 +43,12 @@ def test_get_full_details_with_throttling(self): exception = Throttled(wait=2) assert exception.get_full_details() == { - 'message': 'Request was throttled. Expected available in {} seconds.'.format(2), + 'message': f'Request was throttled. Expected available in {2} seconds.', 'code': 'throttled'} exception = Throttled(wait=2, detail='Slow down!') assert exception.get_full_details() == { - 'message': 'Slow down! Expected available in {} seconds.'.format(2), + 'message': f'Slow down! Expected available in {2} seconds.', 'code': 'throttled'} diff --git a/tests/test_fields.py b/tests/test_fields.py index 7c55dfcc5d..d574b07ebc 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -662,7 +662,7 @@ def test_valid_inputs(self, *args): """ for input_value, expected_output in get_items(self.valid_inputs): assert self.field.run_validation(input_value) == expected_output, \ - 'input value: {}'.format(repr(input_value)) + f'input value: {repr(input_value)}' def test_invalid_inputs(self, *args): """ @@ -672,12 +672,12 @@ def test_invalid_inputs(self, *args): with pytest.raises(serializers.ValidationError) as exc_info: self.field.run_validation(input_value) assert exc_info.value.detail == expected_failure, \ - 'input value: {}'.format(repr(input_value)) + f'input value: {repr(input_value)}' def test_outputs(self, *args): for output_value, expected_output in get_items(self.outputs): assert self.field.to_representation(output_value) == expected_output, \ - 'output value: {}'.format(repr(output_value)) + f'output value: {repr(output_value)}' # Boolean types... @@ -1422,7 +1422,7 @@ class TestDateField(FieldValues): outputs = { datetime.date(2001, 1, 1): '2001-01-01', '2001-01-01': '2001-01-01', - str('2016-01-10'): '2016-01-10', + '2016-01-10': '2016-01-10', None: None, '': None, } @@ -1489,7 +1489,7 @@ class TestDateTimeField(FieldValues): datetime.datetime(2001, 1, 1, 13, 00): '2001-01-01T13:00:00Z', datetime.datetime(2001, 1, 1, 13, 00, tzinfo=utc): '2001-01-01T13:00:00Z', '2001-01-01T00:00:00': '2001-01-01T00:00:00', - str('2016-01-10T00:00:00'): '2016-01-10T00:00:00', + '2016-01-10T00:00:00': '2016-01-10T00:00:00', None: None, '': None, } diff --git a/tests/test_generics.py b/tests/test_generics.py index 8748e8f170..25b96fcbb2 100644 --- a/tests/test_generics.py +++ b/tests/test_generics.py @@ -289,7 +289,7 @@ def test_put_to_filtered_out_instance(self): """ data = {'text': 'foo'} filtered_out_pk = BasicModel.objects.filter(text='filtered out')[0].pk - request = factory.put('/{}'.format(filtered_out_pk), data, format='json') + request = factory.put(f'/{filtered_out_pk}', data, format='json') response = self.view(request, pk=filtered_out_pk).render() assert response.status_code == status.HTTP_404_NOT_FOUND diff --git a/tests/test_pagination.py b/tests/test_pagination.py index d8feae52bd..d8f66e95bc 100644 --- a/tests/test_pagination.py +++ b/tests/test_pagination.py @@ -536,7 +536,7 @@ def test_invalid_limit(self): content = self.get_paginated_content(queryset) next_limit = self.pagination.default_limit next_offset = self.pagination.default_limit - next_url = 'http://testserver/?limit={}&offset={}'.format(next_limit, next_offset) + next_url = f'http://testserver/?limit={next_limit}&offset={next_offset}' assert queryset == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] assert content.get('next') == next_url @@ -549,7 +549,7 @@ def test_zero_limit(self): content = self.get_paginated_content(queryset) next_limit = self.pagination.default_limit next_offset = self.pagination.default_limit - next_url = 'http://testserver/?limit={}&offset={}'.format(next_limit, next_offset) + next_url = f'http://testserver/?limit={next_limit}&offset={next_offset}' assert queryset == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] assert content.get('next') == next_url @@ -565,9 +565,9 @@ def test_max_limit(self): max_limit = self.pagination.max_limit next_offset = offset + max_limit prev_offset = offset - max_limit - base_url = 'http://testserver/?limit={}'.format(max_limit) - next_url = base_url + '&offset={}'.format(next_offset) - prev_url = base_url + '&offset={}'.format(prev_offset) + base_url = f'http://testserver/?limit={max_limit}' + next_url = base_url + f'&offset={next_offset}' + prev_url = base_url + f'&offset={prev_offset}' assert queryset == list(range(51, 66)) assert content.get('next') == next_url assert content.get('previous') == prev_url diff --git a/tests/test_permissions.py b/tests/test_permissions.py index 2c908ba3fe..93fe7b9410 100644 --- a/tests/test_permissions.py +++ b/tests/test_permissions.py @@ -353,7 +353,7 @@ def setUp(self): 'delete': f('delete', model_name) } for perm in perms.values(): - perm = '{}.{}'.format(app_label, perm) + perm = f'{app_label}.{perm}' assign_perm(perm, everyone) everyone.user_set.add(*users.values()) @@ -718,7 +718,7 @@ def has_object_permission(self, request, view, obj): assert hasperm is False def test_operand_holder_is_hashable(self): - assert hash((permissions.IsAuthenticated & permissions.IsAdminUser)) + assert hash(permissions.IsAuthenticated & permissions.IsAdminUser) def test_operand_holder_hash_same_for_same_operands_and_operator(self): first_operand_holder = ( diff --git a/tests/test_relations_pk.py b/tests/test_relations_pk.py index 7a4878a2bf..14513f2bb2 100644 --- a/tests/test_relations_pk.py +++ b/tests/test_relations_pk.py @@ -586,7 +586,7 @@ def test_one_to_one_when_primary_key(self): source = OneToOnePKSourceSerializer(data={'name': 'source-2', 'target': target_pk}) # Then: The source is valid with the serializer if not source.is_valid(): - self.fail("Expected OneToOnePKTargetSerializer to be valid but had errors: {}".format(source.errors)) + self.fail(f"Expected OneToOnePKTargetSerializer to be valid but had errors: {source.errors}") # Then: Saving the serializer creates a new object new_source = source.save() # Then: The new object has the same pk as the target object diff --git a/tests/test_renderers.py b/tests/test_renderers.py index d04ff300ff..1b396575d4 100644 --- a/tests/test_renderers.py +++ b/tests/test_renderers.py @@ -408,7 +408,7 @@ def test_u2028_u2029(self): obj = {'should_escape': '\u2028\u2029'} renderer = JSONRenderer() content = renderer.render(obj, 'application/json') - self.assertEqual(content, '{"should_escape":"\\u2028\\u2029"}'.encode()) + self.assertEqual(content, b'{"should_escape":"\\u2028\\u2029"}') class AsciiJSONRendererTests(TestCase): @@ -421,7 +421,7 @@ class AsciiJSONRenderer(JSONRenderer): 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()) + self.assertEqual(content, b'{"countries":["United Kingdom","France","Espa\\u00f1a"]}') # Tests for caching issue, #346 diff --git a/tests/test_response.py b/tests/test_response.py index a5eeae8825..83f8a67172 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -267,7 +267,7 @@ def test_if_there_is_charset_specified_on_renderer_it_gets_appended(self): """ headers = {"HTTP_ACCEPT": RendererC.media_type} resp = self.client.get('/', **headers) - expected = "{}; charset={}".format(RendererC.media_type, RendererC.charset) + expected = f"{RendererC.media_type}; charset={RendererC.charset}" self.assertEqual(expected, resp['Content-Type']) def test_content_type_set_explicitly_on_response(self): diff --git a/tests/test_routers.py b/tests/test_routers.py index 887f601d54..91a6189d57 100644 --- a/tests/test_routers.py +++ b/tests/test_routers.py @@ -447,9 +447,9 @@ def _test_list_and_detail_route_decorators(self, viewset): url_path = endpoint.url_path if method_name.startswith('list_'): - assert route.url == '^{{prefix}}/{0}{{trailing_slash}}$'.format(url_path) + assert route.url == f'^{{prefix}}/{url_path}{{trailing_slash}}$' else: - assert route.url == '^{{prefix}}/{{lookup}}/{0}{{trailing_slash}}$'.format(url_path) + assert route.url == f'^{{prefix}}/{{lookup}}/{url_path}{{trailing_slash}}$' # check method to function mapping if method_name.endswith('_post'): method_map = 'post' @@ -488,14 +488,14 @@ class TestRegexUrlPath(URLPatternsTestCase, TestCase): def test_regex_url_path_list(self): kwarg = '1234' - response = self.client.get('/regex/list/{}/'.format(kwarg)) + response = self.client.get(f'/regex/list/{kwarg}/') assert response.status_code == 200 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)) + response = self.client.get(f'/regex/{pk}/detail/{kwarg}/') assert response.status_code == 200 assert json.loads(response.content.decode()) == {'pk': pk, 'kwarg': kwarg} @@ -557,14 +557,14 @@ def test_delete(self): def test_list_extra_action(self): kwarg = 1234 - response = self.client.get('/path/list/{}/'.format(kwarg)) + response = self.client.get(f'/path/list/{kwarg}/') assert response.status_code == 200 assert json.loads(response.content.decode()) == {'kwarg': kwarg} def test_detail_extra_action(self): pk = '1' kwarg = 1234 - response = self.client.get('/path/{}/detail/{}/'.format(pk, kwarg)) + response = self.client.get(f'/path/{pk}/detail/{kwarg}/') assert response.status_code == 200 assert json.loads(response.content.decode()) == {'pk': pk, 'kwarg': kwarg} diff --git a/tests/test_validation.py b/tests/test_validation.py index 6e00b48c2e..a2cdd1dcb0 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -148,14 +148,14 @@ def test_max_value_validation_serializer_fails(self): def test_max_value_validation_success(self): obj = ValidationMaxValueValidatorModel.objects.create(number_value=100) - request = factory.patch('/{}'.format(obj.pk), {'number_value': 98}, format='json') + request = factory.patch(f'/{obj.pk}', {'number_value': 98}, format='json') view = UpdateMaxValueValidationModel().as_view() response = view(request, pk=obj.pk).render() assert response.status_code == status.HTTP_200_OK def test_max_value_validation_fail(self): obj = ValidationMaxValueValidatorModel.objects.create(number_value=100) - request = factory.patch('/{}'.format(obj.pk), {'number_value': 101}, format='json') + request = factory.patch(f'/{obj.pk}', {'number_value': 101}, format='json') view = UpdateMaxValueValidationModel().as_view() response = view(request, pk=obj.pk).render() assert response.content == b'{"number_value":["Ensure this value is less than or equal to 100."]}' 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