Skip to content

Commit ea1da76

Browse files
authored
Add pyupgrade to pre-commit hooks (#9682)
1 parent 2fbfaae commit ea1da76

21 files changed

+47
-41
lines changed

.pre-commit-config.yaml

+6
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,9 @@ repos:
3131
hooks:
3232
- id: codespell
3333
exclude: locale|kickstarter-announcement.md|coreapi-0.1.1.js
34+
35+
- repo: https://github.com/asottile/pyupgrade
36+
rev: v3.19.1
37+
hooks:
38+
- id: pyupgrade
39+
args: ["--py39-plus", "--keep-percent-format"]

rest_framework/authtoken/management/commands/drf_create_token.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,4 @@ def handle(self, *args, **options):
4242
username)
4343
)
4444
self.stdout.write(
45-
'Generated token {} for user {}'.format(token.key, username))
45+
f'Generated token {token.key} for user {username}')

rest_framework/fields.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def get_attribute(instance, attrs):
111111
# If we raised an Attribute or KeyError here it'd get treated
112112
# as an omitted field in `Field.get_attribute()`. Instead we
113113
# raise a ValueError to ensure the exception is not masked.
114-
raise ValueError('Exception raised in callable attribute "{}"; original exception was: {}'.format(attr, exc))
114+
raise ValueError(f'Exception raised in callable attribute "{attr}"; original exception was: {exc}')
115115

116116
return instance
117117

@@ -1103,7 +1103,7 @@ def to_representation(self, value):
11031103
if self.localize:
11041104
return localize_input(quantized)
11051105

1106-
return '{:f}'.format(quantized)
1106+
return f'{quantized:f}'
11071107

11081108
def quantize(self, value):
11091109
"""
@@ -1861,7 +1861,7 @@ def __init__(self, method_name=None, **kwargs):
18611861
def bind(self, field_name, parent):
18621862
# The method name defaults to `get_{field_name}`.
18631863
if self.method_name is None:
1864-
self.method_name = 'get_{field_name}'.format(field_name=field_name)
1864+
self.method_name = f'get_{field_name}'
18651865

18661866
super().bind(field_name, parent)
18671867

rest_framework/negotiation.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def select_renderer(self, request, renderers, format_suffix=None):
6565
full_media_type = ';'.join(
6666
(renderer.media_type,) +
6767
tuple(
68-
'{}={}'.format(key, value)
68+
f'{key}={value}'
6969
for key, value in media_type_wrapper.params.items()
7070
)
7171
)

rest_framework/permissions.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ def _queryset(self, view):
225225
if hasattr(view, 'get_queryset'):
226226
queryset = view.get_queryset()
227227
assert queryset is not None, (
228-
'{}.get_queryset() returned None'.format(view.__class__.__name__)
228+
f'{view.__class__.__name__}.get_queryset() returned None'
229229
)
230230
return queryset
231231
return view.queryset

rest_framework/response.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def rendered_content(self):
6666
content_type = self.content_type
6767

6868
if content_type is None and charset is not None:
69-
content_type = "{}; charset={}".format(media_type, charset)
69+
content_type = f"{media_type}; charset={charset}"
7070
elif content_type is None:
7171
content_type = media_type
7272
self['Content-Type'] = content_type

rest_framework/schemas/coreapi.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def get_available_key(self, preferred_key):
6868
current_val = self.methods_counter[preferred_key]
6969
self.methods_counter[preferred_key] += 1
7070

71-
key = '{}_{}'.format(preferred_key, current_val)
71+
key = f'{preferred_key}_{current_val}'
7272
if key not in self:
7373
return key
7474

rest_framework/schemas/openapi.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def get_schema(self, request=None, public=False):
8282
continue
8383
if components_schemas[k] == components[k]:
8484
continue
85-
warnings.warn('Schema component "{}" has been overridden with a different value.'.format(k))
85+
warnings.warn(f'Schema component "{k}" has been overridden with a different value.')
8686

8787
components_schemas.update(components)
8888

@@ -644,7 +644,7 @@ def get_response_serializer(self, path, method):
644644
return self.get_serializer(path, method)
645645

646646
def get_reference(self, serializer):
647-
return {'$ref': '#/components/schemas/{}'.format(self.get_component_name(serializer))}
647+
return {'$ref': f'#/components/schemas/{self.get_component_name(serializer)}'}
648648

649649
def get_request_body(self, path, method):
650650
if method not in ('PUT', 'PATCH', 'POST'):

rest_framework/utils/field_mapping.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def get_unique_validators(field_name, model_field):
6666
"""
6767
Returns a list of UniqueValidators that should be applied to the field.
6868
"""
69-
field_set = set([field_name])
69+
field_set = {field_name}
7070
conditions = {
7171
c.condition
7272
for c in model_field.model._meta.constraints

tests/schemas/test_coreapi.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1234,7 +1234,7 @@ def _verify_cbv_links(self, loc, url, methods=None, suffixes=None):
12341234

12351235
for method, suffix in zip(methods, suffixes):
12361236
if suffix is not None:
1237-
key = '{}_{}'.format(method, suffix)
1237+
key = f'{method}_{suffix}'
12381238
else:
12391239
key = method
12401240
assert loc[key].url == url

tests/schemas/test_managementcommand.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,15 @@ def test_renders_openapi_json_schema(self):
7070

7171
def test_accepts_custom_schema_generator(self):
7272
call_command('generateschema',
73-
'--generator_class={}.{}'.format(__name__, CustomSchemaGenerator.__name__),
73+
f'--generator_class={__name__}.{CustomSchemaGenerator.__name__}',
7474
stdout=self.out)
7575
out_json = yaml.safe_load(self.out.getvalue())
7676
assert out_json == CustomSchemaGenerator.SCHEMA
7777

7878
def test_writes_schema_to_file_on_parameter(self):
7979
fd, path = tempfile.mkstemp()
8080
try:
81-
call_command('generateschema', '--file={}'.format(path), stdout=self.out)
81+
call_command('generateschema', f'--file={path}', stdout=self.out)
8282
# nothing on stdout
8383
assert not self.out.getvalue()
8484

tests/test_exceptions.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ def test_get_full_details_with_throttling(self):
4343

4444
exception = Throttled(wait=2)
4545
assert exception.get_full_details() == {
46-
'message': 'Request was throttled. Expected available in {} seconds.'.format(2),
46+
'message': f'Request was throttled. Expected available in {2} seconds.',
4747
'code': 'throttled'}
4848

4949
exception = Throttled(wait=2, detail='Slow down!')
5050
assert exception.get_full_details() == {
51-
'message': 'Slow down! Expected available in {} seconds.'.format(2),
51+
'message': f'Slow down! Expected available in {2} seconds.',
5252
'code': 'throttled'}
5353

5454

tests/test_fields.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ def test_valid_inputs(self, *args):
662662
"""
663663
for input_value, expected_output in get_items(self.valid_inputs):
664664
assert self.field.run_validation(input_value) == expected_output, \
665-
'input value: {}'.format(repr(input_value))
665+
f'input value: {repr(input_value)}'
666666

667667
def test_invalid_inputs(self, *args):
668668
"""
@@ -672,12 +672,12 @@ def test_invalid_inputs(self, *args):
672672
with pytest.raises(serializers.ValidationError) as exc_info:
673673
self.field.run_validation(input_value)
674674
assert exc_info.value.detail == expected_failure, \
675-
'input value: {}'.format(repr(input_value))
675+
f'input value: {repr(input_value)}'
676676

677677
def test_outputs(self, *args):
678678
for output_value, expected_output in get_items(self.outputs):
679679
assert self.field.to_representation(output_value) == expected_output, \
680-
'output value: {}'.format(repr(output_value))
680+
f'output value: {repr(output_value)}'
681681

682682

683683
# Boolean types...
@@ -1422,7 +1422,7 @@ class TestDateField(FieldValues):
14221422
outputs = {
14231423
datetime.date(2001, 1, 1): '2001-01-01',
14241424
'2001-01-01': '2001-01-01',
1425-
str('2016-01-10'): '2016-01-10',
1425+
'2016-01-10': '2016-01-10',
14261426
None: None,
14271427
'': None,
14281428
}
@@ -1489,7 +1489,7 @@ class TestDateTimeField(FieldValues):
14891489
datetime.datetime(2001, 1, 1, 13, 00): '2001-01-01T13:00:00Z',
14901490
datetime.datetime(2001, 1, 1, 13, 00, tzinfo=utc): '2001-01-01T13:00:00Z',
14911491
'2001-01-01T00:00:00': '2001-01-01T00:00:00',
1492-
str('2016-01-10T00:00:00'): '2016-01-10T00:00:00',
1492+
'2016-01-10T00:00:00': '2016-01-10T00:00:00',
14931493
None: None,
14941494
'': None,
14951495
}

tests/test_generics.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ def test_put_to_filtered_out_instance(self):
289289
"""
290290
data = {'text': 'foo'}
291291
filtered_out_pk = BasicModel.objects.filter(text='filtered out')[0].pk
292-
request = factory.put('/{}'.format(filtered_out_pk), data, format='json')
292+
request = factory.put(f'/{filtered_out_pk}', data, format='json')
293293
response = self.view(request, pk=filtered_out_pk).render()
294294
assert response.status_code == status.HTTP_404_NOT_FOUND
295295

tests/test_pagination.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ def test_invalid_limit(self):
536536
content = self.get_paginated_content(queryset)
537537
next_limit = self.pagination.default_limit
538538
next_offset = self.pagination.default_limit
539-
next_url = 'http://testserver/?limit={}&offset={}'.format(next_limit, next_offset)
539+
next_url = f'http://testserver/?limit={next_limit}&offset={next_offset}'
540540
assert queryset == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
541541
assert content.get('next') == next_url
542542

@@ -549,7 +549,7 @@ def test_zero_limit(self):
549549
content = self.get_paginated_content(queryset)
550550
next_limit = self.pagination.default_limit
551551
next_offset = self.pagination.default_limit
552-
next_url = 'http://testserver/?limit={}&offset={}'.format(next_limit, next_offset)
552+
next_url = f'http://testserver/?limit={next_limit}&offset={next_offset}'
553553
assert queryset == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
554554
assert content.get('next') == next_url
555555

@@ -565,9 +565,9 @@ def test_max_limit(self):
565565
max_limit = self.pagination.max_limit
566566
next_offset = offset + max_limit
567567
prev_offset = offset - max_limit
568-
base_url = 'http://testserver/?limit={}'.format(max_limit)
569-
next_url = base_url + '&offset={}'.format(next_offset)
570-
prev_url = base_url + '&offset={}'.format(prev_offset)
568+
base_url = f'http://testserver/?limit={max_limit}'
569+
next_url = base_url + f'&offset={next_offset}'
570+
prev_url = base_url + f'&offset={prev_offset}'
571571
assert queryset == list(range(51, 66))
572572
assert content.get('next') == next_url
573573
assert content.get('previous') == prev_url

tests/test_permissions.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ def setUp(self):
353353
'delete': f('delete', model_name)
354354
}
355355
for perm in perms.values():
356-
perm = '{}.{}'.format(app_label, perm)
356+
perm = f'{app_label}.{perm}'
357357
assign_perm(perm, everyone)
358358
everyone.user_set.add(*users.values())
359359

@@ -718,7 +718,7 @@ def has_object_permission(self, request, view, obj):
718718
assert hasperm is False
719719

720720
def test_operand_holder_is_hashable(self):
721-
assert hash((permissions.IsAuthenticated & permissions.IsAdminUser))
721+
assert hash(permissions.IsAuthenticated & permissions.IsAdminUser)
722722

723723
def test_operand_holder_hash_same_for_same_operands_and_operator(self):
724724
first_operand_holder = (

tests/test_relations_pk.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ def test_one_to_one_when_primary_key(self):
586586
source = OneToOnePKSourceSerializer(data={'name': 'source-2', 'target': target_pk})
587587
# Then: The source is valid with the serializer
588588
if not source.is_valid():
589-
self.fail("Expected OneToOnePKTargetSerializer to be valid but had errors: {}".format(source.errors))
589+
self.fail(f"Expected OneToOnePKTargetSerializer to be valid but had errors: {source.errors}")
590590
# Then: Saving the serializer creates a new object
591591
new_source = source.save()
592592
# Then: The new object has the same pk as the target object

tests/test_renderers.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ def test_u2028_u2029(self):
408408
obj = {'should_escape': '\u2028\u2029'}
409409
renderer = JSONRenderer()
410410
content = renderer.render(obj, 'application/json')
411-
self.assertEqual(content, '{"should_escape":"\\u2028\\u2029"}'.encode())
411+
self.assertEqual(content, b'{"should_escape":"\\u2028\\u2029"}')
412412

413413

414414
class AsciiJSONRendererTests(TestCase):
@@ -421,7 +421,7 @@ class AsciiJSONRenderer(JSONRenderer):
421421
obj = {'countries': ['United Kingdom', 'France', 'España']}
422422
renderer = AsciiJSONRenderer()
423423
content = renderer.render(obj, 'application/json')
424-
self.assertEqual(content, '{"countries":["United Kingdom","France","Espa\\u00f1a"]}'.encode())
424+
self.assertEqual(content, b'{"countries":["United Kingdom","France","Espa\\u00f1a"]}')
425425

426426

427427
# Tests for caching issue, #346

tests/test_response.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ def test_if_there_is_charset_specified_on_renderer_it_gets_appended(self):
267267
"""
268268
headers = {"HTTP_ACCEPT": RendererC.media_type}
269269
resp = self.client.get('/', **headers)
270-
expected = "{}; charset={}".format(RendererC.media_type, RendererC.charset)
270+
expected = f"{RendererC.media_type}; charset={RendererC.charset}"
271271
self.assertEqual(expected, resp['Content-Type'])
272272

273273
def test_content_type_set_explicitly_on_response(self):

tests/test_routers.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -447,9 +447,9 @@ def _test_list_and_detail_route_decorators(self, viewset):
447447
url_path = endpoint.url_path
448448

449449
if method_name.startswith('list_'):
450-
assert route.url == '^{{prefix}}/{0}{{trailing_slash}}$'.format(url_path)
450+
assert route.url == f'^{{prefix}}/{url_path}{{trailing_slash}}$'
451451
else:
452-
assert route.url == '^{{prefix}}/{{lookup}}/{0}{{trailing_slash}}$'.format(url_path)
452+
assert route.url == f'^{{prefix}}/{{lookup}}/{url_path}{{trailing_slash}}$'
453453
# check method to function mapping
454454
if method_name.endswith('_post'):
455455
method_map = 'post'
@@ -488,14 +488,14 @@ class TestRegexUrlPath(URLPatternsTestCase, TestCase):
488488

489489
def test_regex_url_path_list(self):
490490
kwarg = '1234'
491-
response = self.client.get('/regex/list/{}/'.format(kwarg))
491+
response = self.client.get(f'/regex/list/{kwarg}/')
492492
assert response.status_code == 200
493493
assert json.loads(response.content.decode()) == {'kwarg': kwarg}
494494

495495
def test_regex_url_path_detail(self):
496496
pk = '1'
497497
kwarg = '1234'
498-
response = self.client.get('/regex/{}/detail/{}/'.format(pk, kwarg))
498+
response = self.client.get(f'/regex/{pk}/detail/{kwarg}/')
499499
assert response.status_code == 200
500500
assert json.loads(response.content.decode()) == {'pk': pk, 'kwarg': kwarg}
501501

@@ -557,14 +557,14 @@ def test_delete(self):
557557

558558
def test_list_extra_action(self):
559559
kwarg = 1234
560-
response = self.client.get('/path/list/{}/'.format(kwarg))
560+
response = self.client.get(f'/path/list/{kwarg}/')
561561
assert response.status_code == 200
562562
assert json.loads(response.content.decode()) == {'kwarg': kwarg}
563563

564564
def test_detail_extra_action(self):
565565
pk = '1'
566566
kwarg = 1234
567-
response = self.client.get('/path/{}/detail/{}/'.format(pk, kwarg))
567+
response = self.client.get(f'/path/{pk}/detail/{kwarg}/')
568568
assert response.status_code == 200
569569
assert json.loads(response.content.decode()) == {'pk': pk, 'kwarg': kwarg}
570570

tests/test_validation.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -148,14 +148,14 @@ def test_max_value_validation_serializer_fails(self):
148148

149149
def test_max_value_validation_success(self):
150150
obj = ValidationMaxValueValidatorModel.objects.create(number_value=100)
151-
request = factory.patch('/{}'.format(obj.pk), {'number_value': 98}, format='json')
151+
request = factory.patch(f'/{obj.pk}', {'number_value': 98}, format='json')
152152
view = UpdateMaxValueValidationModel().as_view()
153153
response = view(request, pk=obj.pk).render()
154154
assert response.status_code == status.HTTP_200_OK
155155

156156
def test_max_value_validation_fail(self):
157157
obj = ValidationMaxValueValidatorModel.objects.create(number_value=100)
158-
request = factory.patch('/{}'.format(obj.pk), {'number_value': 101}, format='json')
158+
request = factory.patch(f'/{obj.pk}', {'number_value': 101}, format='json')
159159
view = UpdateMaxValueValidationModel().as_view()
160160
response = view(request, pk=obj.pk).render()
161161
assert response.content == b'{"number_value":["Ensure this value is less than or equal to 100."]}'

0 commit comments

Comments
 (0)