Reverted "Fixed #27818 -- Replaced try/except/pass with contextlib.suppress()."

This reverts commit 550cb3a365
because try/except performs better.
This commit is contained in:
Tim Graham 2017-09-07 08:16:21 -04:00 committed by GitHub
parent 8b2515a450
commit 6e4c6281db
66 changed files with 351 additions and 207 deletions

View File

@ -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

View File

@ -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)

View File

@ -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):

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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):

View File

@ -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)

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 "

View File

@ -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)

View File

@ -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)

View File

@ -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,

View File

@ -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):
"""

View File

@ -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)

View File

@ -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:

View File

@ -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))

View File

@ -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

View File

@ -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):
"""

View File

@ -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,

View File

@ -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))

View File

@ -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):

View File

@ -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)

View File

@ -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 '

View File

@ -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):

View File

@ -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:

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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):

View File

@ -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().

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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):

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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):

View File

@ -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, []

View File

@ -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')

View File

@ -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):

View File

@ -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):

View File

@ -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):

View File

@ -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':

View File

@ -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):

View File

@ -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):

View File

@ -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'})

View File

@ -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')

View File

@ -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):

View File

@ -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)

View File

@ -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

View File

@ -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)