From 2b281cc35ed9d997614ca3c416928d7fabfef1ad Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Sat, 7 Jan 2017 12:11:46 +0100 Subject: [PATCH] Refs #23919 -- Removed most of remaining six usage Thanks Tim Graham for the review. --- django/contrib/admin/options.py | 5 +- django/contrib/admin/sites.py | 3 +- .../contrib/admin/templatetags/admin_urls.py | 3 +- django/contrib/auth/decorators.py | 2 +- .../management/commands/createsuperuser.py | 1 - django/contrib/auth/views.py | 2 +- django/contrib/contenttypes/checks.py | 3 +- .../contenttypes/management/__init__.py | 3 +- .../commands/remove_stale_contenttypes.py | 4 +- .../contrib/gis/db/backends/oracle/adapter.py | 1 - django/contrib/gis/gdal/datasource.py | 1 - django/contrib/gis/gdal/feature.py | 1 - django/contrib/gis/gdal/geometries.py | 8 +- django/contrib/gis/gdal/layer.py | 1 - django/contrib/gis/gdal/raster/band.py | 4 +- django/contrib/gis/geos/collections.py | 1 - django/contrib/gis/geos/coordseq.py | 1 - django/contrib/gis/geos/factory.py | 3 +- django/contrib/gis/geos/geometry.py | 5 +- django/contrib/gis/geos/linestring.py | 1 - django/contrib/gis/geos/mutable_list.py | 2 - django/contrib/gis/geos/point.py | 1 - django/contrib/gis/geos/polygon.py | 1 - django/contrib/gis/geos/prototypes/io.py | 5 +- django/contrib/gis/geos/prototypes/misc.py | 1 - django/contrib/gis/measure.py | 4 +- django/contrib/gis/utils/ogrinspect.py | 1 - django/contrib/messages/storage/cookie.py | 3 +- django/contrib/sessions/backends/cache.py | 1 - django/contrib/sessions/serializers.py | 7 +- django/contrib/sitemaps/__init__.py | 5 +- django/contrib/staticfiles/finders.py | 4 +- django/contrib/staticfiles/handlers.py | 5 +- .../management/commands/collectstatic.py | 1 - django/contrib/staticfiles/storage.py | 8 +- django/contrib/staticfiles/views.py | 2 +- django/contrib/syndication/views.py | 6 +- django/core/cache/backends/db.py | 6 +- django/core/cache/backends/filebased.py | 6 +- django/core/cache/backends/locmem.py | 7 +- django/core/files/storage.py | 2 +- django/core/mail/message.py | 5 +- django/core/management/__init__.py | 4 +- django/core/management/commands/flush.py | 1 - .../management/commands/makemigrations.py | 4 +- .../management/commands/squashmigrations.py | 3 +- django/core/management/templates.py | 2 +- django/core/paginator.py | 3 +- django/core/serializers/__init__.py | 3 +- django/core/serializers/base.py | 9 +- django/core/serializers/python.py | 3 +- django/core/servers/basehttp.py | 2 +- django/core/validators.py | 2 +- django/db/backends/base/base.py | 10 +- django/db/backends/base/creation.py | 3 +- django/db/backends/oracle/base.py | 2 +- django/db/backends/oracle/creation.py | 1 - django/db/backends/postgresql/client.py | 3 +- django/db/backends/sqlite3/creation.py | 1 - django/db/migrations/loader.py | 4 +- django/db/migrations/questioner.py | 1 - django/db/migrations/serializer.py | 5 +- django/db/models/base.py | 4 +- django/db/models/deletion.py | 19 ++- django/db/models/lookups.py | 1 - django/db/models/options.py | 3 +- django/db/models/query.py | 4 +- django/db/models/sql/compiler.py | 1 - django/db/models/sql/query.py | 17 ++- django/db/models/sql/subqueries.py | 5 +- django/dispatch/dispatcher.py | 1 - django/forms/fields.py | 2 +- django/forms/forms.py | 3 +- django/forms/formsets.py | 1 - django/forms/models.py | 5 +- django/forms/widgets.py | 5 +- django/http/cookie.py | 11 +- django/http/multipartparser.py | 10 +- django/http/request.py | 8 +- django/http/response.py | 9 +- django/middleware/common.py | 2 +- django/middleware/csrf.py | 3 +- django/template/defaulttags.py | 5 +- django/template/loader_tags.py | 5 +- django/templatetags/static.py | 3 +- django/test/client.py | 2 +- django/test/runner.py | 2 +- django/test/selenium.py | 3 +- django/test/testcases.py | 9 +- django/test/utils.py | 6 +- django/urls/base.py | 2 +- django/utils/_os.py | 1 - django/utils/autoreload.py | 7 +- django/utils/crypto.py | 1 - django/utils/datastructures.py | 6 +- django/utils/dateparse.py | 9 +- django/utils/encoding.py | 3 +- django/utils/feedgenerator.py | 4 +- django/utils/functional.py | 4 +- django/utils/html.py | 9 +- django/utils/html_parser.py | 8 +- django/utils/http.py | 8 +- django/utils/ipv6.py | 1 - django/utils/regex_helper.py | 1 - django/utils/termcolors.py | 4 +- django/utils/text.py | 7 +- django/utils/translation/template.py | 2 +- django/views/generic/base.py | 3 +- django/views/i18n.py | 3 +- django/views/static.py | 2 +- tests/admin_scripts/tests.py | 2 +- tests/admin_views/admin.py | 2 +- tests/admin_views/tests.py | 2 +- tests/aggregation_regress/tests.py | 3 +- tests/auth_tests/test_deprecated_views.py | 2 +- tests/auth_tests/test_management.py | 51 +++---- tests/auth_tests/test_views.py | 2 +- tests/backends/tests.py | 1 - tests/base/models.py | 5 +- tests/cache/tests.py | 14 +- tests/check_framework/tests.py | 2 +- tests/contenttypes_tests/tests.py | 10 +- tests/db_typecasts/tests.py | 3 +- tests/delete/tests.py | 1 - tests/deprecation/tests.py | 15 +-- tests/file_storage/tests.py | 11 +- tests/file_uploads/tests.py | 3 +- tests/fixtures/tests.py | 14 +- tests/fixtures_regress/tests.py | 2 +- tests/gis_tests/gdal_tests/test_geom.py | 8 +- tests/gis_tests/gdal_tests/test_raster.py | 3 +- tests/gis_tests/geoapp/tests.py | 4 +- tests/gis_tests/geos_tests/test_geos.py | 15 +-- tests/gis_tests/inspectapp/tests.py | 2 +- tests/gis_tests/test_data.py | 3 +- tests/httpwrappers/tests.py | 41 +++--- tests/i18n/test_compilation.py | 2 +- tests/i18n/test_extraction.py | 2 +- tests/inspectdb/tests.py | 2 +- tests/logging_tests/tests.py | 4 +- tests/m2m_through_regress/tests.py | 3 +- tests/mail/tests.py | 2 +- tests/middleware/tests.py | 9 +- tests/migrate_signals/tests.py | 7 +- tests/migrations/models.py | 3 +- tests/migrations/test_commands.py | 125 +++++++++--------- tests/migrations/test_writer.py | 5 +- tests/model_fields/models.py | 3 +- tests/model_fields/test_binaryfield.py | 3 +- tests/model_forms/models.py | 1 - tests/model_forms/tests.py | 3 +- tests/multiple_database/tests.py | 2 +- tests/pagination/tests.py | 3 +- tests/queries/tests.py | 1 - tests/requests/tests.py | 6 +- tests/serializers/test_data.py | 3 +- tests/serializers/test_yaml.py | 2 +- tests/serializers/tests.py | 2 +- tests/servers/tests.py | 4 +- tests/sessions_tests/tests.py | 14 +- tests/sitemaps_tests/test_utils.py | 3 +- tests/staticfiles_tests/test_forms.py | 3 +- tests/staticfiles_tests/test_liveserver.py | 2 +- tests/staticfiles_tests/test_management.py | 31 +++-- tests/staticfiles_tests/test_storage.py | 10 +- tests/swappable_models/tests.py | 5 +- .../syntax_tests/test_static.py | 3 +- tests/template_tests/templatetags/custom.py | 3 +- .../template_tests/templatetags/inclusion.py | 3 +- tests/test_client/views.py | 2 +- tests/test_client_regress/views.py | 2 +- tests/test_runner/test_debug_sql.py | 4 +- tests/test_utils/tests.py | 4 +- tests/timezones/tests.py | 10 +- tests/user_commands/tests.py | 2 +- tests/utils_tests/test_autoreload.py | 3 +- tests/utils_tests/test_baseconv.py | 1 - tests/utils_tests/test_datastructures.py | 12 +- tests/utils_tests/test_lazyobject.py | 3 +- tests/view_tests/tests/test_debug.py | 6 +- 180 files changed, 421 insertions(+), 559 deletions(-) diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index eaa9916056..2d4bbbb933 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -36,7 +36,6 @@ from django.http import HttpResponseRedirect from django.http.response import HttpResponseBase from django.template.response import SimpleTemplateResponse, TemplateResponse from django.urls import reverse -from django.utils import six from django.utils.decorators import method_decorator from django.utils.encoding import force_text from django.utils.html import format_html @@ -92,7 +91,7 @@ FORMFIELD_FOR_DBFIELD_DEFAULTS = { csrf_protect_m = method_decorator(csrf_protect) -class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)): +class BaseModelAdmin(metaclass=forms.MediaDefiningClass): """Functionality common to both ModelAdmin and InlineAdmin.""" raw_id_fields = () @@ -805,7 +804,7 @@ class ModelAdmin(BaseModelAdmin): tuple (name, description). """ choices = [] + default_choices - for func, name, description in six.itervalues(self.get_actions(request)): + for func, name, description in self.get_actions(request).values(): choice = (name, description % model_format_dict(self.opts)) choices.append(choice) return choices diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index b3297d04f6..14b0da7df4 100644 --- a/django/contrib/admin/sites.py +++ b/django/contrib/admin/sites.py @@ -9,7 +9,6 @@ from django.db.models.base import ModelBase from django.http import Http404, HttpResponseRedirect from django.template.response import TemplateResponse from django.urls import NoReverseMatch, reverse -from django.utils import six from django.utils.text import capfirst from django.utils.translation import ugettext as _, ugettext_lazy from django.views.decorators.cache import never_cache @@ -169,7 +168,7 @@ class AdminSite(object): """ Get all the enabled actions as an iterable of (name, func). """ - return six.iteritems(self._actions) + return iter(self._actions.items()) @property def empty_value_display(self): diff --git a/django/contrib/admin/templatetags/admin_urls.py b/django/contrib/admin/templatetags/admin_urls.py index 8e665ec9de..097fbcf040 100644 --- a/django/contrib/admin/templatetags/admin_urls.py +++ b/django/contrib/admin/templatetags/admin_urls.py @@ -1,8 +1,9 @@ +from urllib.parse import parse_qsl, urlparse, urlunparse + from django import template from django.contrib.admin.utils import quote from django.urls import Resolver404, get_script_prefix, resolve from django.utils.http import urlencode -from django.utils.six.moves.urllib.parse import parse_qsl, urlparse, urlunparse register = template.Library() diff --git a/django/contrib/auth/decorators.py b/django/contrib/auth/decorators.py index f6e4c1d5b2..807ea8a3f6 100644 --- a/django/contrib/auth/decorators.py +++ b/django/contrib/auth/decorators.py @@ -1,11 +1,11 @@ from functools import wraps +from urllib.parse import urlparse from django.conf import settings from django.contrib.auth import REDIRECT_FIELD_NAME from django.core.exceptions import PermissionDenied from django.shortcuts import resolve_url from django.utils.decorators import available_attrs -from django.utils.six.moves.urllib.parse import urlparse def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME): diff --git a/django/contrib/auth/management/commands/createsuperuser.py b/django/contrib/auth/management/commands/createsuperuser.py index b9f13b7b05..7a6d0b0231 100644 --- a/django/contrib/auth/management/commands/createsuperuser.py +++ b/django/contrib/auth/management/commands/createsuperuser.py @@ -11,7 +11,6 @@ from django.core import exceptions from django.core.management.base import BaseCommand, CommandError from django.db import DEFAULT_DB_ALIAS from django.utils.encoding import force_str -from django.utils.six.moves import input from django.utils.text import capfirst diff --git a/django/contrib/auth/views.py b/django/contrib/auth/views.py index 1a004e7a84..bf95d11a10 100644 --- a/django/contrib/auth/views.py +++ b/django/contrib/auth/views.py @@ -1,4 +1,5 @@ import warnings +from urllib.parse import urlparse, urlunparse from django.conf import settings # Avoid shadowing the login() and logout() views below. @@ -20,7 +21,6 @@ from django.utils.decorators import method_decorator from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_text from django.utils.http import is_safe_url, urlsafe_base64_decode -from django.utils.six.moves.urllib.parse import urlparse, urlunparse from django.utils.translation import ugettext_lazy as _ from django.views.decorators.cache import never_cache from django.views.decorators.csrf import csrf_protect diff --git a/django/contrib/contenttypes/checks.py b/django/contrib/contenttypes/checks.py index 2355a5e943..d21df40f46 100644 --- a/django/contrib/contenttypes/checks.py +++ b/django/contrib/contenttypes/checks.py @@ -1,7 +1,6 @@ from itertools import chain from django.apps import apps -from django.utils import six def check_generic_foreign_keys(app_configs=None, **kwargs): @@ -13,7 +12,7 @@ def check_generic_foreign_keys(app_configs=None, **kwargs): models = chain.from_iterable(app_config.get_models() for app_config in app_configs) errors = [] fields = ( - obj for model in models for obj in six.itervalues(vars(model)) + obj for model in models for obj in vars(model).values() if isinstance(obj, GenericForeignKey) ) for field in fields: diff --git a/django/contrib/contenttypes/management/__init__.py b/django/contrib/contenttypes/management/__init__.py index d0d5b52f09..6799ef8a23 100644 --- a/django/contrib/contenttypes/management/__init__.py +++ b/django/contrib/contenttypes/management/__init__.py @@ -1,7 +1,6 @@ from django.apps import apps as global_apps from django.db import DEFAULT_DB_ALIAS, migrations, router, transaction from django.db.utils import IntegrityError -from django.utils import six class RenameContentType(migrations.RunPython): @@ -126,7 +125,7 @@ def create_contenttypes(app_config, verbosity=2, interactive=True, using=DEFAULT app_label=app_label, model=model_name, ) - for (model_name, model) in six.iteritems(app_models) + for (model_name, model) in app_models.items() if model_name not in content_types ] ContentType.objects.using(using).bulk_create(cts) diff --git a/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py b/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py index 2a3b23b0d0..e5f77dc7df 100644 --- a/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py +++ b/django/contrib/contenttypes/management/commands/remove_stale_contenttypes.py @@ -3,8 +3,6 @@ from django.contrib.contenttypes.models import ContentType from django.core.management import BaseCommand from django.db import DEFAULT_DB_ALIAS, router from django.db.models.deletion import Collector -from django.utils import six -from django.utils.six.moves import input from ...management import get_contenttypes_and_models @@ -32,7 +30,7 @@ class Command(BaseCommand): if not app_models: continue to_remove = [ - ct for (model_name, ct) in six.iteritems(content_types) + ct for (model_name, ct) in content_types.items() if model_name not in app_models ] # Confirm that the content type is stale before deletion. diff --git a/django/contrib/gis/db/backends/oracle/adapter.py b/django/contrib/gis/db/backends/oracle/adapter.py index 11eb0424aa..7c43391f69 100644 --- a/django/contrib/gis/db/backends/oracle/adapter.py +++ b/django/contrib/gis/db/backends/oracle/adapter.py @@ -2,7 +2,6 @@ from cx_Oracle import CLOB from django.contrib.gis.db.backends.base.adapter import WKTAdapter from django.contrib.gis.geos import GeometryCollection, Polygon -from django.utils.six.moves import range class OracleSpatialAdapter(WKTAdapter): diff --git a/django/contrib/gis/gdal/datasource.py b/django/contrib/gis/gdal/datasource.py index 1ff2326a63..3008da804c 100644 --- a/django/contrib/gis/gdal/datasource.py +++ b/django/contrib/gis/gdal/datasource.py @@ -41,7 +41,6 @@ from django.contrib.gis.gdal.error import GDALException, OGRIndexError from django.contrib.gis.gdal.layer import Layer from django.contrib.gis.gdal.prototypes import ds as capi from django.utils.encoding import force_bytes, force_text -from django.utils.six.moves import range # For more information, see the OGR C API source code: diff --git a/django/contrib/gis/gdal/feature.py b/django/contrib/gis/gdal/feature.py index 8975b9c076..47e8bb1ae3 100644 --- a/django/contrib/gis/gdal/feature.py +++ b/django/contrib/gis/gdal/feature.py @@ -4,7 +4,6 @@ from django.contrib.gis.gdal.field import Field from django.contrib.gis.gdal.geometries import OGRGeometry, OGRGeomType from django.contrib.gis.gdal.prototypes import ds as capi, geom as geom_api from django.utils.encoding import force_bytes, force_text -from django.utils.six.moves import range # For more information, see the OGR C API source code: diff --git a/django/contrib/gis/gdal/geometries.py b/django/contrib/gis/gdal/geometries.py index 28ef2907ac..50c1d9ff65 100644 --- a/django/contrib/gis/gdal/geometries.py +++ b/django/contrib/gis/gdal/geometries.py @@ -51,9 +51,7 @@ from django.contrib.gis.gdal.geomtype import OGRGeomType from django.contrib.gis.gdal.prototypes import geom as capi, srs as srs_api from django.contrib.gis.gdal.srs import CoordTransform, SpatialReference from django.contrib.gis.geometry.regex import hex_regex, json_regex, wkt_regex -from django.utils import six from django.utils.encoding import force_bytes -from django.utils.six.moves import range # For more information, see the OGR C API source code: @@ -71,7 +69,7 @@ class OGRGeometry(GDALBase): # If HEX, unpack input to a binary buffer. if str_instance and hex_regex.match(geom_input): - geom_input = six.memoryview(a2b_hex(geom_input.upper().encode())) + geom_input = memoryview(a2b_hex(geom_input.upper().encode())) str_instance = False # Constructing the geometry, @@ -96,7 +94,7 @@ class OGRGeometry(GDALBase): # (e.g., 'Point', 'POLYGON'). OGRGeomType(geom_input) g = capi.create_geom(OGRGeomType(geom_input).num) - elif isinstance(geom_input, six.memoryview): + elif isinstance(geom_input, memoryview): # WKB was passed in g = self._from_wkb(geom_input) elif isinstance(geom_input, OGRGeomType): @@ -353,7 +351,7 @@ class OGRGeometry(GDALBase): buf = (c_ubyte * sz)() capi.to_wkb(self.ptr, byteorder, byref(buf)) # Returning a buffer of the string at the pointer. - return six.memoryview(string_at(buf, sz)) + return memoryview(string_at(buf, sz)) @property def wkt(self): diff --git a/django/contrib/gis/gdal/layer.py b/django/contrib/gis/gdal/layer.py index fbbede81b0..119abf9459 100644 --- a/django/contrib/gis/gdal/layer.py +++ b/django/contrib/gis/gdal/layer.py @@ -14,7 +14,6 @@ from django.contrib.gis.gdal.prototypes import ( ) from django.contrib.gis.gdal.srs import SpatialReference from django.utils.encoding import force_bytes, force_text -from django.utils.six.moves import range # For more information, see the OGR C API source code: diff --git a/django/contrib/gis/gdal/raster/band.py b/django/contrib/gis/gdal/raster/band.py index bb65cf197e..141dc0e5b6 100644 --- a/django/contrib/gis/gdal/raster/band.py +++ b/django/contrib/gis/gdal/raster/band.py @@ -4,9 +4,7 @@ from django.contrib.gis.gdal.base import GDALBase from django.contrib.gis.gdal.error import GDALException from django.contrib.gis.gdal.prototypes import raster as capi from django.contrib.gis.shortcuts import numpy -from django.utils import six from django.utils.encoding import force_text -from django.utils.six.moves import range from .const import GDAL_INTEGER_TYPES, GDAL_PIXEL_TYPES, GDAL_TO_CTYPES @@ -207,7 +205,7 @@ class GDALBand(GDALBase): access_flag = 1 # Instantiate ctypes array holding the input data - if isinstance(data, (bytes, six.memoryview)) or (numpy and isinstance(data, numpy.ndarray)): + if isinstance(data, (bytes, memoryview)) or (numpy and isinstance(data, numpy.ndarray)): data_array = ctypes_array.from_buffer_copy(data) else: data_array = ctypes_array(*data) diff --git a/django/contrib/gis/geos/collections.py b/django/contrib/gis/geos/collections.py index 4935dbd1c3..e964a1de8f 100644 --- a/django/contrib/gis/geos/collections.py +++ b/django/contrib/gis/geos/collections.py @@ -12,7 +12,6 @@ from django.contrib.gis.geos.libgeos import geos_version_info, get_pointer_arr from django.contrib.gis.geos.linestring import LinearRing, LineString from django.contrib.gis.geos.point import Point from django.contrib.gis.geos.polygon import Polygon -from django.utils.six.moves import range class GeometryCollection(GEOSGeometry): diff --git a/django/contrib/gis/geos/coordseq.py b/django/contrib/gis/geos/coordseq.py index 8722874099..6908b040c0 100644 --- a/django/contrib/gis/geos/coordseq.py +++ b/django/contrib/gis/geos/coordseq.py @@ -10,7 +10,6 @@ from django.contrib.gis.geos.base import GEOSBase from django.contrib.gis.geos.error import GEOSException from django.contrib.gis.geos.libgeos import CS_PTR from django.contrib.gis.shortcuts import numpy -from django.utils.six.moves import range class GEOSCoordSeq(GEOSBase): diff --git a/django/contrib/gis/geos/factory.py b/django/contrib/gis/geos/factory.py index 42cd10c756..54c19aab37 100644 --- a/django/contrib/gis/geos/factory.py +++ b/django/contrib/gis/geos/factory.py @@ -1,5 +1,4 @@ from django.contrib.gis.geos.geometry import GEOSGeometry, hex_regex, wkt_regex -from django.utils import six def fromfile(file_h): @@ -25,7 +24,7 @@ def fromfile(file_h): else: return GEOSGeometry(buf) - return GEOSGeometry(six.memoryview(buf)) + return GEOSGeometry(memoryview(buf)) def fromstr(string, **kwargs): diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py index f7bdf8937f..f49ce2e0de 100644 --- a/django/contrib/gis/geos/geometry.py +++ b/django/contrib/gis/geos/geometry.py @@ -17,7 +17,6 @@ from django.contrib.gis.geos.prepared import PreparedGeometry from django.contrib.gis.geos.prototypes.io import ( ewkb_w, wkb_r, wkb_w, wkt_r, wkt_w, ) -from django.utils import six from django.utils.deconstruct import deconstructible from django.utils.encoding import force_bytes, force_text @@ -67,7 +66,7 @@ class GEOSGeometry(GEOSBase, ListMixin): elif isinstance(geo_input, GEOM_PTR): # When the input is a pointer to a geometry (GEOM_PTR). g = geo_input - elif isinstance(geo_input, six.memoryview): + elif isinstance(geo_input, memoryview): # When the input is a buffer (WKB). g = wkb_r().read(geo_input) elif isinstance(geo_input, GEOSGeometry): @@ -149,7 +148,7 @@ class GEOSGeometry(GEOSBase, ListMixin): def __setstate__(self, state): # Instantiating from the tuple state that was pickled. wkb, srid = state - ptr = wkb_r().read(six.memoryview(wkb)) + ptr = wkb_r().read(memoryview(wkb)) if not ptr: raise GEOSException('Invalid Geometry loaded from pickled state.') self.ptr = ptr diff --git a/django/contrib/gis/geos/linestring.py b/django/contrib/gis/geos/linestring.py index 7bfc004370..6caf6bef34 100644 --- a/django/contrib/gis/geos/linestring.py +++ b/django/contrib/gis/geos/linestring.py @@ -4,7 +4,6 @@ from django.contrib.gis.geos.error import GEOSException from django.contrib.gis.geos.geometry import GEOSGeometry, LinearGeometryMixin from django.contrib.gis.geos.point import Point from django.contrib.gis.shortcuts import numpy -from django.utils.six.moves import range class LineString(LinearGeometryMixin, GEOSGeometry): diff --git a/django/contrib/gis/geos/mutable_list.py b/django/contrib/gis/geos/mutable_list.py index 8896ebc518..082f3b161a 100644 --- a/django/contrib/gis/geos/mutable_list.py +++ b/django/contrib/gis/geos/mutable_list.py @@ -10,8 +10,6 @@ Author: Aryeh Leib Taurog. """ from functools import total_ordering -from django.utils.six.moves import range - @total_ordering class ListMixin(object): diff --git a/django/contrib/gis/geos/point.py b/django/contrib/gis/geos/point.py index fadf5eb414..72de47f9f6 100644 --- a/django/contrib/gis/geos/point.py +++ b/django/contrib/gis/geos/point.py @@ -4,7 +4,6 @@ from django.contrib.gis import gdal from django.contrib.gis.geos import prototypes as capi from django.contrib.gis.geos.error import GEOSException from django.contrib.gis.geos.geometry import GEOSGeometry -from django.utils.six.moves import range class Point(GEOSGeometry): diff --git a/django/contrib/gis/geos/polygon.py b/django/contrib/gis/geos/polygon.py index 0b4de0d3c3..58f1b28c29 100644 --- a/django/contrib/gis/geos/polygon.py +++ b/django/contrib/gis/geos/polygon.py @@ -4,7 +4,6 @@ from django.contrib.gis.geos import prototypes as capi from django.contrib.gis.geos.geometry import GEOSGeometry from django.contrib.gis.geos.libgeos import GEOM_PTR, get_pointer_arr from django.contrib.gis.geos.linestring import LinearRing -from django.utils.six.moves import range class Polygon(GEOSGeometry): diff --git a/django/contrib/gis/geos/prototypes/io.py b/django/contrib/gis/geos/prototypes/io.py index 1cc0ccb8f3..b8b1a06dba 100644 --- a/django/contrib/gis/geos/prototypes/io.py +++ b/django/contrib/gis/geos/prototypes/io.py @@ -7,7 +7,6 @@ from django.contrib.gis.geos.prototypes.errcheck import ( check_geom, check_sized_string, check_string, ) from django.contrib.gis.geos.prototypes.geom import c_uchar_p, geos_char_p -from django.utils import six from django.utils.encoding import force_bytes @@ -147,7 +146,7 @@ class _WKBReader(IOBase): def read(self, wkb): "Returns a _pointer_ to C GEOS Geometry object from the given WKB." - if isinstance(wkb, six.memoryview): + if isinstance(wkb, memoryview): wkb_s = bytes(wkb) return wkb_reader_read(self.ptr, wkb_s, len(wkb_s)) elif isinstance(wkb, (bytes, str)): @@ -240,7 +239,7 @@ class WKBWriter(IOBase): # Fix GEOS output for empty polygon. # See https://trac.osgeo.org/geos/ticket/680. wkb = wkb[:-8] + b'\0' * 4 - return six.memoryview(wkb) + return memoryview(wkb) def write_hex(self, geom): "Returns the HEXEWKB representation of the given geometry." diff --git a/django/contrib/gis/geos/prototypes/misc.py b/django/contrib/gis/geos/prototypes/misc.py index 4a82888d09..2d890c3d31 100644 --- a/django/contrib/gis/geos/prototypes/misc.py +++ b/django/contrib/gis/geos/prototypes/misc.py @@ -7,7 +7,6 @@ from ctypes import POINTER, c_double, c_int from django.contrib.gis.geos.libgeos import GEOM_PTR, GEOSFuncFactory from django.contrib.gis.geos.prototypes.errcheck import check_dbl, check_string from django.contrib.gis.geos.prototypes.geom import geos_char_p -from django.utils.six.moves import range __all__ = ['geos_area', 'geos_distance', 'geos_length', 'geos_isvalidreason'] diff --git a/django/contrib/gis/measure.py b/django/contrib/gis/measure.py index 8691d009a6..a9b9e8a75f 100644 --- a/django/contrib/gis/measure.py +++ b/django/contrib/gis/measure.py @@ -38,8 +38,6 @@ and Geoff Biggs' PhD work on dimensioned units for robotics. from decimal import Decimal from functools import total_ordering -from django.utils import six - __all__ = ['A', 'Area', 'D', 'Distance'] NUMERIC_TYPES = (int, float, Decimal) @@ -187,7 +185,7 @@ class MeasureBase(object): """ val = 0.0 default_unit = self.STANDARD_UNIT - for unit, value in six.iteritems(kwargs): + for unit, value in kwargs.items(): if not isinstance(value, float): value = float(value) if unit in self.UNITS: diff --git a/django/contrib/gis/utils/ogrinspect.py b/django/contrib/gis/utils/ogrinspect.py index c10364491d..52e0e655e4 100644 --- a/django/contrib/gis/utils/ogrinspect.py +++ b/django/contrib/gis/utils/ogrinspect.py @@ -8,7 +8,6 @@ from django.contrib.gis.gdal.field import ( OFTDate, OFTDateTime, OFTInteger, OFTInteger64, OFTReal, OFTString, OFTTime, ) -from django.utils.six.moves import zip def mapping(data_source, geom_name='geom', layer_key=0, multi_geom=False): diff --git a/django/contrib/messages/storage/cookie.py b/django/contrib/messages/storage/cookie.py index dec609dffa..b8d7f7474c 100644 --- a/django/contrib/messages/storage/cookie.py +++ b/django/contrib/messages/storage/cookie.py @@ -3,7 +3,6 @@ import json from django.conf import settings from django.contrib.messages.storage.base import BaseStorage, Message from django.http import SimpleCookie -from django.utils import six from django.utils.crypto import constant_time_compare, salted_hmac from django.utils.safestring import SafeData, mark_safe @@ -42,7 +41,7 @@ class MessageDecoder(json.JSONDecoder): return [self.process_messages(item) for item in obj] if isinstance(obj, dict): return {key: self.process_messages(value) - for key, value in six.iteritems(obj)} + for key, value in obj.items()} return obj def decode(self, s, **kwargs): diff --git a/django/contrib/sessions/backends/cache.py b/django/contrib/sessions/backends/cache.py index d50a17cdd8..c64d7f6a6c 100644 --- a/django/contrib/sessions/backends/cache.py +++ b/django/contrib/sessions/backends/cache.py @@ -3,7 +3,6 @@ from django.contrib.sessions.backends.base import ( CreateError, SessionBase, UpdateError, ) from django.core.cache import caches -from django.utils.six.moves import range KEY_PREFIX = "django.contrib.sessions.cache" diff --git a/django/contrib/sessions/serializers.py b/django/contrib/sessions/serializers.py index b272c9c95d..1badd17f46 100644 --- a/django/contrib/sessions/serializers.py +++ b/django/contrib/sessions/serializers.py @@ -1,9 +1,6 @@ -from django.core.signing import JSONSerializer as BaseJSONSerializer +import pickle -try: - from django.utils.six.moves import cPickle as pickle -except ImportError: - import pickle +from django.core.signing import JSONSerializer as BaseJSONSerializer class PickleSerializer(object): diff --git a/django/contrib/sitemaps/__init__.py b/django/contrib/sitemaps/__init__.py index 5721c8861d..6e30a30f09 100644 --- a/django/contrib/sitemaps/__init__.py +++ b/django/contrib/sitemaps/__init__.py @@ -1,11 +1,12 @@ +from urllib.parse import urlencode +from urllib.request import urlopen + from django.apps import apps as django_apps from django.conf import settings from django.core import paginator from django.core.exceptions import ImproperlyConfigured from django.urls import NoReverseMatch, reverse from django.utils import translation -from django.utils.six.moves.urllib.parse import urlencode -from django.utils.six.moves.urllib.request import urlopen PING_URL = "https://www.google.com/webmasters/tools/ping" diff --git a/django/contrib/staticfiles/finders.py b/django/contrib/staticfiles/finders.py index 81a919bf04..c3da95ddd3 100644 --- a/django/contrib/staticfiles/finders.py +++ b/django/contrib/staticfiles/finders.py @@ -8,7 +8,7 @@ from django.core.exceptions import ImproperlyConfigured from django.core.files.storage import ( FileSystemStorage, Storage, default_storage, ) -from django.utils import lru_cache, six +from django.utils import lru_cache from django.utils._os import safe_join from django.utils.functional import LazyObject, empty from django.utils.module_loading import import_string @@ -143,7 +143,7 @@ class AppDirectoriesFinder(BaseFinder): """ List all files in all app storages. """ - for storage in six.itervalues(self.storages): + for storage in self.storages.values(): if storage.exists(''): # check if storage location exists for path in utils.get_files(storage, ignore_patterns): yield path, storage diff --git a/django/contrib/staticfiles/handlers.py b/django/contrib/staticfiles/handlers.py index 8dedd60ce8..ce8b7e20c1 100644 --- a/django/contrib/staticfiles/handlers.py +++ b/django/contrib/staticfiles/handlers.py @@ -1,9 +1,10 @@ +from urllib.parse import urlparse +from urllib.request import url2pathname + from django.conf import settings from django.contrib.staticfiles import utils from django.contrib.staticfiles.views import serve from django.core.handlers.wsgi import WSGIHandler, get_path_info -from django.utils.six.moves.urllib.parse import urlparse -from django.utils.six.moves.urllib.request import url2pathname class StaticFilesHandler(WSGIHandler): diff --git a/django/contrib/staticfiles/management/commands/collectstatic.py b/django/contrib/staticfiles/management/commands/collectstatic.py index fac96e5bf4..3ee6d354af 100644 --- a/django/contrib/staticfiles/management/commands/collectstatic.py +++ b/django/contrib/staticfiles/management/commands/collectstatic.py @@ -9,7 +9,6 @@ from django.core.management.base import BaseCommand, CommandError from django.core.management.color import no_style from django.utils.encoding import force_text from django.utils.functional import cached_property -from django.utils.six.moves import input class Command(BaseCommand): diff --git a/django/contrib/staticfiles/storage.py b/django/contrib/staticfiles/storage.py index b033243ecc..fe4a7c39f7 100644 --- a/django/contrib/staticfiles/storage.py +++ b/django/contrib/staticfiles/storage.py @@ -4,6 +4,7 @@ import os import posixpath import re from collections import OrderedDict +from urllib.parse import unquote, urldefrag, urlsplit, urlunsplit from django.conf import settings from django.contrib.staticfiles.utils import check_settings, matches_patterns @@ -15,11 +16,6 @@ from django.core.files.base import ContentFile from django.core.files.storage import FileSystemStorage, get_storage_class from django.utils.encoding import force_bytes, force_text from django.utils.functional import LazyObject -from django.utils.six import iteritems -from django.utils.six.moves import range -from django.utils.six.moves.urllib.parse import ( - unquote, urldefrag, urlsplit, urlunsplit, -) class StaticFilesStorage(FileSystemStorage): @@ -293,7 +289,7 @@ class HashedFilesMixin(object): if name in adjustable_paths: old_hashed_name = hashed_name content = original_file.read().decode(settings.FILE_CHARSET) - for extension, patterns in iteritems(self._patterns): + for extension, patterns in self._patterns.items(): if matches_patterns(path, (extension,)): for pattern, template in patterns: converter = self.url_converter(name, hashed_files, template) diff --git a/django/contrib/staticfiles/views.py b/django/contrib/staticfiles/views.py index cec1247e5e..dfdbdac9e9 100644 --- a/django/contrib/staticfiles/views.py +++ b/django/contrib/staticfiles/views.py @@ -5,11 +5,11 @@ development, and SHOULD NOT be used in a production setting. """ import os import posixpath +from urllib.parse import unquote from django.conf import settings from django.contrib.staticfiles import finders from django.http import Http404 -from django.utils.six.moves.urllib.parse import unquote from django.views import static diff --git a/django/contrib/syndication/views.py b/django/contrib/syndication/views.py index fa9c5e7753..2cfe930338 100644 --- a/django/contrib/syndication/views.py +++ b/django/contrib/syndication/views.py @@ -5,7 +5,7 @@ from django.contrib.sites.shortcuts import get_current_site from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist from django.http import Http404, HttpResponse from django.template import TemplateDoesNotExist, loader -from django.utils import feedgenerator, six +from django.utils import feedgenerator from django.utils.encoding import force_text, iri_to_uri from django.utils.html import escape from django.utils.http import http_date @@ -83,9 +83,9 @@ class Feed(object): # catching the TypeError, because something inside the function # may raise the TypeError. This technique is more accurate. try: - code = six.get_function_code(attr) + code = attr.__code__ except AttributeError: - code = six.get_function_code(attr.__call__) + code = attr.__call__.__code__ if code.co_argcount == 2: # one argument is 'self' return attr(obj) else: diff --git a/django/core/cache/backends/db.py b/django/core/cache/backends/db.py index ad805324bd..97f307e24d 100644 --- a/django/core/cache/backends/db.py +++ b/django/core/cache/backends/db.py @@ -1,5 +1,6 @@ "Database cache backend." import base64 +import pickle from datetime import datetime from django.conf import settings @@ -8,11 +9,6 @@ from django.db import DatabaseError, connections, models, router, transaction from django.utils import timezone from django.utils.encoding import force_bytes -try: - from django.utils.six.moves import cPickle as pickle -except ImportError: - import pickle - class Options(object): """A class that will quack like a Django model _meta class. diff --git a/django/core/cache/backends/filebased.py b/django/core/cache/backends/filebased.py index 7c2c5c7edb..88509ed8de 100644 --- a/django/core/cache/backends/filebased.py +++ b/django/core/cache/backends/filebased.py @@ -4,6 +4,7 @@ import glob import hashlib import io import os +import pickle import random import tempfile import time @@ -13,11 +14,6 @@ from django.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache from django.core.files.move import file_move_safe from django.utils.encoding import force_bytes -try: - from django.utils.six.moves import cPickle as pickle -except ImportError: - import pickle - class FileBasedCache(BaseCache): cache_suffix = '.djcache' diff --git a/django/core/cache/backends/locmem.py b/django/core/cache/backends/locmem.py index 8916ad176c..cf86dcaa0c 100644 --- a/django/core/cache/backends/locmem.py +++ b/django/core/cache/backends/locmem.py @@ -1,17 +1,12 @@ "Thread-safe in-memory cache backend." +import pickle import time from contextlib import contextmanager from django.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache from django.utils.synch import RWLock -try: - from django.utils.six.moves import cPickle as pickle -except ImportError: - import pickle - - # Global in-memory store of cache data. Keyed by name, to provide # multiple named local memory caches. _caches = {} diff --git a/django/core/files/storage.py b/django/core/files/storage.py index 9cd4196c23..cf17eea339 100644 --- a/django/core/files/storage.py +++ b/django/core/files/storage.py @@ -1,6 +1,7 @@ import errno import os from datetime import datetime +from urllib.parse import urljoin from django.conf import settings from django.core.exceptions import SuspiciousFileOperation @@ -14,7 +15,6 @@ from django.utils.deconstruct import deconstructible from django.utils.encoding import filepath_to_uri, force_text from django.utils.functional import LazyObject, cached_property from django.utils.module_loading import import_string -from django.utils.six.moves.urllib.parse import urljoin from django.utils.text import get_valid_filename __all__ = ('Storage', 'FileSystemStorage', 'DefaultStorage', 'default_storage') diff --git a/django/core/mail/message.py b/django/core/mail/message.py index a8ea1f0991..117f2dddfc 100644 --- a/django/core/mail/message.py +++ b/django/core/mail/message.py @@ -14,11 +14,10 @@ from email.mime.message import MIMEMessage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.utils import formatdate, getaddresses, parseaddr -from io import BytesIO +from io import BytesIO, StringIO from django.conf import settings from django.core.mail.utils import DNS_NAME -from django.utils import six from django.utils.encoding import force_text # Don't BASE64-encode UTF-8 messages so that we avoid unwanted attention from @@ -164,7 +163,7 @@ class MIMEMixin(): This overrides the default as_string() implementation to not mangle lines that begin with 'From '. See bug #13433 for details. """ - fp = six.StringIO() + fp = StringIO() g = generator.Generator(fp, mangle_from_=False) g.flatten(self, unixfrom=unixfrom, linesep=linesep) return fp.getvalue() diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py index 6b89fff351..00ee58a34b 100644 --- a/django/core/management/__init__.py +++ b/django/core/management/__init__.py @@ -12,7 +12,7 @@ from django.core.management.base import ( BaseCommand, CommandError, CommandParser, handle_default_options, ) from django.core.management.color import color_style -from django.utils import autoreload, lru_cache, six +from django.utils import autoreload, lru_cache from django.utils._os import npath, upath from django.utils.encoding import force_text @@ -154,7 +154,7 @@ class ManagementUtility(object): "Available subcommands:", ] commands_dict = defaultdict(lambda: []) - for name, app in six.iteritems(get_commands()): + for name, app in get_commands().items(): if app == 'django.core': app = 'django' else: diff --git a/django/core/management/commands/flush.py b/django/core/management/commands/flush.py index dbe870f322..8d1621b116 100644 --- a/django/core/management/commands/flush.py +++ b/django/core/management/commands/flush.py @@ -7,7 +7,6 @@ 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 -from django.utils.six.moves import input class Command(BaseCommand): diff --git a/django/core/management/commands/makemigrations.py b/django/core/management/commands/makemigrations.py index b6a31d16fd..3364d958a9 100644 --- a/django/core/management/commands/makemigrations.py +++ b/django/core/management/commands/makemigrations.py @@ -17,8 +17,6 @@ from django.db.migrations.questioner import ( from django.db.migrations.state import ProjectState from django.db.migrations.utils import get_migration_name_timestamp from django.db.migrations.writer import MigrationWriter -from django.utils.six import iteritems -from django.utils.six.moves import zip class Command(BaseCommand): @@ -102,7 +100,7 @@ class Command(BaseCommand): # If app_labels is specified, filter out conflicting migrations for unspecified apps if app_labels: conflicts = { - app_label: conflict for app_label, conflict in iteritems(conflicts) + app_label: conflict for app_label, conflict in conflicts.items() if app_label in app_labels } diff --git a/django/core/management/commands/squashmigrations.py b/django/core/management/commands/squashmigrations.py index dacc8fe6ce..5556b24745 100644 --- a/django/core/management/commands/squashmigrations.py +++ b/django/core/management/commands/squashmigrations.py @@ -7,7 +7,6 @@ from django.db.migrations.loader import AmbiguityError, MigrationLoader from django.db.migrations.migration import SwappableTuple from django.db.migrations.optimizer import MigrationOptimizer from django.db.migrations.writer import MigrationWriter -from django.utils import six from django.utils.version import get_docs_version @@ -86,7 +85,7 @@ class Command(BaseCommand): if self.interactive: answer = None while not answer or answer not in "yn": - answer = six.moves.input("Do you wish to proceed? [yN] ") + answer = input("Do you wish to proceed? [yN] ") if not answer: answer = "n" break diff --git a/django/core/management/templates.py b/django/core/management/templates.py index 775e75201b..ccc4920fe3 100644 --- a/django/core/management/templates.py +++ b/django/core/management/templates.py @@ -10,6 +10,7 @@ import stat import sys import tempfile from os import path +from urllib.request import urlretrieve import django from django.conf import settings @@ -17,7 +18,6 @@ from django.core.management.base import BaseCommand, CommandError from django.core.management.utils import handle_extensions from django.template import Context, Engine from django.utils import archive -from django.utils.six.moves.urllib.request import urlretrieve from django.utils.version import get_docs_version _drive_re = re.compile('^([a-z]):', re.I) diff --git a/django/core/paginator.py b/django/core/paginator.py index ae085bf837..82aad33a15 100644 --- a/django/core/paginator.py +++ b/django/core/paginator.py @@ -2,7 +2,6 @@ import collections import warnings from math import ceil -from django.utils import six from django.utils.functional import cached_property from django.utils.translation import ugettext_lazy as _ @@ -99,7 +98,7 @@ class Paginator(object): Returns a 1-based range of pages for iterating through within a template for loop. """ - return six.moves.range(1, self.num_pages + 1) + return range(1, self.num_pages + 1) def _check_object_list_is_ordered(self): """ diff --git a/django/core/serializers/__init__.py b/django/core/serializers/__init__.py index e62dbf75da..57d149cf0c 100644 --- a/django/core/serializers/__init__.py +++ b/django/core/serializers/__init__.py @@ -21,7 +21,6 @@ import importlib from django.apps import apps from django.conf import settings from django.core.serializers.base import SerializerDoesNotExist -from django.utils import six # Built-in serializers BUILTIN_SERIALIZERS = { @@ -109,7 +108,7 @@ def get_serializer_formats(): def get_public_serializer_formats(): if not _serializers: _load_serializers() - return [k for k, v in six.iteritems(_serializers) if not v.Serializer.internal_use_only] + return [k for k, v in _serializers.items() if not v.Serializer.internal_use_only] def get_deserializer(format): diff --git a/django/core/serializers/base.py b/django/core/serializers/base.py index 2a10fbe19e..bd35c0b797 100644 --- a/django/core/serializers/base.py +++ b/django/core/serializers/base.py @@ -1,8 +1,9 @@ """ Module for abstract serializer/unserializer base classes. """ +from io import StringIO + from django.db import models -from django.utils import six class SerializerDoesNotExist(KeyError): @@ -59,7 +60,7 @@ class Serializer(object): # internal Django use. internal_use_only = False progress_class = ProgressBar - stream_class = six.StringIO + stream_class = StringIO def serialize(self, queryset, **options): """ @@ -158,7 +159,7 @@ class Serializer(object): return self.stream.getvalue() -class Deserializer(six.Iterator): +class Deserializer: """ Abstract base deserializer class. """ @@ -169,7 +170,7 @@ class Deserializer(six.Iterator): """ self.options = options if isinstance(stream_or_string, str): - self.stream = six.StringIO(stream_or_string) + self.stream = StringIO(stream_or_string) else: self.stream = stream_or_string diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py index 9db5c2e6a6..7b7510be41 100644 --- a/django/core/serializers/python.py +++ b/django/core/serializers/python.py @@ -9,7 +9,6 @@ from django.apps import apps from django.conf import settings from django.core.serializers import base from django.db import DEFAULT_DB_ALIAS, models -from django.utils import six from django.utils.encoding import force_text, is_protected_type @@ -113,7 +112,7 @@ def Deserializer(object_list, **options): field_names = field_names_cache[Model] # Handle each field - for (field_name, field_value) in six.iteritems(d["fields"]): + for (field_name, field_value) in d["fields"].items(): if ignore and field_name not in field_names: # skip fields no longer on model diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py index e27378e7a5..da55eac58d 100644 --- a/django/core/servers/basehttp.py +++ b/django/core/servers/basehttp.py @@ -9,6 +9,7 @@ been reviewed for security issues. DON'T USE IT FOR PRODUCTION USE! import logging import socket +import socketserver import sys from wsgiref import simple_server @@ -16,7 +17,6 @@ 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 -from django.utils.six.moves import socketserver __all__ = ('WSGIServer', 'WSGIRequestHandler') diff --git a/django/core/validators.py b/django/core/validators.py index e2fcd6f72e..6e7220c826 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -1,12 +1,12 @@ import os import re +from urllib.parse import urlsplit, urlunsplit from django.core.exceptions import ValidationError from django.utils.deconstruct import deconstructible from django.utils.encoding import force_text from django.utils.functional import SimpleLazyObject from django.utils.ipv6 import is_valid_ipv6_address -from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit from django.utils.translation import ugettext_lazy as _, ungettext_lazy # These values, if given to validate(), will trigger the self.required check. diff --git a/django/db/backends/base/base.py b/django/db/backends/base/base.py index c50cf5266a..ea976519ec 100644 --- a/django/db/backends/base/base.py +++ b/django/db/backends/base/base.py @@ -4,6 +4,7 @@ import warnings from collections import deque from contextlib import contextmanager +import _thread import pytz from django.conf import settings @@ -16,7 +17,6 @@ from django.db.transaction import TransactionManagementError from django.db.utils import DatabaseError, DatabaseErrorWrapper from django.utils import timezone from django.utils.functional import cached_property -from django.utils.six.moves import _thread as thread NO_DB_ALIAS = '__no_db__' @@ -82,7 +82,7 @@ class BaseDatabaseWrapper(object): # Thread-safety related attributes. self.allow_thread_sharing = allow_thread_sharing - self._thread_ident = thread.get_ident() + self._thread_ident = _thread.get_ident() # A list of no-argument functions to run when the transaction commits. # Each entry is an (sids, func) tuple, where sids is a set of the @@ -326,7 +326,7 @@ class BaseDatabaseWrapper(object): if not self._savepoint_allowed(): return - thread_ident = thread.get_ident() + thread_ident = _thread.get_ident() tid = str(thread_ident).replace('-', '') self.savepoint_state += 1 @@ -533,13 +533,13 @@ class BaseDatabaseWrapper(object): authorized to be shared between threads (via the `allow_thread_sharing` property). Raises an exception if the validation fails. """ - if not (self.allow_thread_sharing or self._thread_ident == thread.get_ident()): + if not (self.allow_thread_sharing or self._thread_ident == _thread.get_ident()): raise DatabaseError( "DatabaseWrapper objects created in a " "thread can only be used in that same thread. The object " "with alias '%s' was created in thread id %s and this is " "thread id %s." - % (self.alias, self._thread_ident, thread.get_ident()) + % (self.alias, self._thread_ident, _thread.get_ident()) ) # ##### Miscellaneous ##### diff --git a/django/db/backends/base/creation.py b/django/db/backends/base/creation.py index 0cb6d75ff3..cf3e6c3347 100644 --- a/django/db/backends/base/creation.py +++ b/django/db/backends/base/creation.py @@ -1,11 +1,10 @@ import sys +from io import StringIO from django.apps import apps from django.conf import settings from django.core import serializers from django.db import router -from django.utils.six import StringIO -from django.utils.six.moves import input # The prefix to put on the default database name when creating # the test database. diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index c365c673c5..257dab0b9d 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -516,7 +516,7 @@ class FormatStylePlaceholderCursor(object): return CursorIterator(self.cursor) -class CursorIterator(six.Iterator): +class CursorIterator: """ Cursor iterator wrapper that invokes our custom row factory. """ diff --git a/django/db/backends/oracle/creation.py b/django/db/backends/oracle/creation.py index d34f2a2d50..adbf92b6a3 100644 --- a/django/db/backends/oracle/creation.py +++ b/django/db/backends/oracle/creation.py @@ -5,7 +5,6 @@ from django.db.backends.base.creation import BaseDatabaseCreation from django.db.utils import DatabaseError from django.utils.crypto import get_random_string from django.utils.functional import cached_property -from django.utils.six.moves import input TEST_DATABASE_PREFIX = 'test_' diff --git a/django/db/backends/postgresql/client.py b/django/db/backends/postgresql/client.py index dd3d40c064..005f43ddb8 100644 --- a/django/db/backends/postgresql/client.py +++ b/django/db/backends/postgresql/client.py @@ -3,7 +3,6 @@ import subprocess from django.core.files.temp import NamedTemporaryFile from django.db.backends.base.client import BaseDatabaseClient -from django.utils.six import print_ def _escape_pgpass(txt): @@ -40,7 +39,7 @@ class DatabaseClient(BaseDatabaseClient): # Create temporary .pgpass file. temp_pgpass = NamedTemporaryFile(mode='w+') try: - print_( + print( _escape_pgpass(host) or '*', str(port) or '*', _escape_pgpass(dbname) or '*', diff --git a/django/db/backends/sqlite3/creation.py b/django/db/backends/sqlite3/creation.py index 33661e1357..e58a1303a7 100644 --- a/django/db/backends/sqlite3/creation.py +++ b/django/db/backends/sqlite3/creation.py @@ -5,7 +5,6 @@ import sys from django.core.exceptions import ImproperlyConfigured from django.db.backends.base.creation import BaseDatabaseCreation from django.utils.encoding import force_text -from django.utils.six.moves import input class DatabaseCreation(BaseDatabaseCreation): diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py index 8a42d96e9a..492ad145fd 100644 --- a/django/db/migrations/loader.py +++ b/django/db/migrations/loader.py @@ -1,6 +1,6 @@ import os import sys -from importlib import import_module +from importlib import import_module, reload from django.apps import apps from django.conf import settings @@ -97,7 +97,7 @@ class MigrationLoader(object): continue # Force a reload if it's already loaded (tests need this) if was_loaded: - six.moves.reload_module(module) + reload(module) self.migrated_apps.add(app_config.label) directory = os.path.dirname(module.__file__) # Scan for .py files diff --git a/django/db/migrations/questioner.py b/django/db/migrations/questioner.py index 17b9da8eaf..caae498337 100644 --- a/django/db/migrations/questioner.py +++ b/django/db/migrations/questioner.py @@ -5,7 +5,6 @@ import sys from django.apps import apps from django.db.models.fields import NOT_PROVIDED from django.utils import datetime_safe, timezone -from django.utils.six.moves import input from .loader import MigrationLoader diff --git a/django/db/migrations/serializer.py b/django/db/migrations/serializer.py index bcd2268e2a..4786e7b012 100644 --- a/django/db/migrations/serializer.py +++ b/django/db/migrations/serializer.py @@ -1,3 +1,4 @@ +import builtins import collections import datetime import decimal @@ -10,7 +11,7 @@ from importlib import import_module from django.db import models from django.db.migrations.operations.base import Operation from django.db.migrations.utils import COMPILED_REGEX_TYPE, RegexObject -from django.utils import datetime_safe, six +from django.utils import datetime_safe from django.utils.encoding import force_text from django.utils.functional import LazyObject, Promise from django.utils.timezone import utc @@ -305,7 +306,7 @@ class TypeSerializer(BaseSerializer): return string, set(imports) if hasattr(self.value, "__module__"): module = self.value.__module__ - if module == six.moves.builtins.__name__: + if module == builtins.__name__: return self.value.__name__, set() else: return "%s.%s" % (module, self.value.__name__), {"import %s" % module} diff --git a/django/db/models/base.py b/django/db/models/base.py index 95700edb13..b5f6c1e353 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -26,10 +26,8 @@ from django.db.models.signals import ( class_prepared, post_init, post_save, pre_init, pre_save, ) from django.db.models.utils import make_model_tuple -from django.utils import six from django.utils.encoding import force_str, force_text from django.utils.functional import curry -from django.utils.six.moves import zip from django.utils.text import capfirst, get_text_list from django.utils.translation import ugettext_lazy as _ from django.utils.version import get_version @@ -385,7 +383,7 @@ class ModelState(object): self.adding = True -class Model(six.with_metaclass(ModelBase)): +class Model(metaclass=ModelBase): def __init__(self, *args, **kwargs): # Alias some things as locals to avoid repeat global lookups diff --git a/django/db/models/deletion.py b/django/db/models/deletion.py index 26073be3ba..0793475e65 100644 --- a/django/db/models/deletion.py +++ b/django/db/models/deletion.py @@ -3,7 +3,6 @@ from operator import attrgetter from django.db import IntegrityError, connections, transaction from django.db.models import signals, sql -from django.utils import six class ProtectedError(IntegrityError): @@ -198,7 +197,7 @@ class Collector(object): # Recursively collect concrete model's parent models, but not their # related objects. These will be found by meta.get_fields() concrete_model = model._meta.concrete_model - for ptr in six.itervalues(concrete_model._meta.parents): + for ptr in concrete_model._meta.parents.values(): if ptr: parent_objs = [getattr(obj, ptr.name) for obj in new_objs] self.collect(parent_objs, source=model, @@ -236,7 +235,7 @@ class Collector(object): ) def instances_with_model(self): - for model, instances in six.iteritems(self.data): + for model, instances in self.data.items(): for obj in instances: yield model, obj @@ -285,18 +284,18 @@ class Collector(object): deleted_counter[qs.model._meta.label] += count # update fields - for model, instances_for_fieldvalues in six.iteritems(self.field_updates): + for model, instances_for_fieldvalues in self.field_updates.items(): query = sql.UpdateQuery(model) - for (field, value), instances in six.iteritems(instances_for_fieldvalues): + for (field, value), instances in instances_for_fieldvalues.items(): query.update_batch([obj.pk for obj in instances], {field.name: value}, self.using) # reverse instance collections - for instances in six.itervalues(self.data): + for instances in self.data.values(): instances.reverse() # delete instances - for model, instances in six.iteritems(self.data): + for model, instances in self.data.items(): query = sql.DeleteQuery(model) pk_list = [obj.pk for obj in instances] count = query.delete_batch(pk_list, self.using) @@ -309,11 +308,11 @@ class Collector(object): ) # update collected instances - for model, instances_for_fieldvalues in six.iteritems(self.field_updates): - for (field, value), instances in six.iteritems(instances_for_fieldvalues): + for model, instances_for_fieldvalues in self.field_updates.items(): + for (field, value), instances in instances_for_fieldvalues.items(): for obj in instances: setattr(obj, field.attname, value) - for model, instances in six.iteritems(self.data): + for model, instances in self.data.items(): for instance in instances: setattr(instance, model._meta.pk.attname, None) return sum(deleted_counter.values()), dict(deleted_counter) diff --git a/django/db/models/lookups.py b/django/db/models/lookups.py index b8093ddc34..4b09143661 100644 --- a/django/db/models/lookups.py +++ b/django/db/models/lookups.py @@ -10,7 +10,6 @@ from django.db.models.fields import ( ) from django.db.models.query_utils import RegisterLookupMixin from django.utils.functional import cached_property -from django.utils.six.moves import range class Lookup(object): diff --git a/django/db/models/options.py b/django/db/models/options.py index cf3e031104..7594b70fb2 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -13,7 +13,6 @@ from django.db.models.fields import AutoField from django.db.models.fields.proxy import OrderWrt from django.db.models.fields.related import OneToOneField from django.db.models.query_utils import PathInfo -from django.utils import six from django.utils.datastructures import ImmutableList, OrderedSet from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_text @@ -228,7 +227,7 @@ class Options(object): if self.parents: # Promote the first parent link in lieu of adding yet another # field. - field = next(six.itervalues(self.parents)) + field = next(iter(self.parents.values())) # Look for a local field with the same name as the # first parent link. If a local field has already been # created, use it instead of promoting the parent diff --git a/django/db/models/query.py b/django/db/models/query.py index 69f84d72a9..1c20d9cbf6 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -480,7 +480,7 @@ class QuerySet(object): obj, created = self._create_object_from_params(lookup, params) if created: return obj, created - for k, v in six.iteritems(defaults): + for k, v in defaults.items(): setattr(obj, k, v() if callable(v) else v) obj.save(using=self.db) return obj, False @@ -1170,7 +1170,7 @@ class InstanceCheckMeta(type): return isinstance(instance, QuerySet) and instance.query.is_empty() -class EmptyQuerySet(six.with_metaclass(InstanceCheckMeta)): +class EmptyQuerySet(metaclass=InstanceCheckMeta): """ Marker class usable for checking if a queryset is empty by .none(): isinstance(qs.none(), EmptyQuerySet) -> True diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 37442c06c4..41733210c4 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -11,7 +11,6 @@ from django.db.models.sql.constants import ( from django.db.models.sql.query import Query, get_order_dir from django.db.transaction import TransactionManagementError from django.db.utils import DatabaseError -from django.utils.six.moves import zip FORCE = object() diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py index 57ba7dfc8d..3acef8faf5 100644 --- a/django/db/models/sql/query.py +++ b/django/db/models/sql/query.py @@ -30,7 +30,6 @@ from django.db.models.sql.datastructures import ( from django.db.models.sql.where import ( AND, OR, ExtraWhere, NothingNode, WhereNode, ) -from django.utils import six from django.utils.encoding import force_text from django.utils.tree import Node @@ -104,7 +103,7 @@ class RawQuery(object): if params_type is tuple: params = tuple(adapter(val) for val in self.params) elif params_type is dict: - params = dict((key, adapter(val)) for key, val in six.iteritems(self.params)) + params = {key: adapter(val) for key, val in self.params.items()} else: raise RuntimeError("Unexpected params type: %s" % params_type) @@ -665,23 +664,23 @@ class Query(object): # slight complexity here is handling fields that exist on parent # models. workset = {} - for model, values in six.iteritems(seen): + for model, values in seen.items(): for field in model._meta.fields: if field in values: continue m = field.model._meta.concrete_model add_to_dict(workset, m, field) - for model, values in six.iteritems(must_include): + for model, values in must_include.items(): # If we haven't included a model in workset, we don't add the # corresponding must_include fields for that model, since an # empty set means "include all fields". That's why there's no # "else" branch here. if model in workset: workset[model].update(values) - for model, values in six.iteritems(workset): + for model, values in workset.items(): callback(target, model, values) else: - for model, values in six.iteritems(must_include): + for model, values in must_include.items(): if model in seen: seen[model].update(values) else: @@ -695,7 +694,7 @@ class Query(object): for model in orig_opts.get_parent_list(): if model not in seen: seen[model] = set() - for model, values in six.iteritems(seen): + for model, values in seen.items(): callback(target, model, values) def table_alias(self, table_name, create=False): @@ -813,7 +812,7 @@ class Query(object): (key, col.relabeled_clone(change_map)) for key, col in self._annotations.items()) # 2. Rename the alias in the internal table/alias datastructures. - for old_alias, new_alias in six.iteritems(change_map): + for old_alias, new_alias in change_map.items(): if old_alias not in self.alias_map: continue alias_data = self.alias_map[old_alias].relabeled_clone(change_map) @@ -1698,7 +1697,7 @@ class Query(object): self.group_by.append(col) if self.annotation_select: - for alias, annotation in six.iteritems(self.annotation_select): + for alias, annotation in self.annotation_select.items(): for col in annotation.get_group_by_cols(): self.group_by.append(col) diff --git a/django/db/models/sql/subqueries.py b/django/db/models/sql/subqueries.py index 089f04e04e..cfdadefdff 100644 --- a/django/db/models/sql/subqueries.py +++ b/django/db/models/sql/subqueries.py @@ -9,7 +9,6 @@ from django.db.models.sql.constants import ( CURSOR, GET_ITERATOR_CHUNK_SIZE, NO_RESULTS, ) from django.db.models.sql.query import Query -from django.utils import six __all__ = ['DeleteQuery', 'UpdateQuery', 'InsertQuery', 'AggregateQuery'] @@ -120,7 +119,7 @@ class UpdateQuery(Query): querysets. """ values_seq = [] - for name, val in six.iteritems(values): + for name, val in values.items(): field = self.get_meta().get_field(name) direct = not (field.auto_created and not field.concrete) or not field.concrete model = field.model._meta.concrete_model @@ -164,7 +163,7 @@ class UpdateQuery(Query): if not self.related_updates: return [] result = [] - for model, values in six.iteritems(self.related_updates): + for model, values in self.related_updates.items(): query = UpdateQuery(model) query.values = values if self.related_ids is not None: diff --git a/django/dispatch/dispatcher.py b/django/dispatch/dispatcher.py index 8cf1680b6e..706c9eebbf 100644 --- a/django/dispatch/dispatcher.py +++ b/django/dispatch/dispatcher.py @@ -3,7 +3,6 @@ import threading import weakref from django.utils.inspect import func_accepts_kwargs -from django.utils.six.moves import range def _make_id(target): diff --git a/django/forms/fields.py b/django/forms/fields.py index 5be10708c3..94a7bbbfc2 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -11,6 +11,7 @@ import sys import uuid from decimal import Decimal, DecimalException from io import BytesIO +from urllib.parse import urlsplit, urlunsplit from django.core import validators from django.core.exceptions import ValidationError @@ -30,7 +31,6 @@ from django.utils.dateparse import parse_duration from django.utils.duration import duration_string from django.utils.encoding import force_str, force_text from django.utils.ipv6 import clean_ipv6_address -from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit from django.utils.translation import ugettext_lazy as _, ungettext_lazy __all__ = ( diff --git a/django/forms/forms.py b/django/forms/forms.py index c8086b1361..de19edb668 100644 --- a/django/forms/forms.py +++ b/django/forms/forms.py @@ -12,7 +12,6 @@ from django.forms.fields import Field, FileField # pretty_name is imported for backwards compatibility in Django 1.9 from django.forms.utils import ErrorDict, ErrorList, pretty_name # NOQA from django.forms.widgets import Media, MediaDefiningClass -from django.utils import six from django.utils.encoding import force_text from django.utils.functional import cached_property from django.utils.html import conditional_escape, html_safe @@ -504,7 +503,7 @@ class BaseForm(object): return value -class Form(six.with_metaclass(DeclarativeFieldsMetaclass, BaseForm)): +class Form(BaseForm, metaclass=DeclarativeFieldsMetaclass): "A collection of Fields, plus their associated data." # This is a separate class from BaseForm in order to abstract the way # self.fields is specified. This class (Form) is the one that does the diff --git a/django/forms/formsets.py b/django/forms/formsets.py index 60638c475c..964a83d4ca 100644 --- a/django/forms/formsets.py +++ b/django/forms/formsets.py @@ -6,7 +6,6 @@ from django.forms.widgets import HiddenInput from django.utils.functional import cached_property from django.utils.html import html_safe from django.utils.safestring import mark_safe -from django.utils.six.moves import range from django.utils.translation import ugettext as _, ungettext __all__ = ('BaseFormSet', 'formset_factory', 'all_valid') diff --git a/django/forms/models.py b/django/forms/models.py index c3a1b81c8c..093a7a6078 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -16,7 +16,6 @@ from django.forms.utils import ErrorList from django.forms.widgets import ( HiddenInput, MultipleHiddenInput, SelectMultiple, ) -from django.utils import six from django.utils.encoding import force_text from django.utils.text import capfirst, get_text_list from django.utils.translation import ugettext, ugettext_lazy as _ @@ -250,7 +249,7 @@ class ModelFormMetaclass(DeclarativeFieldsMetaclass): opts.field_classes) # make sure opts.fields doesn't specify an invalid field - none_model_fields = [k for k, v in six.iteritems(fields) if not v] + none_model_fields = [k for k, v in fields.items() if not v] missing_fields = (set(none_model_fields) - set(new_class.declared_fields.keys())) if missing_fields: @@ -457,7 +456,7 @@ class BaseModelForm(BaseForm): save.alters_data = True -class ModelForm(six.with_metaclass(ModelFormMetaclass, BaseModelForm)): +class ModelForm(BaseModelForm, metaclass=ModelFormMetaclass): pass diff --git a/django/forms/widgets.py b/django/forms/widgets.py index e21dba0607..b04864205c 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -11,13 +11,12 @@ from itertools import chain from django.conf import settings from django.forms.utils import to_current_timezone from django.templatetags.static import static -from django.utils import datetime_safe, formats, six +from django.utils import datetime_safe, formats from django.utils.dates import MONTHS from django.utils.encoding import force_str, force_text from django.utils.formats import get_format from django.utils.html import format_html, html_safe from django.utils.safestring import mark_safe -from django.utils.six.moves import range from django.utils.translation import ugettext_lazy from .renderers import get_default_renderer @@ -152,7 +151,7 @@ class MediaDefiningClass(type): return new_class -class Widget(six.with_metaclass(MediaDefiningClass)): +class Widget(metaclass=MediaDefiningClass): needs_multipart_form = False # Determines does this widget need multipart form is_localized = False is_required = False diff --git a/django/http/cookie.py b/django/http/cookie.py index 7251d04c40..f45ef11295 100644 --- a/django/http/cookie.py +++ b/django/http/cookie.py @@ -1,6 +1,5 @@ import sys - -from django.utils.six.moves import http_cookies +from http import cookies # Cookie pickling bug is fixed in Python 2.7.9 and Python 3.4.3+ # http://bugs.python.org/issue22775 @@ -10,11 +9,11 @@ cookie_pickles_properly = ( ) if cookie_pickles_properly: - SimpleCookie = http_cookies.SimpleCookie + SimpleCookie = cookies.SimpleCookie else: - Morsel = http_cookies.Morsel + Morsel = cookies.Morsel - class SimpleCookie(http_cookies.SimpleCookie): + class SimpleCookie(cookies.SimpleCookie): if not cookie_pickles_properly: def __setitem__(self, key, value): # Apply the fix from http://bugs.python.org/issue22775 where @@ -41,5 +40,5 @@ def parse_cookie(cookie): key, val = key.strip(), val.strip() if key or val: # unquote using Python's algorithm. - cookiedict[key] = http_cookies._unquote(val) + cookiedict[key] = cookies._unquote(val) return cookiedict diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py index b1db1f81ca..4cbb98afdd 100644 --- a/django/http/multipartparser.py +++ b/django/http/multipartparser.py @@ -8,6 +8,7 @@ import base64 import binascii import cgi import sys +from urllib.parse import unquote from django.conf import settings from django.core.exceptions import ( @@ -19,7 +20,6 @@ from django.core.files.uploadhandler import ( from django.utils import six from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_text -from django.utils.six.moves.urllib.parse import unquote from django.utils.text import unescape_entities __all__ = ('MultiPartParser', 'MultiPartParserError', 'InputStreamExhausted') @@ -312,7 +312,7 @@ class MultiPartParser(object): handler.file.close() -class LazyStream(six.Iterator): +class LazyStream: """ The LazyStream wrapper allows one to get and "unget" bytes from a stream. @@ -429,7 +429,7 @@ class LazyStream(six.Iterator): ) -class ChunkIter(six.Iterator): +class ChunkIter: """ An iterable that will yield chunks of data. Given a file-like object as the constructor, this object will yield chunks of read operations from that @@ -453,7 +453,7 @@ class ChunkIter(six.Iterator): return self -class InterBoundaryIter(six.Iterator): +class InterBoundaryIter: """ A Producer that will iterate over boundaries. """ @@ -471,7 +471,7 @@ class InterBoundaryIter(six.Iterator): raise StopIteration() -class BoundaryIter(six.Iterator): +class BoundaryIter: """ A Producer that is sensitive to boundaries. diff --git a/django/http/request.py b/django/http/request.py index fe1684ee58..a930c93b26 100644 --- a/django/http/request.py +++ b/django/http/request.py @@ -3,6 +3,7 @@ import re import sys from io import BytesIO from itertools import chain +from urllib.parse import quote, urlencode, urljoin, urlsplit from django.conf import settings from django.core import signing @@ -17,9 +18,6 @@ from django.utils.encoding import ( escape_uri_path, force_bytes, force_str, iri_to_uri, ) from django.utils.http import is_same_domain, limited_parse_qsl -from django.utils.six.moves.urllib.parse import ( - quote, urlencode, urljoin, urlsplit, -) RAISE_ERROR = object() host_validation_re = re.compile(r"^([a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9\.:]+\])(:\d+)?$") @@ -431,14 +429,14 @@ class QueryDict(MultiValueDict): def __copy__(self): result = self.__class__('', mutable=True, encoding=self.encoding) - for key, value in six.iterlists(self): + for key, value in self.lists(): result.setlist(key, value) return result def __deepcopy__(self, memo): result = self.__class__('', mutable=True, encoding=self.encoding) memo[id(self)] = result - for key, value in six.iterlists(self): + for key, value in self.lists(): result.setlist(copy.deepcopy(key, memo), copy.deepcopy(value, memo)) return result diff --git a/django/http/response.py b/django/http/response.py index 1c2677035d..c5294acbbd 100644 --- a/django/http/response.py +++ b/django/http/response.py @@ -4,20 +4,19 @@ import re import sys import time from email.header import Header +from http.client import responses +from urllib.parse import urlparse from django.conf import settings from django.core import signals, signing from django.core.exceptions import DisallowedRedirect from django.core.serializers.json import DjangoJSONEncoder from django.http.cookie import SimpleCookie -from django.utils import six, timezone +from django.utils import timezone from django.utils.encoding import ( force_bytes, force_str, force_text, iri_to_uri, ) from django.utils.http import cookie_date -from django.utils.six.moves import map -from django.utils.six.moves.http_client import responses -from django.utils.six.moves.urllib.parse import urlparse _charset_from_content_type_re = re.compile(r';\s*charset=(?P[^\s;]+)', re.I) @@ -26,7 +25,7 @@ class BadHeaderError(ValueError): pass -class HttpResponseBase(six.Iterator): +class HttpResponseBase: """ An HTTP response base class with dictionary-accessed headers. diff --git a/django/middleware/common.py b/django/middleware/common.py index d18d23fa43..304e6318c4 100644 --- a/django/middleware/common.py +++ b/django/middleware/common.py @@ -1,5 +1,6 @@ import re import warnings +from urllib.parse import urlparse from django import http from django.conf import settings @@ -11,7 +12,6 @@ from django.utils.cache import ( ) from django.utils.deprecation import MiddlewareMixin, RemovedInDjango21Warning from django.utils.encoding import force_text -from django.utils.six.moves.urllib.parse import urlparse class CommonMiddleware(MiddlewareMixin): diff --git a/django/middleware/csrf.py b/django/middleware/csrf.py index 14d3537f29..f6584cbea8 100644 --- a/django/middleware/csrf.py +++ b/django/middleware/csrf.py @@ -7,6 +7,7 @@ against request forgeries from other sites. import logging import re import string +from urllib.parse import urlparse from django.conf import settings from django.core.exceptions import ImproperlyConfigured @@ -16,8 +17,6 @@ from django.utils.crypto import constant_time_compare, get_random_string from django.utils.deprecation import MiddlewareMixin from django.utils.encoding import force_text from django.utils.http import is_same_domain -from django.utils.six.moves import zip -from django.utils.six.moves.urllib.parse import urlparse logger = logging.getLogger('django.security.csrf') diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py index 2c455aff7b..888d837130 100644 --- a/django/template/defaulttags.py +++ b/django/template/defaulttags.py @@ -7,7 +7,7 @@ from datetime import datetime from itertools import cycle as itertools_cycle, groupby from django.conf import settings -from django.utils import six, timezone +from django.utils import timezone from django.utils.encoding import force_text from django.utils.html import conditional_escape, format_html from django.utils.lorem_ipsum import paragraphs, words @@ -521,8 +521,7 @@ class WithNode(Node): return "" def render(self, context): - values = {key: val.resolve(context) for key, val in - six.iteritems(self.extra_context)} + values = {key: val.resolve(context) for key, val in self.extra_context.items()} with context.push(**values): return self.nodelist.render(context) diff --git a/django/template/loader_tags.py b/django/template/loader_tags.py index e5c44c88b0..2c27902238 100644 --- a/django/template/loader_tags.py +++ b/django/template/loader_tags.py @@ -3,7 +3,6 @@ import posixpath import warnings from collections import defaultdict -from django.utils import six from django.utils.deprecation import RemovedInDjango21Warning from django.utils.safestring import mark_safe @@ -25,7 +24,7 @@ class BlockContext(object): self.blocks = defaultdict(list) def add_blocks(self, blocks): - for name, block in six.iteritems(blocks): + for name, block in blocks.items(): self.blocks[name].insert(0, block) def pop(self, name): @@ -183,7 +182,7 @@ class IncludeNode(Node): cache[template_name] = template values = { name: var.resolve(context) - for name, var in six.iteritems(self.extra_context) + for name, var in self.extra_context.items() } if self.isolated_context: return template.render(context.new(values)) diff --git a/django/templatetags/static.py b/django/templatetags/static.py index e4789bda71..4b25eca6a7 100644 --- a/django/templatetags/static.py +++ b/django/templatetags/static.py @@ -1,8 +1,9 @@ +from urllib.parse import quote, urljoin + from django import template from django.apps import apps from django.utils.encoding import iri_to_uri from django.utils.html import conditional_escape -from django.utils.six.moves.urllib.parse import quote, urljoin register = template.Library() diff --git a/django/test/client.py b/django/test/client.py index 1c08ada1cf..3b31dae9bd 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -6,6 +6,7 @@ import sys from copy import copy from importlib import import_module from io import BytesIO +from urllib.parse import urljoin, urlparse, urlsplit from django.conf import settings from django.core.handlers.base import BaseHandler @@ -24,7 +25,6 @@ from django.utils.encoding import force_bytes, force_str, uri_to_iri from django.utils.functional import SimpleLazyObject, curry from django.utils.http import urlencode from django.utils.itercompat import is_iterable -from django.utils.six.moves.urllib.parse import urljoin, urlparse, urlsplit __all__ = ('Client', 'RedirectCycleError', 'RequestFactory', 'encode_file', 'encode_multipart') diff --git a/django/test/runner.py b/django/test/runner.py index 487ec7c682..77a309d8e6 100644 --- a/django/test/runner.py +++ b/django/test/runner.py @@ -8,6 +8,7 @@ import textwrap import unittest import warnings from importlib import import_module +from io import StringIO from django.core.management import call_command from django.db import connections @@ -18,7 +19,6 @@ from django.test.utils import ( ) from django.utils.datastructures import OrderedSet from django.utils.deprecation import RemovedInDjango21Warning -from django.utils.six import StringIO try: import tblib.pickling_support diff --git a/django/test/selenium.py b/django/test/selenium.py index de3744c91e..236f7d8053 100644 --- a/django/test/selenium.py +++ b/django/test/selenium.py @@ -4,7 +4,6 @@ from contextlib import contextmanager from django.test import LiveServerTestCase, tag from django.utils.module_loading import import_string -from django.utils.six import with_metaclass from django.utils.text import capfirst @@ -54,7 +53,7 @@ class SeleniumTestCaseBase(type(LiveServerTestCase)): @tag('selenium') -class SeleniumTestCase(with_metaclass(SeleniumTestCaseBase, LiveServerTestCase)): +class SeleniumTestCase(LiveServerTestCase, metaclass=SeleniumTestCaseBase): implicit_wait = 10 @classmethod diff --git a/django/test/testcases.py b/django/test/testcases.py index 9d08940f5a..dad3fb2df0 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -9,6 +9,8 @@ from contextlib import contextmanager from copy import copy from functools import wraps from unittest.util import safe_repr +from urllib.parse import unquote, urljoin, urlparse, urlsplit +from urllib.request import url2pathname from django.apps import apps from django.conf import settings @@ -31,13 +33,8 @@ from django.test.utils import ( CaptureQueriesContext, ContextList, compare_xml, modify_settings, override_settings, ) -from django.utils import six from django.utils.decorators import classproperty from django.utils.encoding import force_text -from django.utils.six.moves.urllib.parse import ( - unquote, urljoin, urlparse, urlsplit, -) -from django.utils.six.moves.urllib.request import url2pathname from django.views.static import serve __all__ = ('TestCase', 'TransactionTestCase', @@ -921,7 +918,7 @@ class TransactionTestCase(SimpleTestCase): inhibit_post_migrate=inhibit_post_migrate) def assertQuerysetEqual(self, qs, values, transform=repr, ordered=True, msg=None): - items = six.moves.map(transform, qs) + items = map(transform, qs) if not ordered: return self.assertEqual(Counter(items), Counter(values), msg=msg) values = list(values) diff --git a/django/test/utils.py b/django/test/utils.py index 7395396fbb..55428ccf85 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -6,6 +6,7 @@ import time import warnings from contextlib import contextmanager from functools import wraps +from io import StringIO from types import SimpleNamespace from unittest import TestCase, skipIf, skipUnless from xml.dom.minidom import Node, parseString @@ -21,7 +22,6 @@ from django.db.models.options import Options from django.template import Template from django.test.signals import setting_changed, template_rendered from django.urls import get_script_prefix, set_script_prefix -from django.utils import six from django.utils.decorators import available_attrs from django.utils.encoding import force_str from django.utils.translation import deactivate @@ -728,7 +728,7 @@ def captured_output(stream_name): Note: This function and the following ``captured_std*`` are copied from CPython's ``test.support`` module.""" orig_stdout = getattr(sys, stream_name) - setattr(sys, stream_name, six.StringIO()) + setattr(sys, stream_name, StringIO()) try: yield getattr(sys, stream_name) finally: @@ -840,7 +840,7 @@ class LoggingCaptureMixin(object): def setUp(self): self.logger = logging.getLogger('django') self.old_stream = self.logger.handlers[0].stream - self.logger_output = six.StringIO() + self.logger_output = StringIO() self.logger.handlers[0].stream = self.logger_output def tearDown(self): diff --git a/django/urls/base.py b/django/urls/base.py index c09eeed8f6..408bc36ead 100644 --- a/django/urls/base.py +++ b/django/urls/base.py @@ -1,8 +1,8 @@ from threading import local +from urllib.parse import urlsplit, urlunsplit from django.utils.encoding import force_text, iri_to_uri from django.utils.functional import lazy -from django.utils.six.moves.urllib.parse import urlsplit, urlunsplit from django.utils.translation import override from .exceptions import NoReverseMatch, Resolver404 diff --git a/django/utils/_os.py b/django/utils/_os.py index ddf2132f5f..6507e58764 100644 --- a/django/utils/_os.py +++ b/django/utils/_os.py @@ -5,7 +5,6 @@ from os.path import abspath, dirname, join, normcase, sep from django.core.exceptions import SuspiciousFileOperation from django.utils.encoding import force_text - abspathu = abspath diff --git a/django/utils/autoreload.py b/django/utils/autoreload.py index e7c9acbaea..d6a5b1a319 100644 --- a/django/utils/autoreload.py +++ b/django/utils/autoreload.py @@ -35,12 +35,13 @@ import sys import time import traceback +import _thread + from django.apps import apps from django.conf import settings from django.core.signals import request_finished from django.utils import six from django.utils._os import npath -from django.utils.six.moves import _thread as thread # This import does nothing, but it's necessary to avoid some race conditions # in the threading module. See http://code.djangoproject.com/ticket/2330 . @@ -293,7 +294,7 @@ 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) + _thread.start_new_thread(main_func, args, kwargs) try: reloader_thread() except KeyboardInterrupt: @@ -311,7 +312,7 @@ def python_reloader(main_func, args, kwargs): def jython_reloader(main_func, args, kwargs): from _systemrestart import SystemRestart - thread.start_new_thread(main_func, args) + _thread.start_new_thread(main_func, args) while True: if code_changed(): raise SystemRestart diff --git a/django/utils/crypto.py b/django/utils/crypto.py index 554958b6ee..74dd9fd7b0 100644 --- a/django/utils/crypto.py +++ b/django/utils/crypto.py @@ -10,7 +10,6 @@ import time from django.conf import settings from django.utils.encoding import force_bytes -from django.utils.six.moves import range # Use the system PRNG if possible try: diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py index 7367924600..bb8166a734 100644 --- a/django/utils/datastructures.py +++ b/django/utils/datastructures.py @@ -1,8 +1,6 @@ import copy from collections import OrderedDict -from django.utils import six - class OrderedSet(object): """ @@ -189,7 +187,7 @@ class MultiValueDict(dict): def lists(self): """Yields (key, list) pairs.""" - return six.iteritems(super(MultiValueDict, self)) + return iter(super(MultiValueDict, self).items()) def values(self): """Yield the last value on every key list.""" @@ -218,7 +216,7 @@ class MultiValueDict(dict): self.setlistdefault(key).append(value) except TypeError: raise ValueError("MultiValueDict.update() takes either a MultiValueDict or dictionary") - for key, value in six.iteritems(kwargs): + for key, value in kwargs.items(): self.setlistdefault(key).append(value) def dict(self): diff --git a/django/utils/dateparse.py b/django/utils/dateparse.py index b2020b5281..d091100a0d 100644 --- a/django/utils/dateparse.py +++ b/django/utils/dateparse.py @@ -8,7 +8,6 @@ import datetime import re -from django.utils import six from django.utils.timezone import get_fixed_timezone, utc date_re = re.compile( @@ -60,7 +59,7 @@ def parse_date(value): """ match = date_re.match(value) if match: - kw = {k: int(v) for k, v in six.iteritems(match.groupdict())} + kw = {k: int(v) for k, v in match.groupdict().items()} return datetime.date(**kw) @@ -78,7 +77,7 @@ def parse_time(value): kw = match.groupdict() if kw['microsecond']: kw['microsecond'] = kw['microsecond'].ljust(6, '0') - kw = {k: int(v) for k, v in six.iteritems(kw) if v is not None} + kw = {k: int(v) for k, v in kw.items() if v is not None} return datetime.time(**kw) @@ -105,7 +104,7 @@ def parse_datetime(value): if tzinfo[0] == '-': offset = -offset tzinfo = get_fixed_timezone(offset) - kw = {k: int(v) for k, v in six.iteritems(kw) if v is not None} + kw = {k: int(v) for k, v in kw.items() if v is not None} kw['tzinfo'] = tzinfo return datetime.datetime(**kw) @@ -127,5 +126,5 @@ def parse_duration(value): kw['microseconds'] = kw['microseconds'].ljust(6, '0') if kw.get('seconds') and kw.get('microseconds') and kw['seconds'].startswith('-'): kw['microseconds'] = '-' + kw['microseconds'] - kw = {k: float(v) for k, v in six.iteritems(kw) if v is not None} + kw = {k: float(v) for k, v in kw.items() if v is not None} return sign * datetime.timedelta(**kw) diff --git a/django/utils/encoding.py b/django/utils/encoding.py index abd17526c6..71c2985e27 100644 --- a/django/utils/encoding.py +++ b/django/utils/encoding.py @@ -2,11 +2,10 @@ import codecs import datetime import locale from decimal import Decimal -from urllib.parse import unquote_to_bytes +from urllib.parse import quote, unquote_to_bytes from django.utils import six from django.utils.functional import Promise -from django.utils.six.moves.urllib.parse import quote class DjangoUnicodeDecodeError(UnicodeDecodeError): diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py index fbab58b905..33ef20e16b 100644 --- a/django/utils/feedgenerator.py +++ b/django/utils/feedgenerator.py @@ -22,11 +22,11 @@ For definitions of the different versions of RSS, see: http://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004/02/04/incompatible-rss """ import datetime +from io import StringIO +from urllib.parse import urlparse from django.utils import datetime_safe from django.utils.encoding import force_text, iri_to_uri -from django.utils.six import StringIO -from django.utils.six.moves.urllib.parse import urlparse from django.utils.timezone import utc from django.utils.xmlutils import SimplerXMLGenerator diff --git a/django/utils/functional.py b/django/utils/functional.py index 3e35582cbf..0efce6c635 100644 --- a/django/utils/functional.py +++ b/django/utils/functional.py @@ -2,8 +2,6 @@ import copy import operator from functools import total_ordering, wraps -from django.utils import six - # You can't trivially replace this with `functools.partial` because this binds # to classes and returns bound instances, whereas functools.partial (on @@ -193,7 +191,7 @@ def keep_lazy(*resultclasses): @wraps(func) def wrapper(*args, **kwargs): - for arg in list(args) + list(six.itervalues(kwargs)): + for arg in list(args) + list(kwargs.values()): if isinstance(arg, Promise): break else: diff --git a/django/utils/html.py b/django/utils/html.py index 430350fed6..1fb39bb9b6 100644 --- a/django/utils/html.py +++ b/django/utils/html.py @@ -1,15 +1,14 @@ """HTML utilities suitable for global use.""" import re +from urllib.parse import ( + parse_qsl, quote, unquote, urlencode, urlsplit, urlunsplit, +) -from django.utils import six from django.utils.encoding import force_str, force_text from django.utils.functional import keep_lazy, keep_lazy_text from django.utils.http import RFC3986_GENDELIMS, RFC3986_SUBDELIMS from django.utils.safestring import SafeData, SafeText, mark_safe -from django.utils.six.moves.urllib.parse import ( - parse_qsl, quote, unquote, urlencode, urlsplit, urlunsplit, -) from django.utils.text import normalize_newlines from .html_parser import HTMLParseError, HTMLParser @@ -93,7 +92,7 @@ def format_html(format_string, *args, **kwargs): of str.format or % interpolation to build up small HTML fragments. """ args_safe = map(conditional_escape, args) - kwargs_safe = {k: conditional_escape(v) for (k, v) in six.iteritems(kwargs)} + kwargs_safe = {k: conditional_escape(v) for (k, v) in kwargs.items()} return mark_safe(format_string.format(*args_safe, **kwargs_safe)) diff --git a/django/utils/html_parser.py b/django/utils/html_parser.py index d272004f77..e3e19ee9c3 100644 --- a/django/utils/html_parser.py +++ b/django/utils/html_parser.py @@ -1,14 +1,14 @@ -from django.utils.six.moves import html_parser as _html_parser +import html.parser try: - HTMLParseError = _html_parser.HTMLParseError + HTMLParseError = html.parser.HTMLParseError except AttributeError: # create a dummy class for Python 3.5+ where it's been removed class HTMLParseError(Exception): pass -class HTMLParser(_html_parser.HTMLParser): +class HTMLParser(html.parser.HTMLParser): """Explicitly set convert_charrefs to be False. This silences a deprecation warning on Python 3.4, but we can't do @@ -16,4 +16,4 @@ class HTMLParser(_html_parser.HTMLParser): argument. """ def __init__(self, convert_charrefs=False, **kwargs): - _html_parser.HTMLParser.__init__(self, convert_charrefs=convert_charrefs, **kwargs) + html.parser.HTMLParser.__init__(self, convert_charrefs=convert_charrefs, **kwargs) diff --git a/django/utils/http.py b/django/utils/http.py index 0308e14676..ae23eec06a 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -7,6 +7,10 @@ import unicodedata import warnings from binascii import Error as BinasciiError from email.utils import formatdate +from urllib.parse import ( + quote, quote_plus, unquote, unquote_plus, urlencode as original_urlencode, + urlparse, +) from django.core.exceptions import TooManyFieldsSent from django.utils import six @@ -14,10 +18,6 @@ from django.utils.datastructures import MultiValueDict from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_bytes, force_str, force_text from django.utils.functional import keep_lazy_text -from django.utils.six.moves.urllib.parse import ( - quote, quote_plus, unquote, unquote_plus, urlencode as original_urlencode, - urlparse, -) # based on RFC 7232, Appendix C ETAG_MATCH = re.compile(r''' diff --git a/django/utils/ipv6.py b/django/utils/ipv6.py index c41f1e2b46..a1e63be727 100644 --- a/django/utils/ipv6.py +++ b/django/utils/ipv6.py @@ -4,7 +4,6 @@ import re from django.core.exceptions import ValidationError -from django.utils.six.moves import range from django.utils.translation import ugettext_lazy as _ diff --git a/django/utils/regex_helper.py b/django/utils/regex_helper.py index bc4a09b359..f5cfc57156 100644 --- a/django/utils/regex_helper.py +++ b/django/utils/regex_helper.py @@ -8,7 +8,6 @@ should be good enough for a large class of URLS, however. import warnings from django.utils.deprecation import RemovedInDjango21Warning -from django.utils.six.moves import zip # Mapping of an escape character to a representative of that class. So, e.g., # "\w" is replaced by "x" in a reverse URL. A value of None means to ignore diff --git a/django/utils/termcolors.py b/django/utils/termcolors.py index 87ed8c1187..f75e068187 100644 --- a/django/utils/termcolors.py +++ b/django/utils/termcolors.py @@ -2,8 +2,6 @@ termcolors.py """ -from django.utils import six - color_names = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white') foreground = {color_names[x]: '3%s' % x for x in range(8)} background = {color_names[x]: '4%s' % x for x in range(8)} @@ -44,7 +42,7 @@ def colorize(text='', opts=(), **kwargs): code_list = [] if text == '' and len(opts) == 1 and opts[0] == 'reset': return '\x1b[%sm' % RESET - for k, v in six.iteritems(kwargs): + for k, v in kwargs.items(): if k == 'fg': code_list.append(foreground[v]) elif k == 'bg': diff --git a/django/utils/text.py b/django/utils/text.py index 15a9b6160a..d716a0b345 100644 --- a/django/utils/text.py +++ b/django/utils/text.py @@ -1,15 +1,14 @@ +import html.entities import re import unicodedata from gzip import GzipFile from io import BytesIO -from django.utils import six from django.utils.encoding import force_text from django.utils.functional import ( SimpleLazyObject, keep_lazy, keep_lazy_text, lazy, ) from django.utils.safestring import SafeText, mark_safe -from django.utils.six.moves import html_entities from django.utils.translation import pgettext, ugettext as _, ugettext_lazy @@ -369,12 +368,12 @@ def _replace_entity(match): c = int(text[1:], 16) else: c = int(text) - return six.unichr(c) + return chr(c) except ValueError: return match.group(0) else: try: - return six.unichr(html_entities.name2codepoint[text]) + return chr(html.entities.name2codepoint[text]) except (ValueError, KeyError): return match.group(0) diff --git a/django/utils/translation/template.py b/django/utils/translation/template.py index b6d8832f9c..42ff84dc27 100644 --- a/django/utils/translation/template.py +++ b/django/utils/translation/template.py @@ -1,12 +1,12 @@ import re import warnings +from io import StringIO from django.template.base import ( TOKEN_BLOCK, TOKEN_COMMENT, TOKEN_TEXT, TOKEN_VAR, TRANSLATOR_COMMENT_MARK, Lexer, ) from django.utils.encoding import force_text -from django.utils.six import StringIO from . import TranslatorCommentWarning, trim_whitespace diff --git a/django/views/generic/base.py b/django/views/generic/base.py index 4187e70b12..668aef7760 100644 --- a/django/views/generic/base.py +++ b/django/views/generic/base.py @@ -5,7 +5,6 @@ from django import http from django.core.exceptions import ImproperlyConfigured from django.template.response import TemplateResponse from django.urls import NoReverseMatch, reverse -from django.utils import six from django.utils.decorators import classonlymethod logger = logging.getLogger('django.request') @@ -38,7 +37,7 @@ class View(object): """ # Go through keyword arguments, and either save their values to our # instance, or raise an error. - for key, value in six.iteritems(kwargs): + for key, value in kwargs.items(): setattr(self, key, value) @classonlymethod diff --git a/django/views/i18n.py b/django/views/i18n.py index 1fc5461b1c..ada2624795 100644 --- a/django/views/i18n.py +++ b/django/views/i18n.py @@ -7,7 +7,6 @@ from django.apps import apps from django.conf import settings from django.template import Context, Engine from django.urls import translate_url -from django.utils import six from django.utils.encoding import force_text from django.utils.formats import get_format from django.utils.http import is_safe_url, urlunquote @@ -265,7 +264,7 @@ class JavaScriptCatalog(View): catalog = {} trans_cat = self.translation._catalog trans_fallback_cat = self.translation._fallback._catalog if self.translation._fallback else {} - for key, value in itertools.chain(six.iteritems(trans_cat), six.iteritems(trans_fallback_cat)): + for key, value in itertools.chain(iter(trans_cat.items()), iter(trans_fallback_cat.items())): if key == '' or key in catalog: continue if isinstance(key, str): diff --git a/django/views/static.py b/django/views/static.py index bfa171357d..a0f4bdab56 100644 --- a/django/views/static.py +++ b/django/views/static.py @@ -7,6 +7,7 @@ import os import posixpath import re import stat +from urllib.parse import unquote from django.http import ( FileResponse, Http404, HttpResponse, HttpResponseNotModified, @@ -14,7 +15,6 @@ from django.http import ( ) from django.template import Context, Engine, TemplateDoesNotExist, loader from django.utils.http import http_date, parse_http_date -from django.utils.six.moves.urllib.parse import unquote from django.utils.translation import ugettext as _, ugettext_lazy diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index e37e8a4256..868d04196f 100644 --- a/tests/admin_scripts/tests.py +++ b/tests/admin_scripts/tests.py @@ -12,6 +12,7 @@ import subprocess import sys import tempfile import unittest +from io import StringIO import django from django import conf, get_version @@ -27,7 +28,6 @@ from django.test import ( ) from django.utils._os import npath, upath from django.utils.encoding import force_text -from django.utils.six import StringIO custom_templates_dir = os.path.join(os.path.dirname(upath(__file__)), 'custom_templates') diff --git a/tests/admin_views/admin.py b/tests/admin_views/admin.py index b8d35b6d81..ffce2c0f34 100644 --- a/tests/admin_views/admin.py +++ b/tests/admin_views/admin.py @@ -1,5 +1,6 @@ import os import tempfile +from io import StringIO from wsgiref.util import FileWrapper from django import forms @@ -17,7 +18,6 @@ from django.forms.models import BaseModelFormSet from django.http import HttpResponse, StreamingHttpResponse from django.utils.html import format_html from django.utils.safestring import mark_safe -from django.utils.six import StringIO from .forms import MediaActionForm from .models import ( diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index fb404e5fd2..81b7e1f6a4 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -3,6 +3,7 @@ import json import os import re import unittest +from urllib.parse import parse_qsl, urljoin, urlparse from django.contrib.admin import AdminSite, ModelAdmin from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME @@ -36,7 +37,6 @@ from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_bytes, force_text, iri_to_uri from django.utils.html import escape from django.utils.http import urlencode -from django.utils.six.moves.urllib.parse import parse_qsl, urljoin, urlparse from . import customadmin from .admin import CityAdmin, site, site2 diff --git a/tests/aggregation_regress/tests.py b/tests/aggregation_regress/tests.py index afbc7c20b2..bc501fc94e 100644 --- a/tests/aggregation_regress/tests.py +++ b/tests/aggregation_regress/tests.py @@ -12,7 +12,6 @@ from django.db.models import ( ) from django.test import TestCase, skipUnlessAnyDBFeature, skipUnlessDBFeature from django.test.utils import Approximate -from django.utils import six from .models import ( Alfa, Author, Book, Bravo, Charlie, Clues, Entries, HardbackBook, ItemTag, @@ -103,7 +102,7 @@ class AggregationTests(TestCase): s3.books.add(cls.b3, cls.b4, cls.b6) def assertObjectAttrs(self, obj, **kwargs): - for attr, value in six.iteritems(kwargs): + for attr, value in kwargs.items(): self.assertEqual(getattr(obj, attr), value) def test_annotation_with_value(self): diff --git a/tests/auth_tests/test_deprecated_views.py b/tests/auth_tests/test_deprecated_views.py index d084f4dcef..d5088b9d8a 100644 --- a/tests/auth_tests/test_deprecated_views.py +++ b/tests/auth_tests/test_deprecated_views.py @@ -1,6 +1,7 @@ import datetime import itertools import re +from urllib.parse import ParseResult, urlparse from django.conf import settings from django.contrib.auth import SESSION_KEY @@ -14,7 +15,6 @@ from django.test import TestCase, override_settings from django.test.utils import ignore_warnings, patch_logger from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_text -from django.utils.six.moves.urllib.parse import ParseResult, urlparse from .models import CustomUser, UUIDUser from .settings import AUTH_TEMPLATES diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index 9335b75dba..4fd1563f84 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -1,5 +1,7 @@ +import builtins import sys from datetime import date +from io import StringIO from django.apps import apps from django.contrib.auth import management @@ -13,7 +15,6 @@ from django.core.management import call_command from django.core.management.base import CommandError from django.db import migrations from django.test import TestCase, mock, override_settings -from django.utils import six from django.utils.encoding import force_str from django.utils.translation import ugettext_lazy as _ @@ -49,14 +50,14 @@ def mock_inputs(inputs): return response old_getpass = createsuperuser.getpass - old_input = createsuperuser.input + old_input = builtins.input createsuperuser.getpass = mock_getpass - createsuperuser.input = mock_input + builtins.input = mock_input try: test_func(*args) finally: createsuperuser.getpass = old_getpass - createsuperuser.input = old_input + builtins.input = old_input return wrapped return inner @@ -105,8 +106,8 @@ class ChangepasswordManagementCommandTestCase(TestCase): def setUp(self): self.user = User.objects.create_user(username='joe', password='qwerty') - self.stdout = six.StringIO() - self.stderr = six.StringIO() + self.stdout = StringIO() + self.stderr = StringIO() def tearDown(self): self.stdout.close() @@ -168,7 +169,7 @@ class MultiDBChangepasswordManagementCommandTestCase(TestCase): user = User.objects.db_manager('other').create_user(username='joe', password='qwerty') self.assertTrue(user.check_password('qwerty')) - out = six.StringIO() + out = StringIO() call_command('changepassword', username='joe', database='other', stdout=out) command_output = out.getvalue().strip() @@ -188,7 +189,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase): def test_basic_usage(self): "Check the operation of the createsuperuser management command" # We can use the management command to create a superuser - new_io = six.StringIO() + new_io = StringIO() call_command( "createsuperuser", interactive=False, @@ -212,7 +213,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase): username_field = User._meta.get_field('username') old_verbose_name = username_field.verbose_name username_field.verbose_name = _('u\u017eivatel') - new_io = six.StringIO() + new_io = StringIO() try: call_command( "createsuperuser", @@ -228,7 +229,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase): def test_verbosity_zero(self): # We can suppress output on the management command - new_io = six.StringIO() + new_io = StringIO() call_command( "createsuperuser", interactive=False, @@ -244,7 +245,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase): self.assertFalse(u.has_usable_password()) def test_email_in_username(self): - new_io = six.StringIO() + new_io = StringIO() call_command( "createsuperuser", interactive=False, @@ -262,7 +263,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase): # We can use the management command to create a superuser # We skip validation because the temporary substitution of the # swappable User model messes with validation. - new_io = six.StringIO() + new_io = StringIO() call_command( "createsuperuser", interactive=False, @@ -284,7 +285,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase): # We can use the management command to create a superuser # We skip validation because the temporary substitution of the # swappable User model messes with validation. - new_io = six.StringIO() + new_io = StringIO() with self.assertRaises(CommandError): call_command( "createsuperuser", @@ -306,7 +307,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase): 'password': 'nopasswd', }) def createsuperuser(): - new_io = six.StringIO() + new_io = StringIO() call_command( "createsuperuser", interactive=True, @@ -333,7 +334,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase): def isatty(self): return False - out = six.StringIO() + out = StringIO() call_command( "createsuperuser", stdin=FakeStdin(), @@ -355,8 +356,8 @@ class CreatesuperuserManagementCommandTestCase(TestCase): call_command( command, stdin=sentinel, - stdout=six.StringIO(), - stderr=six.StringIO(), + stdout=StringIO(), + stderr=StringIO(), interactive=False, verbosity=0, username='janet', @@ -367,8 +368,8 @@ class CreatesuperuserManagementCommandTestCase(TestCase): command = createsuperuser.Command() call_command( command, - stdout=six.StringIO(), - stderr=six.StringIO(), + stdout=StringIO(), + stderr=StringIO(), interactive=False, verbosity=0, username='joe', @@ -378,7 +379,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase): @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserWithFK') def test_fields_with_fk(self): - new_io = six.StringIO() + new_io = StringIO() group = Group.objects.create(name='mygroup') email = Email.objects.create(email='mymail@gmail.com') call_command( @@ -408,7 +409,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase): @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserWithFK') def test_fields_with_fk_interactive(self): - new_io = six.StringIO() + new_io = StringIO() group = Group.objects.create(name='mygroup') email = Email.objects.create(email='mymail@gmail.com') @@ -438,7 +439,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase): """ Creation should fail if the password fails validation. """ - new_io = six.StringIO() + new_io = StringIO() # Returns '1234567890' the first two times it is called, then # 'password' subsequently. @@ -472,7 +473,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase): """ Creation should fail if the user enters mismatched passwords. """ - new_io = six.StringIO() + new_io = StringIO() # The first two passwords do not match, but the second two do match and # are valid. @@ -505,7 +506,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase): """ Creation should fail if the user enters blank passwords. """ - new_io = six.StringIO() + new_io = StringIO() # The first two passwords are empty strings, but the second two are # valid. @@ -542,7 +543,7 @@ class MultiDBCreatesuperuserTestCase(TestCase): """ changepassword --database should operate on the specified DB. """ - new_io = six.StringIO() + new_io = StringIO() call_command( 'createsuperuser', interactive=False, diff --git a/tests/auth_tests/test_views.py b/tests/auth_tests/test_views.py index f250800921..dd87a5bf00 100644 --- a/tests/auth_tests/test_views.py +++ b/tests/auth_tests/test_views.py @@ -3,6 +3,7 @@ import itertools import os import re from importlib import import_module +from urllib.parse import ParseResult, urlparse from django.apps import apps from django.conf import settings @@ -28,7 +29,6 @@ from django.urls import NoReverseMatch, reverse, reverse_lazy from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_text from django.utils.http import urlquote -from django.utils.six.moves.urllib.parse import ParseResult, urlparse from django.utils.translation import LANGUAGE_SESSION_KEY from .client import PasswordResetConfirmClient diff --git a/tests/backends/tests.py b/tests/backends/tests.py index a7939ed8be..89afb20760 100644 --- a/tests/backends/tests.py +++ b/tests/backends/tests.py @@ -23,7 +23,6 @@ from django.test import ( SimpleTestCase, TestCase, TransactionTestCase, mock, override_settings, skipIfDBFeature, skipUnlessDBFeature, ) -from django.utils.six.moves import range from .models import ( Article, Item, Object, ObjectReference, Person, Post, RawData, Reporter, diff --git a/tests/base/models.py b/tests/base/models.py index fb91522717..b179878704 100644 --- a/tests/base/models.py +++ b/tests/base/models.py @@ -1,5 +1,4 @@ from django.db import models -from django.utils import six # The models definitions below used to crash. Generating models dynamically @@ -11,5 +10,5 @@ class CustomBaseModel(models.base.ModelBase): pass -class MyModel(six.with_metaclass(CustomBaseModel, models.Model)): - """Model subclass with a custom base using six.with_metaclass.""" +class MyModel(models.Model, metaclass=CustomBaseModel): + """Model subclass with a custom base using metaclass.""" diff --git a/tests/cache/tests.py b/tests/cache/tests.py index caeb8a47df..3bf39e2476 100644 --- a/tests/cache/tests.py +++ b/tests/cache/tests.py @@ -3,6 +3,7 @@ import copy import io import os +import pickle import re import shutil import tempfile @@ -33,7 +34,7 @@ from django.test import ( ignore_warnings, mock, override_settings, ) from django.test.signals import setting_changed -from django.utils import six, timezone, translation +from django.utils import timezone, translation from django.utils.cache import ( get_cache_key, learn_cache_key, patch_cache_control, patch_response_headers, patch_vary_headers, @@ -44,11 +45,6 @@ from django.views.decorators.cache import cache_page from .models import Poll, expensive_calculation -try: # Use the same idiom as in cache backends - from django.utils.six.moves import cPickle as pickle -except ImportError: - import pickle - # functions/classes for complex data type tests def f(): @@ -978,7 +974,7 @@ class DBCacheTests(BaseCacheTests, TransactionTestCase): self._perform_cull_test(caches['zero_cull'], 50, 18) def test_second_call_doesnt_crash(self): - out = six.StringIO() + out = io.StringIO() management.call_command('createcachetable', stdout=out) self.assertEqual(out.getvalue(), "Cache table 'test cache table' already exists.\n" * len(settings.CACHES)) @@ -988,7 +984,7 @@ class DBCacheTests(BaseCacheTests, TransactionTestCase): LOCATION='createcachetable_dry_run_mode' )) def test_createcachetable_dry_run_mode(self): - out = six.StringIO() + out = io.StringIO() management.call_command('createcachetable', dry_run=True, stdout=out) output = out.getvalue() self.assertTrue(output.startswith("CREATE TABLE")) @@ -999,7 +995,7 @@ class DBCacheTests(BaseCacheTests, TransactionTestCase): specifying the table name). """ self.drop_table() - out = six.StringIO() + out = io.StringIO() management.call_command( 'createcachetable', 'test cache table', diff --git a/tests/check_framework/tests.py b/tests/check_framework/tests.py index 0e82c10b45..30e1353dc0 100644 --- a/tests/check_framework/tests.py +++ b/tests/check_framework/tests.py @@ -1,4 +1,5 @@ import sys +from io import StringIO from django.apps import apps from django.core import checks @@ -12,7 +13,6 @@ from django.test.utils import ( isolate_apps, override_settings, override_system_checks, ) from django.utils.encoding import force_text -from django.utils.six import StringIO from .models import SimpleModel, my_check diff --git a/tests/contenttypes_tests/tests.py b/tests/contenttypes_tests/tests.py index a46c9f3365..c91c265eaf 100644 --- a/tests/contenttypes_tests/tests.py +++ b/tests/contenttypes_tests/tests.py @@ -390,10 +390,7 @@ class UpdateContentTypesTests(TestCase): # A related object is needed to show that a custom collector with # can_fast_delete=False is needed. ModelWithNullFKToSite.objects.create(post=post) - with mock.patch( - 'django.contrib.contenttypes.management.commands.remove_stale_contenttypes.input', - return_value='yes' - ): + with mock.patch('builtins.input', return_value='yes'): with captured_stdout() as stdout: call_command('remove_stale_contenttypes', verbosity=2, stdout=stdout) self.assertEqual(Post.objects.count(), 0) @@ -409,10 +406,7 @@ class UpdateContentTypesTests(TestCase): interactive mode of remove_stale_contenttypes (the default) should delete stale contenttypes even if there aren't any dependent objects. """ - with mock.patch( - 'django.contrib.contenttypes.management.commands.remove_stale_contenttypes.input', - return_value='yes' - ): + with mock.patch('builtins.input', return_value='yes'): with captured_stdout() as stdout: call_command('remove_stale_contenttypes', verbosity=2) self.assertIn("Deleting stale content type", stdout.getvalue()) diff --git a/tests/db_typecasts/tests.py b/tests/db_typecasts/tests.py index fa9eab164d..56d37c112d 100644 --- a/tests/db_typecasts/tests.py +++ b/tests/db_typecasts/tests.py @@ -4,7 +4,6 @@ import datetime import unittest from django.db.backends import utils as typecasts -from django.utils import six TEST_CASES = { 'typecast_date': ( @@ -53,7 +52,7 @@ TEST_CASES = { class DBTypeCasts(unittest.TestCase): def test_typeCasts(self): - for k, v in six.iteritems(TEST_CASES): + for k, v in TEST_CASES.items(): for inpt, expected in v: got = getattr(typecasts, k)(inpt) self.assertEqual( diff --git a/tests/delete/tests.py b/tests/delete/tests.py index 640dfabf4b..5abae7622e 100644 --- a/tests/delete/tests.py +++ b/tests/delete/tests.py @@ -3,7 +3,6 @@ from math import ceil from django.db import IntegrityError, connection, models from django.db.models.sql.constants import GET_ITERATOR_CHUNK_SIZE from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature -from django.utils.six.moves import range from .models import ( MR, A, Avatar, Base, Child, HiddenUser, HiddenUserProfile, M, M2MFrom, diff --git a/tests/deprecation/tests.py b/tests/deprecation/tests.py index 34056b663b..5c2361f7a0 100644 --- a/tests/deprecation/tests.py +++ b/tests/deprecation/tests.py @@ -2,7 +2,6 @@ import warnings from django.test import SimpleTestCase from django.test.utils import reset_warning_registry -from django.utils import six from django.utils.deprecation import ( DeprecationInstanceCheck, RemovedInNextVersionWarning, RenameMethodsBase, ) @@ -29,7 +28,7 @@ class RenameMethodsTests(SimpleTestCase): with warnings.catch_warnings(record=True) as recorded: warnings.simplefilter('always') - class Manager(six.with_metaclass(RenameManagerMethods)): + class Manager(metaclass=RenameManagerMethods): def old(self): pass self.assertEqual(len(recorded), 1) @@ -43,7 +42,7 @@ class RenameMethodsTests(SimpleTestCase): with warnings.catch_warnings(record=True) as recorded: warnings.simplefilter('ignore') - class Manager(six.with_metaclass(RenameManagerMethods)): + class Manager(metaclass=RenameManagerMethods): def new(self): pass warnings.simplefilter('always') @@ -62,7 +61,7 @@ class RenameMethodsTests(SimpleTestCase): with warnings.catch_warnings(record=True) as recorded: warnings.simplefilter('ignore') - class Manager(six.with_metaclass(RenameManagerMethods)): + class Manager(metaclass=RenameManagerMethods): def old(self): pass warnings.simplefilter('always') @@ -82,7 +81,7 @@ class RenameMethodsTests(SimpleTestCase): with warnings.catch_warnings(record=True) as recorded: warnings.simplefilter('ignore') - class Renamed(six.with_metaclass(RenameManagerMethods)): + class Renamed(metaclass=RenameManagerMethods): def new(self): pass @@ -112,7 +111,7 @@ class RenameMethodsTests(SimpleTestCase): with warnings.catch_warnings(record=True) as recorded: warnings.simplefilter('ignore') - class Deprecated(six.with_metaclass(RenameManagerMethods)): + class Deprecated(metaclass=RenameManagerMethods): def old(self): pass @@ -137,7 +136,7 @@ class RenameMethodsTests(SimpleTestCase): with warnings.catch_warnings(record=True) as recorded: warnings.simplefilter('ignore') - class Renamed(six.with_metaclass(RenameManagerMethods)): + class Renamed(metaclass=RenameManagerMethods): def new(self): pass @@ -168,7 +167,7 @@ class RenameMethodsTests(SimpleTestCase): class DeprecationInstanceCheckTest(SimpleTestCase): def test_warning(self): - class Manager(six.with_metaclass(DeprecationInstanceCheck)): + class Manager(metaclass=DeprecationInstanceCheck): alternative = 'fake.path.Foo' deprecation_warning = RemovedInNextVersionWarning diff --git a/tests/file_storage/tests.py b/tests/file_storage/tests.py index d02b6e2dbc..5aee127c8c 100644 --- a/tests/file_storage/tests.py +++ b/tests/file_storage/tests.py @@ -7,6 +7,8 @@ import threading import time import unittest from datetime import datetime, timedelta +from io import StringIO +from urllib.request import urlopen from django.core.cache import cache from django.core.exceptions import SuspiciousFileOperation, SuspiciousOperation @@ -21,9 +23,8 @@ from django.test import ( ) from django.test.utils import requires_tz_support from django.urls import NoReverseMatch, reverse_lazy -from django.utils import six, timezone +from django.utils import timezone from django.utils._os import upath -from django.utils.six.moves.urllib.request import urlopen from .models import Storage, temp_storage, temp_storage_location @@ -301,7 +302,7 @@ class FileStorageTests(SimpleTestCase): self.assertFalse(file.closed) self.assertFalse(file.file.closed) - file = InMemoryUploadedFile(six.StringIO('1'), '', 'test', 'text/plain', 1, 'utf8') + file = InMemoryUploadedFile(StringIO('1'), '', 'test', 'text/plain', 1, 'utf8') with file: self.assertFalse(file.closed) self.storage.save('path/to/test.file', file) @@ -578,7 +579,7 @@ class DiscardingFalseContentStorageTests(FileStorageTests): When Storage.save() wraps a file-like object in File, it should include the name argument so that bool(file) evaluates to True (#26495). """ - output = six.StringIO('content') + output = StringIO('content') self.storage.save('tests/stringio', output) self.assertTrue(self.storage.exists('tests/stringio')) @@ -788,7 +789,7 @@ class FileFieldStorageTests(TestCase): def test_stringio(self): # Test passing StringIO instance as content argument to save - output = six.StringIO() + output = StringIO() output.write('content') output.seek(0) diff --git a/tests/file_uploads/tests.py b/tests/file_uploads/tests.py index f9cecf96a2..c7315ae142 100644 --- a/tests/file_uploads/tests.py +++ b/tests/file_uploads/tests.py @@ -7,7 +7,7 @@ import shutil import sys import tempfile as sys_tempfile import unittest -from io import BytesIO +from io import BytesIO, StringIO from django.core.files import temp as tempfile from django.core.files.uploadedfile import SimpleUploadedFile @@ -15,7 +15,6 @@ from django.http.multipartparser import MultiPartParser, parse_header from django.test import SimpleTestCase, TestCase, client, override_settings from django.utils.encoding import force_bytes from django.utils.http import urlquote -from django.utils.six import StringIO from . import uploadhandler from .models import FileModel diff --git a/tests/fixtures/tests.py b/tests/fixtures/tests.py index df5067e223..51d8eef51b 100644 --- a/tests/fixtures/tests.py +++ b/tests/fixtures/tests.py @@ -3,6 +3,7 @@ import sys import tempfile import unittest import warnings +from io import StringIO from django.apps import apps from django.contrib.sites.models import Site @@ -15,7 +16,6 @@ from django.db import IntegrityError, connection from django.test import ( TestCase, TransactionTestCase, mock, skipUnlessDBFeature, ) -from django.utils import six from django.utils.encoding import force_text from .models import ( @@ -52,7 +52,7 @@ class DumpDataAssertMixin(object): def _dumpdata_assert(self, args, output, format='json', filename=None, natural_foreign_keys=False, natural_primary_keys=False, use_base_manager=False, exclude_list=[], primary_keys=''): - new_io = six.StringIO() + new_io = StringIO() if filename: filename = os.path.join(tempfile.gettempdir(), filename) management.call_command('dumpdata', *args, **{'format': format, @@ -445,7 +445,7 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase): def test_dumpdata_with_uuid_pks(self): m1 = PrimaryKeyUUIDModel.objects.create() m2 = PrimaryKeyUUIDModel.objects.create() - output = six.StringIO() + output = StringIO() management.call_command( 'dumpdata', 'fixtures.PrimaryKeyUUIDModel', '--pks', ', '.join([str(m1.id), str(m2.id)]), stdout=output, @@ -471,7 +471,7 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase): stdout is a tty, and verbosity > 0. """ management.call_command('loaddata', 'fixture1.json', verbosity=0) - new_io = six.StringIO() + new_io = StringIO() new_io.isatty = lambda: True with NamedTemporaryFile() as file: options = { @@ -485,7 +485,7 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase): # Test no progress bar when verbosity = 0 options['verbosity'] = 0 - new_io = six.StringIO() + new_io = StringIO() new_io.isatty = lambda: True options.update({'stdout': new_io, 'stderr': new_io}) management.call_command('dumpdata', 'fixtures', **options) @@ -583,7 +583,7 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase): ]) def test_loaddata_verbosity_three(self): - output = six.StringIO() + output = StringIO() management.call_command('loaddata', 'fixture1.json', verbosity=3, stdout=output, stderr=output) command_output = force_text(output.getvalue()) self.assertIn( @@ -689,7 +689,7 @@ class NonExistentFixtureTests(TestCase): """ def test_loaddata_not_existent_fixture_file(self): - stdout_output = six.StringIO() + stdout_output = StringIO() with self.assertRaisesMessage(CommandError, "No fixture named 'this_fixture_doesnt_exist' found."): management.call_command('loaddata', 'this_fixture_doesnt_exist', stdout=stdout_output) diff --git a/tests/fixtures_regress/tests.py b/tests/fixtures_regress/tests.py index 7ea9e6cc3e..a3ac7f5977 100644 --- a/tests/fixtures_regress/tests.py +++ b/tests/fixtures_regress/tests.py @@ -3,6 +3,7 @@ import json import os import re import warnings +from io import StringIO from django.core import management, serializers from django.core.exceptions import ImproperlyConfigured @@ -14,7 +15,6 @@ from django.test import ( skipUnlessDBFeature, ) from django.utils._os import upath -from django.utils.six import StringIO from .models import ( Absolute, Animal, Article, Book, Child, Circle1, Circle2, Circle3, diff --git a/tests/gis_tests/gdal_tests/test_geom.py b/tests/gis_tests/gdal_tests/test_geom.py index bc8219772c..4498ce7111 100644 --- a/tests/gis_tests/gdal_tests/test_geom.py +++ b/tests/gis_tests/gdal_tests/test_geom.py @@ -1,19 +1,13 @@ import json +import pickle import unittest from binascii import b2a_hex from unittest import skipUnless from django.contrib.gis.gdal import HAS_GDAL -from django.utils.six.moves import range from ..test_data import TestDataMixin -try: - from django.utils.six.moves import cPickle as pickle -except ImportError: - import pickle - - if HAS_GDAL: from django.contrib.gis.gdal import ( CoordTransform, GDALException, OGRGeometry, OGRGeomType, OGRIndexError, diff --git a/tests/gis_tests/gdal_tests/test_raster.py b/tests/gis_tests/gdal_tests/test_raster.py index 8649e9f231..1a2753c717 100644 --- a/tests/gis_tests/gdal_tests/test_raster.py +++ b/tests/gis_tests/gdal_tests/test_raster.py @@ -49,7 +49,6 @@ from django.contrib.gis.gdal import HAS_GDAL from django.contrib.gis.gdal.error import GDALException from django.contrib.gis.shortcuts import numpy from django.test import SimpleTestCase -from django.utils import six from django.utils._os import upath from ..data.rasters.textrasters import JSON_RASTER @@ -505,7 +504,7 @@ class GDALBandTests(SimpleTestCase): self.assertEqual(result, block) # Set data from memoryview - bandmem.data(six.memoryview(packed_block), (1, 1), (2, 2)) + bandmem.data(memoryview(packed_block), (1, 1), (2, 2)) result = bandmem.data(offset=(1, 1), size=(2, 2)) if numpy: numpy.testing.assert_equal(result, numpy.array(block).reshape(2, 2)) diff --git a/tests/gis_tests/geoapp/tests.py b/tests/gis_tests/geoapp/tests.py index 4324364c0d..bfb84c6800 100644 --- a/tests/gis_tests/geoapp/tests.py +++ b/tests/gis_tests/geoapp/tests.py @@ -1,4 +1,5 @@ import tempfile +from io import StringIO from django.contrib.gis import gdal from django.contrib.gis.db.models import Extent, MakeLine, Union, functions @@ -9,7 +10,6 @@ from django.contrib.gis.geos import ( from django.core.management import call_command from django.db import connection from django.test import TestCase, skipUnlessDBFeature -from django.utils import six from ..utils import no_oracle, oracle, postgis, skipUnlessGISLookup, spatialite from .models import ( @@ -184,7 +184,7 @@ class GeoModelTest(TestCase): """ Test a dumpdata/loaddata cycle with geographic data. """ - out = six.StringIO() + out = StringIO() original_data = list(City.objects.all().order_by('name')) call_command('dumpdata', 'geoapp.City', stdout=out) result = out.getvalue() diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py index 7877e1f2d6..f7024e790e 100644 --- a/tests/gis_tests/geos_tests/test_geos.py +++ b/tests/gis_tests/geos_tests/test_geos.py @@ -1,5 +1,6 @@ import ctypes import json +import pickle import random from binascii import a2b_hex, b2a_hex from io import BytesIO @@ -18,7 +19,6 @@ from django.template import Context from django.template.engine import Engine from django.test import SimpleTestCase, mock from django.utils.encoding import force_bytes -from django.utils.six.moves import range from ..test_data import TestDataMixin @@ -1100,10 +1100,6 @@ class GEOSTest(SimpleTestCase, TestDataMixin): def test_pickle(self): "Testing pickling and unpickling support." - # Using both pickle and cPickle -- just 'cause. - from django.utils.six.moves import cPickle - import pickle - # Creating a list of test geometries for pickling, # and setting the SRID on some of them. def get_geoms(lst, srid=None): @@ -1114,11 +1110,10 @@ class GEOSTest(SimpleTestCase, TestDataMixin): tgeoms.extend(get_geoms(self.geometries.multipolygons, 3857)) for geom in tgeoms: - s1, s2 = cPickle.dumps(geom), pickle.dumps(geom) - g1, g2 = cPickle.loads(s1), pickle.loads(s2) - for tmpg in (g1, g2): - self.assertEqual(geom, tmpg) - self.assertEqual(geom.srid, tmpg.srid) + s1 = pickle.dumps(geom) + g1 = pickle.loads(s1) + self.assertEqual(geom, g1) + self.assertEqual(geom.srid, g1.srid) def test_prepared(self): "Testing PreparedGeometry support." diff --git a/tests/gis_tests/inspectapp/tests.py b/tests/gis_tests/inspectapp/tests.py index b451603e7c..43cf2c2d66 100644 --- a/tests/gis_tests/inspectapp/tests.py +++ b/tests/gis_tests/inspectapp/tests.py @@ -1,12 +1,12 @@ import os import re +from io import StringIO from django.contrib.gis.gdal import HAS_GDAL from django.core.management import call_command from django.db import connection, connections from django.test import TestCase, skipUnlessDBFeature from django.test.utils import modify_settings -from django.utils.six import StringIO from ..test_data import TEST_DATA from ..utils import postgis diff --git a/tests/gis_tests/test_data.py b/tests/gis_tests/test_data.py index 7092bd27b1..9e31b5a599 100644 --- a/tests/gis_tests/test_data.py +++ b/tests/gis_tests/test_data.py @@ -5,7 +5,6 @@ for the GEOS and GDAL tests. import json import os -from django.utils import six from django.utils._os import upath from django.utils.functional import cached_property @@ -22,7 +21,7 @@ def tuplize(seq): def strconvert(d): "Converts all keys in dictionary to str type." - return {str(k): v for k, v in six.iteritems(d)} + return {str(k): v for k, v in d.items()} def get_ds_file(name, ext): diff --git a/tests/httpwrappers/tests.py b/tests/httpwrappers/tests.py index b8d359de41..a4ea614175 100644 --- a/tests/httpwrappers/tests.py +++ b/tests/httpwrappers/tests.py @@ -16,7 +16,6 @@ from django.http import ( StreamingHttpResponse, parse_cookie, ) from django.test import SimpleTestCase -from django.utils import six from django.utils._os import upath from django.utils.encoding import force_str from django.utils.functional import lazystr @@ -56,10 +55,10 @@ class QueryDictTests(SimpleTestCase): q = QueryDict() self.assertEqual(q.getlist('foo'), []) self.assertNotIn('foo', q) - self.assertEqual(list(six.iteritems(q)), []) - self.assertEqual(list(six.iterlists(q)), []) - self.assertEqual(list(six.iterkeys(q)), []) - self.assertEqual(list(six.itervalues(q)), []) + self.assertEqual(list(q.items()), []) + self.assertEqual(list(q.lists()), []) + self.assertEqual(list(q.keys()), []) + self.assertEqual(list(q.values()), []) self.assertEqual(len(q), 0) self.assertEqual(q.urlencode(), '') @@ -86,10 +85,10 @@ class QueryDictTests(SimpleTestCase): self.assertIn('foo', q) self.assertNotIn('bar', q) - self.assertEqual(list(six.iteritems(q)), [('foo', 'bar')]) - self.assertEqual(list(six.iterlists(q)), [('foo', ['bar'])]) - self.assertEqual(list(six.iterkeys(q)), ['foo']) - self.assertEqual(list(six.itervalues(q)), ['bar']) + self.assertEqual(list(q.items()), [('foo', 'bar')]) + self.assertEqual(list(q.lists()), [('foo', ['bar'])]) + self.assertEqual(list(q.keys()), ['foo']) + self.assertEqual(list(q.values()), ['bar']) self.assertEqual(len(q), 1) with self.assertRaises(AttributeError): @@ -146,14 +145,10 @@ class QueryDictTests(SimpleTestCase): self.assertEqual(q['foo'], 'another') self.assertIn('foo', q) - self.assertListEqual(sorted(six.iteritems(q)), - [('foo', 'another'), ('name', 'john')]) - self.assertListEqual(sorted(six.iterlists(q)), - [('foo', ['bar', 'baz', 'another']), ('name', ['john'])]) - self.assertListEqual(sorted(six.iterkeys(q)), - ['foo', 'name']) - self.assertListEqual(sorted(six.itervalues(q)), - ['another', 'john']) + self.assertListEqual(sorted(q.items()), [('foo', 'another'), ('name', 'john')]) + self.assertListEqual(sorted(q.lists()), [('foo', ['bar', 'baz', 'another']), ('name', ['john'])]) + self.assertListEqual(sorted(q.keys()), ['foo', 'name']) + self.assertListEqual(sorted(q.values()), ['another', 'john']) q.update({'foo': 'hello'}) self.assertEqual(q['foo'], 'hello') @@ -193,10 +188,10 @@ class QueryDictTests(SimpleTestCase): self.assertIn('vote', q) self.assertNotIn('foo', q) - self.assertEqual(list(six.iteritems(q)), [('vote', 'no')]) - self.assertEqual(list(six.iterlists(q)), [('vote', ['yes', 'no'])]) - self.assertEqual(list(six.iterkeys(q)), ['vote']) - self.assertEqual(list(six.itervalues(q)), ['no']) + self.assertEqual(list(q.items()), [('vote', 'no')]) + self.assertEqual(list(q.lists()), [('vote', ['yes', 'no'])]) + self.assertEqual(list(q.keys()), ['vote']) + self.assertEqual(list(q.values()), ['no']) self.assertEqual(len(q), 1) with self.assertRaises(AttributeError): @@ -234,11 +229,11 @@ class QueryDictTests(SimpleTestCase): """#13572 - QueryDict with a non-default encoding""" q = QueryDict(str('cur=%A4'), encoding='iso-8859-15') self.assertEqual(q.encoding, 'iso-8859-15') - self.assertEqual(list(six.iteritems(q)), [('cur', '€')]) + self.assertEqual(list(q.items()), [('cur', '€')]) self.assertEqual(q.urlencode(), 'cur=%A4') q = q.copy() self.assertEqual(q.encoding, 'iso-8859-15') - self.assertEqual(list(six.iteritems(q)), [('cur', '€')]) + self.assertEqual(list(q.items()), [('cur', '€')]) self.assertEqual(q.urlencode(), 'cur=%A4') self.assertEqual(copy.copy(q).encoding, 'iso-8859-15') self.assertEqual(copy.deepcopy(q).encoding, 'iso-8859-15') diff --git a/tests/i18n/test_compilation.py b/tests/i18n/test_compilation.py index 3f3bf773bf..159b6d91ec 100644 --- a/tests/i18n/test_compilation.py +++ b/tests/i18n/test_compilation.py @@ -2,6 +2,7 @@ import gettext as gettext_module import os import stat import unittest +from io import StringIO from subprocess import Popen from django.core.management import ( @@ -14,7 +15,6 @@ from django.test import SimpleTestCase, mock, override_settings from django.test.utils import captured_stderr, captured_stdout from django.utils import translation from django.utils.encoding import force_text -from django.utils.six import StringIO from django.utils.translation import ugettext from .utils import RunInTmpDirMixin, copytree diff --git a/tests/i18n/test_extraction.py b/tests/i18n/test_extraction.py index b8342865a9..aaa2a4e8b5 100644 --- a/tests/i18n/test_extraction.py +++ b/tests/i18n/test_extraction.py @@ -4,6 +4,7 @@ import re import shutil import time import warnings +from io import StringIO from unittest import skipUnless from admin_scripts.tests import AdminScriptTestCase @@ -17,7 +18,6 @@ from django.core.management.utils import find_command from django.test import SimpleTestCase, mock, override_settings from django.test.utils import captured_stderr, captured_stdout from django.utils.encoding import force_text -from django.utils.six import StringIO from django.utils.translation import TranslatorCommentWarning from .utils import POFileAssertionMixin, RunInTmpDirMixin, copytree diff --git a/tests/inspectdb/tests.py b/tests/inspectdb/tests.py index 8f17735929..ef26233342 100644 --- a/tests/inspectdb/tests.py +++ b/tests/inspectdb/tests.py @@ -1,11 +1,11 @@ import re +from io import StringIO from unittest import skipUnless from django.core.management import call_command from django.db import connection from django.test import TestCase, mock, skipUnlessDBFeature from django.utils.encoding import force_text -from django.utils.six import StringIO from .models import ColumnTypes diff --git a/tests/logging_tests/tests.py b/tests/logging_tests/tests.py index 134cc71808..a91bcd66bf 100644 --- a/tests/logging_tests/tests.py +++ b/tests/logging_tests/tests.py @@ -1,5 +1,6 @@ import logging from contextlib import contextmanager +from io import StringIO from admin_scripts.tests import AdminScriptTestCase @@ -10,7 +11,6 @@ from django.core.management import color from django.db import connection from django.test import RequestFactory, SimpleTestCase, override_settings from django.test.utils import LoggingCaptureMixin, patch_logger -from django.utils import six from django.utils.log import ( DEFAULT_LOGGING, AdminEmailHandler, CallbackFilter, RequireDebugFalse, RequireDebugTrue, ServerFormatter, @@ -513,7 +513,7 @@ class LogFormattersTests(SimpleTestCase): @contextmanager def patch_django_server_logger(): old_stream = logger.handlers[0].stream - new_stream = six.StringIO() + new_stream = StringIO() logger.handlers[0].stream = new_stream yield new_stream logger.handlers[0].stream = old_stream diff --git a/tests/m2m_through_regress/tests.py b/tests/m2m_through_regress/tests.py index a1739f2960..64be4252bd 100644 --- a/tests/m2m_through_regress/tests.py +++ b/tests/m2m_through_regress/tests.py @@ -1,7 +1,8 @@ +from io import StringIO + from django.contrib.auth.models import User from django.core import management from django.test import TestCase -from django.utils.six import StringIO from .models import ( Car, CarDriver, Driver, Group, Membership, Person, UserMembership, diff --git a/tests/mail/tests.py b/tests/mail/tests.py index 7c2cd8342a..77ea87fe7d 100644 --- a/tests/mail/tests.py +++ b/tests/mail/tests.py @@ -12,6 +12,7 @@ from email import message_from_binary_file, message_from_bytes from email.header import Header from email.mime.text import MIMEText from email.utils import parseaddr +from io import StringIO from smtplib import SMTP, SMTPAuthenticationError, SMTPException from ssl import SSLError @@ -26,7 +27,6 @@ from django.test import SimpleTestCase, override_settings from django.test.utils import requires_tz_support from django.utils._os import upath from django.utils.encoding import force_bytes, force_text -from django.utils.six import StringIO from django.utils.translation import ugettext_lazy diff --git a/tests/middleware/tests.py b/tests/middleware/tests.py index 3c0d3d81ea..8749a9ee50 100644 --- a/tests/middleware/tests.py +++ b/tests/middleware/tests.py @@ -1,7 +1,9 @@ import gzip import random import re +import struct from io import BytesIO +from urllib.parse import quote from django.conf import settings from django.core import mail @@ -19,11 +21,10 @@ from django.middleware.http import ConditionalGetMiddleware from django.test import ( RequestFactory, SimpleTestCase, ignore_warnings, override_settings, ) -from django.utils import six from django.utils.deprecation import RemovedInDjango21Warning from django.utils.encoding import force_str -from django.utils.six.moves import range -from django.utils.six.moves.urllib.parse import quote + +int2byte = struct.Struct(">B").pack @override_settings(ROOT_URLCONF='middleware.urls') @@ -732,7 +733,7 @@ class GZipMiddlewareTest(SimpleTestCase): """ short_string = b"This string is too short to be worth compressing." compressible_string = b'a' * 500 - incompressible_string = b''.join(six.int2byte(random.randint(0, 255)) for _ in range(500)) + incompressible_string = b''.join(int2byte(random.randint(0, 255)) for _ in range(500)) sequence = [b'a' * 500, b'b' * 200, b'a' * 300] sequence_unicode = ['a' * 500, 'é' * 200, 'a' * 300] diff --git a/tests/migrate_signals/tests.py b/tests/migrate_signals/tests.py index 84b6608f46..97f449e805 100644 --- a/tests/migrate_signals/tests.py +++ b/tests/migrate_signals/tests.py @@ -1,9 +1,10 @@ +from io import StringIO + from django.apps import apps from django.core import management from django.db import migrations from django.db.models import signals from django.test import TransactionTestCase, override_settings -from django.utils import six APP_CONFIG = apps.get_app_config('migrate_signals') SIGNAL_ARGS = ['app_config', 'verbosity', 'interactive', 'using', 'plan', 'apps'] @@ -70,7 +71,7 @@ class MigrateSignalTests(TransactionTestCase): post_migrate_receiver = Receiver(signals.post_migrate) management.call_command( 'migrate', database=MIGRATE_DATABASE, verbosity=MIGRATE_VERBOSITY, - interactive=MIGRATE_INTERACTIVE, stdout=six.StringIO(), + interactive=MIGRATE_INTERACTIVE, stdout=StringIO(), ) for receiver in [pre_migrate_receiver, post_migrate_receiver]: @@ -91,7 +92,7 @@ class MigrateSignalTests(TransactionTestCase): """ pre_migrate_receiver = Receiver(signals.pre_migrate) post_migrate_receiver = Receiver(signals.post_migrate) - stdout = six.StringIO() + stdout = StringIO() management.call_command( 'migrate', database=MIGRATE_DATABASE, verbosity=MIGRATE_VERBOSITY, interactive=MIGRATE_INTERACTIVE, stdout=stdout, diff --git a/tests/migrations/models.py b/tests/migrations/models.py index dea320c033..9a34edf349 100644 --- a/tests/migrations/models.py +++ b/tests/migrations/models.py @@ -1,13 +1,12 @@ from django.apps.registry import Apps from django.db import models -from django.utils import six class CustomModelBase(models.base.ModelBase): pass -class ModelWithCustomBase(six.with_metaclass(CustomModelBase, models.Model)): +class ModelWithCustomBase(models.Model, metaclass=CustomModelBase): pass diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py index ca6b42044f..e6de83212e 100644 --- a/tests/migrations/test_commands.py +++ b/tests/migrations/test_commands.py @@ -15,7 +15,6 @@ from django.db.migrations.exceptions import ( ) from django.db.migrations.recorder import MigrationRecorder from django.test import mock, override_settings -from django.utils import six from django.utils.encoding import force_text from .models import UnicodeModel, UnserializableModel @@ -63,7 +62,7 @@ class MigrateTests(MigrationTestBase): 'migrations.migrations_test_apps.migrated_app', ]) def test_migrate_with_system_checks(self): - out = six.StringIO() + out = io.StringIO() call_command('migrate', skip_checks=False, no_color=True, stdout=out) self.assertIn('Apply all migrations: migrated_app', out.getvalue()) @@ -125,7 +124,7 @@ class MigrateTests(MigrationTestBase): with self.assertRaises(DatabaseError): call_command("migrate", "migrations", "0001", verbosity=0) # Run initial migration with an explicit --fake-initial - out = six.StringIO() + out = io.StringIO() with mock.patch('django.core.management.color.supports_color', lambda *args: False): call_command("migrate", "migrations", "0001", fake_initial=True, stdout=out, verbosity=1) call_command("migrate", "migrations", "0001", fake_initial=True, verbosity=0, database="other") @@ -177,7 +176,7 @@ class MigrateTests(MigrationTestBase): """ call_command("migrate", "migrations", "0002", verbosity=0) call_command("migrate", "migrations", "zero", fake=True, verbosity=0) - out = six.StringIO() + out = io.StringIO() with mock.patch('django.core.management.color.supports_color', lambda *args: False): call_command("migrate", "migrations", "0002", fake_initial=True, stdout=out, verbosity=1) value = out.getvalue().lower() @@ -202,7 +201,7 @@ class MigrateTests(MigrationTestBase): showmigrations --list displays migrations and whether or not they're applied. """ - out = six.StringIO() + out = io.StringIO() with mock.patch('django.core.management.color.supports_color', lambda *args: True): call_command("showmigrations", format='list', stdout=out, verbosity=0, no_color=False) self.assertEqual( @@ -214,7 +213,7 @@ class MigrateTests(MigrationTestBase): call_command("migrate", "migrations", "0001", verbosity=0) - out = six.StringIO() + out = io.StringIO() # Giving the explicit app_label tests for selective `show_list` in the command call_command("showmigrations", "migrations", format='list', stdout=out, verbosity=0, no_color=True) self.assertEqual( @@ -231,7 +230,7 @@ class MigrateTests(MigrationTestBase): """ Tests --plan output of showmigrations command """ - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out) self.assertEqual( "[ ] migrations.0001_initial\n" @@ -240,7 +239,7 @@ class MigrateTests(MigrationTestBase): out.getvalue().lower() ) - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out, verbosity=2) self.assertEqual( "[ ] migrations.0001_initial\n" @@ -250,7 +249,7 @@ class MigrateTests(MigrationTestBase): ) call_command("migrate", "migrations", "0003", verbosity=0) - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out) self.assertEqual( "[x] migrations.0001_initial\n" @@ -259,7 +258,7 @@ class MigrateTests(MigrationTestBase): out.getvalue().lower() ) - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out, verbosity=2) self.assertEqual( "[x] migrations.0001_initial\n" @@ -276,11 +275,11 @@ class MigrateTests(MigrationTestBase): """ Tests --plan output of showmigrations command without migrations """ - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out) self.assertEqual("", out.getvalue().lower()) - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out, verbosity=2) self.assertEqual("", out.getvalue().lower()) @@ -289,7 +288,7 @@ class MigrateTests(MigrationTestBase): """ Tests --plan output of showmigrations command with squashed migrations. """ - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out) self.assertEqual( "[ ] migrations.1_auto\n" @@ -300,7 +299,7 @@ class MigrateTests(MigrationTestBase): out.getvalue().lower() ) - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out, verbosity=2) self.assertEqual( "[ ] migrations.1_auto\n" @@ -313,7 +312,7 @@ class MigrateTests(MigrationTestBase): call_command("migrate", "migrations", "3_squashed_5", verbosity=0) - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out) self.assertEqual( "[x] migrations.1_auto\n" @@ -324,7 +323,7 @@ class MigrateTests(MigrationTestBase): out.getvalue().lower() ) - out = six.StringIO() + out = io.StringIO() call_command("showmigrations", format='plan', stdout=out, verbosity=2) self.assertEqual( "[x] migrations.1_auto\n" @@ -345,7 +344,7 @@ class MigrateTests(MigrationTestBase): `showmigrations --plan app_label` output with a single app_label. """ # Single app with no dependencies on other apps. - out = six.StringIO() + out = io.StringIO() call_command('showmigrations', 'mutate_state_b', format='plan', stdout=out) self.assertEqual( '[ ] mutate_state_b.0001_initial\n' @@ -353,7 +352,7 @@ class MigrateTests(MigrationTestBase): out.getvalue() ) # Single app with dependencies. - out = six.StringIO() + out = io.StringIO() call_command('showmigrations', 'author_app', format='plan', stdout=out) self.assertEqual( '[ ] author_app.0001_initial\n' @@ -363,7 +362,7 @@ class MigrateTests(MigrationTestBase): ) # Some migrations already applied. call_command('migrate', 'author_app', '0001', verbosity=0) - out = six.StringIO() + out = io.StringIO() call_command('showmigrations', 'author_app', format='plan', stdout=out) self.assertEqual( '[X] author_app.0001_initial\n' @@ -385,7 +384,7 @@ class MigrateTests(MigrationTestBase): """ # Multiple apps: author_app depends on book_app; mutate_state_b doesn't # depend on other apps. - out = six.StringIO() + out = io.StringIO() call_command('showmigrations', 'mutate_state_b', 'author_app', format='plan', stdout=out) self.assertEqual( '[ ] author_app.0001_initial\n' @@ -397,7 +396,7 @@ class MigrateTests(MigrationTestBase): ) # Multiple apps: args order shouldn't matter (the same result is # expected as above). - out = six.StringIO() + out = io.StringIO() call_command('showmigrations', 'author_app', 'mutate_state_b', format='plan', stdout=out) self.assertEqual( '[ ] author_app.0001_initial\n' @@ -431,7 +430,7 @@ class MigrateTests(MigrationTestBase): """ sqlmigrate outputs forward looking SQL. """ - out = six.StringIO() + out = io.StringIO() call_command("sqlmigrate", "migrations", "0001", stdout=out) output = out.getvalue().lower() @@ -472,7 +471,7 @@ class MigrateTests(MigrationTestBase): # Cannot generate the reverse SQL unless we've applied the migration. call_command("migrate", "migrations", verbosity=0) - out = six.StringIO() + out = io.StringIO() call_command("sqlmigrate", "migrations", "0001", stdout=out, backwards=True) output = out.getvalue().lower() @@ -514,7 +513,7 @@ class MigrateTests(MigrationTestBase): """ Transaction wrappers aren't shown for non-atomic migrations. """ - out = six.StringIO() + out = io.StringIO() call_command("sqlmigrate", "migrations", "0001", stdout=out) output = out.getvalue().lower() queries = [q.strip() for q in output.splitlines()] @@ -541,7 +540,7 @@ class MigrateTests(MigrationTestBase): "B" was not included in the ProjectState that is used to detect soft-applied migrations (#22823). """ - call_command("migrate", "migrated_unapplied_app", stdout=six.StringIO()) + call_command("migrate", "migrated_unapplied_app", stdout=io.StringIO()) # unmigrated_app.SillyModel has a foreign key to 'migrations.Tribble', # but that model is only defined in a migration, so the global app @@ -570,7 +569,7 @@ class MigrateTests(MigrationTestBase): replaced migrations as run. """ recorder = MigrationRecorder(connection) - out = six.StringIO() + out = io.StringIO() call_command("migrate", "migrations", verbosity=0) call_command("showmigrations", "migrations", stdout=out, no_color=True) self.assertEqual( @@ -594,7 +593,7 @@ class MigrateTests(MigrationTestBase): recorder = MigrationRecorder(connection) recorder.record_applied("migrations", "0001_initial") recorder.record_applied("migrations", "0002_second") - out = six.StringIO() + out = io.StringIO() call_command("migrate", "migrations", verbosity=0) call_command("showmigrations", "migrations", stdout=out, no_color=True) self.assertEqual( @@ -683,7 +682,7 @@ class MakeMigrationsTests(MigrationTestBase): empty_connections = ConnectionHandler({'default': {}}) with mock.patch('django.core.management.commands.makemigrations.connections', new=empty_connections): # with no apps - out = six.StringIO() + out = io.StringIO() call_command('makemigrations', stdout=out) self.assertIn('No changes detected', out.getvalue()) # with an app @@ -767,7 +766,7 @@ class MakeMigrationsTests(MigrationTestBase): """ makemigrations exits if in merge mode with no conflicts. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations"): call_command("makemigrations", merge=True, stdout=out) self.assertIn("No conflicts detected to merge.", out.getvalue()) @@ -776,7 +775,7 @@ class MakeMigrationsTests(MigrationTestBase): """ makemigrations exits if a non-existent app is specified. """ - err = six.StringIO() + err = io.StringIO() with self.assertRaises(SystemExit): call_command("makemigrations", "this_app_does_not_exist", stderr=err) self.assertIn("'this_app_does_not_exist' could not be found.", err.getvalue()) @@ -824,7 +823,7 @@ class MakeMigrationsTests(MigrationTestBase): """ makemigrations exits when there are no changes and no apps are specified. """ - out = six.StringIO() + out = io.StringIO() call_command("makemigrations", stdout=out) self.assertIn("No changes detected", out.getvalue()) @@ -832,7 +831,7 @@ class MakeMigrationsTests(MigrationTestBase): """ makemigrations exits when there are no changes to an app. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_no_changes"): call_command("makemigrations", "migrations", stdout=out) self.assertIn("No changes detected in app 'migrations'", out.getvalue()) @@ -842,7 +841,7 @@ class MakeMigrationsTests(MigrationTestBase): makemigrations should detect initial is needed on empty migration modules if no app provided. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_empty"): call_command("makemigrations", stdout=out) self.assertIn("0001_initial.py", out.getvalue()) @@ -851,7 +850,7 @@ class MakeMigrationsTests(MigrationTestBase): """ makemigrations announces the migration at the default verbosity level. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(): call_command("makemigrations", "migrations", stdout=out) self.assertIn("Migrations for 'migrations'", out.getvalue()) @@ -873,7 +872,7 @@ class MakeMigrationsTests(MigrationTestBase): makemigrations enters and exits interactive mode properly. """ # Monkeypatch interactive questioner to auto reject - with mock.patch('django.db.migrations.questioner.input', mock.Mock(return_value='N')): + with mock.patch('builtins.input', mock.Mock(return_value='N')): with self.temporary_migration_module(module="migrations.test_migrations_conflict") as migration_dir: call_command("makemigrations", "migrations", name="merge", merge=True, interactive=True, verbosity=0) merge_file = os.path.join(migration_dir, '0003_merge.py') @@ -884,8 +883,8 @@ class MakeMigrationsTests(MigrationTestBase): makemigrations enters interactive mode and merges properly. """ # Monkeypatch interactive questioner to auto accept - with mock.patch('django.db.migrations.questioner.input', mock.Mock(return_value='y')): - out = six.StringIO() + with mock.patch('builtins.input', mock.Mock(return_value='y')): + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_conflict") as migration_dir: call_command("makemigrations", "migrations", name="merge", merge=True, interactive=True, stdout=out) merge_file = os.path.join(migration_dir, '0003_merge.py') @@ -895,8 +894,8 @@ class MakeMigrationsTests(MigrationTestBase): @mock.patch('django.db.migrations.utils.datetime') def test_makemigrations_default_merge_name(self, mock_datetime): mock_datetime.datetime.now.return_value = datetime.datetime(2016, 1, 2, 3, 4) - with mock.patch('django.db.migrations.questioner.input', mock.Mock(return_value='y')): - out = six.StringIO() + with mock.patch('builtins.input', mock.Mock(return_value='y')): + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_conflict") as migration_dir: call_command("makemigrations", "migrations", merge=True, interactive=True, stdout=out) merge_file = os.path.join(migration_dir, '0003_merge_20160102_0304.py') @@ -915,7 +914,7 @@ class MakeMigrationsTests(MigrationTestBase): class Meta: app_label = "migrations" - out = six.StringIO() + out = io.StringIO() with self.assertRaises(SystemExit): with self.temporary_migration_module(module="migrations.test_migrations_no_default"): call_command("makemigrations", "migrations", interactive=False, stdout=out) @@ -933,7 +932,7 @@ class MakeMigrationsTests(MigrationTestBase): class Meta: app_label = "migrations" - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations"): call_command("makemigrations", "migrations", interactive=False, stdout=out) self.assertIn("Alter field slug on author", out.getvalue()) @@ -949,7 +948,7 @@ class MakeMigrationsTests(MigrationTestBase): class Meta: app_label = "migrations" - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_no_default"): call_command("makemigrations", "migrations", interactive=False, stdout=out) self.assertIn("Delete model SillyModel", out.getvalue()) @@ -966,7 +965,7 @@ class MakeMigrationsTests(MigrationTestBase): class Meta: app_label = "migrations" - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_no_default"): call_command("makemigrations", "migrations", interactive=False, stdout=out) self.assertIn("Remove field silly_field from sillymodel", out.getvalue()) @@ -976,7 +975,7 @@ class MakeMigrationsTests(MigrationTestBase): """ makemigrations properly merges the conflicting migrations with --noinput. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_conflict") as migration_dir: call_command("makemigrations", "migrations", name="merge", merge=True, interactive=False, stdout=out) merge_file = os.path.join(migration_dir, '0003_merge.py') @@ -992,7 +991,7 @@ class MakeMigrationsTests(MigrationTestBase): makemigrations respects --dry-run option when fixing migration conflicts (#24427). """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_conflict") as migration_dir: call_command( "makemigrations", "migrations", name="merge", dry_run=True, @@ -1011,7 +1010,7 @@ class MakeMigrationsTests(MigrationTestBase): `makemigrations --merge --dry-run` writes the merge migration file to stdout with `verbosity == 3` (#24427). """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_conflict") as migration_dir: call_command( "makemigrations", "migrations", name="merge", dry_run=True, @@ -1045,7 +1044,7 @@ class MakeMigrationsTests(MigrationTestBase): class Meta: app_label = "migrations" - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_no_default"): call_command("makemigrations", "migrations", dry_run=True, stdout=out) # Output the expected changes directly, without asking for defaults @@ -1063,7 +1062,7 @@ class MakeMigrationsTests(MigrationTestBase): class Meta: app_label = "migrations" - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_no_default"): call_command("makemigrations", "migrations", dry_run=True, stdout=out, verbosity=3) @@ -1091,7 +1090,7 @@ class MakeMigrationsTests(MigrationTestBase): class Meta: app_label = "migrations" - out = six.StringIO() + out = io.StringIO() migration_module = "migrations.test_migrations_path_doesnt_exist.foo.bar" with self.temporary_migration_module(module=migration_module) as migration_dir: call_command("makemigrations", "migrations", stdout=out) @@ -1110,8 +1109,8 @@ class MakeMigrationsTests(MigrationTestBase): --noinput is specified. """ # Monkeypatch interactive questioner to auto reject - out = six.StringIO() - with mock.patch('django.db.migrations.questioner.input', mock.Mock(return_value='N')): + out = io.StringIO() + with mock.patch('builtins.input', mock.Mock(return_value='N')): with self.temporary_migration_module(module="migrations.test_migrations_conflict") as migration_dir: call_command("makemigrations", "migrations", name="merge", merge=True, stdout=out) merge_file = os.path.join(migration_dir, '0003_merge.py') @@ -1141,8 +1140,8 @@ class MakeMigrationsTests(MigrationTestBase): it has conflicting migrations. """ # Monkeypatch interactive questioner to auto accept - with mock.patch('django.db.migrations.questioner.input', mock.Mock(return_value='y')): - out = six.StringIO() + with mock.patch('builtins.input', mock.Mock(return_value='y')): + out = io.StringIO() with self.temporary_migration_module(app_label="migrated_app") as migration_dir: call_command("makemigrations", "migrated_app", name="merge", merge=True, interactive=True, stdout=out) merge_file = os.path.join(migration_dir, '0003_merge.py') @@ -1159,8 +1158,8 @@ class MakeMigrationsTests(MigrationTestBase): don't belong to a given app. """ # Monkeypatch interactive questioner to auto accept - with mock.patch('django.db.migrations.questioner.input', mock.Mock(return_value='N')): - out = six.StringIO() + with mock.patch('builtins.input', mock.Mock(return_value='N')): + out = io.StringIO() with mock.patch('django.core.management.color.supports_color', lambda *args: False): call_command( "makemigrations", "conflicting_app_with_dependencies", @@ -1232,7 +1231,7 @@ class MakeMigrationsTests(MigrationTestBase): they are outside of the current tree, in which case the absolute path should be shown. """ - out = six.StringIO() + out = io.StringIO() apps.register_model('migrations', UnicodeModel) with self.temporary_migration_module() as migration_dir: call_command("makemigrations", "migrations", stdout=out) @@ -1245,7 +1244,7 @@ class MakeMigrationsTests(MigrationTestBase): Windows if Django is installed on a different drive than where the migration files are created. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module() as migration_dir: with mock.patch('os.path.relpath', side_effect=ValueError): call_command('makemigrations', 'migrations', stdout=out) @@ -1263,7 +1262,7 @@ class MakeMigrationsTests(MigrationTestBase): with self.assertRaisesMessage(InconsistentMigrationHistory, msg): call_command("makemigrations") - @mock.patch('django.db.migrations.questioner.input', return_value='1') + @mock.patch('builtins.input', return_value='1') @mock.patch('django.db.migrations.questioner.sys.stdin', mock.MagicMock(encoding=sys.getdefaultencoding())) def test_makemigrations_auto_now_add_interactive(self, *args): """ @@ -1278,8 +1277,8 @@ class MakeMigrationsTests(MigrationTestBase): app_label = 'migrations' # Monkeypatch interactive questioner to auto accept - with mock.patch('django.db.migrations.questioner.sys.stdout', new_callable=six.StringIO) as prompt_stdout: - out = six.StringIO() + with mock.patch('django.db.migrations.questioner.sys.stdout', new_callable=io.StringIO) as prompt_stdout: + out = io.StringIO() with self.temporary_migration_module(module='migrations.test_auto_now_add'): call_command('makemigrations', 'migrations', interactive=True, stdout=out) output = out.getvalue() @@ -1316,7 +1315,7 @@ class SquashMigrationsTests(MigrationTestBase): """ squashmigrations optimizes operations. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations"): call_command("squashmigrations", "migrations", "0002", interactive=False, verbosity=1, stdout=out) self.assertIn("Optimized from 8 operations to 3 operations.", out.getvalue()) @@ -1325,7 +1324,7 @@ class SquashMigrationsTests(MigrationTestBase): """ squashmigrations --no-optimize doesn't optimize operations. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations"): call_command("squashmigrations", "migrations", "0002", interactive=False, verbosity=1, no_optimize=True, stdout=out) @@ -1335,7 +1334,7 @@ class SquashMigrationsTests(MigrationTestBase): """ squashmigrations accepts a starting migration. """ - out = six.StringIO() + out = io.StringIO() with self.temporary_migration_module(module="migrations.test_migrations_no_changes") as migration_dir: call_command("squashmigrations", "migrations", "0002", "0003", interactive=False, verbosity=1, stdout=out) diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py index 59fd8eece5..fb16b441d1 100644 --- a/tests/migrations/test_writer.py +++ b/tests/migrations/test_writer.py @@ -8,6 +8,7 @@ import sys import tokenize import unittest import uuid +from io import StringIO import custom_migration_operations.more_operations import custom_migration_operations.operations @@ -20,7 +21,7 @@ from django.db.migrations.writer import ( MigrationWriter, OperationWriter, SettingsReference, ) from django.test import SimpleTestCase, ignore_warnings, mock -from django.utils import datetime_safe, six +from django.utils import datetime_safe from django.utils._os import upath from django.utils.deconstruct import deconstructible from django.utils.encoding import force_str @@ -561,7 +562,7 @@ class WriterTests(SimpleTestCase): self.assertIn("Migration", result) # In order to preserve compatibility with Python 3.2 unicode literals # prefix shouldn't be added to strings. - tokens = tokenize.generate_tokens(six.StringIO(str(output)).readline) + tokens = tokenize.generate_tokens(StringIO(str(output)).readline) for token_type, token_source, (srow, scol), __, line in tokens: if token_type == tokenize.STRING: self.assertFalse( diff --git a/tests/model_fields/models.py b/tests/model_fields/models.py index 019301d5e2..4830fb9ed2 100644 --- a/tests/model_fields/models.py +++ b/tests/model_fields/models.py @@ -12,7 +12,6 @@ from django.db.models.fields.files import ImageField, ImageFieldFile from django.db.models.fields.related import ( ForeignKey, ForeignObject, ManyToManyField, OneToOneField, ) -from django.utils import six try: from PIL import Image @@ -51,7 +50,7 @@ class Whiz(models.Model): c = models.IntegerField(choices=CHOICES, null=True) -class Counter(six.Iterator): +class Counter: def __init__(self): self.n = 1 diff --git a/tests/model_fields/test_binaryfield.py b/tests/model_fields/test_binaryfield.py index 641dc17287..9d97d1118f 100644 --- a/tests/model_fields/test_binaryfield.py +++ b/tests/model_fields/test_binaryfield.py @@ -1,6 +1,5 @@ from django.core.exceptions import ValidationError from django.test import TestCase -from django.utils import six from .models import DataModel @@ -9,7 +8,7 @@ class BinaryFieldTests(TestCase): binary_data = b'\x00\x46\xFE' def test_set_and_retrieve(self): - data_set = (self.binary_data, six.memoryview(self.binary_data)) + data_set = (self.binary_data, memoryview(self.binary_data)) for bdata in data_set: dm = DataModel(data=bdata) dm.save() diff --git a/tests/model_forms/models.py b/tests/model_forms/models.py index 0914fc2587..f85ae8e1fd 100644 --- a/tests/model_forms/models.py +++ b/tests/model_forms/models.py @@ -16,7 +16,6 @@ from django.core.exceptions import ValidationError from django.core.files.storage import FileSystemStorage from django.db import models from django.utils._os import upath -from django.utils.six.moves import range temp_storage_dir = tempfile.mkdtemp() temp_storage = FileSystemStorage(temp_storage_dir) diff --git a/tests/model_forms/tests.py b/tests/model_forms/tests.py index 27143e97f4..adb90d6d14 100644 --- a/tests/model_forms/tests.py +++ b/tests/model_forms/tests.py @@ -17,7 +17,6 @@ from django.forms.models import ( ) from django.template import Context, Template from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature -from django.utils import six from django.utils._os import upath from .models import ( @@ -2954,7 +2953,7 @@ class CustomMetaclass(ModelFormMetaclass): return new -class CustomMetaclassForm(six.with_metaclass(CustomMetaclass, forms.ModelForm)): +class CustomMetaclassForm(forms.ModelForm, metaclass=CustomMetaclass): pass diff --git a/tests/multiple_database/tests.py b/tests/multiple_database/tests.py index 7e936216b7..3487894fd9 100644 --- a/tests/multiple_database/tests.py +++ b/tests/multiple_database/tests.py @@ -1,5 +1,6 @@ import datetime import pickle +from io import StringIO from operator import attrgetter from django.contrib.auth.models import User @@ -9,7 +10,6 @@ from django.db import DEFAULT_DB_ALIAS, connections, router, transaction from django.db.models import signals from django.db.utils import ConnectionRouter from django.test import SimpleTestCase, TestCase, override_settings -from django.utils.six import StringIO from .models import Book, Person, Pet, Review, UserProfile from .routers import AuthRouter, TestRouter, WriteRouter diff --git a/tests/pagination/tests.py b/tests/pagination/tests.py index cc3a0efbc2..2e2e2d37db 100644 --- a/tests/pagination/tests.py +++ b/tests/pagination/tests.py @@ -6,7 +6,6 @@ from django.core.paginator import ( UnorderedObjectListWarning, ) from django.test import TestCase -from django.utils import six from .custom import ValidAdjacentNumsPaginator from .models import Article @@ -240,7 +239,7 @@ class PaginationTests(unittest.TestCase): """ Paginator.page_range should be an iterator. """ - self.assertIsInstance(Paginator([1, 2, 3], 2).page_range, type(six.moves.range(0))) + self.assertIsInstance(Paginator([1, 2, 3], 2).page_range, type(range(0))) class ModelPaginationTests(TestCase): diff --git a/tests/queries/tests.py b/tests/queries/tests.py index ed323be154..1f9094e49f 100644 --- a/tests/queries/tests.py +++ b/tests/queries/tests.py @@ -11,7 +11,6 @@ from django.db.models.sql.constants import LOUTER from django.db.models.sql.where import NothingNode, WhereNode from django.test import TestCase, skipUnlessDBFeature from django.test.utils import CaptureQueriesContext -from django.utils.six.moves import range from .models import ( FK1, Annotation, Article, Author, BaseA, Book, CategoryItem, diff --git a/tests/requests/tests.py b/tests/requests/tests.py index 09b08540f4..54fe797728 100644 --- a/tests/requests/tests.py +++ b/tests/requests/tests.py @@ -1,7 +1,9 @@ import time from datetime import datetime, timedelta +from http import cookies from io import BytesIO from itertools import chain +from urllib.parse import urlencode as original_urlencode from django.core.exceptions import SuspiciousOperation from django.core.handlers.wsgi import LimitedStream, WSGIRequest @@ -14,8 +16,6 @@ from django.test.client import FakePayload from django.test.utils import freeze_time, str_prefix from django.utils.encoding import force_str from django.utils.http import cookie_date, urlencode -from django.utils.six.moves import http_cookies -from django.utils.six.moves.urllib.parse import urlencode as original_urlencode from django.utils.timezone import utc @@ -262,7 +262,7 @@ class RequestsTests(SimpleTestCase): example_cookie = response.cookies['example'] # A compat cookie may be in use -- check that it has worked # both as an output string, and using the cookie attributes - self.assertIn('; %s' % http_cookies.Morsel._reserved['httponly'], str(example_cookie)) + self.assertIn('; %s' % cookies.Morsel._reserved['httponly'], str(example_cookie)) self.assertTrue(example_cookie['httponly']) def test_unicode_cookie(self): diff --git a/tests/serializers/test_data.py b/tests/serializers/test_data.py index 2e9527f982..966df682b2 100644 --- a/tests/serializers/test_data.py +++ b/tests/serializers/test_data.py @@ -13,7 +13,6 @@ import uuid from django.core import serializers from django.db import connection, models from django.test import TestCase -from django.utils import six from .models import ( Anchor, AutoNowDateTimeData, BigIntegerData, BinaryData, BooleanData, @@ -197,7 +196,7 @@ uuid_obj = uuid.uuid4() test_data = [ # Format: (data type, PK value, Model Class, data) - (data_obj, 1, BinaryData, six.memoryview(b"\x05\xFD\x00")), + (data_obj, 1, BinaryData, memoryview(b"\x05\xFD\x00")), (data_obj, 2, BinaryData, None), (data_obj, 5, BooleanData, True), (data_obj, 6, BooleanData, False), diff --git a/tests/serializers/test_yaml.py b/tests/serializers/test_yaml.py index f3988d7ff1..542c28fb2e 100644 --- a/tests/serializers/test_yaml.py +++ b/tests/serializers/test_yaml.py @@ -1,10 +1,10 @@ import importlib import unittest +from io import StringIO from django.core import management, serializers from django.core.serializers.base import DeserializationError from django.test import SimpleTestCase, TestCase, TransactionTestCase -from django.utils.six import StringIO from .models import Author from .tests import SerializersTestBase, SerializersTransactionTestBase diff --git a/tests/serializers/tests.py b/tests/serializers/tests.py index 656bc4b4db..5c30d66082 100644 --- a/tests/serializers/tests.py +++ b/tests/serializers/tests.py @@ -1,4 +1,5 @@ from datetime import datetime +from io import StringIO from django.core import serializers from django.core.serializers import SerializerDoesNotExist @@ -10,7 +11,6 @@ from django.test import ( ) from django.test.utils import Approximate from django.utils.functional import curry -from django.utils.six import StringIO from .models import ( Actor, Article, Author, AuthorProfile, BaseModel, Category, ComplexModel, diff --git a/tests/servers/tests.py b/tests/servers/tests.py index ee0d8629cf..8f7e3253e7 100644 --- a/tests/servers/tests.py +++ b/tests/servers/tests.py @@ -5,12 +5,12 @@ import contextlib import errno import os import socket +from urllib.error import HTTPError +from urllib.request import urlopen from django.test import LiveServerTestCase, override_settings from django.utils._os import upath from django.utils.http import urlencode -from django.utils.six.moves.urllib.error import HTTPError -from django.utils.six.moves.urllib.request import urlopen from .models import Person diff --git a/tests/sessions_tests/tests.py b/tests/sessions_tests/tests.py index ae57f1d919..29de5782d9 100644 --- a/tests/sessions_tests/tests.py +++ b/tests/sessions_tests/tests.py @@ -6,6 +6,7 @@ import sys import tempfile import unittest from datetime import timedelta +from http import cookies from django.conf import settings from django.contrib.sessions.backends.base import UpdateError @@ -31,9 +32,8 @@ from django.test import ( RequestFactory, TestCase, ignore_warnings, override_settings, ) from django.test.utils import patch_logger -from django.utils import six, timezone +from django.utils import timezone from django.utils.encoding import force_text -from django.utils.six.moves import http_cookies from .models import SessionStore as CustomDatabaseSession @@ -122,7 +122,7 @@ class SessionTestsMixin(object): self.session['x'] = 1 self.session.modified = False self.session.accessed = False - i = six.iterkeys(self.session) + i = iter(self.session.keys()) self.assertTrue(hasattr(i, '__iter__')) self.assertTrue(self.session.accessed) self.assertFalse(self.session.modified) @@ -132,7 +132,7 @@ class SessionTestsMixin(object): self.session['x'] = 1 self.session.modified = False self.session.accessed = False - i = six.itervalues(self.session) + i = iter(self.session.values()) self.assertTrue(hasattr(i, '__iter__')) self.assertTrue(self.session.accessed) self.assertFalse(self.session.modified) @@ -142,7 +142,7 @@ class SessionTestsMixin(object): self.session['x'] = 1 self.session.modified = False self.session.accessed = False - i = six.iteritems(self.session) + i = iter(self.session.items()) self.assertTrue(hasattr(i, '__iter__')) self.assertTrue(self.session.accessed) self.assertFalse(self.session.modified) @@ -661,7 +661,7 @@ class SessionMiddlewareTests(TestCase): self.assertTrue( response.cookies[settings.SESSION_COOKIE_NAME]['httponly']) self.assertIn( - http_cookies.Morsel._reserved['httponly'], + cookies.Morsel._reserved['httponly'], str(response.cookies[settings.SESSION_COOKIE_NAME]) ) @@ -679,7 +679,7 @@ class SessionMiddlewareTests(TestCase): response = middleware.process_response(request, response) self.assertFalse(response.cookies[settings.SESSION_COOKIE_NAME]['httponly']) - self.assertNotIn(http_cookies.Morsel._reserved['httponly'], + self.assertNotIn(cookies.Morsel._reserved['httponly'], str(response.cookies[settings.SESSION_COOKIE_NAME])) def test_session_save_on_500(self): diff --git a/tests/sitemaps_tests/test_utils.py b/tests/sitemaps_tests/test_utils.py index ba1eadd5d1..dc4d6511f3 100644 --- a/tests/sitemaps_tests/test_utils.py +++ b/tests/sitemaps_tests/test_utils.py @@ -1,9 +1,10 @@ +from urllib.parse import urlencode + from django.contrib.sitemaps import ( SitemapNotFound, _get_sitemap_full_url, ping_google, ) from django.core.exceptions import ImproperlyConfigured from django.test import mock, modify_settings, override_settings -from django.utils.six.moves.urllib.parse import urlencode from .base import SitemapTestsBase diff --git a/tests/staticfiles_tests/test_forms.py b/tests/staticfiles_tests/test_forms.py index e3d4772662..4666520bc1 100644 --- a/tests/staticfiles_tests/test_forms.py +++ b/tests/staticfiles_tests/test_forms.py @@ -1,8 +1,9 @@ +from urllib.parse import urljoin + from django.contrib.staticfiles import storage from django.contrib.staticfiles.templatetags.staticfiles import static from django.forms import Media from django.test import SimpleTestCase, override_settings -from django.utils.six.moves.urllib.parse import urljoin class StaticTestStorage(storage.StaticFilesStorage): diff --git a/tests/staticfiles_tests/test_liveserver.py b/tests/staticfiles_tests/test_liveserver.py index 1714ae8b1b..b3727bea12 100644 --- a/tests/staticfiles_tests/test_liveserver.py +++ b/tests/staticfiles_tests/test_liveserver.py @@ -6,12 +6,12 @@ django.test.LiveServerTestCase. import contextlib import os +from urllib.request import urlopen from django.contrib.staticfiles.testing import StaticLiveServerTestCase from django.core.exceptions import ImproperlyConfigured from django.test import modify_settings, override_settings from django.utils._os import upath -from django.utils.six.moves.urllib.request import urlopen TEST_ROOT = os.path.dirname(upath(__file__)) TEST_SETTINGS = { diff --git a/tests/staticfiles_tests/test_management.py b/tests/staticfiles_tests/test_management.py index 7d17f2abe1..310c152d06 100644 --- a/tests/staticfiles_tests/test_management.py +++ b/tests/staticfiles_tests/test_management.py @@ -4,6 +4,7 @@ import os import shutil import tempfile import unittest +from io import StringIO from admin_scripts.tests import AdminScriptTestCase @@ -14,7 +15,7 @@ from django.core.exceptions import ImproperlyConfigured from django.core.management import call_command from django.test import mock, override_settings from django.test.utils import extend_sys_path -from django.utils import six, timezone +from django.utils import timezone from django.utils._os import symlinks_supported from django.utils.encoding import force_text from django.utils.functional import empty @@ -38,7 +39,7 @@ class TestFindStatic(TestDefaults, CollectionTestCase): Test ``findstatic`` management command. """ def _get_file(self, filepath): - path = call_command('findstatic', filepath, all=False, verbosity=0, stdout=six.StringIO()) + path = call_command('findstatic', filepath, all=False, verbosity=0, stdout=StringIO()) with codecs.open(force_text(path), "r", "utf-8") as f: return f.read() @@ -46,7 +47,7 @@ class TestFindStatic(TestDefaults, CollectionTestCase): """ findstatic returns all candidate files if run without --first and -v1. """ - result = call_command('findstatic', 'test/file.txt', verbosity=1, stdout=six.StringIO()) + result = call_command('findstatic', 'test/file.txt', verbosity=1, stdout=StringIO()) lines = [l.strip() for l in result.split('\n')] self.assertEqual(len(lines), 3) # three because there is also the "Found here" line self.assertIn('project', force_text(lines[1])) @@ -56,7 +57,7 @@ class TestFindStatic(TestDefaults, CollectionTestCase): """ findstatic returns all candidate files if run without --first and -v0. """ - result = call_command('findstatic', 'test/file.txt', verbosity=0, stdout=six.StringIO()) + result = call_command('findstatic', 'test/file.txt', verbosity=0, stdout=StringIO()) lines = [l.strip() for l in result.split('\n')] self.assertEqual(len(lines), 2) self.assertIn('project', force_text(lines[0])) @@ -67,7 +68,7 @@ class TestFindStatic(TestDefaults, CollectionTestCase): findstatic returns all candidate files if run without --first and -v2. Also, test that findstatic returns the searched locations with -v2. """ - result = call_command('findstatic', 'test/file.txt', verbosity=2, stdout=six.StringIO()) + result = call_command('findstatic', 'test/file.txt', verbosity=2, stdout=StringIO()) lines = [l.strip() for l in result.split('\n')] self.assertIn('project', force_text(lines[1])) self.assertIn('apps', force_text(lines[2])) @@ -89,7 +90,7 @@ class TestFindStatic(TestDefaults, CollectionTestCase): class TestConfiguration(StaticFilesTestCase): def test_location_empty(self): msg = 'without having set the STATIC_ROOT setting to a filesystem path' - err = six.StringIO() + err = StringIO() for root in ['', None]: with override_settings(STATIC_ROOT=root): with self.assertRaisesMessage(ImproperlyConfigured, msg): @@ -188,10 +189,9 @@ class TestInteractiveMessages(CollectionTestCase): return _input def test_warning_when_clearing_staticdir(self): - stdout = six.StringIO() + stdout = StringIO() self.run_collectstatic() - with mock.patch('django.contrib.staticfiles.management.commands.collectstatic.input', - side_effect=self.mock_input(stdout)): + with mock.patch('builtins.input', side_effect=self.mock_input(stdout)): call_command('collectstatic', interactive=True, clear=True, stdout=stdout) output = force_text(stdout.getvalue()) @@ -199,17 +199,16 @@ class TestInteractiveMessages(CollectionTestCase): self.assertIn(self.delete_warning_msg, output) def test_warning_when_overwriting_files_in_staticdir(self): - stdout = six.StringIO() + stdout = StringIO() self.run_collectstatic() - with mock.patch('django.contrib.staticfiles.management.commands.collectstatic.input', - side_effect=self.mock_input(stdout)): + with mock.patch('builtins.input', side_effect=self.mock_input(stdout)): call_command('collectstatic', interactive=True, stdout=stdout) output = force_text(stdout.getvalue()) self.assertIn(self.overwrite_warning_msg, output) self.assertNotIn(self.delete_warning_msg, output) def test_no_warning_when_staticdir_does_not_exist(self): - stdout = six.StringIO() + stdout = StringIO() shutil.rmtree(settings.STATIC_ROOT) call_command('collectstatic', interactive=True, stdout=stdout) output = force_text(stdout.getvalue()) @@ -218,7 +217,7 @@ class TestInteractiveMessages(CollectionTestCase): self.assertIn(self.files_copied_msg, output) def test_no_warning_for_empty_staticdir(self): - stdout = six.StringIO() + stdout = StringIO() static_dir = tempfile.mkdtemp(prefix='collectstatic_empty_staticdir_test') with override_settings(STATIC_ROOT=static_dir): call_command('collectstatic', interactive=True, stdout=stdout) @@ -347,7 +346,7 @@ class TestCollectionOverwriteWarning(CollectionTestCase): the command at highest verbosity, which is why we can't just call e.g. BaseCollectionTestCase.run_collectstatic() """ - out = six.StringIO() + out = StringIO() call_command('collectstatic', interactive=False, verbosity=3, stdout=out, **kwargs) return force_text(out.getvalue()) @@ -407,7 +406,7 @@ class TestCollectionNeverCopyStorage(CollectionTestCase): NeverCopyRemoteStorage.get_modified_time() returns a datetime in the future to simulate an unmodified file. """ - stdout = six.StringIO() + stdout = StringIO() self.run_collectstatic(stdout=stdout, verbosity=2) output = force_text(stdout.getvalue()) self.assertIn("Skipping 'test.txt' (not modified)", output) diff --git a/tests/staticfiles_tests/test_storage.py b/tests/staticfiles_tests/test_storage.py index 6333be7549..e299feea78 100644 --- a/tests/staticfiles_tests/test_storage.py +++ b/tests/staticfiles_tests/test_storage.py @@ -3,6 +3,7 @@ import shutil import sys import tempfile import unittest +from io import StringIO from django.conf import settings from django.contrib.staticfiles import finders, storage @@ -11,7 +12,6 @@ from django.contrib.staticfiles.management.commands.collectstatic import \ from django.core.cache.backends.base import BaseCache from django.core.management import call_command from django.test import override_settings -from django.utils import six from django.utils.encoding import force_text from .cases import CollectionTestCase @@ -172,7 +172,7 @@ class TestHashedFiles(object): ) def test_import_loop(self): finders.get_finder.cache_clear() - err = six.StringIO() + err = StringIO() with self.assertRaisesMessage(RuntimeError, 'Max post-process passes exceeded'): call_command('collectstatic', interactive=False, verbosity=0, stderr=err) self.assertEqual("Post-processing 'All' failed!\n\n", err.getvalue()) @@ -225,7 +225,7 @@ class TestHashedFiles(object): post_processing indicates the origin of the error when it fails. """ finders.get_finder.cache_clear() - err = six.StringIO() + err = StringIO() with self.assertRaises(Exception): call_command('collectstatic', interactive=False, verbosity=0, stderr=err) self.assertEqual("Post-processing 'faulty.css' failed!\n\n", err.getvalue()) @@ -429,7 +429,7 @@ class TestCollectionManifestStorage(TestHashedFiles, CollectionTestCase): with self.assertRaisesMessage(ValueError, err_msg): self.hashed_file_path(missing_file_name) - content = six.StringIO() + content = StringIO() content.write('Found') configured_storage.save(missing_file_name, content) # File exists on disk @@ -566,7 +566,7 @@ class TestCollectionHashedFilesCache(CollectionTestCase): def test_file_change_after_collectstatic(self): finders.get_finder.cache_clear() - err = six.StringIO() + err = StringIO() call_command('collectstatic', interactive=False, verbosity=0, stderr=err) with open(self.testimage_path, 'w+b') as f: f.write(b"new content of png file to change it's hash") diff --git a/tests/swappable_models/tests.py b/tests/swappable_models/tests.py index b67aece8c0..e9d15db015 100644 --- a/tests/swappable_models/tests.py +++ b/tests/swappable_models/tests.py @@ -1,10 +1,11 @@ -from swappable_models.models import Article +from io import StringIO from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType from django.core import management from django.test import TestCase, override_settings -from django.utils.six import StringIO + +from .models import Article class SwappableModelTests(TestCase): diff --git a/tests/template_tests/syntax_tests/test_static.py b/tests/template_tests/syntax_tests/test_static.py index deb0ce6c78..345f943caf 100644 --- a/tests/template_tests/syntax_tests/test_static.py +++ b/tests/template_tests/syntax_tests/test_static.py @@ -1,6 +1,7 @@ +from urllib.parse import urljoin + from django.conf import settings from django.test import SimpleTestCase, override_settings -from django.utils.six.moves.urllib.parse import urljoin from ..utils import setup diff --git a/tests/template_tests/templatetags/custom.py b/tests/template_tests/templatetags/custom.py index 363e7094ce..485f49a82d 100644 --- a/tests/template_tests/templatetags/custom.py +++ b/tests/template_tests/templatetags/custom.py @@ -2,7 +2,6 @@ import operator from django import template from django.template.defaultfilters import stringfilter -from django.utils import six from django.utils.html import escape, format_html register = template.Library() @@ -114,7 +113,7 @@ simple_only_unlimited_args.anything = "Expected simple_only_unlimited_args __dic def simple_unlimited_args_kwargs(one, two='hi', *args, **kwargs): """Expected simple_unlimited_args_kwargs __doc__""" # Sort the dictionary by key to guarantee the order for testing. - sorted_kwarg = sorted(six.iteritems(kwargs), key=operator.itemgetter(0)) + sorted_kwarg = sorted(kwargs.items(), key=operator.itemgetter(0)) return "simple_unlimited_args_kwargs - Expected result: %s / %s" % ( ', '.join(str(arg) for arg in [one, two] + list(args)), ', '.join('%s=%s' % (k, v) for (k, v) in sorted_kwarg) diff --git a/tests/template_tests/templatetags/inclusion.py b/tests/template_tests/templatetags/inclusion.py index 745dd7ffae..60f654ec00 100644 --- a/tests/template_tests/templatetags/inclusion.py +++ b/tests/template_tests/templatetags/inclusion.py @@ -1,7 +1,6 @@ import operator from django.template import Engine, Library -from django.utils import six engine = Engine(app_dirs=True) register = Library() @@ -215,7 +214,7 @@ inclusion_tag_use_l10n.anything = "Expected inclusion_tag_use_l10n __dict__" def inclusion_unlimited_args_kwargs(one, two='hi', *args, **kwargs): """Expected inclusion_unlimited_args_kwargs __doc__""" # Sort the dictionary by key to guarantee the order for testing. - sorted_kwarg = sorted(six.iteritems(kwargs), key=operator.itemgetter(0)) + sorted_kwarg = sorted(kwargs.items(), key=operator.itemgetter(0)) return {"result": "inclusion_unlimited_args_kwargs - Expected result: %s / %s" % ( ', '.join(str(arg) for arg in [one, two] + list(args)), ', '.join('%s=%s' % (k, v) for (k, v) in sorted_kwarg) diff --git a/tests/test_client/views.py b/tests/test_client/views.py index af30c4283d..e9a28449ec 100644 --- a/tests/test_client/views.py +++ b/tests/test_client/views.py @@ -1,3 +1,4 @@ +from urllib.parse import urlencode from xml.dom.minidom import parseString from django.contrib.auth.decorators import login_required, permission_required @@ -13,7 +14,6 @@ from django.shortcuts import render from django.template import Context, Template from django.test import Client from django.utils.decorators import method_decorator -from django.utils.six.moves.urllib.parse import urlencode def get_view(request): diff --git a/tests/test_client_regress/views.py b/tests/test_client_regress/views.py index ce60c0398c..854cdc3bc0 100644 --- a/tests/test_client_regress/views.py +++ b/tests/test_client_regress/views.py @@ -1,4 +1,5 @@ import json +from urllib.parse import urlencode from django.conf import settings from django.contrib.auth.decorators import login_required @@ -8,7 +9,6 @@ from django.shortcuts import render from django.template.loader import render_to_string from django.test import Client from django.test.client import CONTENT_TYPE_RE -from django.utils.six.moves.urllib.parse import urlencode class CustomTestException(Exception): diff --git a/tests/test_runner/test_debug_sql.py b/tests/test_runner/test_debug_sql.py index c6b9b01dbc..1b36fbc876 100644 --- a/tests/test_runner/test_debug_sql.py +++ b/tests/test_runner/test_debug_sql.py @@ -1,10 +1,10 @@ import sys import unittest +from io import StringIO from django.db import connection from django.test import TestCase from django.test.runner import DiscoverRunner -from django.utils import six from .models import Person @@ -33,7 +33,7 @@ class TestDebugSQL(unittest.TestCase): suite.addTest(self.ErrorTest()) suite.addTest(self.PassingTest()) old_config = runner.setup_databases() - stream = six.StringIO() + stream = StringIO() resultclass = runner.get_resultclass() runner.test_runner( verbosity=verbosity, diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py index 4d29f1a491..f8eda7ed39 100644 --- a/tests/test_utils/tests.py +++ b/tests/test_utils/tests.py @@ -1,5 +1,6 @@ import sys import unittest +from io import StringIO from django.conf.urls import url from django.contrib.staticfiles.finders import get_finder, get_finders @@ -18,7 +19,6 @@ from django.test.utils import ( setup_test_environment, ) from django.urls import NoReverseMatch, reverse -from django.utils import six from django.utils._os import abspathu from .models import Car, Person, PossessedCar @@ -117,7 +117,7 @@ class SkippingClassTestCase(SimpleTestCase): test_suite.addTest(SkippedTestsSubclass('test_will_be_skipped')) except unittest.SkipTest: self.fail("SkipTest should not be raised at this stage") - result = unittest.TextTestRunner(stream=six.StringIO()).run(test_suite) + result = unittest.TextTestRunner(stream=StringIO()).run(test_suite) self.assertEqual(result.testsRun, 3) self.assertEqual(len(result.skipped), 2) self.assertEqual(result.skipped[0][1], 'Database has feature(s) __class__') diff --git a/tests/timezones/tests.py b/tests/timezones/tests.py index 7f7c8228e8..e5a67f745e 100644 --- a/tests/timezones/tests.py +++ b/tests/timezones/tests.py @@ -23,7 +23,7 @@ from django.test import ( ) from django.test.utils import requires_tz_support from django.urls import reverse -from django.utils import six, timezone +from django.utils import timezone from django.utils.timezone import timedelta from .forms import ( @@ -888,8 +888,8 @@ class TemplateTests(SimpleTestCase): } } - for k1, dt in six.iteritems(datetimes): - for k2, tpl in six.iteritems(templates): + for k1, dt in datetimes.items(): + for k2, tpl in templates.items(): ctx = Context({'dt': dt, 'ICT': ICT}) actual = tpl.render(ctx) expected = results[k1][k2] @@ -901,8 +901,8 @@ class TemplateTests(SimpleTestCase): results['ict']['notag'] = t('ict', 'eat', 'utc', 'ict') with self.settings(USE_TZ=False): - for k1, dt in six.iteritems(datetimes): - for k2, tpl in six.iteritems(templates): + for k1, dt in datetimes.items(): + for k2, tpl in templates.items(): ctx = Context({'dt': dt, 'ICT': ICT}) actual = tpl.render(ctx) expected = results[k1][k2] diff --git a/tests/user_commands/tests.py b/tests/user_commands/tests.py index 4e4f5dc911..cfc4f5fb2e 100644 --- a/tests/user_commands/tests.py +++ b/tests/user_commands/tests.py @@ -1,4 +1,5 @@ import os +from io import StringIO from admin_scripts.tests import AdminScriptTestCase @@ -11,7 +12,6 @@ from django.test import SimpleTestCase, mock, override_settings from django.test.utils import captured_stderr, extend_sys_path from django.utils import translation from django.utils._os import upath -from django.utils.six import StringIO from .management.commands import dance diff --git a/tests/utils_tests/test_autoreload.py b/tests/utils_tests/test_autoreload.py index 5d42af62c8..4036df8dd8 100644 --- a/tests/utils_tests/test_autoreload.py +++ b/tests/utils_tests/test_autoreload.py @@ -4,13 +4,14 @@ import shutil import tempfile from importlib import import_module +import _thread + from django import conf from django.contrib import admin from django.test import SimpleTestCase, mock, override_settings from django.test.utils import extend_sys_path from django.utils import autoreload from django.utils._os import npath -from django.utils.six.moves import _thread from django.utils.translation import trans_real LOCALE_PATH = os.path.join(os.path.dirname(__file__), 'locale') diff --git a/tests/utils_tests/test_baseconv.py b/tests/utils_tests/test_baseconv.py index 538189bbe6..948b991ad3 100644 --- a/tests/utils_tests/test_baseconv.py +++ b/tests/utils_tests/test_baseconv.py @@ -3,7 +3,6 @@ from unittest import TestCase from django.utils.baseconv import ( BaseConverter, base2, base16, base36, base56, base62, base64, ) -from django.utils.six.moves import range class TestBaseConv(TestCase): diff --git a/tests/utils_tests/test_datastructures.py b/tests/utils_tests/test_datastructures.py index f917a2ae4e..df7020eac5 100644 --- a/tests/utils_tests/test_datastructures.py +++ b/tests/utils_tests/test_datastructures.py @@ -5,7 +5,6 @@ Tests for stuff in django.utils.datastructures. import copy from django.test import SimpleTestCase -from django.utils import six from django.utils.datastructures import ( DictWrapper, ImmutableList, MultiValueDict, MultiValueDictKeyError, OrderedSet, @@ -40,12 +39,12 @@ class MultiValueDictTests(SimpleTestCase): self.assertEqual(d.get('name'), 'Simon') self.assertEqual(d.getlist('name'), ['Adrian', 'Simon']) self.assertEqual( - sorted(six.iteritems(d)), + sorted(d.items()), [('name', 'Simon'), ('position', 'Developer')] ) self.assertEqual( - sorted(six.iterlists(d)), + sorted(d.lists()), [('name', ['Adrian', 'Simon']), ('position', ['Developer'])] ) @@ -60,8 +59,7 @@ class MultiValueDictTests(SimpleTestCase): d.setlist('lastname', ['Holovaty', 'Willison']) self.assertEqual(d.getlist('lastname'), ['Holovaty', 'Willison']) - self.assertEqual(sorted(six.itervalues(d)), - ['Developer', 'Simon', 'Willison']) + self.assertEqual(sorted(d.values()), ['Developer', 'Simon', 'Willison']) def test_appendlist(self): d = MultiValueDict() @@ -95,8 +93,8 @@ class MultiValueDictTests(SimpleTestCase): 'pm': ['Rory'], }) d = mvd.dict() - self.assertEqual(sorted(six.iterkeys(d)), sorted(six.iterkeys(mvd))) - for key in six.iterkeys(mvd): + self.assertEqual(sorted(d.keys()), sorted(mvd.keys())) + for key in mvd.keys(): self.assertEqual(d[key], mvd[key]) self.assertEqual({}, MultiValueDict().dict()) diff --git a/tests/utils_tests/test_lazyobject.py b/tests/utils_tests/test_lazyobject.py index 8c9b997b3c..513123ea00 100644 --- a/tests/utils_tests/test_lazyobject.py +++ b/tests/utils_tests/test_lazyobject.py @@ -4,7 +4,6 @@ import sys import warnings from unittest import TestCase -from django.utils import six from django.utils.functional import LazyObject, SimpleLazyObject, empty from .models import Category, CategoryInfo @@ -300,7 +299,7 @@ class SimpleLazyObjectTestCase(LazyObjectTestCase): obj = self.lazy_wrap(42) # __repr__ contains __repr__ of setup function and does not evaluate # the SimpleLazyObject - six.assertRegex(self, repr(obj), '^