summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/contrib/admin/models.py5
-rw-r--r--django/contrib/admin/sites.py9
-rw-r--r--django/contrib/auth/middleware.py6
-rw-r--r--django/contrib/contenttypes/fields.py5
-rw-r--r--django/contrib/contenttypes/models.py5
-rw-r--r--django/contrib/contenttypes/views.py10
-rw-r--r--django/contrib/gis/db/backends/spatialite/schema.py10
-rw-r--r--django/contrib/gis/db/models/fields.py5
-rw-r--r--django/contrib/gis/gdal/layer.py5
-rw-r--r--django/contrib/gis/utils/__init__.py6
-rw-r--r--django/contrib/messages/storage/cookie.py5
-rw-r--r--django/contrib/sessions/backends/base.py5
-rw-r--r--django/contrib/sessions/backends/file.py9
-rw-r--r--django/contrib/sitemaps/__init__.py9
-rw-r--r--django/contrib/sites/models.py10
-rw-r--r--django/contrib/staticfiles/management/commands/collectstatic.py5
-rw-r--r--django/contrib/syndication/views.py9
-rw-r--r--django/core/cache/backends/filebased.py15
-rw-r--r--django/core/cache/backends/locmem.py19
-rw-r--r--django/core/files/move.py9
-rw-r--r--django/core/files/storage.py19
-rw-r--r--django/core/management/__init__.py13
-rw-r--r--django/core/management/base.py9
-rw-r--r--django/core/management/commands/flush.py5
-rw-r--r--django/core/management/commands/shell.py5
-rw-r--r--django/core/validators.py5
-rw-r--r--django/db/backends/postgresql/client.py9
-rw-r--r--django/db/backends/sqlite3/operations.py10
-rw-r--r--django/db/migrations/autodetector.py5
-rw-r--r--django/db/migrations/state.py6
-rw-r--r--django/db/migrations/writer.py5
-rw-r--r--django/db/models/expressions.py5
-rw-r--r--django/db/models/options.py17
-rw-r--r--django/db/models/query.py10
-rw-r--r--django/db/models/sql/query.py5
-rw-r--r--django/forms/fields.py5
-rw-r--r--django/forms/forms.py5
-rw-r--r--django/forms/formsets.py6
-rw-r--r--django/forms/models.py5
-rw-r--r--django/forms/widgets.py5
-rw-r--r--django/http/response.py13
-rw-r--r--django/template/backends/base.py11
-rw-r--r--django/template/defaultfilters.py9
-rw-r--r--django/test/signals.py13
-rw-r--r--django/urls/base.py9
-rw-r--r--django/utils/autoreload.py21
-rw-r--r--django/utils/datastructures.py5
-rw-r--r--django/utils/dateformat.py11
-rw-r--r--django/utils/formats.py9
-rw-r--r--django/utils/http.py5
-rw-r--r--django/utils/translation/__init__.py8
-rw-r--r--django/utils/translation/trans_real.py13
-rw-r--r--django/views/debug.py9
-rw-r--r--tests/admin_scripts/tests.py9
-rw-r--r--tests/backends/tests.py5
-rw-r--r--tests/bash_completion/tests.py5
-rw-r--r--tests/handlers/views.py6
-rw-r--r--tests/mail/tests.py9
-rw-r--r--tests/postgres_tests/test_aggregates.py5
-rw-r--r--tests/postgres_tests/test_array.py5
-rw-r--r--tests/postgres_tests/test_hstore.py5
-rw-r--r--tests/postgres_tests/test_json.py5
-rw-r--r--tests/postgres_tests/test_ranges.py5
-rwxr-xr-xtests/runtests.py9
-rw-r--r--tests/staticfiles_tests/storage.py5
-rw-r--r--tests/transaction_hooks/tests.py34
66 files changed, 351 insertions, 207 deletions
diff --git a/django/contrib/admin/models.py b/django/contrib/admin/models.py
index 4443f13dac..82b3cc0585 100644
--- a/django/contrib/admin/models.py
+++ b/django/contrib/admin/models.py
@@ -1,5 +1,4 @@
import json
-from contextlib import suppress
from django.conf import settings
from django.contrib.admin.utils import quote
@@ -138,6 +137,8 @@ class LogEntry(models.Model):
"""
if self.content_type and self.object_id:
url_name = 'admin:%s_%s_change' % (self.content_type.app_label, self.content_type.model)
- with suppress(NoReverseMatch):
+ try:
return reverse(url_name, args=(quote(self.object_id),))
+ except NoReverseMatch:
+ pass
return None
diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py
index e68dfa1e8b..c0767c15ee 100644
--- a/django/contrib/admin/sites.py
+++ b/django/contrib/admin/sites.py
@@ -1,4 +1,3 @@
-from contextlib import suppress
from functools import update_wrapper
from weakref import WeakSet
@@ -428,11 +427,15 @@ class AdminSite:
'perms': perms,
}
if perms.get('change'):
- with suppress(NoReverseMatch):
+ try:
model_dict['admin_url'] = reverse('admin:%s_%s_changelist' % info, current_app=self.name)
+ except NoReverseMatch:
+ pass
if perms.get('add'):
- with suppress(NoReverseMatch):
+ try:
model_dict['add_url'] = reverse('admin:%s_%s_add' % info, current_app=self.name)
+ except NoReverseMatch:
+ pass
if app_label in app_dict:
app_dict[app_label]['models'].append(model_dict)
diff --git a/django/contrib/auth/middleware.py b/django/contrib/auth/middleware.py
index 0b3365cb3a..f0102c4455 100644
--- a/django/contrib/auth/middleware.py
+++ b/django/contrib/auth/middleware.py
@@ -1,5 +1,3 @@
-from contextlib import suppress
-
from django.conf import settings
from django.contrib import auth
from django.contrib.auth import load_backend
@@ -91,8 +89,10 @@ class RemoteUserMiddleware(MiddlewareMixin):
"""
backend_str = request.session[auth.BACKEND_SESSION_KEY]
backend = auth.load_backend(backend_str)
- with suppress(AttributeError): # Backend has no clean_username method.
+ try:
username = backend.clean_username(username)
+ except AttributeError: # Backend has no clean_username method.
+ pass
return username
def _remove_invalid_user(self, request):
diff --git a/django/contrib/contenttypes/fields.py b/django/contrib/contenttypes/fields.py
index 0884089d92..21367c4195 100644
--- a/django/contrib/contenttypes/fields.py
+++ b/django/contrib/contenttypes/fields.py
@@ -1,5 +1,4 @@
from collections import defaultdict
-from contextlib import suppress
from django.contrib.contenttypes.models import ContentType
from django.core import checks
@@ -237,8 +236,10 @@ class GenericForeignKey(FieldCacheMixin):
rel_obj = None
if ct_id is not None:
ct = self.get_content_type(id=ct_id, using=instance._state.db)
- with suppress(ObjectDoesNotExist):
+ try:
rel_obj = ct.get_object_for_this_type(pk=pk_val)
+ except ObjectDoesNotExist:
+ pass
self.set_cached_value(instance, rel_obj)
return rel_obj
diff --git a/django/contrib/contenttypes/models.py b/django/contrib/contenttypes/models.py
index 066474e49f..ad2e0bc904 100644
--- a/django/contrib/contenttypes/models.py
+++ b/django/contrib/contenttypes/models.py
@@ -1,5 +1,4 @@
from collections import defaultdict
-from contextlib import suppress
from django.apps import apps
from django.db import models
@@ -39,8 +38,10 @@ class ContentTypeManager(models.Manager):
for the same model don't hit the database.
"""
opts = self._get_opts(model, for_concrete_model)
- with suppress(KeyError):
+ try:
return self._get_from_cache(opts)
+ except KeyError:
+ pass
# The ContentType entry was not found in the cache, therefore we
# proceed to load or create it.
diff --git a/django/contrib/contenttypes/views.py b/django/contrib/contenttypes/views.py
index c527687250..d67f071569 100644
--- a/django/contrib/contenttypes/views.py
+++ b/django/contrib/contenttypes/views.py
@@ -1,5 +1,3 @@
-from contextlib import suppress
-
from django.apps import apps
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.requests import RequestSite
@@ -55,10 +53,12 @@ def shortcut(request, content_type_id, object_id):
# First, look for an many-to-many relationship to Site.
for field in opts.many_to_many:
if field.remote_field.model is Site:
- with suppress(IndexError):
+ try:
# Caveat: In the case of multiple related Sites, this just
# selects the *first* one, which is arbitrary.
object_domain = getattr(obj, field.name).all()[0].domain
+ except IndexError:
+ pass
if object_domain is not None:
break
@@ -77,8 +77,10 @@ def shortcut(request, content_type_id, object_id):
# Fall back to the current site (if possible).
if object_domain is None:
- with suppress(Site.DoesNotExist):
+ try:
object_domain = Site.objects.get_current(request).domain
+ except Site.DoesNotExist:
+ pass
else:
# Fall back to the current request's site.
diff --git a/django/contrib/gis/db/backends/spatialite/schema.py b/django/contrib/gis/db/backends/spatialite/schema.py
index 3122b79e7e..6f4e3380db 100644
--- a/django/contrib/gis/db/backends/spatialite/schema.py
+++ b/django/contrib/gis/db/backends/spatialite/schema.py
@@ -1,5 +1,3 @@
-from contextlib import suppress
-
from django.db.backends.sqlite3.schema import DatabaseSchemaEditor
from django.db.utils import DatabaseError
@@ -91,13 +89,15 @@ class SpatialiteSchemaEditor(DatabaseSchemaEditor):
self.remove_geometry_metadata(model, field)
# Make sure all geom stuff is gone
for geom_table in self.geometry_tables:
- with suppress(DatabaseError):
+ try:
self.execute(
self.sql_discard_geometry_columns % {
"geom_table": geom_table,
"table": self.quote_name(model._meta.db_table),
}
)
+ except DatabaseError:
+ pass
super().delete_model(model, **kwargs)
def add_field(self, model, field):
@@ -138,7 +138,7 @@ class SpatialiteSchemaEditor(DatabaseSchemaEditor):
super().alter_db_table(model, old_db_table, new_db_table)
# Repoint any straggler names
for geom_table in self.geometry_tables:
- with suppress(DatabaseError):
+ try:
self.execute(
self.sql_update_geometry_columns % {
"geom_table": geom_table,
@@ -146,6 +146,8 @@ class SpatialiteSchemaEditor(DatabaseSchemaEditor):
"new_table": self.quote_name(new_db_table),
}
)
+ except DatabaseError:
+ pass
# Re-add geometry-ness and rename spatial index tables
for field in model._meta.local_fields:
if isinstance(field, GeometryField):
diff --git a/django/contrib/gis/db/models/fields.py b/django/contrib/gis/db/models/fields.py
index 8265815c30..d165313468 100644
--- a/django/contrib/gis/db/models/fields.py
+++ b/django/contrib/gis/db/models/fields.py
@@ -1,5 +1,4 @@
from collections import defaultdict, namedtuple
-from contextlib import suppress
from django.contrib.gis import forms, gdal
from django.contrib.gis.db.models.proxy import SpatialProxy
@@ -157,8 +156,10 @@ class BaseSpatialField(Field):
if isinstance(value, gdal.GDALRaster):
return value
elif is_candidate:
- with suppress(GDALException):
+ try:
return gdal.GDALRaster(value)
+ except GDALException:
+ pass
elif isinstance(value, dict):
try:
return gdal.GDALRaster(value)
diff --git a/django/contrib/gis/gdal/layer.py b/django/contrib/gis/gdal/layer.py
index a2b86c46bd..a2b7fe2211 100644
--- a/django/contrib/gis/gdal/layer.py
+++ b/django/contrib/gis/gdal/layer.py
@@ -1,4 +1,3 @@
-from contextlib import suppress
from ctypes import byref, c_double
from django.contrib.gis.gdal.base import GDALBase
@@ -77,8 +76,10 @@ class Layer(GDALBase):
"""
if self._random_read:
# If the Layer supports random reading, return.
- with suppress(GDALException):
+ try:
return Feature(capi.get_feature(self.ptr, feat_id), self)
+ except GDALException:
+ pass
else:
# Random access isn't supported, have to increment through
# each feature until the given feature ID is encountered.
diff --git a/django/contrib/gis/utils/__init__.py b/django/contrib/gis/utils/__init__.py
index 88de2a4773..800b2dbb89 100644
--- a/django/contrib/gis/utils/__init__.py
+++ b/django/contrib/gis/utils/__init__.py
@@ -1,14 +1,14 @@
"""
This module contains useful utilities for GeoDjango.
"""
-from contextlib import suppress
-
from django.contrib.gis.utils.ogrinfo import ogrinfo # NOQA
from django.contrib.gis.utils.ogrinspect import mapping, ogrinspect # NOQA
from django.contrib.gis.utils.srs import add_srs_entry # NOQA
from django.core.exceptions import ImproperlyConfigured
-with suppress(ImproperlyConfigured):
+try:
# LayerMapping requires DJANGO_SETTINGS_MODULE to be set,
# and ImproperlyConfigured is raised if that's not the case.
from django.contrib.gis.utils.layermapping import LayerMapping, LayerMapError # NOQA
+except ImproperlyConfigured:
+ pass
diff --git a/django/contrib/messages/storage/cookie.py b/django/contrib/messages/storage/cookie.py
index 6d5df1af9d..49270cac17 100644
--- a/django/contrib/messages/storage/cookie.py
+++ b/django/contrib/messages/storage/cookie.py
@@ -1,5 +1,4 @@
import json
-from contextlib import suppress
from django.conf import settings
from django.contrib.messages.storage.base import BaseStorage, Message
@@ -154,10 +153,12 @@ class CookieStorage(BaseStorage):
if len(bits) == 2:
hash, value = bits
if constant_time_compare(hash, self._hash(value)):
- with suppress(ValueError):
+ try:
# If we get here (and the JSON decode works), everything is
# good. In any other case, drop back and return None.
return json.loads(value, cls=MessageDecoder)
+ except ValueError:
+ pass
# Mark the data as used (so it gets removed) since something was wrong
# with the data.
self.used = True
diff --git a/django/contrib/sessions/backends/base.py b/django/contrib/sessions/backends/base.py
index 3ff79b7a39..64955b8bb7 100644
--- a/django/contrib/sessions/backends/base.py
+++ b/django/contrib/sessions/backends/base.py
@@ -1,7 +1,6 @@
import base64
import logging
import string
-from contextlib import suppress
from datetime import datetime, timedelta
from django.conf import settings
@@ -263,8 +262,10 @@ class SessionBase:
"""
if value is None:
# Remove any custom expiration for this session.
- with suppress(KeyError):
+ try:
del self['_session_expiry']
+ except KeyError:
+ pass
return
if isinstance(value, timedelta):
value = timezone.now() + value
diff --git a/django/contrib/sessions/backends/file.py b/django/contrib/sessions/backends/file.py
index 540228b790..0a724f7e0a 100644
--- a/django/contrib/sessions/backends/file.py
+++ b/django/contrib/sessions/backends/file.py
@@ -3,7 +3,6 @@ import logging
import os
import shutil
import tempfile
-from contextlib import suppress
from django.conf import settings
from django.contrib.sessions.backends.base import (
@@ -156,7 +155,7 @@ class SessionStore(SessionBase):
# See ticket #8616.
dir, prefix = os.path.split(session_file_name)
- with suppress(OSError, IOError, EOFError):
+ try:
output_file_fd, output_file_name = tempfile.mkstemp(dir=dir, prefix=prefix + '_out_')
renamed = False
try:
@@ -173,6 +172,8 @@ class SessionStore(SessionBase):
finally:
if not renamed:
os.unlink(output_file_name)
+ except (OSError, IOError, EOFError):
+ pass
def exists(self, session_key):
return os.path.exists(self._key_to_file(session_key))
@@ -182,8 +183,10 @@ class SessionStore(SessionBase):
if self.session_key is None:
return
session_key = self.session_key
- with suppress(OSError):
+ try:
os.unlink(self._key_to_file(session_key))
+ except OSError:
+ pass
def clean(self):
pass
diff --git a/django/contrib/sitemaps/__init__.py b/django/contrib/sitemaps/__init__.py
index 8f984ae3dc..bd1139ff70 100644
--- a/django/contrib/sitemaps/__init__.py
+++ b/django/contrib/sitemaps/__init__.py
@@ -1,4 +1,3 @@
-from contextlib import suppress
from urllib.parse import urlencode
from urllib.request import urlopen
@@ -37,9 +36,11 @@ def _get_sitemap_full_url(sitemap_url):
# First, try to get the "index" sitemap URL.
sitemap_url = reverse('django.contrib.sitemaps.views.index')
except NoReverseMatch:
- with suppress(NoReverseMatch):
+ try:
# Next, try for the "global" sitemap URL.
sitemap_url = reverse('django.contrib.sitemaps.views.sitemap')
+ except NoReverseMatch:
+ pass
if sitemap_url is None:
raise SitemapNotFound("You didn't provide a sitemap_url, and the sitemap URL couldn't be auto-detected.")
@@ -88,8 +89,10 @@ class Sitemap:
if site is None:
if django_apps.is_installed('django.contrib.sites'):
Site = django_apps.get_model('sites.Site')
- with suppress(Site.DoesNotExist):
+ try:
site = Site.objects.get_current()
+ except Site.DoesNotExist:
+ pass
if site is None:
raise ImproperlyConfigured(
"To use sitemaps, either enable the sites framework or pass "
diff --git a/django/contrib/sites/models.py b/django/contrib/sites/models.py
index 9112efbfb5..19f52e4487 100644
--- a/django/contrib/sites/models.py
+++ b/django/contrib/sites/models.py
@@ -1,5 +1,4 @@
import string
-from contextlib import suppress
from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.db import models
@@ -108,11 +107,14 @@ def clear_site_cache(sender, **kwargs):
"""
instance = kwargs['instance']
using = kwargs['using']
- with suppress(KeyError):
+ try:
del SITE_CACHE[instance.pk]
-
- with suppress(KeyError, Site.DoesNotExist):
+ except KeyError:
+ pass
+ try:
del SITE_CACHE[Site.objects.using(using).get(pk=instance.pk).domain]
+ except (KeyError, Site.DoesNotExist):
+ pass
pre_save.connect(clear_site_cache, sender=Site)
diff --git a/django/contrib/staticfiles/management/commands/collectstatic.py b/django/contrib/staticfiles/management/commands/collectstatic.py
index 7e81ef19ee..e5ae48f9fe 100644
--- a/django/contrib/staticfiles/management/commands/collectstatic.py
+++ b/django/contrib/staticfiles/management/commands/collectstatic.py
@@ -1,6 +1,5 @@
import os
from collections import OrderedDict
-from contextlib import suppress
from django.apps import apps
from django.contrib.staticfiles.finders import get_finders
@@ -313,8 +312,10 @@ class Command(BaseCommand):
else:
self.log("Linking '%s'" % source_path, level=1)
full_path = self.storage.path(prefixed_path)
- with suppress(OSError):
+ try:
os.makedirs(os.path.dirname(full_path))
+ except OSError:
+ pass
try:
if os.path.lexists(full_path):
os.unlink(full_path)
diff --git a/django/contrib/syndication/views.py b/django/contrib/syndication/views.py
index f0dcdb3e62..a8b98c84ae 100644
--- a/django/contrib/syndication/views.py
+++ b/django/contrib/syndication/views.py
@@ -1,5 +1,4 @@
from calendar import timegm
-from contextlib import suppress
from django.conf import settings
from django.contrib.sites.shortcuts import get_current_site
@@ -153,13 +152,17 @@ class Feed:
title_tmp = None
if self.title_template is not None:
- with suppress(TemplateDoesNotExist):
+ try:
title_tmp = loader.get_template(self.title_template)
+ except TemplateDoesNotExist:
+ pass
description_tmp = None
if self.description_template is not None:
- with suppress(TemplateDoesNotExist):
+ try:
description_tmp = loader.get_template(self.description_template)
+ except TemplateDoesNotExist:
+ pass
for item in self._get_dynamic_attr('items', obj):
context = self.get_context_data(item=item, site=current_site,
diff --git a/django/core/cache/backends/filebased.py b/django/core/cache/backends/filebased.py
index deceffaa0d..dccc3fdc65 100644
--- a/django/core/cache/backends/filebased.py
+++ b/django/core/cache/backends/filebased.py
@@ -7,7 +7,6 @@ import random
import tempfile
import time
import zlib
-from contextlib import suppress
from django.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache
from django.core.files.move import file_move_safe
@@ -30,10 +29,12 @@ class FileBasedCache(BaseCache):
def get(self, key, default=None, version=None):
fname = self._key_to_file(key, version)
- with suppress(FileNotFoundError):
+ try:
with open(fname, 'rb') as f:
if not self._is_expired(f):
return pickle.loads(zlib.decompress(f.read()))
+ except FileNotFoundError:
+ pass
return default
def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
@@ -59,9 +60,11 @@ class FileBasedCache(BaseCache):
def _delete(self, fname):
if not fname.startswith(self._dir) or not os.path.exists(fname):
return
- with suppress(FileNotFoundError):
- # The file may have been removed by another process.
+ try:
os.remove(fname)
+ except FileNotFoundError:
+ # The file may have been removed by another process.
+ pass
def has_key(self, key, version=None):
fname = self._key_to_file(key, version)
@@ -90,8 +93,10 @@ class FileBasedCache(BaseCache):
def _createdir(self):
if not os.path.exists(self._dir):
- with suppress(FileExistsError):
+ try:
os.makedirs(self._dir, 0o700)
+ except FileExistsError:
+ pass
def _key_to_file(self, key, version=None):
"""
diff --git a/django/core/cache/backends/locmem.py b/django/core/cache/backends/locmem.py
index 20b6dd4212..b2600d3169 100644
--- a/django/core/cache/backends/locmem.py
+++ b/django/core/cache/backends/locmem.py
@@ -1,7 +1,7 @@
"Thread-safe in-memory cache backend."
import pickle
import time
-from contextlib import contextmanager, suppress
+from contextlib import contextmanager
from django.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache
from django.utils.synch import RWLock
@@ -50,9 +50,11 @@ class LocMemCache(BaseCache):
return default
with (self._lock.writer() if acquire_lock else dummy()):
- with suppress(KeyError):
+ try:
del self._cache[key]
del self._expire_info[key]
+ except KeyError:
+ pass
return default
def _set(self, key, value, timeout=DEFAULT_TIMEOUT):
@@ -87,9 +89,11 @@ class LocMemCache(BaseCache):
return True
with self._lock.writer():
- with suppress(KeyError):
+ try:
del self._cache[key]
del self._expire_info[key]
+ except KeyError:
+ pass
return False
def _has_expired(self, key):
@@ -107,11 +111,14 @@ class LocMemCache(BaseCache):
self._delete(k)
def _delete(self, key):
- with suppress(KeyError):
+ try:
del self._cache[key]
-
- with suppress(KeyError):
+ except KeyError:
+ pass
+ try:
del self._expire_info[key]
+ except KeyError:
+ pass
def delete(self, key, version=None):
key = self.make_key(key, version=version)
diff --git a/django/core/files/move.py b/django/core/files/move.py
index 310e064a2d..4d791ac263 100644
--- a/django/core/files/move.py
+++ b/django/core/files/move.py
@@ -7,7 +7,6 @@ Move a file in the safest way possible::
import errno
import os
-from contextlib import suppress
from shutil import copystat
from django.core.files import locks
@@ -42,14 +41,16 @@ def file_move_safe(old_file_name, new_file_name, chunk_size=1024 * 64, allow_ove
if _samefile(old_file_name, new_file_name):
return
- # OSError happens with os.rename() if moving to another filesystem or when
- # moving opened files on certain operating systems.
- with suppress(OSError):
+ try:
if not allow_overwrite and os.access(new_file_name, os.F_OK):
raise IOError("Destination file %s exists and allow_overwrite is False" % new_file_name)
os.rename(old_file_name, new_file_name)
return
+ except OSError:
+ # OSError happens with os.rename() if moving to another filesystem or
+ # when moving opened files on certain operating systems.
+ pass
# first open the old file, so that it won't go away
with open(old_file_name, 'rb') as old_file:
diff --git a/django/core/files/storage.py b/django/core/files/storage.py
index fa98bb198a..30788d6d75 100644
--- a/django/core/files/storage.py
+++ b/django/core/files/storage.py
@@ -1,5 +1,4 @@
import os
-from contextlib import suppress
from datetime import datetime
from urllib.parse import urljoin
@@ -224,10 +223,7 @@ class FileSystemStorage(Storage):
# Create any intermediate directories that do not exist.
directory = os.path.dirname(full_path)
if not os.path.exists(directory):
- # There's a race between os.path.exists() and os.makedirs().
- # If os.makedirs() fails with FileNotFoundError, the directory
- # was created concurrently.
- with suppress(FileNotFoundError):
+ try:
if self.directory_permissions_mode is not None:
# os.makedirs applies the global umask, so we reset it,
# for consistency with file_permissions_mode behavior.
@@ -238,6 +234,11 @@ class FileSystemStorage(Storage):
os.umask(old_umask)
else:
os.makedirs(directory)
+ except FileNotFoundError:
+ # There's a race between os.path.exists() and os.makedirs().
+ # If os.makedirs() fails with FileNotFoundError, the directory
+ # was created concurrently.
+ pass
if not os.path.isdir(directory):
raise IOError("%s exists and is not a directory." % directory)
@@ -293,13 +294,15 @@ class FileSystemStorage(Storage):
assert name, "The name argument is not allowed to be empty."
name = self.path(name)
# If the file or directory exists, delete it from the filesystem.
- # FileNotFoundError is raised if the file or directory was removed
- # concurrently.
- with suppress(FileNotFoundError):
+ try:
if os.path.isdir(name):
os.rmdir(name)
else:
os.remove(name)
+ except FileNotFoundError:
+ # FileNotFoundError is raised if the file or directory was removed
+ # concurrently.
+ pass
def exists(self, name):
return os.path.exists(self.path(name))
diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py
index b68692d60a..77c060c21c 100644
--- a/django/core/management/__init__.py
+++ b/django/core/management/__init__.py
@@ -3,7 +3,6 @@ import os
import pkgutil
import sys
from collections import OrderedDict, defaultdict
-from contextlib import suppress
from importlib import import_module
import django
@@ -262,12 +261,14 @@ class ManagementUtility:
subcommand_cls = self.fetch_command(cwords[0])
# special case: add the names of installed apps to options
if cwords[0] in ('dumpdata', 'sqlmigrate', 'sqlsequencereset', 'test'):
- # Fail silently if DJANGO_SETTINGS_MODULE isn't set. The
- # user will find out once they execute the command.
- with suppress(ImportError):
+ try:
app_configs = apps.get_app_configs()
# Get the last part of the dotted path as the app name.
options.extend((app_config.label, 0) for app_config in app_configs)
+ except ImportError:
+ # Fail silently if DJANGO_SETTINGS_MODULE isn't set. The
+ # user will find out once they execute the command.
+ pass
parser = subcommand_cls.create_parser('', cwords[0])
options.extend(
(min(s_opt.option_strings), s_opt.nargs != 0)
@@ -306,9 +307,11 @@ class ManagementUtility:
parser.add_argument('--settings')
parser.add_argument('--pythonpath')
parser.add_argument('args', nargs='*') # catch-all
- with suppress(CommandError): # Ignore any option errors at this point.
+ try:
options, args = parser.parse_known_args(self.argv[2:])
handle_default_options(options)
+ except CommandError:
+ pass # Ignore any option errors at this point.
try:
settings.INSTALLED_APPS
diff --git a/django/core/management/base.py b/django/core/management/base.py
index b53b414fdb..41b6b0fa91 100644
--- a/django/core/management/base.py
+++ b/django/core/management/base.py
@@ -5,7 +5,6 @@ be executed through ``django-admin`` or ``manage.py``).
import os
import sys
from argparse import ArgumentParser
-from contextlib import suppress
from io import TextIOBase
import django
@@ -298,10 +297,12 @@ class BaseCommand:
self.stderr.write('%s: %s' % (e.__class__.__name__, e))
sys.exit(1)
finally:
- # Ignore if connections aren't setup at this point (e.g. no
- # configured settings).
- with suppress(ImproperlyConfigured):
+ try:
connections.close_all()
+ except ImproperlyConfigured:
+ # Ignore if connections aren't setup at this point (e.g. no
+ # configured settings).
+ pass
def execute(self, *args, **options):
"""
diff --git a/django/core/management/commands/flush.py b/django/core/management/commands/flush.py
index 0df5f67e39..f6ae83940a 100644
--- a/django/core/management/commands/flush.py
+++ b/django/core/management/commands/flush.py
@@ -1,4 +1,3 @@
-from contextlib import suppress
from importlib import import_module
from django.apps import apps
@@ -40,8 +39,10 @@ class Command(BaseCommand):
# Import the 'management' module within each installed app, to register
# dispatcher events.
for app_config in apps.get_app_configs():
- with suppress(ImportError):
+ try:
import_module('.management', app_config.name)
+ except ImportError:
+ pass
sql_list = sql_flush(self.style, connection, only_django=True,
reset_sequences=reset_sequences,
diff --git a/django/core/management/commands/shell.py b/django/core/management/commands/shell.py
index ce013bcec0..7c9a43434a 100644
--- a/django/core/management/commands/shell.py
+++ b/django/core/management/commands/shell.py
@@ -2,7 +2,6 @@ import os
import select
import sys
import traceback
-from contextlib import suppress
from django.core.management import BaseCommand, CommandError
from django.utils.datastructures import OrderedSet
@@ -96,6 +95,8 @@ class Command(BaseCommand):
available_shells = [options['interface']] if options['interface'] else self.shells
for shell in available_shells:
- with suppress(ImportError):
+ try:
return getattr(self, shell)(options)
+ except ImportError:
+ pass
raise CommandError("Couldn't import {} interface.".format(shell))
diff --git a/django/core/validators.py b/django/core/validators.py
index c6d5e6e06a..b36ab60704 100644
--- a/django/core/validators.py
+++ b/django/core/validators.py
@@ -1,7 +1,6 @@
import ipaddress
import os
import re
-from contextlib import suppress
from urllib.parse import urlsplit, urlunsplit
from django.core.exceptions import ValidationError
@@ -215,9 +214,11 @@ class EmailValidator:
literal_match = self.literal_regex.match(domain_part)
if literal_match:
ip_address = literal_match.group(1)
- with suppress(ValidationError):
+ try:
validate_ipv46_address(ip_address)
return True
+ except ValidationError:
+ pass
return False
def __eq__(self, other):
diff --git a/django/db/backends/postgresql/client.py b/django/db/backends/postgresql/client.py
index 8d08b0d5cf..6d4cc9b692 100644
--- a/django/db/backends/postgresql/client.py
+++ b/django/db/backends/postgresql/client.py
@@ -1,7 +1,6 @@
import os
import signal
import subprocess
-from contextlib import suppress
from django.core.files.temp import NamedTemporaryFile
from django.db.backends.base.client import BaseDatabaseClient
@@ -41,9 +40,7 @@ class DatabaseClient(BaseDatabaseClient):
if passwd:
# Create temporary .pgpass file.
temp_pgpass = NamedTemporaryFile(mode='w+')
- # If the current locale can't encode the data, let the user
- # input the password manually.
- with suppress(UnicodeEncodeError):
+ try:
print(
_escape_pgpass(host) or '*',
str(port) or '*',
@@ -55,6 +52,10 @@ class DatabaseClient(BaseDatabaseClient):
flush=True,
)
os.environ['PGPASSFILE'] = temp_pgpass.name
+ except UnicodeEncodeError:
+ # If the current locale can't encode the data, let the
+ # user input the password manually.
+ pass
# Allow SIGINT to pass to psql to abort queries.
signal.signal(signal.SIGINT, signal.SIG_IGN)
subprocess.check_call(args)
diff --git a/django/db/backends/sqlite3/operations.py b/django/db/backends/sqlite3/operations.py
index 774d549461..408848c9ad 100644
--- a/django/db/backends/sqlite3/operations.py
+++ b/django/db/backends/sqlite3/operations.py
@@ -1,6 +1,5 @@
import datetime
import uuid
-from contextlib import suppress
from django.conf import settings
from django.core.exceptions import FieldError
@@ -36,10 +35,13 @@ class DatabaseOperations(BaseDatabaseOperations):
bad_aggregates = (aggregates.Sum, aggregates.Avg, aggregates.Variance, aggregates.StdDev)
if isinstance(expression, bad_aggregates):
for expr in expression.get_source_expressions():
- # Not every subexpression has an output_field which is fine
- # to ignore.
- with suppress(FieldError):
+ try:
output_field = expr.output_field
+ except FieldError:
+ # Not every subexpression has an output_field which is fine
+ # to ignore.
+ pass
+ else:
if isinstance(output_field, bad_fields):
raise NotImplementedError(
'You cannot use Sum, Avg, StdDev, and Variance '
diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py
index e79e745978..ece58b9bab 100644
--- a/django/db/migrations/autodetector.py
+++ b/django/db/migrations/autodetector.py
@@ -1,6 +1,5 @@
import functools
import re
-from contextlib import suppress
from itertools import chain
from django.conf import settings
@@ -435,7 +434,7 @@ class MigrationAutodetector:
Place potential swappable models first in lists of created models (only
real way to solve #22783).
"""
- with suppress(LookupError):
+ try:
model = self.new_apps.get_model(item[0], item[1])
base_names = [base.__name__ for base in model.__bases__]
string_version = "%s.%s" % (item[0], item[1])
@@ -446,6 +445,8 @@ class MigrationAutodetector:
settings.AUTH_USER_MODEL.lower() == string_version.lower()
):
return ("___" + item[0], "___" + item[1])
+ except LookupError:
+ pass
return item
def generate_renamed_models(self):
diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py
index 563f837c3b..dc644161fc 100644
--- a/django/db/migrations/state.py
+++ b/django/db/migrations/state.py
@@ -1,6 +1,6 @@
import copy
from collections import OrderedDict
-from contextlib import contextmanager, suppress
+from contextlib import contextmanager
from django.apps import AppConfig
from django.apps.registry import Apps, apps as global_apps
@@ -338,9 +338,11 @@ class StateApps(Apps):
self.clear_cache()
def unregister_model(self, app_label, model_name):
- with suppress(KeyError):
+ try:
del self.all_models[app_label][model_name]
del self.app_configs[app_label].models[model_name]
+ except KeyError:
+ pass
class ModelState:
diff --git a/django/db/migrations/writer.py b/django/db/migrations/writer.py
index 00ff03e494..aa296db8c5 100644
--- a/django/db/migrations/writer.py
+++ b/django/db/migrations/writer.py
@@ -1,6 +1,5 @@
import os
import re
-from contextlib import suppress
from importlib import import_module
from django import get_version
@@ -223,8 +222,10 @@ class MigrationWriter:
except ImportError:
pass
else:
- with suppress(ValueError):
+ try:
return module_dir(migrations_module)
+ except ValueError:
+ pass
# Alright, see if it's a direct submodule of the app
app_config = apps.get_app_config(self.migration.app_label)
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index ff7921b520..db62541559 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -1,6 +1,5 @@
import copy
import datetime
-from contextlib import suppress
from decimal import Decimal
from django.core.exceptions import EmptyResultSet, FieldError
@@ -17,9 +16,11 @@ class SQLiteNumericMixin:
"""
def as_sqlite(self, compiler, connection, **extra_context):
sql, params = self.as_sql(compiler, connection, **extra_context)
- with suppress(FieldError):
+ try:
if self.output_field.get_internal_type() == 'DecimalField':
sql = 'CAST(%s AS NUMERIC)' % sql
+ except FieldError:
+ pass
return sql, params
diff --git a/django/db/models/options.py b/django/db/models/options.py
index c81a61c916..9f0746bd58 100644
--- a/django/db/models/options.py
+++ b/django/db/models/options.py
@@ -3,7 +3,6 @@ import inspect
import warnings
from bisect import bisect
from collections import OrderedDict, defaultdict
-from contextlib import suppress
from django.apps import apps
from django.conf import settings
@@ -269,8 +268,10 @@ class Options:
# is a cached property, and all the models haven't been loaded yet, so
# we need to make sure we don't cache a string reference.
if field.is_relation and hasattr(field.remote_field, 'model') and field.remote_field.model:
- with suppress(AttributeError):
+ try:
field.remote_field.model._meta._expire_cache(forward=False)
+ except AttributeError:
+ pass
self._expire_cache()
else:
self._expire_cache(reverse=False)
@@ -518,8 +519,10 @@ class Options:
# Due to the way Django's internals work, get_field() should also
# be able to fetch a field by attname. In the case of a concrete
# field with relation, includes the *_id name too
- with suppress(AttributeError):
+ try:
res[field.attname] = field
+ except AttributeError:
+ pass
return res
@cached_property
@@ -531,8 +534,10 @@ class Options:
# Due to the way Django's internals work, get_field() should also
# be able to fetch a field by attname. In the case of a concrete
# field with relation, includes the *_id name too
- with suppress(AttributeError):
+ try:
res[field.attname] = field
+ except AttributeError:
+ pass
return res
def get_field(self, field_name):
@@ -749,10 +754,12 @@ class Options:
# Creates a cache key composed of all arguments
cache_key = (forward, reverse, include_parents, include_hidden, topmost_call)
- with suppress(KeyError):
+ try:
# In order to avoid list manipulation. Always return a shallow copy
# of the results.
return self._get_fields_cache[cache_key]
+ except KeyError:
+ pass
fields = []
# Recursively call _get_fields() on each parent, with the same
diff --git a/django/db/models/query.py b/django/db/models/query.py
index a690ba4b72..42fb728190 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -7,7 +7,6 @@ import operator
import sys
import warnings
from collections import OrderedDict, namedtuple
-from contextlib import suppress
from functools import lru_cache
from itertools import chain
@@ -521,8 +520,10 @@ class QuerySet:
return obj, True
except IntegrityError:
exc_info = sys.exc_info()
- with suppress(self.model.DoesNotExist):
+ try:
return self.get(**lookup), False
+ except self.model.DoesNotExist:
+ pass
raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
def _extract_model_params(self, defaults, **kwargs):
@@ -1337,8 +1338,11 @@ class RawQuerySet:
# Adjust any column names which don't match field names
for (query_name, model_name) in self.translations.items():
# Ignore translations for nonexistent column names
- with suppress(ValueError):
+ try:
index = columns.index(query_name)
+ except ValueError:
+ pass
+ else:
columns[index] = model_name
return columns
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 509d97e65d..017edea873 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -7,7 +7,6 @@ databases). The abstraction barrier only works one way: this module has to know
all about the internals of models in order to get the information it needs.
"""
from collections import Counter, Iterator, Mapping, OrderedDict, namedtuple
-from contextlib import suppress
from itertools import chain, count, product
from string import ascii_uppercase
@@ -313,8 +312,10 @@ class Query:
obj.subq_aliases = self.subq_aliases.copy()
obj.used_aliases = self.used_aliases.copy()
# Clear the cached_property
- with suppress(AttributeError):
+ try:
del obj.base_table
+ except AttributeError:
+ pass
return obj
def chain(self, klass=None):
diff --git a/django/forms/fields.py b/django/forms/fields.py
index 805018786a..9246676527 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -9,7 +9,6 @@ import math
import os
import re
import uuid
-from contextlib import suppress
from decimal import Decimal, DecimalException
from io import BytesIO
from urllib.parse import urlsplit, urlunsplit
@@ -1093,7 +1092,7 @@ class FilePathField(ChoiceField):
f = os.path.join(root, f)
self.choices.append((f, f.replace(path, "", 1)))
else:
- with suppress(OSError):
+ try:
for f in sorted(os.listdir(self.path)):
if f == '__pycache__':
continue
@@ -1102,6 +1101,8 @@ class FilePathField(ChoiceField):
(self.allow_folders and os.path.isdir(full_file))) and
(self.match is None or self.match_re.search(f))):
self.choices.append((full_file, f))
+ except OSError:
+ pass
self.widget.choices = self.choices
diff --git a/django/forms/forms.py b/django/forms/forms.py
index 0b434b24f8..e2e7c645ff 100644
--- a/django/forms/forms.py
+++ b/django/forms/forms.py
@@ -4,7 +4,6 @@ Form classes
import copy
from collections import OrderedDict
-from contextlib import suppress
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
# BoundField is imported for backwards compatibility in Django 1.9
@@ -126,8 +125,10 @@ class BaseForm:
return
fields = OrderedDict()
for key in field_order:
- with suppress(KeyError): # ignore unknown fields
+ try:
fields[key] = self.fields.pop(key)
+ except KeyError: # ignore unknown fields
+ pass
fields.update(self.fields) # add remaining fields in original order
self.fields = fields
diff --git a/django/forms/formsets.py b/django/forms/formsets.py
index 7332e4b2f4..5133164f7a 100644
--- a/django/forms/formsets.py
+++ b/django/forms/formsets.py
@@ -1,5 +1,3 @@
-from contextlib import suppress
-
from django.core.exceptions import ValidationError
from django.forms import Form
from django.forms.fields import BooleanField, IntegerField
@@ -162,8 +160,10 @@ class BaseFormSet:
defaults['data'] = self.data
defaults['files'] = self.files
if self.initial and 'initial' not in kwargs:
- with suppress(IndexError):
+ try:
defaults['initial'] = self.initial[i]
+ except IndexError:
+ pass
# Allow extra forms to be empty, unless they're part of
# the minimum forms.
if i >= self.initial_form_count() and i >= self.min_num:
diff --git a/django/forms/models.py b/django/forms/models.py
index ffa8982506..4435bf9722 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -4,7 +4,6 @@ and database field objects.
"""
from collections import OrderedDict
-from contextlib import suppress
from itertools import chain
from django.core.exceptions import (
@@ -615,8 +614,10 @@ class BaseModelFormSet(BaseFormSet):
kwargs['instance'] = self.get_queryset()[i]
elif self.initial_extra:
# Set initial values for extra forms
- with suppress(IndexError):
+ try:
kwargs['initial'] = self.initial_extra[i - self.initial_form_count()]
+ except IndexError:
+ pass
form = super()._construct_form(i, **kwargs)
if pk_required:
form.fields[self.model._meta.pk.name].required = True
diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index dbb3b2e851..47396213d9 100644
--- a/django/forms/widgets.py
+++ b/django/forms/widgets.py
@@ -6,7 +6,6 @@ import copy
import datetime
import re
import warnings
-from contextlib import suppress
from itertools import chain
from django.conf import settings
@@ -651,8 +650,10 @@ class ChoiceWidget(Widget):
def value_from_datadict(self, data, files, name):
getter = data.get
if self.allow_multiple_selected:
- with suppress(AttributeError):
+ try:
getter = data.getlist
+ except AttributeError:
+ pass
return getter(name)
def format_value(self, value):
diff --git a/django/http/response.py b/django/http/response.py
index 384de9fb84..1083fd7dca 100644
--- a/django/http/response.py
+++ b/django/http/response.py
@@ -3,7 +3,6 @@ import json
import re
import sys
import time
-from contextlib import suppress
from email.header import Header
from http.client import responses
from urllib.parse import urlparse
@@ -137,8 +136,10 @@ class HttpResponseBase:
self._headers[header.lower()] = (header, value)
def __delitem__(self, header):
- with suppress(KeyError):
+ try:
del self._headers[header.lower()]
+ except KeyError:
+ pass
def __getitem__(self, header):
return self._headers[header.lower()][1]
@@ -237,8 +238,10 @@ class HttpResponseBase:
# See http://blog.dscpl.com.au/2012/10/obligations-for-calling-close-on.html
def close(self):
for closable in self._closable_objects:
- with suppress(Exception):
+ try:
closable.close()
+ except Exception:
+ pass
self.closed = True
signals.request_finished.send(sender=self._handler_class)
@@ -304,8 +307,10 @@ class HttpResponse(HttpResponseBase):
if hasattr(value, '__iter__') and not isinstance(value, (bytes, str)):
content = b''.join(self.make_bytes(chunk) for chunk in value)
if hasattr(value, 'close'):
- with suppress(Exception):
+ try:
value.close()
+ except Exception:
+ pass
else:
content = self.make_bytes(value)
# Create a list of properly encoded bytestrings to support write().
diff --git a/django/template/backends/base.py b/django/template/backends/base.py
index 4156365b97..c47c95e51e 100644
--- a/django/template/backends/base.py
+++ b/django/template/backends/base.py
@@ -1,5 +1,3 @@
-from contextlib import suppress
-
from django.core.exceptions import (
ImproperlyConfigured, SuspiciousFileOperation,
)
@@ -75,8 +73,9 @@ class BaseEngine:
directory traversal attacks.
"""
for template_dir in self.template_dirs:
- # SuspiciousFileOperation occurs if the jointed path is located
- # outside of this template_dir (it might be inside another one,
- # so this isn't fatal).
- with suppress(SuspiciousFileOperation):
+ try:
yield safe_join(template_dir, template_name)
+ except SuspiciousFileOperation:
+ # The joined path was located outside of this template_dir
+ # (it might be inside another one, so this isn't fatal).
+ pass
diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py
index b18b41c293..b172be6239 100644
--- a/django/template/defaultfilters.py
+++ b/django/template/defaultfilters.py
@@ -1,7 +1,6 @@
"""Default variable filters."""
import random as random_module
import re
-from contextlib import suppress
from decimal import ROUND_HALF_UP, Context, Decimal, InvalidOperation
from functools import wraps
from operator import itemgetter
@@ -609,7 +608,7 @@ def unordered_list(value, autoescape=True):
def walk_items(item_list):
item_iterator = iter(item_list)
- with suppress(StopIteration):
+ try:
item = next(item_iterator)
while True:
try:
@@ -628,6 +627,8 @@ def unordered_list(value, autoescape=True):
continue
yield item, None
item = next_item
+ except StopIteration:
+ pass
def list_formatter(item_list, tabs=1):
indent = '\t' * tabs
@@ -877,9 +878,11 @@ def pluralize(value, arg='s'):
except ValueError: # Invalid string that's not a number.
pass
except TypeError: # Value isn't a string or a number; maybe it's a list?
- with suppress(TypeError): # len() of unsized object.
+ try:
if len(value) != 1:
return plural_suffix
+ except TypeError: # len() of unsized object.
+ pass
return singular_suffix
diff --git a/django/test/signals.py b/django/test/signals.py
index 3507c69add..a623e756ce 100644
--- a/django/test/signals.py
+++ b/django/test/signals.py
@@ -2,7 +2,6 @@ import os
import threading
import time
import warnings
-from contextlib import suppress
from django.apps import apps
from django.core.exceptions import ImproperlyConfigured
@@ -64,10 +63,14 @@ def update_connections_time_zone(**kwargs):
# Reset the database connections' time zone
if kwargs['setting'] in {'TIME_ZONE', 'USE_TZ'}:
for conn in connections.all():
- with suppress(AttributeError):
+ try:
del conn.timezone
- with suppress(AttributeError):
+ except AttributeError:
+ pass
+ try:
del conn.timezone_name
+ except AttributeError:
+ pass
conn.ensure_timezone()
@@ -86,8 +89,10 @@ def reset_template_engines(**kwargs):
'INSTALLED_APPS',
}:
from django.template import engines
- with suppress(AttributeError):
+ try:
del engines.templates
+ except AttributeError:
+ pass
engines._templates = None
engines._engines = {}
from django.template.engine import Engine
diff --git a/django/urls/base.py b/django/urls/base.py
index 26084dbe3e..6dccdd2e7d 100644
--- a/django/urls/base.py
+++ b/django/urls/base.py
@@ -1,4 +1,3 @@
-from contextlib import suppress
from threading import local
from urllib.parse import urlsplit, urlunsplit
@@ -54,7 +53,7 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None):
ns = path.pop()
current_ns = current_path.pop() if current_path else None
# Lookup the name to see if it could be an app identifier.
- with suppress(KeyError):
+ try:
app_list = resolver.app_dict[ns]
# Yes! Path part matches an app in the current Resolver.
if current_ns and current_ns in app_list:
@@ -65,6 +64,8 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None):
# The name isn't shared by one of the instances (i.e.,
# the default) so pick the first instance as the default.
ns = app_list[0]
+ except KeyError:
+ pass
if ns != current_ns:
current_path = None
@@ -118,8 +119,10 @@ def clear_script_prefix():
"""
Unset the script prefix for the current thread.
"""
- with suppress(AttributeError):
+ try:
del _prefixes.value
+ except AttributeError:
+ pass
def set_urlconf(urlconf_name):
diff --git a/django/utils/autoreload.py b/django/utils/autoreload.py
index a872d42d65..2784a89aeb 100644
--- a/django/utils/autoreload.py
+++ b/django/utils/autoreload.py
@@ -34,7 +34,6 @@ import subprocess
import sys
import time
import traceback
-from contextlib import suppress
import _thread
@@ -44,8 +43,10 @@ from django.core.signals import request_finished
# This import does nothing, but it's necessary to avoid some race conditions
# in the threading module. See http://code.djangoproject.com/ticket/2330 .
-with suppress(ImportError):
+try:
import threading # NOQA
+except ImportError:
+ pass
try:
import termios
@@ -53,7 +54,7 @@ except ImportError:
termios = None
USE_INOTIFY = False
-with suppress(ImportError):
+try:
# Test whether inotify is enabled and likely to work
import pyinotify
@@ -61,6 +62,8 @@ with suppress(ImportError):
if fd >= 0:
USE_INOTIFY = True
os.close(fd)
+except ImportError:
+ pass
RUN_RELOADER = True
@@ -207,8 +210,10 @@ def code_changed():
continue
if mtime != _mtimes[filename]:
_mtimes = {}
- with suppress(ValueError):
+ try:
del _error_files[_error_files.index(filename)]
+ except ValueError:
+ pass
return I18N_MODIFIED if filename.endswith('.mo') else FILE_MODIFIED
return False
@@ -287,15 +292,19 @@ def restart_with_reloader():
def python_reloader(main_func, args, kwargs):
if os.environ.get("RUN_MAIN") == "true":
_thread.start_new_thread(main_func, args, kwargs)
- with suppress(KeyboardInterrupt):
+ try:
reloader_thread()
+ except KeyboardInterrupt:
+ pass
else:
- with suppress(KeyboardInterrupt):
+ try:
exit_code = restart_with_reloader()
if exit_code < 0:
os.kill(os.getpid(), -exit_code)
else:
sys.exit(exit_code)
+ except KeyboardInterrupt:
+ pass
def jython_reloader(main_func, args, kwargs):
diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py
index 7713b08e8c..127c6dc774 100644
--- a/django/utils/datastructures.py
+++ b/django/utils/datastructures.py
@@ -1,6 +1,5 @@
import copy
from collections import OrderedDict
-from contextlib import suppress
class OrderedSet:
@@ -19,8 +18,10 @@ class OrderedSet:
del self.dict[item]
def discard(self, item):
- with suppress(KeyError):
+ try:
self.remove(item)
+ except KeyError:
+ pass
def __iter__(self):
return iter(self.dict)
diff --git a/django/utils/dateformat.py b/django/utils/dateformat.py
index d811e83965..d3f586aacf 100644
--- a/django/utils/dateformat.py
+++ b/django/utils/dateformat.py
@@ -14,7 +14,6 @@ import calendar
import datetime
import re
import time
-from contextlib import suppress
from django.utils.dates import (
MONTHS, MONTHS_3, MONTHS_ALT, MONTHS_AP, WEEKDAYS, WEEKDAYS_ABBR,
@@ -82,9 +81,11 @@ class TimeFormat(Formatter):
if not self.timezone:
return ""
- with suppress(NotImplementedError):
+ try:
if hasattr(self.data, 'tzinfo') and self.data.tzinfo:
return self.data.tzname() or ''
+ except NotImplementedError:
+ pass
return ""
def f(self):
@@ -165,11 +166,13 @@ class TimeFormat(Formatter):
return ""
name = None
- with suppress(Exception):
+ try:
+ name = self.timezone.tzname(self.data)
+ except Exception:
# pytz raises AmbiguousTimeError during the autumn DST change.
# This happens mainly when __init__ receives a naive datetime
# and sets self.timezone = get_default_timezone().
- name = self.timezone.tzname(self.data)
+ pass
if name is None:
name = self.format('O')
return str(name)
diff --git a/django/utils/formats.py b/django/utils/formats.py
index 33865d93a8..f19449ec1e 100644
--- a/django/utils/formats.py
+++ b/django/utils/formats.py
@@ -1,7 +1,6 @@
import datetime
import decimal
import unicodedata
-from contextlib import suppress
from importlib import import_module
from django.conf import settings
@@ -80,8 +79,10 @@ def iter_format_modules(lang, format_module_path=None):
locales.append(locale.split('_')[0])
for location in format_locations:
for loc in locales:
- with suppress(ImportError):
+ try:
yield import_module('%s.formats' % (location % loc))
+ except ImportError:
+ pass
def get_format_modules(lang=None, reverse=False):
@@ -109,8 +110,10 @@ def get_format(format_type, lang=None, use_l10n=None):
if use_l10n and lang is None:
lang = get_language()
cache_key = (format_type, lang)
- with suppress(KeyError):
+ try:
return _format_cache[cache_key]
+ except KeyError:
+ pass
# The requested format_type has not been cached yet. Try to find it in any
# of the format_modules for the given lang if l10n is enabled. If it's not
diff --git a/django/utils/http.py b/django/utils/http.py
index 0870f1f180..07b6ae246a 100644
--- a/django/utils/http.py
+++ b/django/utils/http.py
@@ -5,7 +5,6 @@ import re
import unicodedata
import warnings
from binascii import Error as BinasciiError
-from contextlib import suppress
from email.utils import formatdate
from urllib.parse import (
ParseResult, SplitResult, _coerce_args, _splitnetloc, _splitparams, quote,
@@ -166,8 +165,10 @@ def parse_http_date_safe(date):
"""
Same as parse_http_date, but return None if the input is invalid.
"""
- with suppress(Exception):
+ try:
return parse_http_date(date)
+ except Exception:
+ pass
# Base 36 functions: useful for generating compact URLs
diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py
index 4a6840782c..b4586885c4 100644
--- a/django/utils/translation/__init__.py
+++ b/django/utils/translation/__init__.py
@@ -3,7 +3,7 @@ Internationalization support.
"""
import re
import warnings
-from contextlib import ContextDecorator, suppress
+from contextlib import ContextDecorator
from django.utils.deprecation import RemovedInDjango21Warning
from django.utils.functional import lazy
@@ -126,9 +126,11 @@ def lazy_number(func, resultclass, number=None, **kwargs):
number_value = rhs
kwargs['number'] = number_value
translated = func(**kwargs)
- # String may not contain a placeholder for the number.
- with suppress(TypeError):
+ try:
translated = translated % rhs
+ except TypeError:
+ # String doesn't contain a placeholder for the number.
+ pass
return translated
proxy = lazy(lambda **kwargs: NumberAwareString(), NumberAwareString)(**kwargs)
diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py
index f36c21f0a1..6b3aeb127e 100644
--- a/django/utils/translation/trans_real.py
+++ b/django/utils/translation/trans_real.py
@@ -6,7 +6,6 @@ import re
import sys
import warnings
from collections import OrderedDict
-from contextlib import suppress
from threading import local
from django.apps import apps
@@ -257,8 +256,10 @@ def get_language():
"""Return the currently selected language."""
t = getattr(_active, "value", None)
if t is not None:
- with suppress(AttributeError):
+ try:
return t.to_language()
+ except AttributeError:
+ pass
# If we don't have a real translation object, assume it's the default language.
return settings.LANGUAGE_CODE
@@ -424,8 +425,10 @@ def get_supported_language_variant(lang_code, strict=False):
if lang_code:
# If 'fr-ca' is not supported, try special fallback or language-only 'fr'.
possible_lang_codes = [lang_code]
- with suppress(KeyError):
+ try:
possible_lang_codes.extend(LANG_INFO[lang_code]['fallback'])
+ except KeyError:
+ pass
generic_lang_code = lang_code.split('-')[0]
possible_lang_codes.append(generic_lang_code)
supported_lang_codes = get_languages()
@@ -483,8 +486,10 @@ def get_language_from_request(request, check_path=False):
lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME)
- with suppress(LookupError):
+ try:
return get_supported_language_variant(lang_code)
+ except LookupError:
+ pass
accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
for accept_lang, unused in parse_accept_lang_header(accept):
diff --git a/django/views/debug.py b/django/views/debug.py
index 35cff6338f..a0af0c96f4 100644
--- a/django/views/debug.py
+++ b/django/views/debug.py
@@ -2,7 +2,6 @@ import functools
import re
import sys
import types
-from contextlib import suppress
from pathlib import Path
from django.conf import settings
@@ -348,14 +347,18 @@ class ExceptionReporter:
"""
source = None
if loader is not None and hasattr(loader, "get_source"):
- with suppress(ImportError):
+ try:
source = loader.get_source(module_name)
+ except ImportError:
+ pass
if source is not None:
source = source.splitlines()
if source is None:
- with suppress(OSError, IOError):
+ try:
with open(filename, 'rb') as fp:
source = fp.read().splitlines()
+ except (OSError, IOError):
+ pass
if source is None:
return None, [], None, []
diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py
index b8bcea35f0..096984032f 100644
--- a/tests/admin_scripts/tests.py
+++ b/tests/admin_scripts/tests.py
@@ -12,7 +12,6 @@ import subprocess
import sys
import tempfile
import unittest
-from contextlib import suppress
from io import StringIO
from unittest import mock
@@ -96,10 +95,12 @@ class AdminScriptTestCase(unittest.TestCase):
# Also try to remove the compiled file; if it exists, it could
# mess up later tests that depend upon the .py file not existing
- with suppress(OSError):
+ try:
if sys.platform.startswith('java'):
# Jython produces module$py.class files
os.remove(re.sub(r'\.py$', '$py.class', full_name))
+ except OSError:
+ pass
# Also remove a __pycache__ directory, if it exists
cache_name = os.path.join(self.test_dir, '__pycache__')
if os.path.isdir(cache_name):
@@ -165,8 +166,10 @@ class AdminScriptTestCase(unittest.TestCase):
def run_manage(self, args, settings_file=None):
def safe_remove(path):
- with suppress(OSError):
+ try:
os.remove(path)
+ except OSError:
+ pass
conf_dir = os.path.dirname(conf.__file__)
template_manage_py = os.path.join(conf_dir, 'project_template', 'manage.py-tpl')
diff --git a/tests/backends/tests.py b/tests/backends/tests.py
index 30c1cbf86d..6d38625a98 100644
--- a/tests/backends/tests.py
+++ b/tests/backends/tests.py
@@ -3,7 +3,6 @@ import datetime
import threading
import unittest
import warnings
-from contextlib import suppress
from django.core.management.color import no_style
from django.db import (
@@ -390,8 +389,10 @@ class BackendTestCase(TransactionTestCase):
finally:
# Clean up the mess created by connection._close(). Since the
# connection is already closed, this crashes on some backends.
- with suppress(Exception):
+ try:
connection.close()
+ except Exception:
+ pass
@override_settings(DEBUG=True)
def test_queries(self):
diff --git a/tests/bash_completion/tests.py b/tests/bash_completion/tests.py
index ba2a5ea773..1d35e1f28e 100644
--- a/tests/bash_completion/tests.py
+++ b/tests/bash_completion/tests.py
@@ -4,7 +4,6 @@ A series of tests to establish that the command-line bash completion works.
import os
import sys
import unittest
-from contextlib import suppress
from django.apps import apps
from django.core.management import ManagementUtility
@@ -51,8 +50,10 @@ class BashCompletionTests(unittest.TestCase):
def _run_autocomplete(self):
util = ManagementUtility(argv=sys.argv)
with captured_stdout() as stdout:
- with suppress(SystemExit):
+ try:
util.autocomplete()
+ except SystemExit:
+ pass
return stdout.getvalue().strip().split('\n')
def test_django_admin_py(self):
diff --git a/tests/handlers/views.py b/tests/handlers/views.py
index 3c1fa5b802..22b94de3b9 100644
--- a/tests/handlers/views.py
+++ b/tests/handlers/views.py
@@ -1,12 +1,12 @@
-from contextlib import suppress
-
from django.core.exceptions import SuspiciousOperation
from django.db import connection, transaction
from django.http import HttpResponse, StreamingHttpResponse
from django.views.decorators.csrf import csrf_exempt
-with suppress(ImportError): # Python < 3.5
+try:
from http import HTTPStatus
+except ImportError: # Python < 3.5
+ pass
def regular(request):
diff --git a/tests/mail/tests.py b/tests/mail/tests.py
index b759484e04..29a56d6e74 100644
--- a/tests/mail/tests.py
+++ b/tests/mail/tests.py
@@ -8,7 +8,6 @@ import socket
import sys
import tempfile
import threading
-from contextlib import suppress
from email import message_from_binary_file, message_from_bytes
from email.header import Header
from email.mime.text import MIMEText
@@ -1135,10 +1134,12 @@ class ConsoleBackendTests(BaseEmailBackendTests, SimpleTestCase):
class FakeSMTPChannel(smtpd.SMTPChannel):
def collect_incoming_data(self, data):
- # Ignore decode error in SSL/TLS connection tests as the test only
- # cares whether the connection attempt was made.
- with suppress(UnicodeDecodeError):
+ try:
smtpd.SMTPChannel.collect_incoming_data(self, data)
+ except UnicodeDecodeError:
+ # Ignore decode error in SSL/TLS connection tests as the test only
+ # cares whether the connection attempt was made.
+ pass
def smtp_AUTH(self, arg):
if arg == 'CRAM-MD5':
diff --git a/tests/postgres_tests/test_aggregates.py b/tests/postgres_tests/test_aggregates.py
index 1fe8a1bf03..056d08441b 100644
--- a/tests/postgres_tests/test_aggregates.py
+++ b/tests/postgres_tests/test_aggregates.py
@@ -1,5 +1,4 @@
import json
-from contextlib import suppress
from django.db.models.expressions import F, Value
from django.test.testcases import skipUnlessDBFeature
@@ -8,12 +7,14 @@ from django.test.utils import Approximate
from . import PostgreSQLTestCase
from .models import AggregateTestModel, StatTestModel
-with suppress(ImportError): # psycopg2 is not installed
+try:
from django.contrib.postgres.aggregates import (
ArrayAgg, BitAnd, BitOr, BoolAnd, BoolOr, Corr, CovarPop, JSONBAgg,
RegrAvgX, RegrAvgY, RegrCount, RegrIntercept, RegrR2, RegrSlope,
RegrSXX, RegrSXY, RegrSYY, StatAggregate, StringAgg,
)
+except ImportError:
+ pass # psycopg2 is not installed
class TestGeneralAggregate(PostgreSQLTestCase):
diff --git a/tests/postgres_tests/test_array.py b/tests/postgres_tests/test_array.py
index 7378b5c12d..e2e4ccdeb2 100644
--- a/tests/postgres_tests/test_array.py
+++ b/tests/postgres_tests/test_array.py
@@ -2,7 +2,6 @@ import decimal
import json
import unittest
import uuid
-from contextlib import suppress
from django import forms
from django.core import exceptions, serializers, validators
@@ -20,11 +19,13 @@ from .models import (
PostgreSQLModel, Tag,
)
-with suppress(ImportError):
+try:
from django.contrib.postgres.fields import ArrayField
from django.contrib.postgres.forms import (
SimpleArrayField, SplitArrayField, SplitArrayWidget,
)
+except ImportError:
+ pass
class TestSaveLoad(PostgreSQLTestCase):
diff --git a/tests/postgres_tests/test_hstore.py b/tests/postgres_tests/test_hstore.py
index 55b179ba5e..069e570f51 100644
--- a/tests/postgres_tests/test_hstore.py
+++ b/tests/postgres_tests/test_hstore.py
@@ -1,5 +1,4 @@
import json
-from contextlib import suppress
from django.core import exceptions, serializers
from django.forms import Form
@@ -8,10 +7,12 @@ from django.test.utils import modify_settings
from . import PostgreSQLTestCase
from .models import HStoreModel
-with suppress(ImportError):
+try:
from django.contrib.postgres import forms
from django.contrib.postgres.fields import HStoreField
from django.contrib.postgres.validators import KeysValidator
+except ImportError:
+ pass
@modify_settings(INSTALLED_APPS={'append': 'django.contrib.postgres'})
diff --git a/tests/postgres_tests/test_json.py b/tests/postgres_tests/test_json.py
index 20650ae95b..2506fc36d6 100644
--- a/tests/postgres_tests/test_json.py
+++ b/tests/postgres_tests/test_json.py
@@ -1,6 +1,5 @@
import datetime
import uuid
-from contextlib import suppress
from decimal import Decimal
from django.core import exceptions, serializers
@@ -12,9 +11,11 @@ from django.utils.html import escape
from . import PostgreSQLTestCase
from .models import JSONModel
-with suppress(ImportError):
+try:
from django.contrib.postgres import forms
from django.contrib.postgres.fields import JSONField
+except ImportError:
+ pass
@skipUnlessDBFeature('has_jsonb_datatype')
diff --git a/tests/postgres_tests/test_ranges.py b/tests/postgres_tests/test_ranges.py
index da72240bf4..d87ad36438 100644
--- a/tests/postgres_tests/test_ranges.py
+++ b/tests/postgres_tests/test_ranges.py
@@ -1,6 +1,5 @@
import datetime
import json
-from contextlib import suppress
from django import forms
from django.core import exceptions, serializers
@@ -11,12 +10,14 @@ from django.utils import timezone
from . import PostgreSQLTestCase
from .models import RangeLookupsModel, RangesModel
-with suppress(ImportError):
+try:
from psycopg2.extras import DateRange, DateTimeTZRange, NumericRange
from django.contrib.postgres import fields as pg_fields, forms as pg_forms
from django.contrib.postgres.validators import (
RangeMaxValueValidator, RangeMinValueValidator,
)
+except ImportError:
+ pass
class TestSaveLoad(PostgreSQLTestCase):
diff --git a/tests/runtests.py b/tests/runtests.py
index 08e53f4cb1..7f4f1670c5 100755
--- a/tests/runtests.py
+++ b/tests/runtests.py
@@ -8,7 +8,6 @@ import subprocess
import sys
import tempfile
import warnings
-from contextlib import suppress
import django
from django.apps import apps
@@ -316,8 +315,10 @@ def bisect_tests(bisection_label, options, test_labels, parallel):
# Make sure the bisection point isn't in the test list
# Also remove tests that need to be run in specific combinations
for label in [bisection_label, 'model_inheritance_same_model_name']:
- with suppress(ValueError):
+ try:
test_labels.remove(label)
+ except ValueError:
+ pass
subprocess_args = get_subprocess_args(options)
@@ -365,8 +366,10 @@ def paired_tests(paired_test, options, test_labels, parallel):
# Make sure the constant member of the pair isn't in the test list
# Also remove tests that need to be run in specific combinations
for label in [paired_test, 'model_inheritance_same_model_name']:
- with suppress(ValueError):
+ try:
test_labels.remove(label)
+ except ValueError:
+ pass
subprocess_args = get_subprocess_args(options)
diff --git a/tests/staticfiles_tests/storage.py b/tests/staticfiles_tests/storage.py
index 0dcfd77a70..7a1f72c130 100644
--- a/tests/staticfiles_tests/storage.py
+++ b/tests/staticfiles_tests/storage.py
@@ -1,5 +1,4 @@
import os
-from contextlib import suppress
from datetime import datetime, timedelta
from django.conf import settings
@@ -49,8 +48,10 @@ class PathNotImplementedStorage(storage.Storage):
def delete(self, name):
name = self._path(name)
- with suppress(FileNotFoundError):
+ try:
os.remove(name)
+ except FileNotFoundError:
+ pass
def path(self, name):
raise NotImplementedError
diff --git a/tests/transaction_hooks/tests.py b/tests/transaction_hooks/tests.py
index ed3cf18be2..81ff0066a1 100644
--- a/tests/transaction_hooks/tests.py
+++ b/tests/transaction_hooks/tests.py
@@ -1,5 +1,3 @@
-from contextlib import suppress
-
from django.db import connection, transaction
from django.test import TransactionTestCase, skipUnlessDBFeature
@@ -50,10 +48,12 @@ class TestConnectionOnCommit(TransactionTestCase):
self.assertDone([1])
def test_does_not_execute_if_transaction_rolled_back(self):
- with suppress(ForcedError):
+ try:
with transaction.atomic():
self.do(1)
raise ForcedError()
+ except ForcedError:
+ pass
self.assertDone([])
@@ -71,10 +71,12 @@ class TestConnectionOnCommit(TransactionTestCase):
with transaction.atomic():
self.do(1)
# one failed savepoint
- with suppress(ForcedError):
+ try:
with transaction.atomic():
self.do(2)
raise ForcedError()
+ except ForcedError:
+ pass
# another successful savepoint
with transaction.atomic():
self.do(3)
@@ -84,21 +86,25 @@ class TestConnectionOnCommit(TransactionTestCase):
def test_no_hooks_run_from_failed_transaction(self):
"""If outer transaction fails, no hooks from within it run."""
- with suppress(ForcedError):
+ try:
with transaction.atomic():
with transaction.atomic():
self.do(1)
raise ForcedError()
+ except ForcedError:
+ pass
self.assertDone([])
def test_inner_savepoint_rolled_back_with_outer(self):
with transaction.atomic():
- with suppress(ForcedError):
+ try:
with transaction.atomic():
with transaction.atomic():
self.do(1)
raise ForcedError()
+ except ForcedError:
+ pass
self.do(2)
self.assertDone([2])
@@ -107,9 +113,11 @@ class TestConnectionOnCommit(TransactionTestCase):
with transaction.atomic():
with transaction.atomic():
self.do(1)
- with suppress(ForcedError):
+ try:
with transaction.atomic(savepoint=False):
raise ForcedError()
+ except ForcedError:
+ pass
self.assertDone([])
@@ -117,9 +125,11 @@ class TestConnectionOnCommit(TransactionTestCase):
with transaction.atomic():
with transaction.atomic():
self.do(1)
- with suppress(ForcedError):
+ try:
with transaction.atomic():
raise ForcedError()
+ except ForcedError:
+ pass
self.assertDone([1])
@@ -141,10 +151,12 @@ class TestConnectionOnCommit(TransactionTestCase):
self.assertDone([1, 2]) # not [1, 1, 2]
def test_hooks_cleared_after_rollback(self):
- with suppress(ForcedError):
+ try:
with transaction.atomic():
self.do(1)
raise ForcedError()
+ except ForcedError:
+ pass
with transaction.atomic():
self.do(2)
@@ -165,9 +177,11 @@ class TestConnectionOnCommit(TransactionTestCase):
self.assertDone([2])
def test_error_in_hook_doesnt_prevent_clearing_hooks(self):
- with suppress(ForcedError):
+ try:
with transaction.atomic():
transaction.on_commit(lambda: self.notify('error'))
+ except ForcedError:
+ pass
with transaction.atomic():
self.do(1)