diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 20bce0c8d6..b48d007409 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -1,4 +1,3 @@ -import sys from collections import OrderedDict from django.contrib.admin import FieldListFilter @@ -17,7 +16,6 @@ from django.core.exceptions import ( from django.core.paginator import InvalidPage from django.db import models from django.urls import reverse -from django.utils import six from django.utils.encoding import force_text from django.utils.http import urlencode from django.utils.translation import ugettext @@ -151,7 +149,7 @@ class ChangeList: use_distinct = use_distinct or lookup_needs_distinct(self.lookup_opts, key) return filter_specs, bool(filter_specs), lookup_params, use_distinct except FieldDoesNotExist as e: - six.reraise(IncorrectLookupParameters, IncorrectLookupParameters(e), sys.exc_info()[2]) + raise IncorrectLookupParameters(e) from e def get_query_string(self, new_params=None, remove=None): if new_params is None: diff --git a/django/contrib/gis/db/backends/oracle/introspection.py b/django/contrib/gis/db/backends/oracle/introspection.py index 764ce7d243..886441a9d0 100644 --- a/django/contrib/gis/db/backends/oracle/introspection.py +++ b/django/contrib/gis/db/backends/oracle/introspection.py @@ -1,9 +1,6 @@ -import sys - import cx_Oracle from django.db.backends.oracle.introspection import DatabaseIntrospection -from django.utils import six class OracleIntrospection(DatabaseIntrospection): @@ -24,12 +21,11 @@ class OracleIntrospection(DatabaseIntrospection): (table_name.upper(), geo_col.upper()) ) row = cursor.fetchone() - except Exception as msg: - new_msg = ( + except Exception as exc: + raise Exception( 'Could not find entry in USER_SDO_GEOM_METADATA ' - 'corresponding to "%s"."%s"\n' - 'Error message: %s.') % (table_name, geo_col, msg) - six.reraise(Exception, Exception(new_msg), sys.exc_info()[2]) + 'corresponding to "%s"."%s"' % (table_name, geo_col) + ) from exc # TODO: Research way to find a more specific geometry field type for # the column's contents. diff --git a/django/contrib/gis/db/backends/spatialite/base.py b/django/contrib/gis/db/backends/spatialite/base.py index 799e9f1671..287c643ce8 100644 --- a/django/contrib/gis/db/backends/spatialite/base.py +++ b/django/contrib/gis/db/backends/spatialite/base.py @@ -1,4 +1,3 @@ -import sys from ctypes.util import find_library from django.conf import settings @@ -6,7 +5,6 @@ from django.core.exceptions import ImproperlyConfigured from django.db.backends.sqlite3.base import ( DatabaseWrapper as SQLiteDatabaseWrapper, SQLiteCursorWrapper, ) -from django.utils import six from .client import SpatiaLiteClient from .features import DatabaseFeatures @@ -53,11 +51,10 @@ class DatabaseWrapper(SQLiteDatabaseWrapper): cur = conn.cursor(factory=SQLiteCursorWrapper) try: cur.execute("SELECT load_extension(%s)", (self.spatialite_lib,)) - except Exception as msg: - new_msg = ( - 'Unable to load the SpatiaLite library extension ' - '"%s" because: %s') % (self.spatialite_lib, msg) - six.reraise(ImproperlyConfigured, ImproperlyConfigured(new_msg), sys.exc_info()[2]) + except Exception as exc: + raise ImproperlyConfigured( + 'Unable to load the SpatiaLite library extension "%s"' % self.spatialite_lib + ) from exc cur.close() return conn diff --git a/django/contrib/gis/db/backends/spatialite/operations.py b/django/contrib/gis/db/backends/spatialite/operations.py index cc46b4b91f..5fab0b4df7 100644 --- a/django/contrib/gis/db/backends/spatialite/operations.py +++ b/django/contrib/gis/db/backends/spatialite/operations.py @@ -4,7 +4,6 @@ https://web.archive.org/web/20130407175746/http://www.gaia-gis.it/gaia-sins/spat http://www.gaia-gis.it/gaia-sins/spatialite-sql-4.2.1.html """ import re -import sys from django.contrib.gis.db.backends.base.operations import \ BaseSpatialOperations @@ -15,7 +14,6 @@ from django.contrib.gis.geometry.backend import Geometry from django.contrib.gis.measure import Distance from django.core.exceptions import ImproperlyConfigured from django.db.backends.sqlite3.operations import DatabaseOperations -from django.utils import six from django.utils.functional import cached_property @@ -123,12 +121,13 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations): """Determine the version of the SpatiaLite library.""" try: version = self.spatialite_version_tuple()[1:] - except Exception as msg: - new_msg = ( - 'Cannot determine the SpatiaLite version for the "%s" ' - 'database (error was "%s"). Was the SpatiaLite initialization ' - 'SQL loaded on this database?') % (self.connection.settings_dict['NAME'], msg) - six.reraise(ImproperlyConfigured, ImproperlyConfigured(new_msg), sys.exc_info()[2]) + except Exception as exc: + raise ImproperlyConfigured( + 'Cannot determine the SpatiaLite version for the "%s" database. ' + 'Was the SpatiaLite initialization SQL loaded on this database?' % ( + self.connection.settings_dict['NAME'], + ) + ) from exc if version < (4, 0, 0): raise ImproperlyConfigured('GeoDjango only supports SpatiaLite versions 4.0.0 and above.') return version diff --git a/django/contrib/gis/utils/layermapping.py b/django/contrib/gis/utils/layermapping.py index 9093ae84d6..621ee49752 100644 --- a/django/contrib/gis/utils/layermapping.py +++ b/django/contrib/gis/utils/layermapping.py @@ -20,7 +20,6 @@ from django.contrib.gis.gdal.field import ( ) from django.core.exceptions import FieldDoesNotExist, ObjectDoesNotExist from django.db import connections, models, router, transaction -from django.utils import six from django.utils.encoding import force_text @@ -456,9 +455,10 @@ class LayerMapping: # Creating the CoordTransform object return CoordTransform(self.source_srs, target_srs) - except Exception as msg: - new_msg = 'Could not translate between the data source and model geometry: %s' % msg - six.reraise(LayerMapError, LayerMapError(new_msg), sys.exc_info()[2]) + except Exception as exc: + raise LayerMapError( + 'Could not translate between the data source and model geometry.' + ) from exc def geometry_field(self): "Returns the GeometryField instance associated with the geographic column." diff --git a/django/core/management/commands/flush.py b/django/core/management/commands/flush.py index 8d1621b116..7a77c38bdd 100644 --- a/django/core/management/commands/flush.py +++ b/django/core/management/commands/flush.py @@ -1,4 +1,3 @@ -import sys from importlib import import_module from django.apps import apps @@ -6,7 +5,6 @@ from django.core.management.base import BaseCommand, CommandError from django.core.management.color import no_style from django.core.management.sql import emit_post_migrate_signal, sql_flush from django.db import DEFAULT_DB_ALIAS, connections, transaction -from django.utils import six class Command(BaseCommand): @@ -67,16 +65,17 @@ Are you sure you want to do this? with connection.cursor() as cursor: for sql in sql_list: cursor.execute(sql) - except Exception as e: - new_msg = ( + except Exception as exc: + raise CommandError( "Database %s couldn't be flushed. Possible reasons:\n" " * The database isn't running or isn't configured correctly.\n" " * At least one of the expected database tables doesn't exist.\n" " * The SQL was invalid.\n" "Hint: Look at the output of 'django-admin sqlflush'. " - "That's the SQL this command wasn't able to run.\n" - "The full error: %s") % (connection.settings_dict['NAME'], e) - six.reraise(CommandError, CommandError(new_msg), sys.exc_info()[2]) + "That's the SQL this command wasn't able to run.\n" % ( + connection.settings_dict['NAME'], + ) + ) from exc # Empty sql_list may signify an empty database and post_migrate would then crash if sql_list and not inhibit_post_migrate: diff --git a/django/core/management/utils.py b/django/core/management/utils.py index 07a14bd731..5903e53341 100644 --- a/django/core/management/utils.py +++ b/django/core/management/utils.py @@ -1,9 +1,7 @@ import os -import sys from subprocess import PIPE, Popen from django.apps import apps as installed_apps -from django.utils import six from django.utils.crypto import get_random_string from django.utils.encoding import DEFAULT_LOCALE_ENCODING, force_text @@ -18,10 +16,8 @@ def popen_wrapper(args, os_err_exc_type=CommandError, stdout_encoding='utf-8'): """ try: p = Popen(args, shell=False, stdout=PIPE, stderr=PIPE, close_fds=os.name != 'nt') - except OSError as e: - strerror = force_text(e.strerror, DEFAULT_LOCALE_ENCODING, strings_only=True) - six.reraise(os_err_exc_type, os_err_exc_type('Error executing %s: %s' % - (args[0], strerror)), sys.exc_info()[2]) + except OSError as err: + raise os_err_exc_type('Error executing %s' % args[0]) from err output, errors = p.communicate() return ( force_text(output, stdout_encoding, strings_only=True, errors='strict'), diff --git a/django/core/serializers/json.py b/django/core/serializers/json.py index b87d807571..79db71cadf 100644 --- a/django/core/serializers/json.py +++ b/django/core/serializers/json.py @@ -5,14 +5,12 @@ Serialize data to/from JSON import datetime import decimal import json -import sys import uuid from django.core.serializers.base import DeserializationError from django.core.serializers.python import ( Deserializer as PythonDeserializer, Serializer as PythonSerializer, ) -from django.utils import six from django.utils.duration import duration_iso_string from django.utils.functional import Promise from django.utils.timezone import is_aware @@ -77,11 +75,10 @@ def Deserializer(stream_or_string, **options): objects = json.loads(stream_or_string) for obj in PythonDeserializer(objects, **options): yield obj - except GeneratorExit: + except (GeneratorExit, DeserializationError): raise - except Exception as e: - # Map to deserializer error - six.reraise(DeserializationError, DeserializationError(e), sys.exc_info()[2]) + except Exception as exc: + raise DeserializationError() from exc class DjangoJSONEncoder(json.JSONEncoder): diff --git a/django/core/serializers/pyyaml.py b/django/core/serializers/pyyaml.py index 16583782b9..89594728cb 100644 --- a/django/core/serializers/pyyaml.py +++ b/django/core/serializers/pyyaml.py @@ -6,7 +6,6 @@ Requires PyYaml (http://pyyaml.org/), but that's checked for in __init__. import collections import decimal -import sys from io import StringIO import yaml @@ -16,7 +15,6 @@ from django.core.serializers.python import ( Deserializer as PythonDeserializer, Serializer as PythonSerializer, ) from django.db import models -from django.utils import six # Use the C (faster) implementation if possible try: @@ -78,8 +76,7 @@ def Deserializer(stream_or_string, **options): try: for obj in PythonDeserializer(yaml.load(stream, Loader=SafeLoader), **options): yield obj - except GeneratorExit: + except (GeneratorExit, DeserializationError): raise - except Exception as e: - # Map to deserializer error - six.reraise(DeserializationError, DeserializationError(e), sys.exc_info()[2]) + except Exception as exc: + raise DeserializationError() from exc diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py index 5a551b8ab1..3e1141122b 100644 --- a/django/core/servers/basehttp.py +++ b/django/core/servers/basehttp.py @@ -15,7 +15,6 @@ from wsgiref import simple_server from django.core.exceptions import ImproperlyConfigured from django.core.wsgi import get_wsgi_application -from django.utils import six from django.utils.module_loading import import_string __all__ = ('WSGIServer', 'WSGIRequestHandler') @@ -43,16 +42,11 @@ def get_internal_wsgi_application(): try: return import_string(app_path) - except ImportError as e: - msg = ( - "WSGI application '%(app_path)s' could not be loaded; " - "Error importing module: '%(exception)s'" % ({ - 'app_path': app_path, - 'exception': e, - }) - ) - six.reraise(ImproperlyConfigured, ImproperlyConfigured(msg), - sys.exc_info()[2]) + except ImportError as err: + raise ImproperlyConfigured( + "WSGI application '%s' could not be loaded; " + "Error importing module." % app_path + ) from err def is_broken_pipe_error(): diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 1b5dc864b0..38c349caea 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -4,23 +4,21 @@ MySQL database backend for Django. Requires mysqlclient: https://pypi.python.org/pypi/mysqlclient/ """ import re -import sys from django.core.exceptions import ImproperlyConfigured from django.db import utils from django.db.backends import utils as backend_utils from django.db.backends.base.base import BaseDatabaseWrapper -from django.utils import six from django.utils.functional import cached_property from django.utils.safestring import SafeBytes, SafeText try: import MySQLdb as Database -except ImportError as e: +except ImportError as err: raise ImproperlyConfigured( - 'Error loading MySQLdb module: %s.\n' - 'Did you install mysqlclient or MySQL-python?' % e - ) + 'Error loading MySQLdb module.\n' + 'Did you install mysqlclient or MySQL-python?' + ) from err from MySQLdb.constants import CLIENT, FIELD_TYPE # isort:skip from MySQLdb.converters import conversions # isort:skip @@ -88,7 +86,7 @@ class CursorWrapper: # Map some error codes to IntegrityError, since they seem to be # misclassified and Django would prefer the more logical place. if e.args[0] in self.codes_for_integrityerror: - six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2]) + raise utils.IntegrityError(*tuple(e.args)) raise def executemany(self, query, args): @@ -98,7 +96,7 @@ class CursorWrapper: # Map some error codes to IntegrityError, since they seem to be # misclassified and Django would prefer the more logical place. if e.args[0] in self.codes_for_integrityerror: - six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2]) + raise utils.IntegrityError(*tuple(e.args)) raise def __getattr__(self, attr): diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 8d6b48e52a..fbbee227ee 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -7,13 +7,11 @@ import datetime import decimal import os import platform -import sys from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.db import utils from django.db.backends.base.base import BaseDatabaseWrapper -from django.utils import six from django.utils.encoding import force_bytes, force_text from django.utils.functional import cached_property @@ -261,7 +259,7 @@ class DatabaseWrapper(BaseDatabaseWrapper): x = e.args[0] if hasattr(x, 'code') and hasattr(x, 'message') \ and x.code == 2091 and 'ORA-02291' in x.message: - six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2]) + raise utils.IntegrityError(*tuple(e.args)) raise # Oracle doesn't support releasing savepoints. But we fake them when query diff --git a/django/db/migrations/graph.py b/django/db/migrations/graph.py index 1d144d7d25..7fdc850a77 100644 --- a/django/db/migrations/graph.py +++ b/django/db/migrations/graph.py @@ -1,10 +1,8 @@ -import sys import warnings from collections import deque from functools import total_ordering from django.db.migrations.state import ProjectState -from django.utils import six from django.utils.datastructures import OrderedSet from .exceptions import CircularDependencyError, NodeNotFoundError @@ -178,16 +176,12 @@ class MigrationGraph: replaced = set(replaced) try: replacement_node = self.node_map[replacement] - except KeyError as exc: - exc_value = NodeNotFoundError( + except KeyError as err: + raise NodeNotFoundError( "Unable to find replacement node %r. It was either never added" " to the migration graph, or has been removed." % (replacement, ), replacement - ) - exc_value.__cause__ = exc - if not hasattr(exc, '__traceback__'): - exc.__traceback__ = sys.exc_info()[2] - six.reraise(NodeNotFoundError, exc_value, sys.exc_info()[2]) + ) from err for replaced_key in replaced: self.nodes.pop(replaced_key, None) replaced_node = self.node_map.pop(replaced_key, None) @@ -218,16 +212,12 @@ class MigrationGraph: self.nodes.pop(replacement, None) try: replacement_node = self.node_map.pop(replacement) - except KeyError as exc: - exc_value = NodeNotFoundError( + except KeyError as err: + raise NodeNotFoundError( "Unable to remove replacement node %r. It was either never added" " to the migration graph, or has been removed already." % (replacement, ), replacement - ) - exc_value.__cause__ = exc - if not hasattr(exc, '__traceback__'): - exc.__traceback__ = sys.exc_info()[2] - six.reraise(NodeNotFoundError, exc_value, sys.exc_info()[2]) + ) from err replaced_nodes = set() replaced_nodes_parents = set() for key in replaced: diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py index 1237a37c26..b980aaf2f3 100644 --- a/django/db/migrations/loader.py +++ b/django/db/migrations/loader.py @@ -6,7 +6,6 @@ from django.apps import apps from django.conf import settings from django.db.migrations.graph import MigrationGraph from django.db.migrations.recorder import MigrationRecorder -from django.utils import six from .exceptions import ( AmbiguityError, BadMigrationError, InconsistentMigrationHistory, @@ -256,7 +255,7 @@ class MigrationLoader: is_replaced = any(candidate in self.graph.nodes for candidate in candidates) if not is_replaced: tries = ', '.join('%s.%s' % c for c in candidates) - exc_value = NodeNotFoundError( + raise NodeNotFoundError( "Migration {0} depends on nonexistent node ('{1}', '{2}'). " "Django tried to replace migration {1}.{2} with any of [{3}] " "but wasn't able to because some of the replaced migrations " @@ -264,11 +263,7 @@ class MigrationLoader: exc.origin, exc.node[0], exc.node[1], tries ), exc.node - ) - exc_value.__cause__ = exc - if not hasattr(exc, '__traceback__'): - exc.__traceback__ = sys.exc_info()[2] - six.reraise(NodeNotFoundError, exc_value, sys.exc_info()[2]) + ) from exc raise exc def check_consistent_history(self, connection): diff --git a/django/db/models/query.py b/django/db/models/query.py index f4d56a269b..dcb1360054 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -21,7 +21,7 @@ from django.db.models.fields import AutoField from django.db.models.functions import Trunc from django.db.models.query_utils import InvalidQuery, Q from django.db.models.sql.constants import CURSOR -from django.utils import six, timezone +from django.utils import timezone from django.utils.functional import cached_property, partition from django.utils.version import get_version @@ -498,7 +498,7 @@ class QuerySet: return self.get(**lookup), False except self.model.DoesNotExist: pass - six.reraise(*exc_info) + raise exc_info[0](exc_info[1]).with_traceback(exc_info[2]) def _extract_model_params(self, defaults, **kwargs): """ diff --git a/django/db/utils.py b/django/db/utils.py index a35de01ffa..7ef57fd8a3 100644 --- a/django/db/utils.py +++ b/django/db/utils.py @@ -5,7 +5,6 @@ from threading import local from django.conf import settings from django.core.exceptions import ImproperlyConfigured -from django.utils import six from django.utils.functional import cached_property from django.utils.module_loading import import_string @@ -90,7 +89,7 @@ class DatabaseErrorWrapper: # the connection unusable. if dj_exc_type not in (DataError, IntegrityError): self.wrapper.errors_occurred = True - six.reraise(dj_exc_type, dj_exc_value, traceback) + raise dj_exc_value.with_traceback(traceback) def __call__(self, func): # Note that we are intentionally not using @wraps here for performance diff --git a/django/forms/fields.py b/django/forms/fields.py index b88f3ea61a..a3bdcd1713 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -7,7 +7,6 @@ import datetime import itertools import os import re -import sys import uuid from decimal import Decimal, DecimalException from io import BytesIO @@ -26,7 +25,7 @@ from django.forms.widgets import ( SplitDateTimeWidget, SplitHiddenDateTimeWidget, TextInput, TimeInput, URLInput, ) -from django.utils import formats, six +from django.utils import formats from django.utils.dateparse import parse_duration from django.utils.duration import duration_string from django.utils.encoding import force_text @@ -650,12 +649,12 @@ class ImageField(FileField): # Pillow doesn't detect the MIME type of all formats. In those # cases, content_type will be None. f.content_type = Image.MIME.get(image.format) - except Exception: + except Exception as exc: # Pillow doesn't recognize it as an image. - six.reraise(ValidationError, ValidationError( + raise ValidationError( self.error_messages['invalid_image'], code='invalid_image', - ), sys.exc_info()[2]) + ) from exc if hasattr(f, 'seek') and callable(f.seek): f.seek(0) return f diff --git a/django/forms/utils.py b/django/forms/utils.py index b23e6be0cc..b199803ccc 100644 --- a/django/forms/utils.py +++ b/django/forms/utils.py @@ -1,10 +1,9 @@ import json -import sys from collections import UserList from django.conf import settings from django.core.exceptions import ValidationError # backwards compatibility -from django.utils import six, timezone +from django.utils import timezone from django.utils.encoding import force_text from django.utils.html import escape, format_html, format_html_join, html_safe from django.utils.translation import ugettext_lazy as _ @@ -156,18 +155,14 @@ def from_current_timezone(value): current_timezone = timezone.get_current_timezone() try: return timezone.make_aware(value, current_timezone) - except Exception: - message = _( - '%(datetime)s couldn\'t be interpreted ' - 'in time zone %(current_timezone)s; it ' - 'may be ambiguous or it may not exist.' - ) - params = {'datetime': value, 'current_timezone': current_timezone} - six.reraise(ValidationError, ValidationError( - message, + except Exception as exc: + raise ValidationError( + _('%(datetime)s couldn\'t be interpreted ' + 'in time zone %(current_timezone)s; it ' + 'may be ambiguous or it may not exist.'), code='ambiguous_timezone', - params=params, - ), sys.exc_info()[2]) + params={'datetime': value, 'current_timezone': current_timezone} + ) from exc return value diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py index ff7e36e321..6a0ff2c86c 100644 --- a/django/http/multipartparser.py +++ b/django/http/multipartparser.py @@ -7,7 +7,6 @@ file upload handlers for processing. import base64 import binascii import cgi -import sys from urllib.parse import unquote from django.conf import settings @@ -17,7 +16,6 @@ from django.core.exceptions import ( from django.core.files.uploadhandler import ( SkipFile, StopFutureHandlers, StopUpload, ) -from django.utils import six from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_text from django.utils.text import unescape_entities @@ -247,10 +245,9 @@ class MultiPartParser: try: chunk = base64.b64decode(stripped_chunk) - except Exception as e: + except Exception as exc: # Since this is only a chunk, any error is an unfixable error. - msg = "Could not decode base64 data: %r" % e - six.reraise(MultiPartParserError, MultiPartParserError(msg), sys.exc_info()[2]) + raise MultiPartParserError("Could not decode base64 data.") from exc for i, handler in enumerate(handlers): chunk_length = len(chunk) diff --git a/django/http/request.py b/django/http/request.py index 554e05217d..bae0b6f3ec 100644 --- a/django/http/request.py +++ b/django/http/request.py @@ -1,6 +1,5 @@ import copy import re -import sys from io import BytesIO from itertools import chain from urllib.parse import quote, urlencode, urljoin, urlsplit @@ -12,7 +11,6 @@ from django.core.exceptions import ( ) from django.core.files import uploadhandler from django.http.multipartparser import MultiPartParser, MultiPartParserError -from django.utils import six from django.utils.datastructures import ImmutableList, MultiValueDict from django.utils.encoding import escape_uri_path, force_bytes, iri_to_uri from django.utils.http import is_same_domain, limited_parse_qsl @@ -263,7 +261,7 @@ class HttpRequest: try: self._body = self.read() except IOError as e: - six.reraise(UnreadablePostError, UnreadablePostError(*e.args), sys.exc_info()[2]) + raise UnreadablePostError(*e.args) from e self._stream = BytesIO(self._body) return self._body @@ -322,14 +320,14 @@ class HttpRequest: try: return self._stream.read(*args, **kwargs) except IOError as e: - six.reraise(UnreadablePostError, UnreadablePostError(*e.args), sys.exc_info()[2]) + raise UnreadablePostError(*e.args) from e def readline(self, *args, **kwargs): self._read_started = True try: return self._stream.readline(*args, **kwargs) except IOError as e: - six.reraise(UnreadablePostError, UnreadablePostError(*e.args), sys.exc_info()[2]) + raise UnreadablePostError(*e.args) from e def xreadlines(self): while True: diff --git a/django/template/backends/django.py b/django/template/backends/django.py index 33022d8bbb..eaa7c8fdc2 100644 --- a/django/template/backends/django.py +++ b/django/template/backends/django.py @@ -1,4 +1,3 @@ -import sys from importlib import import_module from pkgutil import walk_packages @@ -8,7 +7,6 @@ from django.template import TemplateDoesNotExist from django.template.context import make_context from django.template.engine import Engine from django.template.library import InvalidTemplateLibrary -from django.utils import six from .base import BaseEngine @@ -83,7 +81,7 @@ def reraise(exc, backend): Reraise TemplateDoesNotExist while maintaining template debug information. """ new = copy_exception(exc, backend) - six.reraise(exc.__class__, new, sys.exc_info()[2]) + raise new from exc def get_installed_libraries(): diff --git a/django/template/backends/jinja2.py b/django/template/backends/jinja2.py index df2eefa925..3c5f7231bf 100644 --- a/django/template/backends/jinja2.py +++ b/django/template/backends/jinja2.py @@ -1,10 +1,7 @@ -import sys - import jinja2 from django.conf import settings from django.template import TemplateDoesNotExist, TemplateSyntaxError -from django.utils import six from django.utils.functional import cached_property from django.utils.module_loading import import_string @@ -41,15 +38,11 @@ class Jinja2(BaseEngine): try: return Template(self.env.get_template(template_name), self) except jinja2.TemplateNotFound as exc: - six.reraise( - TemplateDoesNotExist, - TemplateDoesNotExist(exc.name, backend=self), - sys.exc_info()[2], - ) + raise TemplateDoesNotExist(exc.name, backend=self) from exc except jinja2.TemplateSyntaxError as exc: new = TemplateSyntaxError(exc.args) new.template_debug = get_exception_info(exc) - six.reraise(TemplateSyntaxError, new, sys.exc_info()[2]) + raise new from exc @cached_property def template_context_processors(self): diff --git a/django/templatetags/i18n.py b/django/templatetags/i18n.py index 407ce87609..456c5071ac 100644 --- a/django/templatetags/i18n.py +++ b/django/templatetags/i18n.py @@ -1,10 +1,8 @@ -import sys - from django.conf import settings from django.template import Library, Node, TemplateSyntaxError, Variable from django.template.base import TOKEN_TEXT, TOKEN_VAR, render_value_in_context from django.template.defaulttags import token_kwargs -from django.utils import six, translation +from django.utils import translation from django.utils.safestring import SafeData, mark_safe register = Library() @@ -388,8 +386,9 @@ def do_translate(parser, token): try: value = remaining.pop(0) except IndexError: - msg = "No argument provided to the '%s' tag for the context option." % bits[0] - six.reraise(TemplateSyntaxError, TemplateSyntaxError(msg), sys.exc_info()[2]) + raise TemplateSyntaxError( + "No argument provided to the '%s' tag for the context option." % bits[0] + ) if value in invalid_context: raise TemplateSyntaxError( "Invalid argument '%s' provided to the '%s' tag for the context option" % (value, bits[0]), @@ -399,8 +398,9 @@ def do_translate(parser, token): try: value = remaining.pop(0) except IndexError: - msg = "No argument provided to the '%s' tag for the as option." % bits[0] - six.reraise(TemplateSyntaxError, TemplateSyntaxError(msg), sys.exc_info()[2]) + raise TemplateSyntaxError( + "No argument provided to the '%s' tag for the as option." % bits[0] + ) asvar = value else: raise TemplateSyntaxError( @@ -481,18 +481,18 @@ def do_block_translate(parser, token): value = remaining_bits.pop(0) value = parser.compile_filter(value) except Exception: - msg = ( - '"context" in %r tag expected ' - 'exactly one argument.') % bits[0] - six.reraise(TemplateSyntaxError, TemplateSyntaxError(msg), sys.exc_info()[2]) + raise TemplateSyntaxError( + '"context" in %r tag expected exactly one argument.' % bits[0] + ) elif option == "trimmed": value = True elif option == "asvar": try: value = remaining_bits.pop(0) except IndexError: - msg = "No argument provided to the '%s' tag for the asvar option." % bits[0] - six.reraise(TemplateSyntaxError, TemplateSyntaxError(msg), sys.exc_info()[2]) + raise TemplateSyntaxError( + "No argument provided to the '%s' tag for the asvar option." % bits[0] + ) asvar = value else: raise TemplateSyntaxError('Unknown argument for %r tag: %r.' % diff --git a/django/test/client.py b/django/test/client.py index f09051d2d5..e793dac775 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -20,7 +20,6 @@ from django.template import TemplateDoesNotExist from django.test import signals from django.test.utils import ContextList from django.urls import resolve -from django.utils import six from django.utils.encoding import force_bytes, uri_to_iri from django.utils.functional import SimpleLazyObject, curry from django.utils.http import urlencode @@ -494,7 +493,7 @@ class Client(RequestFactory): if self.exc_info: exc_info = self.exc_info self.exc_info = None - six.reraise(*exc_info) + raise exc_info[0](exc_info[1]).with_traceback(exc_info[2]) # Save the client and request that stimulated the response. response.client = self diff --git a/django/utils/autoreload.py b/django/utils/autoreload.py index 6255da1c84..3fe47200ee 100644 --- a/django/utils/autoreload.py +++ b/django/utils/autoreload.py @@ -40,7 +40,6 @@ import _thread from django.apps import apps from django.conf import settings from django.core.signals import request_finished -from django.utils import six # This import does nothing, but it's necessary to avoid some race conditions # in the threading module. See http://code.djangoproject.com/ticket/2330 . @@ -247,7 +246,7 @@ def check_errors(fn): def raise_last_exception(): global _exception if _exception is not None: - six.reraise(*_exception) + raise _exception[0](_exception[1]).with_traceback(_exception[2]) def ensure_echo_on(): diff --git a/django/utils/http.py b/django/utils/http.py index 7b15dc2812..afa7368ee8 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -2,7 +2,6 @@ import base64 import calendar import datetime import re -import sys import unicodedata import warnings from binascii import Error as BinasciiError @@ -13,7 +12,6 @@ from urllib.parse import ( ) from django.core.exceptions import TooManyFieldsSent -from django.utils import six from django.utils.datastructures import MultiValueDict from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_bytes, force_str, force_text @@ -163,8 +161,8 @@ def parse_http_date(date): sec = int(m.group('sec')) result = datetime.datetime(year, month, day, hour, min, sec) return calendar.timegm(result.utctimetuple()) - except Exception: - six.reraise(ValueError, ValueError("%r is not a valid date" % date), sys.exc_info()[2]) + except Exception as exc: + raise ValueError("%r is not a valid date" % date) from exc def parse_http_date_safe(date): diff --git a/django/utils/module_loading.py b/django/utils/module_loading.py index ed2b8da635..5e5fa0e69e 100644 --- a/django/utils/module_loading.py +++ b/django/utils/module_loading.py @@ -1,11 +1,8 @@ import copy import os -import sys from importlib import import_module from importlib.util import find_spec as importlib_find -from django.utils import six - def import_string(dotted_path): """ @@ -14,18 +11,17 @@ def import_string(dotted_path): """ try: module_path, class_name = dotted_path.rsplit('.', 1) - except ValueError: - msg = "%s doesn't look like a module path" % dotted_path - six.reraise(ImportError, ImportError(msg), sys.exc_info()[2]) + except ValueError as err: + raise ImportError("%s doesn't look like a module path" % dotted_path) from err module = import_module(module_path) try: return getattr(module, class_name) - except AttributeError: - msg = 'Module "%s" does not define a "%s" attribute/class' % ( + except AttributeError as err: + raise ImportError('Module "%s" does not define a "%s" attribute/class' % ( module_path, class_name) - six.reraise(ImportError, ImportError(msg), sys.exc_info()[2]) + ) from err def autodiscover_modules(*args, **kwargs): diff --git a/tests/gis_tests/tests.py b/tests/gis_tests/tests.py index 6b689cf9b0..0cbfd97dcc 100644 --- a/tests/gis_tests/tests.py +++ b/tests/gis_tests/tests.py @@ -1,9 +1,7 @@ -import sys import unittest from django.core.exceptions import ImproperlyConfigured from django.db import ProgrammingError -from django.utils import six try: from django.contrib.gis.db.backends.postgis.operations import PostGISOperations @@ -19,7 +17,7 @@ except ImproperlyConfigured as e: if e.args and e.args[0].startswith('Could not import user-defined GEOMETRY_BACKEND'): HAS_POSTGRES = False else: - six.reraise(*sys.exc_info()) + raise if HAS_POSTGRES: