stop ignoring ruff rule B904 (#22641)
This commit is contained in:
Родитель
dc4170d11f
Коммит
dd200ad058
|
@ -35,9 +35,7 @@ exclude = [
|
|||
line-length = 88
|
||||
|
||||
[tool.ruff.lint]
|
||||
ignore = [
|
||||
"B904", # Within an `except` clause, raise exceptions with `raise ... from err|None`
|
||||
]
|
||||
ignore = []
|
||||
select = [
|
||||
"B", # flake8-bugbear
|
||||
"E", # pycodestyle errors
|
||||
|
|
|
@ -239,14 +239,14 @@ class AddonAbuseReportSerializer(BaseAbuseReportSerializer):
|
|||
|
||||
try:
|
||||
is_value_unknown = value not in reversed_choices
|
||||
except TypeError:
|
||||
except TypeError as exc:
|
||||
# Log the invalid type and raise a validation error.
|
||||
log.warning(
|
||||
'Invalid type for abuse report %s value submitted: %s',
|
||||
field_name,
|
||||
str(data[field_name])[:255],
|
||||
)
|
||||
raise serializers.ValidationError({field_name: _('Invalid value')})
|
||||
raise serializers.ValidationError({field_name: _('Invalid value')}) from exc
|
||||
|
||||
if is_value_unknown:
|
||||
log.warning(
|
||||
|
|
|
@ -225,9 +225,9 @@ def cinder_webhook(request):
|
|||
|
||||
try:
|
||||
cinder_job = CinderJob.objects.get(job_id=job_id)
|
||||
except CinderJob.DoesNotExist:
|
||||
except CinderJob.DoesNotExist as exc:
|
||||
log.debug('CinderJob instance not found for job id %s', job_id)
|
||||
raise ValidationError('No matching job id found')
|
||||
raise ValidationError('No matching job id found') from exc
|
||||
|
||||
if cinder_job.resolvable_in_reviewer_tools:
|
||||
log.debug('Cinder webhook decision for reviewer resolvable job skipped.')
|
||||
|
|
|
@ -141,12 +141,12 @@ def add_email_to_activity_log(parser):
|
|||
uuid = parser.get_uuid()
|
||||
try:
|
||||
token = ActivityLogToken.objects.get(uuid=uuid)
|
||||
except (ActivityLogToken.DoesNotExist, ValidationError):
|
||||
except (ActivityLogToken.DoesNotExist, ValidationError) as exc:
|
||||
log.warning('An email was skipped with non-existing uuid %s.', uuid)
|
||||
raise ActivityEmailUUIDError(
|
||||
'UUID found in email address TO: header but is not a valid token '
|
||||
'(%s).' % uuid
|
||||
)
|
||||
) from exc
|
||||
|
||||
version = token.version
|
||||
user = token.user
|
||||
|
|
|
@ -465,8 +465,8 @@ class AddonAdmin(AMOModelAdmin):
|
|||
try:
|
||||
if lookup_field in ('slug', 'guid'):
|
||||
addon = self.get_queryset(request).get(**{lookup_field: object_id})
|
||||
except Addon.DoesNotExist:
|
||||
raise http.Http404
|
||||
except Addon.DoesNotExist as exc:
|
||||
raise http.Http404 from exc
|
||||
# Don't get in an infinite loop if addon.slug.isdigit().
|
||||
if addon and addon.id and addon.id != object_id:
|
||||
url = request.path.replace(object_id, str(addon.id), 1)
|
||||
|
@ -596,8 +596,8 @@ class ReplacementAddonForm(AMOModelForm):
|
|||
except forms.ValidationError as validation_error:
|
||||
# Re-raise the ValidationError about full paths for SITE_URL.
|
||||
raise validation_error
|
||||
except Exception:
|
||||
raise forms.ValidationError('Path [%s] is not valid' % path)
|
||||
except Exception as exc:
|
||||
raise forms.ValidationError('Path [%s] is not valid' % path) from exc
|
||||
return path
|
||||
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ def addon_view(f, qs=Addon.objects.all, include_deleted_when_checking_versions=F
|
|||
addon = qs().get(id=addon_id)
|
||||
elif lookup_field == 'guid':
|
||||
addon = qs().get(guid=addon_id)
|
||||
except Addon.DoesNotExist:
|
||||
raise http.Http404
|
||||
except Addon.DoesNotExist as exc:
|
||||
raise http.Http404 from exc
|
||||
# Don't get in an infinite loop if addon.slug.isdigit().
|
||||
if addon.slug and addon.slug != addon_id:
|
||||
url = request.path.replace(addon_id, addon.slug, 1)
|
||||
|
|
|
@ -230,8 +230,10 @@ class SourceFileField(serializers.FileField):
|
|||
mode = 'r:bz2' if ext == '.bz2' else 'r:gz'
|
||||
with SafeTar.open(mode=mode, fileobj=data):
|
||||
pass
|
||||
except (zipfile.BadZipFile, tarfile.ReadError, OSError, EOFError):
|
||||
raise exceptions.ValidationError(gettext('Invalid or broken archive.'))
|
||||
except (zipfile.BadZipFile, tarfile.ReadError, OSError, EOFError) as exc:
|
||||
raise exceptions.ValidationError(
|
||||
gettext('Invalid or broken archive.')
|
||||
) from exc
|
||||
|
||||
return data
|
||||
|
||||
|
@ -262,8 +264,10 @@ class VersionCompatibilityField(serializers.Field):
|
|||
for app_name, min_max in data.items():
|
||||
try:
|
||||
app = amo.APPS[app_name]
|
||||
except KeyError:
|
||||
raise exceptions.ValidationError(gettext('Invalid app specified'))
|
||||
except KeyError as exc:
|
||||
raise exceptions.ValidationError(
|
||||
gettext('Invalid app specified')
|
||||
) from exc
|
||||
|
||||
existing_app = existing.get(app)
|
||||
# we need to copy() to avoid changing the instance before save
|
||||
|
@ -278,10 +282,10 @@ class VersionCompatibilityField(serializers.Field):
|
|||
elif version:
|
||||
apps_versions.max = apps_versions.get_default_maximum_appversion()
|
||||
|
||||
except AppVersion.DoesNotExist:
|
||||
except AppVersion.DoesNotExist as exc:
|
||||
raise exceptions.ValidationError(
|
||||
gettext('Unknown max app version specified')
|
||||
)
|
||||
) from exc
|
||||
|
||||
try:
|
||||
app_version_qs = app_version_qs.filter(~Q(version__contains='*'))
|
||||
|
@ -290,10 +294,10 @@ class VersionCompatibilityField(serializers.Field):
|
|||
apps_versions.min_or_max_explicitly_set = True
|
||||
elif version:
|
||||
apps_versions.min = apps_versions.get_default_minimum_appversion()
|
||||
except AppVersion.DoesNotExist:
|
||||
except AppVersion.DoesNotExist as exc:
|
||||
raise exceptions.ValidationError(
|
||||
gettext('Unknown min app version specified')
|
||||
)
|
||||
) from exc
|
||||
|
||||
if existing_app and existing_app.locked_from_manifest:
|
||||
if (
|
||||
|
|
|
@ -500,7 +500,7 @@ class DeveloperVersionSerializer(VersionSerializer):
|
|||
try:
|
||||
self.parsed_data = parse_addon(value, addon=self.addon, user=request.user)
|
||||
except DuplicateAddonID as exc:
|
||||
raise Conflict({self.field_name: exc.messages})
|
||||
raise Conflict({self.field_name: exc.messages}) from exc
|
||||
return value
|
||||
|
||||
def validate_is_disabled(self, disable):
|
||||
|
@ -562,13 +562,13 @@ class DeveloperVersionSerializer(VersionSerializer):
|
|||
try:
|
||||
ReviewedSourceFileValidator()(data['source'], self.fields['source'])
|
||||
except exceptions.ValidationError as exc:
|
||||
raise exceptions.ValidationError({'source': exc.detail})
|
||||
raise exceptions.ValidationError({'source': exc.detail}) from exc
|
||||
|
||||
if 'compatible_apps' in data:
|
||||
try:
|
||||
self._post_validate_compatibility(data['compatible_apps'])
|
||||
except exceptions.ValidationError as exc:
|
||||
raise exceptions.ValidationError({'compatibility': exc.detail})
|
||||
raise exceptions.ValidationError({'compatibility': exc.detail}) from exc
|
||||
|
||||
return data
|
||||
|
||||
|
@ -793,7 +793,7 @@ class CurrentVersionSerializer(SimpleVersionSerializer):
|
|||
application = value[0]
|
||||
appversions = dict(zip(('min', 'max'), value[1:], strict=True))
|
||||
except ValueError as exc:
|
||||
raise exceptions.ParseError(str(exc))
|
||||
raise exceptions.ParseError(str(exc)) from exc
|
||||
|
||||
version_qs = Version.objects.latest_public_compatible_with(
|
||||
application, appversions
|
||||
|
@ -928,8 +928,8 @@ class AddonPendingAuthorSerializer(AddonAuthorSerializer):
|
|||
def validate_user_id(self, value):
|
||||
try:
|
||||
user = UserProfile.objects.get(id=value)
|
||||
except UserProfile.DoesNotExist:
|
||||
raise exceptions.ValidationError(gettext('Account not found.'))
|
||||
except UserProfile.DoesNotExist as exc:
|
||||
raise exceptions.ValidationError(gettext('Account not found.')) from exc
|
||||
|
||||
if not EmailUserRestriction.allow_email(
|
||||
user.email, restriction_type=RESTRICTION_TYPES.ADDON_SUBMISSION
|
||||
|
@ -950,13 +950,13 @@ class AddonPendingAuthorSerializer(AddonAuthorSerializer):
|
|||
raise DjangoValidationError('') # raise so we can catch below.
|
||||
for validator in user._meta.get_field('display_name').validators:
|
||||
validator(user.display_name)
|
||||
except DjangoValidationError:
|
||||
except DjangoValidationError as exc:
|
||||
raise exceptions.ValidationError(
|
||||
gettext(
|
||||
'The account needs a display name before it can be added as an '
|
||||
'author.'
|
||||
)
|
||||
)
|
||||
) from exc
|
||||
|
||||
return value
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class VerifyMozillaTrademark:
|
|||
try:
|
||||
verify_mozilla_trademark(value, user)
|
||||
except forms.ValidationError as exc:
|
||||
raise exceptions.ValidationError(exc.message)
|
||||
raise exceptions.ValidationError(exc.message) from exc
|
||||
|
||||
|
||||
class VersionLicenseValidator:
|
||||
|
@ -159,7 +159,7 @@ class VersionAddonMetadataValidator(AddonMetadataValidator):
|
|||
'version: {missing_addon_metadata}.'
|
||||
).format(missing_addon_metadata=list(exc.detail)),
|
||||
code='required',
|
||||
)
|
||||
) from exc
|
||||
|
||||
|
||||
class AddonDefaultLocaleValidator:
|
||||
|
|
|
@ -865,8 +865,8 @@ class AddonPendingAuthorViewSet(CreateModelMixin, AddonAuthorViewSet):
|
|||
def get_object_for_request(self, request):
|
||||
try:
|
||||
return self.get_queryset().get(user=request.user)
|
||||
except AddonUserPendingConfirmation.DoesNotExist:
|
||||
raise exceptions.PermissionDenied()
|
||||
except AddonUserPendingConfirmation.DoesNotExist as exc:
|
||||
raise exceptions.PermissionDenied() from exc
|
||||
|
||||
def perform_create(self, serializer):
|
||||
instance = serializer.save()
|
||||
|
@ -995,8 +995,8 @@ class AddonFeaturedView(AddonSearchView):
|
|||
def get(self, request, *args, **kwargs):
|
||||
try:
|
||||
page_size = int(self.request.GET.get('page_size', api_settings.PAGE_SIZE))
|
||||
except ValueError:
|
||||
raise exceptions.ParseError('Invalid page_size parameter')
|
||||
except ValueError as exc:
|
||||
raise exceptions.ParseError('Invalid page_size parameter') from exc
|
||||
|
||||
# Simulate pagination-like results, without actual pagination.
|
||||
queryset = self.filter_queryset(self.get_queryset()[:page_size])
|
||||
|
@ -1061,16 +1061,16 @@ class LanguageToolsView(ListAPIView):
|
|||
# app parameter is mandatory with appversion
|
||||
try:
|
||||
application = AddonAppQueryParam(self.request.GET).get_value()
|
||||
except ValueError:
|
||||
except ValueError as exc:
|
||||
raise exceptions.ParseError(
|
||||
'Invalid or missing app parameter while appversion parameter is '
|
||||
'set.'
|
||||
)
|
||||
) from exc
|
||||
try:
|
||||
value = AddonAppVersionQueryParam(self.request.GET).get_values()
|
||||
appversions = {'min': value[1], 'max': value[2]}
|
||||
except ValueError:
|
||||
raise exceptions.ParseError('Invalid appversion parameter.')
|
||||
except ValueError as exc:
|
||||
raise exceptions.ParseError('Invalid appversion parameter.') from exc
|
||||
else:
|
||||
appversions = None
|
||||
application = None
|
||||
|
@ -1082,11 +1082,11 @@ class LanguageToolsView(ListAPIView):
|
|||
if AddonTypeQueryParam.query_param in self.request.GET or appversions:
|
||||
try:
|
||||
addon_types = tuple(AddonTypeQueryParam(self.request.GET).get_values())
|
||||
except ValueError:
|
||||
except ValueError as exc:
|
||||
raise exceptions.ParseError(
|
||||
'Invalid or missing type parameter while appversion '
|
||||
'parameter is set.'
|
||||
)
|
||||
) from exc
|
||||
else:
|
||||
addon_types = (amo.ADDON_LPAPP, amo.ADDON_DICT)
|
||||
|
||||
|
|
|
@ -118,8 +118,8 @@ class AMOModelAdminChangeList(ChangeList):
|
|||
else:
|
||||
try:
|
||||
result_list = paginator.page(self.page_num).object_list
|
||||
except InvalidPage:
|
||||
raise IncorrectLookupParameters
|
||||
except InvalidPage as exc:
|
||||
raise IncorrectLookupParameters from exc
|
||||
|
||||
self.result_count = result_count
|
||||
self.show_full_result_count = self.model_admin.show_full_result_count
|
||||
|
|
|
@ -56,7 +56,7 @@ class IPAddressBinaryField(VarBinaryField):
|
|||
# bytestring - i.e. what's stored in the db; or an IPv4Address|IPv6Address.
|
||||
return ipaddress.ip_address(value) if value is not None else None
|
||||
except Exception as exc:
|
||||
raise exceptions.ValidationError(exc)
|
||||
raise exceptions.ValidationError(exc) from exc
|
||||
|
||||
def get_prep_value(self, value):
|
||||
return self.to_python(value).packed if value is not None else None
|
||||
|
@ -85,10 +85,10 @@ class ReCaptchaField(UpstreamReCaptchaField):
|
|||
def validate_cidr(value):
|
||||
try:
|
||||
ipaddress.ip_network(value)
|
||||
except ValueError:
|
||||
except ValueError as exc:
|
||||
raise exceptions.ValidationError(
|
||||
_('Enter a valid IP4 or IP6 network.'), code='invalid'
|
||||
)
|
||||
) from exc
|
||||
|
||||
|
||||
class CIDRField(models.Field):
|
||||
|
@ -122,7 +122,7 @@ class CIDRField(models.Field):
|
|||
try:
|
||||
return ipaddress.ip_network(value)
|
||||
except Exception as exc:
|
||||
raise exceptions.ValidationError(exc)
|
||||
raise exceptions.ValidationError(exc) from exc
|
||||
|
||||
def get_prep_lookup(self, lookup_type, value):
|
||||
if lookup_type == 'exact':
|
||||
|
|
|
@ -20,8 +20,8 @@ class Command(BaseCommand):
|
|||
def handle(self, *args, **options):
|
||||
try:
|
||||
do_addnewversion(options['application_name'], options['version'])
|
||||
except IndexError:
|
||||
raise CommandError(self.help)
|
||||
except IndexError as exc:
|
||||
raise CommandError(self.help) from exc
|
||||
|
||||
msg = 'Adding version {!r} to application {!r}\n'.format(
|
||||
options['version'],
|
||||
|
@ -36,5 +36,5 @@ def do_addnewversion(application, version):
|
|||
raise CommandError('Application %r does not exist.' % application)
|
||||
try:
|
||||
AppVersion.objects.create(application=amo.APPS[application].id, version=version)
|
||||
except IntegrityError as e:
|
||||
raise CommandError(f'Version {version!r} already exists: {e!r}')
|
||||
except IntegrityError as exc:
|
||||
raise CommandError(f'Version {version!r} already exists: {exc!r}') from exc
|
||||
|
|
|
@ -330,10 +330,10 @@ class SetRemoteAddrFromForwardedFor(MiddlewareMixin):
|
|||
if not value:
|
||||
raise IndexError
|
||||
request.META['REMOTE_ADDR'] = value
|
||||
except IndexError:
|
||||
except IndexError as exc:
|
||||
# Shouldn't happen, must be a misconfiguration, raise an error
|
||||
# rather than potentially use/record incorrect IPs.
|
||||
raise ImproperlyConfigured('Invalid HTTP_X_FORWARDED_FOR')
|
||||
raise ImproperlyConfigured('Invalid HTTP_X_FORWARDED_FOR') from exc
|
||||
|
||||
|
||||
class RequestIdMiddleware(MiddlewareMixin):
|
||||
|
|
|
@ -44,8 +44,8 @@ class ESPaginator(Paginator):
|
|||
"""
|
||||
try:
|
||||
number = int(number)
|
||||
except (TypeError, ValueError):
|
||||
raise PageNotAnInteger('That page number is not an integer')
|
||||
except (TypeError, ValueError) as exc:
|
||||
raise PageNotAnInteger('That page number is not an integer') from exc
|
||||
if number < 1:
|
||||
raise EmptyPage('That page number is less than 1')
|
||||
return number
|
||||
|
|
|
@ -479,8 +479,8 @@ def get_sitemap_path(section, app, page=1):
|
|||
raise InvalidSection
|
||||
try:
|
||||
page = int(page)
|
||||
except ValueError:
|
||||
raise PageNotAnInteger
|
||||
except ValueError as exc:
|
||||
raise PageNotAnInteger from exc
|
||||
if app is None:
|
||||
# If we don't have a section or app, we don't need a complex directory
|
||||
# structure and we can call the first page 'sitemap' for convenience
|
||||
|
|
|
@ -1209,13 +1209,13 @@ def safe_exec(string, value=None, globals_=None, locals_=None):
|
|||
locals_ = locals_ or {}
|
||||
try:
|
||||
exec(force_str(string), globals_ or globals(), locals_)
|
||||
except Exception as e:
|
||||
except Exception as exc:
|
||||
if value:
|
||||
raise AssertionError(
|
||||
f'Could not exec {string.strip()!r} (from value {value!r}): {e}'
|
||||
)
|
||||
f'Could not exec {string.strip()!r} (from value {value!r}): {exc}'
|
||||
) from exc
|
||||
else:
|
||||
raise AssertionError(f'Could not exec {string.strip()!r}: {e}')
|
||||
raise AssertionError(f'Could not exec {string.strip()!r}: {exc}') from exc
|
||||
return locals_
|
||||
|
||||
|
||||
|
|
|
@ -245,11 +245,11 @@ def sitemap(request):
|
|||
)
|
||||
patch_cache_control(response, max_age=60 * 60)
|
||||
|
||||
except EmptyPage:
|
||||
raise Http404('Page %s empty' % page)
|
||||
except PageNotAnInteger:
|
||||
raise Http404('No page "%s"' % page)
|
||||
except InvalidSection:
|
||||
raise Http404('No sitemap available for section: %r' % section)
|
||||
except EmptyPage as exc:
|
||||
raise Http404('Page %s empty' % page) from exc
|
||||
except PageNotAnInteger as exc:
|
||||
raise Http404('No page "%s"' % page) from exc
|
||||
except InvalidSection as exc:
|
||||
raise Http404('No sitemap available for section: %r' % section) from exc
|
||||
|
||||
return response
|
||||
|
|
|
@ -113,7 +113,7 @@ class SessionIDAuthentication(BaseAuthentication):
|
|||
|
||||
try:
|
||||
check_and_update_fxa_access_token(request)
|
||||
except IdentificationError:
|
||||
except IdentificationError as exc:
|
||||
log.info(
|
||||
'User access token refresh failed; user needs to login to FxA again'
|
||||
)
|
||||
|
@ -123,7 +123,7 @@ class SessionIDAuthentication(BaseAuthentication):
|
|||
),
|
||||
'code': 'ERROR_AUTHENTICATION_EXPIRED',
|
||||
}
|
||||
raise exceptions.AuthenticationFailed(msg)
|
||||
raise exceptions.AuthenticationFailed(msg) from exc
|
||||
|
||||
# Set user in thread like UserAndAddrMiddleware does.
|
||||
core.set_user(user)
|
||||
|
@ -183,18 +183,18 @@ class JWTKeyAuthentication(BaseAuthentication):
|
|||
)
|
||||
# Re-raise to deal with them properly.
|
||||
raise exc
|
||||
except TypeError:
|
||||
except TypeError as exc:
|
||||
msg = gettext('Wrong type for one or more keys in payload')
|
||||
raise exceptions.AuthenticationFailed(msg)
|
||||
except jwt.ExpiredSignatureError:
|
||||
raise exceptions.AuthenticationFailed(msg) from exc
|
||||
except jwt.ExpiredSignatureError as exc:
|
||||
msg = gettext('Signature has expired.')
|
||||
raise exceptions.AuthenticationFailed(msg)
|
||||
except jwt.DecodeError:
|
||||
raise exceptions.AuthenticationFailed(msg) from exc
|
||||
except jwt.DecodeError as exc:
|
||||
msg = gettext('Error decoding signature.')
|
||||
raise exceptions.AuthenticationFailed(msg)
|
||||
except jwt.InvalidTokenError:
|
||||
raise exceptions.AuthenticationFailed(msg) from exc
|
||||
except jwt.InvalidTokenError as exc:
|
||||
msg = gettext('Invalid JWT Token.')
|
||||
raise exceptions.AuthenticationFailed(msg)
|
||||
raise exceptions.AuthenticationFailed(msg) from exc
|
||||
# Note: AuthenticationFailed can also be raised directly from our
|
||||
# jwt_decode_handler.
|
||||
|
||||
|
@ -220,9 +220,9 @@ class JWTKeyAuthentication(BaseAuthentication):
|
|||
raise exceptions.AuthenticationFailed(msg)
|
||||
try:
|
||||
api_key = APIKey.get_jwt_key(key=payload['iss'])
|
||||
except APIKey.DoesNotExist:
|
||||
except APIKey.DoesNotExist as exc:
|
||||
msg = 'Invalid API Key.'
|
||||
raise exceptions.AuthenticationFailed(msg)
|
||||
raise exceptions.AuthenticationFailed(msg) from exc
|
||||
|
||||
if api_key.user.deleted:
|
||||
msg = 'User account is disabled.'
|
||||
|
@ -269,8 +269,12 @@ class UnsubscribeTokenAuthentication(BaseAuthentication):
|
|||
request.data.get('token'), request.data.get('hash')
|
||||
)
|
||||
user = UserProfile.objects.get(email=email)
|
||||
except ValueError:
|
||||
raise exceptions.AuthenticationFailed(gettext('Invalid token or hash.'))
|
||||
except UserProfile.DoesNotExist:
|
||||
raise exceptions.AuthenticationFailed(gettext('Email address not found.'))
|
||||
except ValueError as exc:
|
||||
raise exceptions.AuthenticationFailed(
|
||||
gettext('Invalid token or hash.')
|
||||
) from exc
|
||||
except UserProfile.DoesNotExist as exc:
|
||||
raise exceptions.AuthenticationFailed(
|
||||
gettext('Email address not found.')
|
||||
) from exc
|
||||
return (user, None)
|
||||
|
|
|
@ -374,11 +374,11 @@ class SlugOrPrimaryKeyRelatedField(serializers.RelatedField):
|
|||
except Exception:
|
||||
try:
|
||||
return self.queryset.get(**{self.slug_field: data})
|
||||
except ObjectDoesNotExist:
|
||||
except ObjectDoesNotExist as exc:
|
||||
msg = _('Invalid pk or slug "%s" - object does not exist.') % smart_str(
|
||||
data
|
||||
)
|
||||
raise exceptions.ValidationError(msg)
|
||||
raise exceptions.ValidationError(msg) from exc
|
||||
|
||||
|
||||
class OutgoingSerializerMixin:
|
||||
|
|
|
@ -55,9 +55,11 @@ def jwt_decode_handler(token, get_api_key=APIKey.get_jwt_key):
|
|||
|
||||
try:
|
||||
api_key = get_api_key(key=token_data['iss'])
|
||||
except ObjectDoesNotExist:
|
||||
except ObjectDoesNotExist as exc:
|
||||
log.info('No API key for JWT issuer: {}'.format(token_data['iss']))
|
||||
raise exceptions.AuthenticationFailed(detail='Unknown JWT iss (issuer).')
|
||||
raise exceptions.AuthenticationFailed(
|
||||
detail='Unknown JWT iss (issuer).'
|
||||
) from exc
|
||||
|
||||
# TODO: add nonce checking to prevent replays. bug 1213354.
|
||||
|
||||
|
@ -94,7 +96,7 @@ def jwt_decode_handler(token, get_api_key=APIKey.get_jwt_key):
|
|||
'Missing required claim during JWT authentication: '
|
||||
'{e.__class__.__name__}: {e}'.format(e=exc)
|
||||
)
|
||||
raise exceptions.AuthenticationFailed(detail=f'Invalid JWT: {exc}.')
|
||||
raise exceptions.AuthenticationFailed(detail=f'Invalid JWT: {exc}.') from exc
|
||||
except (jwt.exceptions.ImmatureSignatureError, jwt.InvalidIssuedAtError) as exc:
|
||||
log.info(
|
||||
'Invalid iat during JWT authentication: '
|
||||
|
@ -103,7 +105,7 @@ def jwt_decode_handler(token, get_api_key=APIKey.get_jwt_key):
|
|||
raise exceptions.AuthenticationFailed(
|
||||
detail='JWT iat (issued at time) is invalid. Make sure your '
|
||||
'system clock is synchronized with something like TLSdate.'
|
||||
)
|
||||
) from exc
|
||||
except Exception as exc:
|
||||
log.warning(
|
||||
'Unhandled exception during JWT authentication: '
|
||||
|
|
|
@ -300,8 +300,8 @@ class ByHttpMethod(BasePermission):
|
|||
def has_permission(self, request, view):
|
||||
try:
|
||||
perm = self.method_permissions[request.method.lower()]
|
||||
except KeyError:
|
||||
raise MethodNotAllowed(request.method)
|
||||
except KeyError as exc:
|
||||
raise MethodNotAllowed(request.method) from exc
|
||||
result = perm.has_permission(request, view)
|
||||
if not result and hasattr(perm, 'message'):
|
||||
self.message = perm.message
|
||||
|
@ -310,8 +310,8 @@ class ByHttpMethod(BasePermission):
|
|||
def has_object_permission(self, request, view, obj):
|
||||
try:
|
||||
perm = self.method_permissions[request.method.lower()]
|
||||
except KeyError:
|
||||
raise MethodNotAllowed(request.method)
|
||||
except KeyError as exc:
|
||||
raise MethodNotAllowed(request.method) from exc
|
||||
result = perm.has_object_permission(request, view, obj)
|
||||
if not result and hasattr(perm, 'message'):
|
||||
self.message = perm.message
|
||||
|
|
|
@ -13,8 +13,8 @@ class OneOrMorePrintableCharacterAPIValidator(OneOrMorePrintableCharacterValidat
|
|||
def __call__(self, value):
|
||||
try:
|
||||
return super().__call__(value)
|
||||
except DjangoValidationError:
|
||||
raise exceptions.ValidationError(self.message)
|
||||
except DjangoValidationError as exc:
|
||||
raise exceptions.ValidationError(self.message) from exc
|
||||
|
||||
|
||||
class NoURLsValidator:
|
||||
|
@ -22,4 +22,4 @@ class NoURLsValidator:
|
|||
try:
|
||||
verify_no_urls(value)
|
||||
except DjangoValidationError as exc:
|
||||
raise exceptions.ValidationError(exc.message)
|
||||
raise exceptions.ValidationError(exc.message) from exc
|
||||
|
|
|
@ -22,8 +22,8 @@ class ActivityFeedRSS(Feed):
|
|||
try:
|
||||
rsskey = request.GET.get('privaterss')
|
||||
rsskey = uuid.UUID(rsskey)
|
||||
except ValueError:
|
||||
raise http.Http404
|
||||
except ValueError as exc:
|
||||
raise http.Http404 from exc
|
||||
|
||||
key = get_object_or_404(RssKey, key=rsskey.hex)
|
||||
return key
|
||||
|
|
|
@ -413,13 +413,13 @@ class AuthorWaitingConfirmationForm(AuthorForm):
|
|||
raise forms.ValidationError('') # Caught below.
|
||||
for validator in name_validators:
|
||||
validator(user.display_name)
|
||||
except forms.ValidationError:
|
||||
except forms.ValidationError as exc:
|
||||
raise forms.ValidationError(
|
||||
gettext(
|
||||
'The account needs a display name before it can be added '
|
||||
'as an author.'
|
||||
)
|
||||
)
|
||||
) from exc
|
||||
return user
|
||||
|
||||
|
||||
|
@ -738,8 +738,10 @@ class WithSourceMixin:
|
|||
raise forms.ValidationError(
|
||||
self.get_invalid_source_file_type_message()
|
||||
)
|
||||
except (zipfile.BadZipFile, tarfile.ReadError, OSError, EOFError):
|
||||
raise forms.ValidationError(gettext('Invalid or broken archive.'))
|
||||
except (zipfile.BadZipFile, tarfile.ReadError, OSError, EOFError) as exc:
|
||||
raise forms.ValidationError(
|
||||
gettext('Invalid or broken archive.')
|
||||
) from exc
|
||||
return source
|
||||
|
||||
|
||||
|
|
|
@ -101,8 +101,8 @@ MDN_BASE = 'https://developer.mozilla.org/en-US/Add-ons'
|
|||
def get_fileupload_by_uuid_or_40x(value, *, user):
|
||||
try:
|
||||
UUID(value)
|
||||
except ValueError:
|
||||
raise http.Http404()
|
||||
except ValueError as exc:
|
||||
raise http.Http404() from exc
|
||||
upload = get_object_or_404(FileUpload, uuid=value)
|
||||
if upload.user != user:
|
||||
raise PermissionDenied
|
||||
|
@ -731,8 +731,8 @@ def json_file_validation(request, addon_id, addon, file_id):
|
|||
file = get_object_or_404(File, version__addon=addon, id=file_id)
|
||||
try:
|
||||
result = file.validation
|
||||
except File.validation.RelatedObjectDoesNotExist:
|
||||
raise http.Http404
|
||||
except File.validation.RelatedObjectDoesNotExist as exc:
|
||||
raise http.Http404 from exc
|
||||
return JsonResponse(
|
||||
{
|
||||
'validation': result.processed_validation,
|
||||
|
|
|
@ -181,8 +181,10 @@ class ManifestJSONExtractor:
|
|||
self.data = json.loads(json_string)
|
||||
if not isinstance(self.data, dict):
|
||||
raise TypeError()
|
||||
except Exception:
|
||||
raise InvalidManifest(gettext('Could not parse the manifest file.'))
|
||||
except Exception as exc:
|
||||
raise InvalidManifest(
|
||||
gettext('Could not parse the manifest file.')
|
||||
) from exc
|
||||
|
||||
def get(self, key, default=None):
|
||||
return self.data.get(key, default)
|
||||
|
@ -343,17 +345,17 @@ class ManifestJSONExtractor:
|
|||
qs = AppVersion.objects.filter(application=app.id)
|
||||
try:
|
||||
min_appver = qs.get(version=strict_min_version)
|
||||
except AppVersion.DoesNotExist:
|
||||
except AppVersion.DoesNotExist as exc:
|
||||
msg = gettext(
|
||||
'Unknown "strict_min_version" {appver} for {app}'.format(
|
||||
app=app.pretty, appver=strict_min_version
|
||||
)
|
||||
)
|
||||
raise forms.ValidationError(msg)
|
||||
raise forms.ValidationError(msg) from exc
|
||||
|
||||
try:
|
||||
max_appver = qs.get(version=strict_max_version)
|
||||
except AppVersion.DoesNotExist:
|
||||
except AppVersion.DoesNotExist as exc:
|
||||
# If the specified strict_max_version can't be found, raise an
|
||||
# error: we used to use '*' instead but this caused more
|
||||
# problems, especially with langpacks that are really specific
|
||||
|
@ -363,7 +365,7 @@ class ManifestJSONExtractor:
|
|||
app=app.pretty, appver=strict_max_version
|
||||
)
|
||||
)
|
||||
raise forms.ValidationError(msg)
|
||||
raise forms.ValidationError(msg) from exc
|
||||
|
||||
if app == amo.ANDROID and self.gecko_android is not EMPTY_FALLBACK_DICT:
|
||||
originated_from = amo.APPVERSIONS_ORIGINATED_FROM_MANIFEST_GECKO_ANDROID
|
||||
|
@ -389,11 +391,13 @@ class ManifestJSONExtractor:
|
|||
dictionaries = self.get('dictionaries', EMPTY_FALLBACK_DICT)
|
||||
key = force_str(list(dictionaries.keys())[0])
|
||||
return key[:255]
|
||||
except (IndexError, UnicodeDecodeError):
|
||||
except (IndexError, UnicodeDecodeError) as exc:
|
||||
# This shouldn't happen: the linter should prevent it, but
|
||||
# just in case, handle the error (without bothering with
|
||||
# translations as users should never see this).
|
||||
raise forms.ValidationError('Invalid dictionaries object or langpack_id.')
|
||||
raise forms.ValidationError(
|
||||
'Invalid dictionaries object or langpack_id.'
|
||||
) from exc
|
||||
|
||||
def parse(self, minimal=False):
|
||||
data = {
|
||||
|
@ -542,7 +546,7 @@ def archive_member_validator(member, ignore_filename_errors=False):
|
|||
|
||||
try:
|
||||
force_str(filename)
|
||||
except UnicodeDecodeError:
|
||||
except UnicodeDecodeError as exc:
|
||||
# We can't log the filename unfortunately since it's encoding
|
||||
# is obviously broken :-/
|
||||
log.warning('Extraction error, invalid file name encoding')
|
||||
|
@ -550,7 +554,7 @@ def archive_member_validator(member, ignore_filename_errors=False):
|
|||
'Invalid file name in archive. Please make sure '
|
||||
'all filenames are utf-8 or latin1 encoded.'
|
||||
)
|
||||
raise InvalidArchiveFile(msg)
|
||||
raise InvalidArchiveFile(msg) from exc
|
||||
|
||||
if not ignore_filename_errors:
|
||||
if (
|
||||
|
@ -733,17 +737,22 @@ def extract_extension_to_dest(source, dest=None, force_fsync=False):
|
|||
archive.extractall(target)
|
||||
else:
|
||||
raise FileNotFoundError # Unsupported file, shouldn't be reached
|
||||
except (zipfile.BadZipFile, tarfile.ReadError, OSError, forms.ValidationError) as e:
|
||||
except (
|
||||
zipfile.BadZipFile,
|
||||
tarfile.ReadError,
|
||||
OSError,
|
||||
forms.ValidationError,
|
||||
) as exc:
|
||||
if tempdir is not None:
|
||||
rm_local_tmp_dir(tempdir)
|
||||
if isinstance(e, (FileNotFoundError, forms.ValidationError)):
|
||||
if isinstance(exc, (FileNotFoundError, forms.ValidationError)):
|
||||
# We let FileNotFoundError (which are a subclass of IOError, or
|
||||
# rather OSError but that's an alias) and ValidationError be
|
||||
# raised, the caller will have to deal with it.
|
||||
raise
|
||||
# Any other exceptions we caught, we raise a generic ValidationError
|
||||
# instead.
|
||||
raise forms.ValidationError(gettext('Invalid or broken archive.'))
|
||||
raise forms.ValidationError(gettext('Invalid or broken archive.')) from exc
|
||||
return target
|
||||
|
||||
|
||||
|
@ -844,14 +853,16 @@ def parse_xpi(
|
|||
|
||||
except forms.ValidationError:
|
||||
raise
|
||||
except zipfile.BadZipFile:
|
||||
raise forms.ValidationError(gettext('Invalid or corrupted file.'))
|
||||
except Exception as exception:
|
||||
except zipfile.BadZipFile as exc:
|
||||
raise forms.ValidationError(gettext('Invalid or corrupted file.')) from exc
|
||||
except Exception as exc:
|
||||
# We don't really know what happened, so even though we return a
|
||||
# generic message about the manifest, don't raise InvalidManifest: it's
|
||||
# not just invalid, it's worse... We want the validation to stop there.
|
||||
log.exception(f'XPI parse error ({exception.__class__})')
|
||||
raise forms.ValidationError(gettext('Could not parse the manifest file.'))
|
||||
log.exception(f'XPI parse error ({exc.__class__})')
|
||||
raise forms.ValidationError(
|
||||
gettext('Could not parse the manifest file.')
|
||||
) from exc
|
||||
|
||||
if minimal:
|
||||
return xpi_info
|
||||
|
@ -1078,8 +1089,8 @@ def write_crx_as_xpi(chunks, target):
|
|||
start_position = 12 + header_length
|
||||
else:
|
||||
raise InvalidOrUnsupportedCrx('Unsupported CRX version')
|
||||
except struct.error:
|
||||
raise InvalidOrUnsupportedCrx('Invalid or corrupt CRX file')
|
||||
except struct.error as exc:
|
||||
raise InvalidOrUnsupportedCrx('Invalid or corrupt CRX file') from exc
|
||||
|
||||
# We can start reading the zip to write it where it needs to live on
|
||||
# the filesystem and then return the hash to the caller. If we somehow
|
||||
|
|
|
@ -255,10 +255,10 @@ class AddonGitRepository:
|
|||
try:
|
||||
master_ref = 'refs/heads/master'
|
||||
git_repository.lookup_reference(master_ref)
|
||||
except KeyError:
|
||||
except KeyError as exc:
|
||||
message = f'Reference "{master_ref}" not found'
|
||||
log.exception(message)
|
||||
raise MissingMasterBranchError(message)
|
||||
raise MissingMasterBranchError(message) from exc
|
||||
|
||||
return git_repository
|
||||
|
||||
|
@ -393,10 +393,10 @@ class AddonGitRepository:
|
|||
"""Lookup or create the branch named `name`"""
|
||||
try:
|
||||
branch = self.git_repository.branches.get(name)
|
||||
except pygit2.GitError:
|
||||
except pygit2.GitError as exc:
|
||||
message = f'Reference for branch "{name}" is broken'
|
||||
log.exception(message)
|
||||
raise BrokenRefError(message)
|
||||
raise BrokenRefError(message) from exc
|
||||
|
||||
if branch is None:
|
||||
branch = self.git_repository.create_branch(
|
||||
|
|
|
@ -10,8 +10,10 @@ def get_grouped_ratings(request, addon):
|
|||
show_grouped_ratings = serializers.BooleanField().to_internal_value(
|
||||
request.GET['show_grouped_ratings']
|
||||
)
|
||||
except serializers.ValidationError:
|
||||
raise ParseError('show_grouped_ratings parameter should be a boolean')
|
||||
except serializers.ValidationError as exc:
|
||||
raise ParseError(
|
||||
'show_grouped_ratings parameter should be a boolean'
|
||||
) from exc
|
||||
if show_grouped_ratings and addon:
|
||||
try:
|
||||
aggregate = addon.ratingaggregate
|
||||
|
|
|
@ -199,11 +199,11 @@ class RatingViewSet(AddonChildMixin, ModelViewSet):
|
|||
)
|
||||
if show_flags_for != request.user.pk:
|
||||
raise serializers.ValidationError
|
||||
except serializers.ValidationError:
|
||||
except serializers.ValidationError as exc:
|
||||
raise ParseError(
|
||||
'show_flags_for parameter value should be equal to '
|
||||
'the user id of the authenticated user'
|
||||
)
|
||||
) from exc
|
||||
return self._should_include_flags
|
||||
|
||||
def check_permissions(self, request):
|
||||
|
@ -242,14 +242,14 @@ class RatingViewSet(AddonChildMixin, ModelViewSet):
|
|||
if user_identifier:
|
||||
try:
|
||||
user_identifier = int(user_identifier)
|
||||
except ValueError:
|
||||
raise ParseError('user parameter should be an integer.')
|
||||
except ValueError as exc:
|
||||
raise ParseError('user parameter should be an integer.') from exc
|
||||
qs = qs.filter(user=user_identifier)
|
||||
if version_identifier:
|
||||
try:
|
||||
version_identifier = int(version_identifier)
|
||||
except ValueError:
|
||||
raise ParseError('version parameter should be an integer.')
|
||||
except ValueError as exc:
|
||||
raise ParseError('version parameter should be an integer.') from exc
|
||||
qs = qs.filter(version=version_identifier)
|
||||
elif addon_identifier:
|
||||
# When filtering on addon but not on version, only return the
|
||||
|
@ -270,23 +270,23 @@ class RatingViewSet(AddonChildMixin, ModelViewSet):
|
|||
if score_filter:
|
||||
try:
|
||||
scores = [int(score) for score in score_filter.split(',')]
|
||||
except ValueError:
|
||||
except ValueError as exc:
|
||||
raise ParseError(
|
||||
'score parameter should be an integer or a list of '
|
||||
'integers (separated by a comma).'
|
||||
)
|
||||
) from exc
|
||||
qs = qs.filter(rating__in=scores)
|
||||
if exclude_ratings:
|
||||
try:
|
||||
exclude_ratings = [
|
||||
int(rating) for rating in exclude_ratings.split(',')
|
||||
]
|
||||
except ValueError:
|
||||
except ValueError as exc:
|
||||
raise ParseError(
|
||||
'exclude_ratings parameter should be an '
|
||||
'integer or a list of integers '
|
||||
'(separated by a comma).'
|
||||
)
|
||||
) from exc
|
||||
qs = qs.exclude(pk__in=exclude_ratings)
|
||||
|
||||
if not addon_identifier:
|
||||
|
@ -316,11 +316,11 @@ class RatingViewSet(AddonChildMixin, ModelViewSet):
|
|||
)
|
||||
if show_permissions_for != request.user.pk:
|
||||
raise serializers.ValidationError
|
||||
except serializers.ValidationError:
|
||||
except serializers.ValidationError as exc:
|
||||
raise ParseError(
|
||||
'show_permissions_for parameter value should be equal to '
|
||||
'the user id of the authenticated user'
|
||||
)
|
||||
) from exc
|
||||
extra_data['can_reply'] = self.check_can_reply_permission_for_ratings_list()
|
||||
# Call this here so the validation checks on the `show_flags_for` are
|
||||
# carried out even when there are no results to serialize.
|
||||
|
|
|
@ -472,8 +472,8 @@ class AutoApprovalSummary(ModelBase):
|
|||
old_version = self.find_previous_confirmed_version()
|
||||
old_size = find_code_size(old_version) if old_version else 0
|
||||
new_size = find_code_size(self.version)
|
||||
except FileValidation.DoesNotExist:
|
||||
raise AutoApprovalNoValidationResultError()
|
||||
except FileValidation.DoesNotExist as exc:
|
||||
raise AutoApprovalNoValidationResultError() from exc
|
||||
# We don't really care about whether it's a negative or positive change
|
||||
# in size, we just need the absolute value (if there is no current
|
||||
# public version, that value ends up being the total code size of the
|
||||
|
@ -520,8 +520,8 @@ class AutoApprovalSummary(ModelBase):
|
|||
def _count_linter_flag(cls, version, flag):
|
||||
try:
|
||||
validation = version.file.validation
|
||||
except FileValidation.DoesNotExist:
|
||||
raise AutoApprovalNoValidationResultError()
|
||||
except FileValidation.DoesNotExist as exc:
|
||||
raise AutoApprovalNoValidationResultError() from exc
|
||||
validation_data = json.loads(validation.validation)
|
||||
return sum(
|
||||
flag in message['id'] for message in validation_data.get('messages', [])
|
||||
|
@ -531,8 +531,8 @@ class AutoApprovalSummary(ModelBase):
|
|||
def _count_metadata_property(cls, version, prop):
|
||||
try:
|
||||
validation = version.file.validation
|
||||
except FileValidation.DoesNotExist:
|
||||
raise AutoApprovalNoValidationResultError()
|
||||
except FileValidation.DoesNotExist as exc:
|
||||
raise AutoApprovalNoValidationResultError() from exc
|
||||
validation_data = json.loads(validation.validation)
|
||||
return len(validation_data.get('metadata', {}).get(prop, []))
|
||||
|
||||
|
|
|
@ -90,8 +90,10 @@ class FileEntriesMixin:
|
|||
# Caching the commit to avoid calling revparse_single many times.
|
||||
try:
|
||||
return self.git_repo.revparse_single(self._get_version().git_hash)
|
||||
except pygit2.InvalidSpecError:
|
||||
raise NotFound("Couldn't find the requested version in git-repository")
|
||||
except pygit2.InvalidSpecError as exc:
|
||||
raise NotFound(
|
||||
"Couldn't find the requested version in git-repository"
|
||||
) from exc
|
||||
|
||||
@cached_property
|
||||
def tree(self):
|
||||
|
|
|
@ -1019,8 +1019,8 @@ def download_git_stored_file(request, version_id, filename):
|
|||
|
||||
try:
|
||||
addon = version.addon
|
||||
except Addon.DoesNotExist:
|
||||
raise http.Http404
|
||||
except Addon.DoesNotExist as exc:
|
||||
raise http.Http404 from exc
|
||||
|
||||
if version.channel == amo.CHANNEL_LISTED:
|
||||
is_owner = acl.check_addon_ownership(request.user, addon, allow_developer=True)
|
||||
|
@ -1045,8 +1045,8 @@ def download_git_stored_file(request, version_id, filename):
|
|||
if blob_or_tree.type == pygit2.GIT_OBJ_TREE:
|
||||
return http.HttpResponseBadRequest("Can't serve directories")
|
||||
selected_file = serializer._get_entries()[filename]
|
||||
except (KeyError, NotFound):
|
||||
raise http.Http404()
|
||||
except (KeyError, NotFound) as exc:
|
||||
raise http.Http404() from exc
|
||||
|
||||
actual_blob = serializer.git_repo[blob_or_tree.oid]
|
||||
|
||||
|
@ -1225,8 +1225,8 @@ class AddonReviewerViewSet(GenericViewSet):
|
|||
raise PermissionDenied
|
||||
try:
|
||||
result = file.validation
|
||||
except File.validation.RelatedObjectDoesNotExist:
|
||||
raise http.Http404
|
||||
except File.validation.RelatedObjectDoesNotExist as exc:
|
||||
raise http.Http404 from exc
|
||||
return JsonResponse(
|
||||
{
|
||||
'validation': result.processed_validation,
|
||||
|
|
|
@ -195,11 +195,11 @@ class AbstractScannerRule(ModelBase):
|
|||
'definition': _('The definition is not valid: %(error)s')
|
||||
% {'error': syntaxError}
|
||||
}
|
||||
)
|
||||
except Exception:
|
||||
) from syntaxError
|
||||
except Exception as exc:
|
||||
raise ValidationError(
|
||||
{'definition': _('An error occurred when compiling the definition')}
|
||||
)
|
||||
) from exc
|
||||
|
||||
|
||||
class ScannerRule(AbstractScannerRule):
|
||||
|
|
|
@ -122,9 +122,9 @@ def _run_scanner_for_url(scanner_result, url, scanner, api_url, api_key):
|
|||
|
||||
try:
|
||||
data = response.json()
|
||||
except ValueError:
|
||||
except ValueError as exc:
|
||||
# Log the response body when JSON decoding has failed.
|
||||
raise ValueError(response.text)
|
||||
raise ValueError(response.text) from exc
|
||||
|
||||
if response.status_code != 200 or 'error' in data:
|
||||
raise ValueError(data)
|
||||
|
@ -446,9 +446,9 @@ def call_mad_api(all_results, upload_pk):
|
|||
|
||||
try:
|
||||
data = response.json()
|
||||
except ValueError:
|
||||
except ValueError as exc:
|
||||
# Log the response body when JSON decoding has failed.
|
||||
raise ValueError(response.text)
|
||||
raise ValueError(response.text) from exc
|
||||
|
||||
if response.status_code != 200:
|
||||
raise ValueError(data)
|
||||
|
|
|
@ -265,10 +265,10 @@ class AddonGuidQueryParam(AddonQueryMultiParam):
|
|||
value = force_str(urlsafe_base64_decode(force_str(value[4:])))
|
||||
if not amo.ADDON_GUID_PATTERN.match(value):
|
||||
raise ValueError()
|
||||
except (TypeError, ValueError):
|
||||
except (TypeError, ValueError) as exc:
|
||||
raise ValueError(
|
||||
gettext('Invalid Return To AMO guid (not in base64url format?)')
|
||||
)
|
||||
) from exc
|
||||
# Filter on the now decoded guid param as normal...
|
||||
filters = super().get_es_query([value])
|
||||
# If the switch to enable all listed add-ons for RTAMO is on, we
|
||||
|
@ -310,7 +310,7 @@ class AddonCategoryQueryParam(AddonQueryParam):
|
|||
try:
|
||||
types = AddonTypeQueryParam(self.query_data).get_values()
|
||||
self.reverse_dict = [CATEGORIES[type_] for type_ in types]
|
||||
except KeyError:
|
||||
except KeyError as exc:
|
||||
raise ValueError(
|
||||
gettext(
|
||||
'Invalid combination of "%s" and "%s" parameters.'
|
||||
|
@ -319,7 +319,7 @@ class AddonCategoryQueryParam(AddonQueryParam):
|
|||
self.query_param,
|
||||
)
|
||||
)
|
||||
)
|
||||
) from exc
|
||||
|
||||
def get_value(self):
|
||||
value = super().get_value()
|
||||
|
@ -938,7 +938,7 @@ class SearchParameterFilter(BaseFilterBackend):
|
|||
if param_class.query_param in request.GET:
|
||||
clauses.extend(param_class(request.GET).get_es_query())
|
||||
except ValueError as exc:
|
||||
raise serializers.ValidationError(*exc.args)
|
||||
raise serializers.ValidationError(*exc.args) from exc
|
||||
return clauses
|
||||
|
||||
def filter_queryset(self, request, qs, view):
|
||||
|
@ -1061,8 +1061,8 @@ class SortingFilter(BaseFilterBackend):
|
|||
|
||||
try:
|
||||
order_by = [self.SORTING_PARAMS[name] for name in split_sort_params]
|
||||
except KeyError:
|
||||
raise serializers.ValidationError('Invalid "sort" parameter.')
|
||||
except KeyError as exc:
|
||||
raise serializers.ValidationError('Invalid "sort" parameter.') from exc
|
||||
|
||||
return qs.sort(*order_by)
|
||||
|
||||
|
|
|
@ -267,8 +267,8 @@ class UserAdmin(AMOModelAdmin):
|
|||
try:
|
||||
if lookup_field == 'email':
|
||||
user = UserProfile.objects.get(email=object_id)
|
||||
except UserProfile.DoesNotExist:
|
||||
raise http.Http404
|
||||
except UserProfile.DoesNotExist as exc:
|
||||
raise http.Http404 from exc
|
||||
url = request.path.replace(object_id, str(user.id), 1)
|
||||
if request.GET:
|
||||
url += '?' + request.GET.urlencode()
|
||||
|
|
|
@ -26,8 +26,8 @@ class Command(BaseCommand):
|
|||
|
||||
try:
|
||||
profile = UserProfile.objects.get(email=email)
|
||||
except UserProfile.DoesNotExist:
|
||||
raise CommandError('User with email %s not found' % email)
|
||||
except UserProfile.DoesNotExist as exc:
|
||||
raise CommandError('User with email %s not found' % email) from exc
|
||||
|
||||
admin_msg = ''
|
||||
if set_admin:
|
||||
|
|
|
@ -73,7 +73,7 @@ and email address and that's it.
|
|||
'You must use --%s with --noinput.' % field_name
|
||||
)
|
||||
except exceptions.ValidationError as exc:
|
||||
raise CommandError('; '.join(exc.messages))
|
||||
raise CommandError('; '.join(exc.messages)) from exc
|
||||
else:
|
||||
user_data = {
|
||||
field_name: self.get_value(field_name)
|
||||
|
|
|
@ -37,9 +37,9 @@ class UnsubscribeCode:
|
|||
try:
|
||||
decoded = base64.urlsafe_b64decode(force_bytes(code))
|
||||
email = decoded
|
||||
except (ValueError, TypeError):
|
||||
except (ValueError, TypeError) as exc:
|
||||
# Data is broken
|
||||
raise ValueError
|
||||
raise ValueError from exc
|
||||
|
||||
if cls.make_secret(decoded) != hash:
|
||||
log.info('[Tampering] Unsubscribe link data does not match hash')
|
||||
|
|
|
@ -38,9 +38,9 @@ def do_adduser(user, group):
|
|||
|
||||
GroupUser.objects.create(user=user, group=group)
|
||||
|
||||
except IntegrityError as e:
|
||||
raise CommandError('User is already in that group? %s' % e)
|
||||
except UserProfile.DoesNotExist:
|
||||
raise CommandError(f'User ({user}) does not exist.')
|
||||
except Group.DoesNotExist:
|
||||
raise CommandError(f'Group ({group}) does not exist.')
|
||||
except IntegrityError as exc:
|
||||
raise CommandError('User is already in that group? %s' % exc) from exc
|
||||
except UserProfile.DoesNotExist as exc:
|
||||
raise CommandError(f'User ({user}) does not exist.') from exc
|
||||
except Group.DoesNotExist as exc:
|
||||
raise CommandError(f'Group ({group}) does not exist.') from exc
|
||||
|
|
|
@ -37,7 +37,7 @@ def do_removeuser(user, group):
|
|||
|
||||
# Doesn't actually check if the user was in the group or not.
|
||||
GroupUser.objects.filter(user=user, group=group).delete()
|
||||
except UserProfile.DoesNotExist:
|
||||
raise CommandError(f'User ({user}) does not exist.')
|
||||
except Group.DoesNotExist:
|
||||
raise CommandError(f'Group ({group}) does not exist.')
|
||||
except UserProfile.DoesNotExist as exc:
|
||||
raise CommandError(f'User ({user}) does not exist.') from exc
|
||||
except Group.DoesNotExist as exc:
|
||||
raise CommandError(f'Group ({group}) does not exist.') from exc
|
||||
|
|
Загрузка…
Ссылка в новой задаче