diff options
| author | Claude Paroz <claude@2xlibre.net> | 2017-01-07 12:11:46 +0100 |
|---|---|---|
| committer | Claude Paroz <claude@2xlibre.net> | 2017-01-18 21:33:28 +0100 |
| commit | 2b281cc35ed9d997614ca3c416928d7fabfef1ad (patch) | |
| tree | d3e73cf44b15139aa9f1f53e398942ba64f5e190 /django | |
| parent | 7b2f2e74adb36a4334e83130f6abc2f79d395235 (diff) | |
Refs #23919 -- Removed most of remaining six usage
Thanks Tim Graham for the review.
Diffstat (limited to 'django')
110 files changed, 169 insertions, 267 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<charset>[^\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 "<WithNode>" 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 |
