Skip to content
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

Refactor: Replace try/except with contextlib.suppress() #8676

Merged
merged 1 commit into from Oct 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 7 additions & 13 deletions rest_framework/fields.py
@@ -1,3 +1,4 @@
import contextlib
import copy
import datetime
import decimal
Expand Down Expand Up @@ -690,15 +691,13 @@ class BooleanField(Field):
NULL_VALUES = {'null', 'Null', 'NULL', '', None}

def to_internal_value(self, data):
try:
with contextlib.suppress(TypeError):
if data in self.TRUE_VALUES:
return True
elif data in self.FALSE_VALUES:
return False
elif data in self.NULL_VALUES and self.allow_null:
return None
except TypeError: # Input is an unhashable type
pass
self.fail('invalid', input=data)

def to_representation(self, value):
Expand Down Expand Up @@ -1158,19 +1157,14 @@ def to_internal_value(self, value):
return self.enforce_timezone(value)

for input_format in input_formats:
if input_format.lower() == ISO_8601:
try:
with contextlib.suppress(ValueError, TypeError):
if input_format.lower() == ISO_8601:
parsed = parse_datetime(value)
if parsed is not None:
return self.enforce_timezone(parsed)
except (ValueError, TypeError):
pass
else:
try:
parsed = self.datetime_parser(value, input_format)
return self.enforce_timezone(parsed)
except (ValueError, TypeError):
pass

parsed = self.datetime_parser(value, input_format)
return self.enforce_timezone(parsed)

humanized_format = humanize_datetime.datetime_formats(input_formats)
self.fail('invalid', format=humanized_format)
Expand Down
17 changes: 5 additions & 12 deletions rest_framework/pagination.py
Expand Up @@ -2,6 +2,8 @@
Pagination serializers determine the structure of the output that should
be used for paginated responses.
"""

import contextlib
from base64 import b64decode, b64encode
from collections import OrderedDict, namedtuple
from urllib import parse
Expand Down Expand Up @@ -257,15 +259,12 @@ def get_paginated_response_schema(self, schema):

def get_page_size(self, request):
if self.page_size_query_param:
try:
with contextlib.suppress(KeyError, ValueError):
return _positive_int(
request.query_params[self.page_size_query_param],
strict=True,
cutoff=self.max_page_size
)
except (KeyError, ValueError):
pass

return self.page_size

def get_next_link(self):
Expand Down Expand Up @@ -430,15 +429,12 @@ def get_paginated_response_schema(self, schema):

def get_limit(self, request):
if self.limit_query_param:
try:
with contextlib.suppress(KeyError, ValueError):
return _positive_int(
request.query_params[self.limit_query_param],
strict=True,
cutoff=self.max_limit
)
except (KeyError, ValueError):
pass

return self.default_limit

def get_offset(self, request):
Expand Down Expand Up @@ -680,15 +676,12 @@ def paginate_queryset(self, queryset, request, view=None):

def get_page_size(self, request):
if self.page_size_query_param:
try:
with contextlib.suppress(KeyError, ValueError):
return _positive_int(
request.query_params[self.page_size_query_param],
strict=True,
cutoff=self.max_page_size
)
except (KeyError, ValueError):
pass

return self.page_size

def get_next_link(self):
Expand Down
13 changes: 5 additions & 8 deletions rest_framework/parsers.py
Expand Up @@ -4,7 +4,9 @@
They give us a generic way of being able to handle various media types
on the request, such as form content or json encoded data.
"""

import codecs
import contextlib

from django.conf import settings
from django.core.files.uploadhandler import StopFutureHandlers
Expand Down Expand Up @@ -193,17 +195,12 @@ def get_filename(self, stream, media_type, parser_context):
Detects the uploaded file name. First searches a 'filename' url kwarg.
Then tries to parse Content-Disposition header.
"""
try:
with contextlib.suppress(KeyError):
return parser_context['kwargs']['filename']
except KeyError:
pass

try:
with contextlib.suppress(AttributeError, KeyError, ValueError):
meta = parser_context['request'].META
disposition, params = parse_header_parameters(meta['HTTP_CONTENT_DISPOSITION'])
if 'filename*' in params:
return params['filename*']
else:
return params['filename']
except (AttributeError, KeyError, ValueError):
pass
return params['filename']
6 changes: 2 additions & 4 deletions rest_framework/relations.py
@@ -1,3 +1,4 @@
import contextlib
import sys
from collections import OrderedDict
from urllib import parse
Expand Down Expand Up @@ -170,7 +171,7 @@ def use_pk_only_optimization(self):
def get_attribute(self, instance):
if self.use_pk_only_optimization() and self.source_attrs:
# Optimized case, return a mock object only containing the pk attribute.
try:
with contextlib.suppress(AttributeError):
attribute_instance = get_attribute(instance, self.source_attrs[:-1])
value = attribute_instance.serializable_value(self.source_attrs[-1])
if is_simple_callable(value):
Expand All @@ -183,9 +184,6 @@ def get_attribute(self, instance):
value = getattr(value, 'pk', value)

return PKOnlyObject(pk=value)
except AttributeError:
pass

# Standard case, return the object instance.
return super().get_attribute(instance)

Expand Down
12 changes: 4 additions & 8 deletions rest_framework/renderers.py
Expand Up @@ -6,7 +6,9 @@

REST framework also provides an HTML renderer that renders the browsable API.
"""

import base64
import contextlib
from collections import OrderedDict
from urllib import parse

Expand Down Expand Up @@ -72,11 +74,8 @@ def get_indent(self, accepted_media_type, renderer_context):
# then pretty print the result.
# Note that we coerce `indent=0` into `indent=None`.
base_media_type, params = parse_header_parameters(accepted_media_type)
try:
with contextlib.suppress(KeyError, ValueError, TypeError):
return zero_as_none(max(min(int(params['indent']), 8), 0))
except (KeyError, ValueError, TypeError):
pass

# If 'indent' is provided in the context, then pretty print the result.
# E.g. If we're being called by the BrowsableAPIRenderer.
return renderer_context.get('indent', None)
Expand Down Expand Up @@ -488,11 +487,8 @@ def get_rendered_html_form(self, data, view, method, request):
return

if existing_serializer is not None:
try:
with contextlib.suppress(TypeError):
return self.render_form_for_serializer(existing_serializer)
except TypeError:
pass

if has_serializer:
if method in ('PUT', 'PATCH'):
serializer = view.get_serializer(instance=instance, **kwargs)
Expand Down
6 changes: 3 additions & 3 deletions rest_framework/serializers.py
Expand Up @@ -10,6 +10,8 @@
2. The process of marshalling between python primitives and request and
response content is handled by parsers and renderers.
"""

import contextlib
import copy
import inspect
import traceback
Expand Down Expand Up @@ -1496,12 +1498,10 @@ def _get_model_fields(self, field_names, declared_fields, extra_kwargs):
# they can't be nested attribute lookups.
continue

try:
with contextlib.suppress(FieldDoesNotExist):
field = model._meta.get_field(source)
if isinstance(field, DjangoModelField):
model_fields[source] = field
except FieldDoesNotExist:
pass

return model_fields

Expand Down
6 changes: 3 additions & 3 deletions rest_framework/utils/encoders.py
@@ -1,6 +1,8 @@
"""
Helper classes for parsers.
"""

import contextlib
import datetime
import decimal
import json # noqa
Expand Down Expand Up @@ -58,10 +60,8 @@ def default(self, obj):
)
elif hasattr(obj, '__getitem__'):
cls = (list if isinstance(obj, (list, tuple)) else dict)
try:
with contextlib.suppress(Exception):
return cls(obj)
except Exception:
pass
elif hasattr(obj, '__iter__'):
return tuple(item for item in obj)
return super().default(obj)
5 changes: 2 additions & 3 deletions rest_framework/utils/serializer_helpers.py
@@ -1,3 +1,4 @@
import contextlib
import sys
from collections import OrderedDict
from collections.abc import Mapping, MutableMapping
Expand Down Expand Up @@ -103,15 +104,13 @@ def as_form_field(self):
# When HTML form input is used and the input is not valid
# value will be a JSONString, rather than a JSON primitive.
if not getattr(value, 'is_json_string', False):
try:
with contextlib.suppress(TypeError, ValueError):
value = json.dumps(
self.value,
sort_keys=True,
indent=4,
separators=(',', ': '),
)
except (TypeError, ValueError):
pass
return self.__class__(self._field, value, self.errors, self._prefix)


Expand Down