From 3cb2457f46b3e40ff6b6acffcb3fd44cbea091e5 Mon Sep 17 00:00:00 2001 From: Aymeric Augustin Date: Fri, 20 Jul 2012 14:22:00 +0200 Subject: [PATCH] [py3] Replaced basestring by six.string_types. --- django/conf/__init__.py | 5 +++-- django/conf/urls/__init__.py | 5 +++-- django/contrib/admin/helpers.py | 3 ++- django/contrib/admin/util.py | 2 +- django/contrib/formtools/utils.py | 3 ++- django/contrib/gis/admin/widgets.py | 5 +++-- .../gis/db/backends/oracle/operations.py | 2 +- .../gis/db/backends/postgis/operations.py | 2 +- .../db/backends/spatialite/introspection.py | 3 ++- .../gis/db/backends/spatialite/operations.py | 2 +- django/contrib/gis/db/backends/util.py | 4 +++- django/contrib/gis/db/models/fields.py | 3 ++- django/contrib/gis/db/models/proxy.py | 3 ++- django/contrib/gis/db/models/query.py | 4 +++- django/contrib/gis/gdal/datasource.py | 10 +++++---- django/contrib/gis/gdal/driver.py | 10 +++++---- django/contrib/gis/gdal/feature.py | 16 +++++++------- django/contrib/gis/gdal/geometries.py | 8 +++---- django/contrib/gis/gdal/geomtype.py | 8 ++++--- django/contrib/gis/gdal/srs.py | 4 ++-- django/contrib/gis/geoip/base.py | 6 ++++-- django/contrib/gis/geoip/tests.py | 4 +++- django/contrib/gis/geos/factory.py | 4 +++- django/contrib/gis/geos/geometry.py | 8 ++++--- django/contrib/gis/geos/prototypes/io.py | 8 ++++--- django/contrib/gis/geos/tests/test_geos.py | 5 +++-- django/contrib/gis/geos/tests/test_io.py | 9 ++++---- django/contrib/gis/maps/google/overlays.py | 11 +++++----- django/contrib/gis/measure.py | 2 +- django/contrib/gis/utils/layermapping.py | 9 ++++---- django/contrib/gis/utils/ogrinspect.py | 3 ++- django/contrib/gis/utils/wkt.py | 8 ++++--- django/core/cache/backends/memcached.py | 4 +++- django/core/mail/backends/filebased.py | 3 ++- django/core/mail/message.py | 9 ++++---- django/core/management/validation.py | 7 ++++--- django/core/serializers/base.py | 3 ++- django/core/serializers/json.py | 3 ++- django/core/serializers/pyyaml.py | 3 ++- django/core/urlresolvers.py | 7 ++++--- django/core/validators.py | 3 ++- django/db/backends/oracle/base.py | 7 ++++--- django/db/models/fields/__init__.py | 7 ++++--- django/db/models/fields/files.py | 3 ++- django/db/models/fields/related.py | 21 ++++++++++--------- django/db/models/options.py | 5 +++-- django/db/utils.py | 3 ++- django/forms/extras/widgets.py | 3 ++- django/forms/fields.py | 5 +++-- django/forms/widgets.py | 3 ++- django/template/base.py | 3 ++- django/template/loader.py | 3 ++- django/template/response.py | 3 ++- django/templatetags/i18n.py | 3 ++- django/templatetags/tz.py | 3 ++- django/test/_doctest.py | 10 ++++----- django/test/client.py | 2 +- django/test/html.py | 19 +++++++++-------- django/test/utils.py | 3 ++- django/utils/archive.py | 4 +++- django/utils/checksums.py | 4 +++- django/utils/dictconfig.py | 4 +++- django/utils/encoding.py | 4 ++-- django/utils/formats.py | 2 +- django/utils/regex_helper.py | 4 +++- django/utils/timezone.py | 5 +++-- django/views/debug.py | 3 ++- django/views/i18n.py | 7 ++++--- tests/modeltests/field_subclassing/fields.py | 3 ++- tests/modeltests/serializers/tests.py | 3 ++- tests/regressiontests/forms/tests/fields.py | 3 ++- tests/regressiontests/i18n/commands/tests.py | 4 +++- .../staticfiles_tests/tests.py | 3 ++- 73 files changed, 230 insertions(+), 150 deletions(-) diff --git a/django/conf/__init__.py b/django/conf/__init__.py index 5e4b412f32..77454b3fb9 100644 --- a/django/conf/__init__.py +++ b/django/conf/__init__.py @@ -15,6 +15,7 @@ from django.conf import global_settings from django.core.exceptions import ImproperlyConfigured from django.utils.functional import LazyObject, empty from django.utils import importlib +from django.utils import six ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE" @@ -73,7 +74,7 @@ class BaseSettings(object): elif name == "ADMIN_MEDIA_PREFIX": warnings.warn("The ADMIN_MEDIA_PREFIX setting has been removed; " "use STATIC_URL instead.", DeprecationWarning) - elif name == "ALLOWED_INCLUDE_ROOTS" and isinstance(value, basestring): + elif name == "ALLOWED_INCLUDE_ROOTS" and isinstance(value, six.string_types): raise ValueError("The ALLOWED_INCLUDE_ROOTS setting must be set " "to a tuple, not a string.") object.__setattr__(self, name, value) @@ -102,7 +103,7 @@ class Settings(BaseSettings): if setting == setting.upper(): setting_value = getattr(mod, setting) if setting in tuple_settings and \ - isinstance(setting_value, basestring): + isinstance(setting_value, six.string_types): warnings.warn("The %s setting must be a tuple. Please fix your " "settings, as auto-correction is now deprecated." % setting, PendingDeprecationWarning) diff --git a/django/conf/urls/__init__.py b/django/conf/urls/__init__.py index 0b6ab6496e..04fb1dff59 100644 --- a/django/conf/urls/__init__.py +++ b/django/conf/urls/__init__.py @@ -2,6 +2,7 @@ from django.core.urlresolvers import (RegexURLPattern, RegexURLResolver, LocaleRegexURLResolver) from django.core.exceptions import ImproperlyConfigured from django.utils.importlib import import_module +from django.utils import six __all__ = ['handler403', 'handler404', 'handler500', 'include', 'patterns', 'url'] @@ -20,7 +21,7 @@ def include(arg, namespace=None, app_name=None): # No namespace hint - use manually provided namespace urlconf_module = arg - if isinstance(urlconf_module, basestring): + if isinstance(urlconf_module, six.string_types): urlconf_module = import_module(urlconf_module) patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module) @@ -52,7 +53,7 @@ def url(regex, view, kwargs=None, name=None, prefix=''): urlconf_module, app_name, namespace = view return RegexURLResolver(regex, urlconf_module, kwargs, app_name=app_name, namespace=namespace) else: - if isinstance(view, basestring): + if isinstance(view, six.string_types): if not view: raise ImproperlyConfigured('Empty URL pattern view name not permitted (for pattern %r)' % regex) if prefix: diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py index ac29d19469..11b14dcb51 100644 --- a/django/contrib/admin/helpers.py +++ b/django/contrib/admin/helpers.py @@ -12,6 +12,7 @@ from django.template.defaultfilters import capfirst from django.utils.encoding import force_unicode, smart_unicode from django.utils.html import conditional_escape, format_html from django.utils.safestring import mark_safe +from django.utils import six from django.utils.translation import ugettext_lazy as _ from django.conf import settings @@ -49,7 +50,7 @@ class AdminForm(object): try: fieldset_name, fieldset_options = self.fieldsets[0] field_name = fieldset_options['fields'][0] - if not isinstance(field_name, basestring): + if not isinstance(field_name, six.string_types): field_name = field_name[0] return self.form[field_name] except (KeyError, IndexError): diff --git a/django/contrib/admin/util.py b/django/contrib/admin/util.py index 1d43585fcd..a529bacd18 100644 --- a/django/contrib/admin/util.py +++ b/django/contrib/admin/util.py @@ -52,7 +52,7 @@ def quote(s): quoting is slightly different so that it doesn't get automatically unquoted by the Web browser. """ - if not isinstance(s, basestring): + if not isinstance(s, six.string_types): return s res = list(s) for i in range(len(res)): diff --git a/django/contrib/formtools/utils.py b/django/contrib/formtools/utils.py index 96a0092a35..8763cded07 100644 --- a/django/contrib/formtools/utils.py +++ b/django/contrib/formtools/utils.py @@ -2,6 +2,7 @@ import pickle from django.utils.crypto import salted_hmac +from django.utils import six def form_hmac(form): @@ -16,7 +17,7 @@ def form_hmac(form): value = bf.data or '' else: value = bf.field.clean(bf.data) or '' - if isinstance(value, basestring): + if isinstance(value, six.string_types): value = value.strip() data.append((bf.name, value)) diff --git a/django/contrib/gis/admin/widgets.py b/django/contrib/gis/admin/widgets.py index c7b48e4263..47570d3f9d 100644 --- a/django/contrib/gis/admin/widgets.py +++ b/django/contrib/gis/admin/widgets.py @@ -1,6 +1,7 @@ from django.forms.widgets import Textarea from django.template import loader, Context from django.templatetags.static import static +from django.utils import six from django.utils import translation from django.contrib.gis.gdal import OGRException @@ -25,7 +26,7 @@ class OpenLayersWidget(Textarea): # If a string reaches here (via a validation error on another # field) then just reconstruct the Geometry. - if isinstance(value, basestring): + if isinstance(value, six.string_types): try: value = GEOSGeometry(value) except (GEOSException, ValueError): @@ -109,7 +110,7 @@ class OpenLayersWidget(Textarea): """ Compare geographic value of data with its initial value. """ # Ensure we are dealing with a geographic object - if isinstance(initial, basestring): + if isinstance(initial, six.string_types): try: initial = GEOSGeometry(initial) except (GEOSException, ValueError): diff --git a/django/contrib/gis/db/backends/oracle/operations.py b/django/contrib/gis/db/backends/oracle/operations.py index 3a189ea1fe..4e33942f7a 100644 --- a/django/contrib/gis/db/backends/oracle/operations.py +++ b/django/contrib/gis/db/backends/oracle/operations.py @@ -121,7 +121,7 @@ class OracleOperations(DatabaseOperations, BaseSpatialOperations): 'exact' : SDOOperation('SDO_EQUAL'), 'overlaps' : SDOOperation('SDO_OVERLAPS'), 'same_as' : SDOOperation('SDO_EQUAL'), - 'relate' : (SDORelate, basestring), # Oracle uses a different syntax, e.g., 'mask=inside+touch' + 'relate' : (SDORelate, six.string_types), # Oracle uses a different syntax, e.g., 'mask=inside+touch' 'touches' : SDOOperation('SDO_TOUCH'), 'within' : SDOOperation('SDO_INSIDE'), } diff --git a/django/contrib/gis/db/backends/postgis/operations.py b/django/contrib/gis/db/backends/postgis/operations.py index 8f190882e1..a6340ce22b 100644 --- a/django/contrib/gis/db/backends/postgis/operations.py +++ b/django/contrib/gis/db/backends/postgis/operations.py @@ -162,7 +162,7 @@ class PostGISOperations(DatabaseOperations, BaseSpatialOperations): 'overlaps' : PostGISFunction(prefix, 'Overlaps'), 'contains' : PostGISFunction(prefix, 'Contains'), 'intersects' : PostGISFunction(prefix, 'Intersects'), - 'relate' : (PostGISRelate, basestring), + 'relate' : (PostGISRelate, six.string_types), } # Valid distance types and substitutions diff --git a/django/contrib/gis/db/backends/spatialite/introspection.py b/django/contrib/gis/db/backends/spatialite/introspection.py index 1b5952ceac..4f12ade114 100644 --- a/django/contrib/gis/db/backends/spatialite/introspection.py +++ b/django/contrib/gis/db/backends/spatialite/introspection.py @@ -1,5 +1,6 @@ from django.contrib.gis.gdal import OGRGeomType from django.db.backends.sqlite3.introspection import DatabaseIntrospection, FlexibleFieldLookupDict +from django.utils import six class GeoFlexibleFieldLookupDict(FlexibleFieldLookupDict): """ @@ -43,7 +44,7 @@ class SpatiaLiteIntrospection(DatabaseIntrospection): field_params = {} if srid != 4326: field_params['srid'] = srid - if isinstance(dim, basestring) and 'Z' in dim: + if isinstance(dim, six.string_types) and 'Z' in dim: field_params['dim'] = 3 finally: cursor.close() diff --git a/django/contrib/gis/db/backends/spatialite/operations.py b/django/contrib/gis/db/backends/spatialite/operations.py index ffd7d33dad..1d7c4fab52 100644 --- a/django/contrib/gis/db/backends/spatialite/operations.py +++ b/django/contrib/gis/db/backends/spatialite/operations.py @@ -90,7 +90,7 @@ class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations): 'overlaps' : SpatiaLiteFunction('Overlaps'), 'contains' : SpatiaLiteFunction('Contains'), 'intersects' : SpatiaLiteFunction('Intersects'), - 'relate' : (SpatiaLiteRelate, basestring), + 'relate' : (SpatiaLiteRelate, six.string_types), # Returns true if B's bounding box completely contains A's bounding box. 'contained' : SpatiaLiteFunction('MbrWithin'), # Returns true if A's bounding box completely contains B's bounding box. diff --git a/django/contrib/gis/db/backends/util.py b/django/contrib/gis/db/backends/util.py index b50c8e222e..b899934a01 100644 --- a/django/contrib/gis/db/backends/util.py +++ b/django/contrib/gis/db/backends/util.py @@ -3,13 +3,15 @@ A collection of utility routines and classes used by the spatial backends. """ +from django.utils import six + def gqn(val): """ The geographic quote name function; used for quoting tables and geometries (they use single rather than the double quotes of the backend quotename function). """ - if isinstance(val, basestring): + if isinstance(val, six.string_types): if isinstance(val, unicode): val = val.encode('ascii') return "'%s'" % val else: diff --git a/django/contrib/gis/db/models/fields.py b/django/contrib/gis/db/models/fields.py index 2b1660763a..17630d0899 100644 --- a/django/contrib/gis/db/models/fields.py +++ b/django/contrib/gis/db/models/fields.py @@ -4,6 +4,7 @@ from django.utils.translation import ugettext_lazy as _ from django.contrib.gis import forms from django.contrib.gis.db.models.proxy import GeometryProxy from django.contrib.gis.geometry.backend import Geometry, GeometryException +from django.utils import six # Local cache of the spatial_ref_sys table, which holds SRID data for each # spatial database alias. This cache exists so that the database isn't queried @@ -159,7 +160,7 @@ class GeometryField(Field): # from the given string input. if isinstance(geom, Geometry): pass - elif isinstance(geom, basestring) or hasattr(geom, '__geo_interface__'): + elif isinstance(geom, six.string_types) or hasattr(geom, '__geo_interface__'): try: geom = Geometry(geom) except GeometryException: diff --git a/django/contrib/gis/db/models/proxy.py b/django/contrib/gis/db/models/proxy.py index e569dd5c4f..413610fc5c 100644 --- a/django/contrib/gis/db/models/proxy.py +++ b/django/contrib/gis/db/models/proxy.py @@ -5,6 +5,7 @@ corresponding to geographic model fields. Thanks to Robert Coup for providing this functionality (see #4322). """ +from django.utils import six class GeometryProxy(object): def __init__(self, klass, field): @@ -53,7 +54,7 @@ class GeometryProxy(object): if isinstance(value, self._klass) and (str(value.geom_type).upper() == gtype or gtype == 'GEOMETRY'): # Assigning the SRID to the geometry. if value.srid is None: value.srid = self._field.srid - elif value is None or isinstance(value, (basestring, buffer)): + elif value is None or isinstance(value, six.string_types + (buffer,)): # Set with None, WKT, HEX, or WKB pass else: diff --git a/django/contrib/gis/db/models/query.py b/django/contrib/gis/db/models/query.py index a11b1213f4..dd2983aecc 100644 --- a/django/contrib/gis/db/models/query.py +++ b/django/contrib/gis/db/models/query.py @@ -8,6 +8,8 @@ from django.contrib.gis.geometry.backend import Geometry from django.contrib.gis.measure import Area, Distance from django.utils import six +from django.utils import six + class GeoQuerySet(QuerySet): "The Geographic QuerySet." @@ -534,7 +536,7 @@ class GeoQuerySet(QuerySet): geo_field = settings['geo_field'] # The attribute to attach to the model. - if not isinstance(model_att, basestring): model_att = att + if not isinstance(model_att, six.string_types): model_att = att # Special handling for any argument that is a geometry. for name in settings['geom_args']: diff --git a/django/contrib/gis/gdal/datasource.py b/django/contrib/gis/gdal/datasource.py index e5f3602ddb..1797ed3320 100644 --- a/django/contrib/gis/gdal/datasource.py +++ b/django/contrib/gis/gdal/datasource.py @@ -45,6 +45,8 @@ from django.contrib.gis.gdal.layer import Layer # Getting the ctypes prototypes for the DataSource. from django.contrib.gis.gdal.prototypes import ds as capi +from django.utils import six + # For more information, see the OGR C API source code: # http://www.gdal.org/ogr/ogr__api_8h.html # @@ -65,7 +67,7 @@ class DataSource(GDALBase): if not capi.get_driver_count(): capi.register_all() - if isinstance(ds_input, basestring): + if isinstance(ds_input, six.string_types): # The data source driver is a void pointer. ds_driver = Driver.ptr_type() try: @@ -84,7 +86,7 @@ class DataSource(GDALBase): self.ptr = ds self.driver = Driver(ds_driver) else: - # Raise an exception if the returned pointer is NULL + # Raise an exception if the returned pointer is NULL raise OGRException('Invalid data source file "%s"' % ds_input) def __del__(self): @@ -98,7 +100,7 @@ class DataSource(GDALBase): def __getitem__(self, index): "Allows use of the index [] operator to get a layer at the index." - if isinstance(index, basestring): + if isinstance(index, six.string_types): l = capi.get_layer_by_name(self.ptr, index) if not l: raise OGRIndexError('invalid OGR Layer name given: "%s"' % index) elif isinstance(index, int): @@ -108,7 +110,7 @@ class DataSource(GDALBase): else: raise TypeError('Invalid index type: %s' % type(index)) return Layer(l, self) - + def __len__(self): "Returns the number of layers within the data source." return self.layer_count diff --git a/django/contrib/gis/gdal/driver.py b/django/contrib/gis/gdal/driver.py index 1753db2b2b..de4dc61c63 100644 --- a/django/contrib/gis/gdal/driver.py +++ b/django/contrib/gis/gdal/driver.py @@ -1,9 +1,11 @@ -# prerequisites imports +# prerequisites imports from ctypes import c_void_p from django.contrib.gis.gdal.base import GDALBase from django.contrib.gis.gdal.error import OGRException from django.contrib.gis.gdal.prototypes import ds as capi +from django.utils import six + # For more information, see the OGR C API source code: # http://www.gdal.org/ogr/ogr__api_8h.html # @@ -18,11 +20,11 @@ class Driver(GDALBase): 'tiger' : 'TIGER', 'tiger/line' : 'TIGER', } - + def __init__(self, dr_input): "Initializes an OGR driver on either a string or integer input." - if isinstance(dr_input, basestring): + if isinstance(dr_input, six.string_types): # If a string name of the driver was passed in self._register() @@ -57,7 +59,7 @@ class Driver(GDALBase): # Only register all if the driver count is 0 (or else all drivers # will be registered over and over again) if not self.driver_count: capi.register_all() - + # Driver properties @property def driver_count(self): diff --git a/django/contrib/gis/gdal/feature.py b/django/contrib/gis/gdal/feature.py index 47fd9e522e..52eadfa06f 100644 --- a/django/contrib/gis/gdal/feature.py +++ b/django/contrib/gis/gdal/feature.py @@ -7,6 +7,8 @@ from django.contrib.gis.gdal.geometries import OGRGeometry, OGRGeomType # ctypes function prototypes from django.contrib.gis.gdal.prototypes import ds as capi, geom as geom_api +from django.utils import six + # For more information, see the OGR C API source code: # http://www.gdal.org/ogr/ogr__api_8h.html # @@ -30,17 +32,17 @@ class Feature(GDALBase): """ Gets the Field object at the specified index, which may be either an integer or the Field's string label. Note that the Field object - is not the field's _value_ -- use the `get` method instead to + is not the field's _value_ -- use the `get` method instead to retrieve the value (e.g. an integer) instead of a Field instance. """ - if isinstance(index, basestring): + if isinstance(index, six.string_types): i = self.index(index) else: if index < 0 or index > self.num_fields: raise OGRIndexError('index out of range') i = index return Field(self.ptr, i) - + def __iter__(self): "Iterates over each field in the Feature." for i in xrange(self.num_fields): @@ -49,7 +51,7 @@ class Feature(GDALBase): def __len__(self): "Returns the count of fields in this feature." return self.num_fields - + def __str__(self): "The string name of the feature." return 'Feature FID %d in Layer<%s>' % (self.fid, self.layer_name) @@ -63,7 +65,7 @@ class Feature(GDALBase): def fid(self): "Returns the feature identifier." return capi.get_fid(self.ptr) - + @property def layer_name(self): "Returns the name of the layer for the feature." @@ -77,7 +79,7 @@ class Feature(GDALBase): @property def fields(self): "Returns a list of fields in the Feature." - return [capi.get_field_name(capi.get_field_defn(self._fdefn, i)) + return [capi.get_field_name(capi.get_field_defn(self._fdefn, i)) for i in xrange(self.num_fields)] @property @@ -91,7 +93,7 @@ class Feature(GDALBase): def geom_type(self): "Returns the OGR Geometry Type for this Feture." return OGRGeomType(capi.get_fd_geom_type(self._fdefn)) - + #### Feature Methods #### def get(self, field): """ diff --git a/django/contrib/gis/gdal/geometries.py b/django/contrib/gis/gdal/geometries.py index 617c4acef4..f38aeba838 100644 --- a/django/contrib/gis/gdal/geometries.py +++ b/django/contrib/gis/gdal/geometries.py @@ -71,7 +71,7 @@ class OGRGeometry(GDALBase): def __init__(self, geom_input, srs=None): "Initializes Geometry on either WKT or an OGR pointer as input." - str_instance = isinstance(geom_input, basestring) + str_instance = isinstance(geom_input, six.string_types) # If HEX, unpack input to to a binary buffer. if str_instance and hex_regex.match(geom_input): @@ -283,7 +283,7 @@ class OGRGeometry(GDALBase): # (decremented) when this geometry's destructor is called. if isinstance(srs, SpatialReference): srs_ptr = srs.ptr - elif isinstance(srs, six.integer_types + (basestring,)): + elif isinstance(srs, six.integer_types + six.string_types): sr = SpatialReference(srs) srs_ptr = sr.ptr else: @@ -412,7 +412,7 @@ class OGRGeometry(GDALBase): capi.geom_transform(self.ptr, coord_trans.ptr) elif isinstance(coord_trans, SpatialReference): capi.geom_transform_to(self.ptr, coord_trans.ptr) - elif isinstance(coord_trans, six.integer_types + (basestring,)): + elif isinstance(coord_trans, six.integer_types + six.string_types): sr = SpatialReference(coord_trans) capi.geom_transform_to(self.ptr, sr.ptr) else: @@ -687,7 +687,7 @@ class GeometryCollection(OGRGeometry): for g in geom: capi.add_geom(self.ptr, g.ptr) else: capi.add_geom(self.ptr, geom.ptr) - elif isinstance(geom, basestring): + elif isinstance(geom, six.string_types): tmp = OGRGeometry(geom) capi.add_geom(self.ptr, tmp.ptr) else: diff --git a/django/contrib/gis/gdal/geomtype.py b/django/contrib/gis/gdal/geomtype.py index 3bf94d4815..fe4b89adeb 100644 --- a/django/contrib/gis/gdal/geomtype.py +++ b/django/contrib/gis/gdal/geomtype.py @@ -1,5 +1,7 @@ from django.contrib.gis.gdal.error import OGRException +from django.utils import six + #### OGRGeomType #### class OGRGeomType(object): "Encapulates OGR Geometry Types." @@ -32,7 +34,7 @@ class OGRGeomType(object): "Figures out the correct OGR Type based upon the input." if isinstance(type_input, OGRGeomType): num = type_input.num - elif isinstance(type_input, basestring): + elif isinstance(type_input, six.string_types): type_input = type_input.lower() if type_input == 'geometry': type_input='unknown' num = self._str_types.get(type_input, None) @@ -44,7 +46,7 @@ class OGRGeomType(object): num = type_input else: raise TypeError('Invalid OGR input type given.') - + # Setting the OGR geometry type number. self.num = num @@ -59,7 +61,7 @@ class OGRGeomType(object): """ if isinstance(other, OGRGeomType): return self.num == other.num - elif isinstance(other, basestring): + elif isinstance(other, six.string_types): return self.name.lower() == other.lower() elif isinstance(other, int): return self.num == other diff --git a/django/contrib/gis/gdal/srs.py b/django/contrib/gis/gdal/srs.py index ad07ed27b8..6003ce75ad 100644 --- a/django/contrib/gis/gdal/srs.py +++ b/django/contrib/gis/gdal/srs.py @@ -54,7 +54,7 @@ class SpatialReference(GDALBase): buf = c_char_p('') srs_type = 'user' - if isinstance(srs_input, basestring): + if isinstance(srs_input, six.string_types): # Encoding to ASCII if unicode passed in. if isinstance(srs_input, unicode): srs_input = srs_input.encode('ascii') @@ -135,7 +135,7 @@ class SpatialReference(GDALBase): The attribute value for the given target node (e.g. 'PROJCS'). The index keyword specifies an index of the child node to return. """ - if not isinstance(target, basestring) or not isinstance(index, int): + if not isinstance(target, six.string_types) or not isinstance(index, int): raise TypeError return capi.get_attr_value(self.ptr, target, index) diff --git a/django/contrib/gis/geoip/base.py b/django/contrib/gis/geoip/base.py index e00e0a4d93..944240c811 100644 --- a/django/contrib/gis/geoip/base.py +++ b/django/contrib/gis/geoip/base.py @@ -10,6 +10,8 @@ from django.contrib.gis.geoip.prototypes import ( GeoIP_country_code_by_addr, GeoIP_country_code_by_name, GeoIP_country_name_by_addr, GeoIP_country_name_by_name) +from django.utils import six + # Regular expressions for recognizing the GeoIP free database editions. free_regex = re.compile(r'^GEO-\d{3}FREE') lite_regex = re.compile(r'^GEO-\d{3}LITE') @@ -86,7 +88,7 @@ class GeoIP(object): if not path: path = GEOIP_SETTINGS.get('GEOIP_PATH', None) if not path: raise GeoIPException('GeoIP path must be provided via parameter or the GEOIP_PATH setting.') - if not isinstance(path, basestring): + if not isinstance(path, six.string_types): raise TypeError('Invalid path type: %s' % type(path).__name__) if os.path.isdir(path): @@ -129,7 +131,7 @@ class GeoIP(object): def _check_query(self, query, country=False, city=False, city_or_country=False): "Helper routine for checking the query and database availability." # Making sure a string was passed in for the query. - if not isinstance(query, basestring): + if not isinstance(query, six.string_types): raise TypeError('GeoIP query must be a string, not type %s' % type(query).__name__) # GeoIP only takes ASCII-encoded strings. diff --git a/django/contrib/gis/geoip/tests.py b/django/contrib/gis/geoip/tests.py index 1d9132ba6f..e53230d9ad 100644 --- a/django/contrib/gis/geoip/tests.py +++ b/django/contrib/gis/geoip/tests.py @@ -6,6 +6,8 @@ from django.contrib.gis.geos import GEOSGeometry from django.contrib.gis.geoip import GeoIP, GeoIPException from django.utils import unittest +from django.utils import six + # Note: Requires use of both the GeoIP country and city datasets. # The GEOIP_DATA path should be the only setting set (the directory # should contain links or the actual database files 'GeoIP.dat' and @@ -35,7 +37,7 @@ class GeoIPTest(unittest.TestCase): bad_params = (23, 'foo', 15.23) for bad in bad_params: self.assertRaises(GeoIPException, GeoIP, cache=bad) - if isinstance(bad, basestring): + if isinstance(bad, six.string_types): e = GeoIPException else: e = TypeError diff --git a/django/contrib/gis/geos/factory.py b/django/contrib/gis/geos/factory.py index ee33f14d19..fbd7d5a3e9 100644 --- a/django/contrib/gis/geos/factory.py +++ b/django/contrib/gis/geos/factory.py @@ -1,12 +1,14 @@ from django.contrib.gis.geos.geometry import GEOSGeometry, wkt_regex, hex_regex +from django.utils import six + def fromfile(file_h): """ Given a string file name, returns a GEOSGeometry. The file may contain WKB, WKT, or HEX. """ # If given a file name, get a real handle. - if isinstance(file_h, basestring): + if isinstance(file_h, six.string_types): with open(file_h, 'rb') as file_h: buf = file_h.read() else: diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py index 2d8ac53dbd..703b11bc02 100644 --- a/django/contrib/gis/geos/geometry.py +++ b/django/contrib/gis/geos/geometry.py @@ -27,6 +27,8 @@ from django.contrib.gis.geos.prototypes.io import wkt_r, wkt_w, wkb_r, wkb_w, ew # For recognizing geometry input. from django.contrib.gis.geometry.regex import hex_regex, wkt_regex, json_regex +from django.utils import six + class GEOSGeometry(GEOSBase, ListMixin): "A class that, generally, encapsulates a GEOS geometry." @@ -52,7 +54,7 @@ class GEOSGeometry(GEOSBase, ListMixin): The `srid` keyword is used to specify the Source Reference Identifier (SRID) number for this Geometry. If not set, the SRID will be None. """ - if isinstance(geo_input, basestring): + if isinstance(geo_input, six.string_types): if isinstance(geo_input, unicode): # Encoding to ASCII, WKT or HEXEWKB doesn't need any more. geo_input = geo_input.encode('ascii') @@ -153,7 +155,7 @@ class GEOSGeometry(GEOSBase, ListMixin): Equivalence testing, a Geometry may be compared with another Geometry or a WKT representation. """ - if isinstance(other, basestring): + if isinstance(other, six.string_types): return self.wkt == other elif isinstance(other, GEOSGeometry): return self.equals_exact(other) @@ -333,7 +335,7 @@ class GEOSGeometry(GEOSBase, ListMixin): Returns true if the elements in the DE-9IM intersection matrix for the two Geometries match the elements in pattern. """ - if not isinstance(pattern, basestring) or len(pattern) > 9: + if not isinstance(pattern, six.string_types) or len(pattern) > 9: raise GEOSException('invalid intersection matrix pattern') return capi.geos_relatepattern(self.ptr, other.ptr, pattern) diff --git a/django/contrib/gis/geos/prototypes/io.py b/django/contrib/gis/geos/prototypes/io.py index 56f702243d..053b9948a2 100644 --- a/django/contrib/gis/geos/prototypes/io.py +++ b/django/contrib/gis/geos/prototypes/io.py @@ -6,6 +6,8 @@ from django.contrib.gis.geos.prototypes.errcheck import check_geom, check_string from django.contrib.gis.geos.prototypes.geom import c_uchar_p, geos_char_p from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc +from django.utils import six + ### The WKB/WKT Reader/Writer structures and pointers ### class WKTReader_st(Structure): pass class WKTWriter_st(Structure): pass @@ -118,7 +120,7 @@ class _WKTReader(IOBase): ptr_type = WKT_READ_PTR def read(self, wkt): - if not isinstance(wkt, basestring): raise TypeError + if not isinstance(wkt, six.string_types): raise TypeError return wkt_reader_read(self.ptr, wkt) class _WKBReader(IOBase): @@ -131,7 +133,7 @@ class _WKBReader(IOBase): if isinstance(wkb, buffer): wkb_s = str(wkb) return wkb_reader_read(self.ptr, wkb_s, len(wkb_s)) - elif isinstance(wkb, basestring): + elif isinstance(wkb, six.string_types): return wkb_reader_read_hex(self.ptr, wkb, len(wkb)) else: raise TypeError @@ -195,7 +197,7 @@ class WKBWriter(IOBase): # `ThreadLocalIO` object holds instances of the WKT and WKB reader/writer # objects that are local to the thread. The `GEOSGeometry` internals # access these instances by calling the module-level functions, defined -# below. +# below. class ThreadLocalIO(threading.local): wkt_r = None wkt_w = None diff --git a/django/contrib/gis/geos/tests/test_geos.py b/django/contrib/gis/geos/tests/test_geos.py index 18f1fb65be..b1d00d5241 100644 --- a/django/contrib/gis/geos/tests/test_geos.py +++ b/django/contrib/gis/geos/tests/test_geos.py @@ -8,6 +8,7 @@ from django.contrib.gis.geos.base import gdal, numpy, GEOSBase from django.contrib.gis.geos.libgeos import GEOS_PREPARE from django.contrib.gis.geometry.test_data import TestDataMixin +from django.utils import six from django.utils import unittest @@ -1004,7 +1005,7 @@ class GEOSTest(unittest.TestCase, TestDataMixin): g = GEOSGeometry("POINT(0 0)") self.assertTrue(g.valid) - self.assertTrue(isinstance(g.valid_reason, basestring)) + self.assertTrue(isinstance(g.valid_reason, six.string_types)) self.assertEqual(g.valid_reason, "Valid Geometry") print("\nBEGIN - expecting GEOS_NOTICE; safe to ignore.\n") @@ -1012,7 +1013,7 @@ class GEOSTest(unittest.TestCase, TestDataMixin): g = GEOSGeometry("LINESTRING(0 0, 0 0)") self.assertTrue(not g.valid) - self.assertTrue(isinstance(g.valid_reason, basestring)) + self.assertTrue(isinstance(g.valid_reason, six.string_types)) self.assertTrue(g.valid_reason.startswith("Too few points in geometry component")) print("\nEND - expecting GEOS_NOTICE; safe to ignore.\n") diff --git a/django/contrib/gis/geos/tests/test_io.py b/django/contrib/gis/geos/tests/test_io.py index 50c36684a0..b39d705f03 100644 --- a/django/contrib/gis/geos/tests/test_io.py +++ b/django/contrib/gis/geos/tests/test_io.py @@ -1,6 +1,7 @@ import binascii import unittest from django.contrib.gis.geos import GEOSGeometry, WKTReader, WKTWriter, WKBReader, WKBWriter, geos_version_info +from django.utils import six class GEOSIOTest(unittest.TestCase): @@ -17,7 +18,7 @@ class GEOSIOTest(unittest.TestCase): for geom in (g1, g2): self.assertEqual(ref, geom) - # Should only accept basestring objects. + # Should only accept six.string_types objects. self.assertRaises(TypeError, wkt_r.read, 1) self.assertRaises(TypeError, wkt_r.read, buffer('foo')) @@ -48,7 +49,7 @@ class GEOSIOTest(unittest.TestCase): bad_input = (1, 5.23, None, False) for bad_wkb in bad_input: self.assertRaises(TypeError, wkb_r.read, bad_wkb) - + def test04_wkbwriter(self): wkb_w = WKBWriter() @@ -67,7 +68,7 @@ class GEOSIOTest(unittest.TestCase): for bad_byteorder in (-1, 2, 523, 'foo', None): # Equivalent of `wkb_w.byteorder = bad_byteorder` self.assertRaises(ValueError, wkb_w._set_byteorder, bad_byteorder) - + # Setting the byteorder to 0 (for Big Endian) wkb_w.byteorder = 0 self.assertEqual(hex2, wkb_w.write_hex(g)) @@ -79,7 +80,7 @@ class GEOSIOTest(unittest.TestCase): # Now, trying out the 3D and SRID flags. g = GEOSGeometry('POINT (5 23 17)') g.srid = 4326 - + hex3d = '0101000080000000000000144000000000000037400000000000003140' wkb3d = buffer(binascii.a2b_hex(hex3d)) hex3d_srid = '01010000A0E6100000000000000000144000000000000037400000000000003140' diff --git a/django/contrib/gis/maps/google/overlays.py b/django/contrib/gis/maps/google/overlays.py index eaf12dad6d..28603ac422 100644 --- a/django/contrib/gis/maps/google/overlays.py +++ b/django/contrib/gis/maps/google/overlays.py @@ -1,6 +1,7 @@ from django.contrib.gis.geos import fromstr, Point, LineString, LinearRing, Polygon from django.utils.functional import total_ordering from django.utils.safestring import mark_safe +from django.utils import six class GEvent(object): @@ -98,7 +99,7 @@ class GPolygon(GOverlayBase): fill_opacity: The opacity of the polygon fill. Defaults to 0.4. """ - if isinstance(poly, basestring): poly = fromstr(poly) + if isinstance(poly, six.string_types): poly = fromstr(poly) if isinstance(poly, (tuple, list)): poly = Polygon(poly) if not isinstance(poly, Polygon): raise TypeError('GPolygon may only initialize on GEOS Polygons.') @@ -148,7 +149,7 @@ class GPolyline(GOverlayBase): The opacity of the polyline, between 0 and 1. Defaults to 1. """ # If a GEOS geometry isn't passed in, try to contsruct one. - if isinstance(geom, basestring): geom = fromstr(geom) + if isinstance(geom, six.string_types): geom = fromstr(geom) if isinstance(geom, (tuple, list)): geom = Polygon(geom) # Generating the lat/lng coordinate pairs. if isinstance(geom, (LineString, LinearRing)): @@ -239,9 +240,9 @@ class GIcon(object): def __lt__(self, other): return self.varname < other.varname - + def __hash__(self): - # XOR with hash of GIcon type so that hash('varname') won't + # XOR with hash of GIcon type so that hash('varname') won't # equal hash(GIcon('varname')). return hash(self.__class__) ^ hash(self.varname) @@ -278,7 +279,7 @@ class GMarker(GOverlayBase): Draggable option for GMarker, disabled by default. """ # If a GEOS geometry isn't passed in, try to construct one. - if isinstance(geom, basestring): geom = fromstr(geom) + if isinstance(geom, six.string_types): geom = fromstr(geom) if isinstance(geom, (tuple, list)): geom = Point(geom) if isinstance(geom, Point): self.latlng = self.latlng_from_coords(geom.coords) diff --git a/django/contrib/gis/measure.py b/django/contrib/gis/measure.py index 24e8075cab..ba7817e51c 100644 --- a/django/contrib/gis/measure.py +++ b/django/contrib/gis/measure.py @@ -58,7 +58,7 @@ class MeasureBase(object): def __init__(self, default_unit=None, **kwargs): value, self._default_unit = self.default_units(kwargs) setattr(self, self.STANDARD_UNIT, value) - if default_unit and isinstance(default_unit, basestring): + if default_unit and isinstance(default_unit, six.string_types): self._default_unit = default_unit def _get_standard(self): diff --git a/django/contrib/gis/utils/layermapping.py b/django/contrib/gis/utils/layermapping.py index 48d6c1b70e..770bbe63db 100644 --- a/django/contrib/gis/utils/layermapping.py +++ b/django/contrib/gis/utils/layermapping.py @@ -17,6 +17,7 @@ from django.contrib.gis.gdal.field import ( OFTDate, OFTDateTime, OFTInteger, OFTReal, OFTString, OFTTime) from django.db import models, transaction from django.contrib.localflavor.us.models import USStateField +from django.utils import six # LayerMapping exceptions. class LayerMapError(Exception): pass @@ -74,7 +75,7 @@ class LayerMapping(object): argument usage. """ # Getting the DataSource and the associated Layer. - if isinstance(data, basestring): + if isinstance(data, six.string_types): self.ds = DataSource(data) else: self.ds = data @@ -249,7 +250,7 @@ class LayerMapping(object): sr = source_srs elif isinstance(source_srs, self.spatial_backend.spatial_ref_sys()): sr = source_srs.srs - elif isinstance(source_srs, (int, basestring)): + elif isinstance(source_srs, (int, six.string_types)): sr = SpatialReference(source_srs) else: # Otherwise just pulling the SpatialReference from the layer @@ -266,7 +267,7 @@ class LayerMapping(object): # List of fields to determine uniqueness with for attr in unique: if not attr in self.mapping: raise ValueError - elif isinstance(unique, basestring): + elif isinstance(unique, six.string_types): # Only a single field passed in. if unique not in self.mapping: raise ValueError else: @@ -312,7 +313,7 @@ class LayerMapping(object): will construct and return the uniqueness keyword arguments -- a subset of the feature kwargs. """ - if isinstance(self.unique, basestring): + if isinstance(self.unique, six.string_types): return {self.unique : kwargs[self.unique]} else: return dict((fld, kwargs[fld]) for fld in self.unique) diff --git a/django/contrib/gis/utils/ogrinspect.py b/django/contrib/gis/utils/ogrinspect.py index a9a0362eef..f87bb24c7f 100644 --- a/django/contrib/gis/utils/ogrinspect.py +++ b/django/contrib/gis/utils/ogrinspect.py @@ -9,6 +9,7 @@ from future_builtins import zip # Requires GDAL to use. from django.contrib.gis.gdal import DataSource from django.contrib.gis.gdal.field import OFTDate, OFTDateTime, OFTInteger, OFTReal, OFTString, OFTTime +from django.utils import six def mapping(data_source, geom_name='geom', layer_key=0, multi_geom=False): """ @@ -24,7 +25,7 @@ def mapping(data_source, geom_name='geom', layer_key=0, multi_geom=False): `multi_geom` => Boolean (default: False) - specify as multigeometry. """ - if isinstance(data_source, basestring): + if isinstance(data_source, six.string_types): # Instantiating the DataSource from the string. data_source = DataSource(data_source) elif isinstance(data_source, DataSource): diff --git a/django/contrib/gis/utils/wkt.py b/django/contrib/gis/utils/wkt.py index 4aecc6247d..d60eed31bd 100644 --- a/django/contrib/gis/utils/wkt.py +++ b/django/contrib/gis/utils/wkt.py @@ -2,9 +2,11 @@ Utilities for manipulating Geometry WKT. """ +from django.utils import six + def precision_wkt(geom, prec): """ - Returns WKT text of the geometry according to the given precision (an + Returns WKT text of the geometry according to the given precision (an integer or a string). If the precision is an integer, then the decimal places of coordinates WKT will be truncated to that number: @@ -14,12 +16,12 @@ def precision_wkt(geom, prec): >>> precision(geom, 1) 'POINT (5.0 23.0)' - If the precision is a string, it must be valid Python format string + If the precision is a string, it must be valid Python format string (e.g., '%20.7f') -- thus, you should know what you're doing. """ if isinstance(prec, int): num_fmt = '%%.%df' % prec - elif isinstance(prec, basestring): + elif isinstance(prec, six.string_types): num_fmt = prec else: raise TypeError diff --git a/django/core/cache/backends/memcached.py b/django/core/cache/backends/memcached.py index 951c1eda26..e7724f1b91 100644 --- a/django/core/cache/backends/memcached.py +++ b/django/core/cache/backends/memcached.py @@ -5,10 +5,12 @@ from threading import local from django.core.cache.backends.base import BaseCache, InvalidCacheBackendError +from django.utils import six + class BaseMemcachedCache(BaseCache): def __init__(self, server, params, library, value_not_found_exception): super(BaseMemcachedCache, self).__init__(params) - if isinstance(server, basestring): + if isinstance(server, six.string_types): self._servers = server.split(';') else: self._servers = server diff --git a/django/core/mail/backends/filebased.py b/django/core/mail/backends/filebased.py index 674ca32f3f..4a74c34f1f 100644 --- a/django/core/mail/backends/filebased.py +++ b/django/core/mail/backends/filebased.py @@ -6,6 +6,7 @@ import os from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.core.mail.backends.console import EmailBackend as ConsoleEmailBackend +from django.utils import six class EmailBackend(ConsoleEmailBackend): def __init__(self, *args, **kwargs): @@ -15,7 +16,7 @@ class EmailBackend(ConsoleEmailBackend): else: self.file_path = getattr(settings, 'EMAIL_FILE_PATH',None) # Make sure self.file_path is a string. - if not isinstance(self.file_path, basestring): + if not isinstance(self.file_path, six.string_types): raise ImproperlyConfigured('Path for saving emails is invalid: %r' % self.file_path) self.file_path = os.path.abspath(self.file_path) # Make sure that self.file_path is an directory if it exists. diff --git a/django/core/mail/message.py b/django/core/mail/message.py index 82f6b6900f..629ad464f9 100644 --- a/django/core/mail/message.py +++ b/django/core/mail/message.py @@ -16,6 +16,7 @@ from io import BytesIO from django.conf import settings from django.core.mail.utils import DNS_NAME from django.utils.encoding import smart_str, force_unicode +from django.utils import six # Don't BASE64-encode UTF-8 messages so that we avoid unwanted attention from @@ -96,7 +97,7 @@ def forbid_multi_line_headers(name, val, encoding): def sanitize_address(addr, encoding): - if isinstance(addr, basestring): + if isinstance(addr, six.string_types): addr = parseaddr(force_unicode(addr)) nm, addr = addr nm = str(Header(nm, encoding)) @@ -180,17 +181,17 @@ class EmailMessage(object): necessary encoding conversions. """ if to: - assert not isinstance(to, basestring), '"to" argument must be a list or tuple' + assert not isinstance(to, six.string_types), '"to" argument must be a list or tuple' self.to = list(to) else: self.to = [] if cc: - assert not isinstance(cc, basestring), '"cc" argument must be a list or tuple' + assert not isinstance(cc, six.string_types), '"cc" argument must be a list or tuple' self.cc = list(cc) else: self.cc = [] if bcc: - assert not isinstance(bcc, basestring), '"bcc" argument must be a list or tuple' + assert not isinstance(bcc, six.string_types), '"bcc" argument must be a list or tuple' self.bcc = list(bcc) else: self.bcc = [] diff --git a/django/core/management/validation.py b/django/core/management/validation.py index 7cd6958abf..51eeae4e91 100644 --- a/django/core/management/validation.py +++ b/django/core/management/validation.py @@ -3,6 +3,7 @@ import sys from django.core.management.color import color_style from django.utils.encoding import smart_str from django.utils.itercompat import is_iterable +from django.utils import six class ModelErrorCollection: def __init__(self, outfile=sys.stdout): @@ -93,7 +94,7 @@ def get_validation_errors(outfile, app=None): if isinstance(f, models.FilePathField) and not (f.allow_files or f.allow_folders): e.add(opts, '"%s": FilePathFields must have either allow_files or allow_folders set to True.' % f.name) if f.choices: - if isinstance(f.choices, basestring) or not is_iterable(f.choices): + if isinstance(f.choices, six.string_types) or not is_iterable(f.choices): e.add(opts, '"%s": "choices" should be iterable (e.g., a tuple or list).' % f.name) else: for c in f.choices: @@ -168,7 +169,7 @@ def get_validation_errors(outfile, app=None): if f.unique: e.add(opts, "ManyToManyFields cannot be unique. Remove the unique argument on '%s'." % f.name) - if f.rel.through is not None and not isinstance(f.rel.through, basestring): + if f.rel.through is not None and not isinstance(f.rel.through, six.string_types): from_model, to_model = cls, f.rel.to if from_model == to_model and f.rel.symmetrical and not f.rel.through._meta.auto_created: e.add(opts, "Many-to-many fields with intermediate tables cannot be symmetrical.") @@ -239,7 +240,7 @@ def get_validation_errors(outfile, app=None): "to %s and %s" % (f.name, f.rel.through._meta.object_name, f.rel.to._meta.object_name, cls._meta.object_name) ) - elif isinstance(f.rel.through, basestring): + elif isinstance(f.rel.through, six.string_types): e.add(opts, "'%s' specifies an m2m relation through model %s, " "which has not been installed" % (f.name, f.rel.through) ) diff --git a/django/core/serializers/base.py b/django/core/serializers/base.py index 04053c1f8f..19886f7d53 100644 --- a/django/core/serializers/base.py +++ b/django/core/serializers/base.py @@ -6,6 +6,7 @@ from io import BytesIO from django.db import models from django.utils.encoding import smart_unicode +from django.utils import six class SerializerDoesNotExist(KeyError): """The requested serializer was not found.""" @@ -123,7 +124,7 @@ class Deserializer(object): Init this serializer given a stream or a string """ self.options = options - if isinstance(stream_or_string, basestring): + if isinstance(stream_or_string, six.string_types): self.stream = BytesIO(stream_or_string) else: self.stream = stream_or_string diff --git a/django/core/serializers/json.py b/django/core/serializers/json.py index 941b9e0ba8..8b56d0e7b8 100644 --- a/django/core/serializers/json.py +++ b/django/core/serializers/json.py @@ -13,6 +13,7 @@ from django.core.serializers.base import DeserializationError from django.core.serializers.python import Serializer as PythonSerializer from django.core.serializers.python import Deserializer as PythonDeserializer from django.utils.encoding import smart_str +from django.utils import six from django.utils.timezone import is_aware class Serializer(PythonSerializer): @@ -63,7 +64,7 @@ def Deserializer(stream_or_string, **options): if isinstance(stream_or_string, bytes): stream_or_string = stream_or_string.decode('utf-8') try: - if isinstance(stream_or_string, basestring): + if isinstance(stream_or_string, six.string_types): objects = json.loads(stream_or_string) else: objects = json.load(stream_or_string) diff --git a/django/core/serializers/pyyaml.py b/django/core/serializers/pyyaml.py index 73e92d557f..ac0e6cf82d 100644 --- a/django/core/serializers/pyyaml.py +++ b/django/core/serializers/pyyaml.py @@ -13,6 +13,7 @@ from django.core.serializers.base import DeserializationError from django.core.serializers.python import Serializer as PythonSerializer from django.core.serializers.python import Deserializer as PythonDeserializer from django.utils.encoding import smart_str +from django.utils import six class DjangoSafeDumper(yaml.SafeDumper): @@ -53,7 +54,7 @@ def Deserializer(stream_or_string, **options): """ if isinstance(stream_or_string, bytes): stream_or_string = stream_or_string.decode('utf-8') - if isinstance(stream_or_string, basestring): + if isinstance(stream_or_string, six.string_types): stream = StringIO(stream_or_string) else: stream = stream_or_string diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py index a5248f2a5d..e88975f849 100644 --- a/django/core/urlresolvers.py +++ b/django/core/urlresolvers.py @@ -19,6 +19,7 @@ from django.utils.functional import memoize, lazy from django.utils.importlib import import_module from django.utils.module_loading import module_has_submodule from django.utils.regex_helper import normalize +from django.utils import six from django.utils.translation import get_language @@ -159,7 +160,7 @@ class LocaleRegexProvider(object): """ language_code = get_language() if language_code not in self._regex_dict: - if isinstance(self._regex, basestring): + if isinstance(self._regex, six.string_types): regex = self._regex else: regex = force_unicode(self._regex) @@ -228,7 +229,7 @@ class RegexURLResolver(LocaleRegexProvider): LocaleRegexProvider.__init__(self, regex) # urlconf_name is a string representing the module containing URLconfs. self.urlconf_name = urlconf_name - if not isinstance(urlconf_name, basestring): + if not isinstance(urlconf_name, six.string_types): self._urlconf_module = self.urlconf_name self.callback = None self.default_kwargs = default_kwargs or {} @@ -434,7 +435,7 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, prefix=None, current if prefix is None: prefix = get_script_prefix() - if not isinstance(viewname, basestring): + if not isinstance(viewname, six.string_types): view = viewname else: parts = viewname.split(':') diff --git a/django/core/validators.py b/django/core/validators.py index c7c89786da..47c1cbf1cd 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -7,6 +7,7 @@ from django.core.exceptions import ValidationError from django.utils.translation import ugettext_lazy as _ from django.utils.encoding import smart_unicode from django.utils.ipv6 import is_valid_ipv6_address +from django.utils import six # These values, if given to validate(), will trigger the self.required check. EMPTY_VALUES = (None, '', [], (), {}) @@ -25,7 +26,7 @@ class RegexValidator(object): self.code = code # Compile the regex if it was not passed pre-compiled. - if isinstance(self.regex, basestring): + if isinstance(self.regex, six.string_types): self.regex = re.compile(self.regex) def __call__(self, value): diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index e093f7e84e..9ac41a5741 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -10,6 +10,7 @@ import decimal import sys import warnings +from django.utils import six def _setup_environment(environ): import platform @@ -361,7 +362,7 @@ WHEN (new.%(col_name)s IS NULL) if value is None: return None - if isinstance(value, basestring): + if isinstance(value, six.string_types): return datetime.datetime.strptime(value, '%H:%M:%S') # Oracle doesn't support tz-aware times @@ -596,7 +597,7 @@ class OracleParam(object): if hasattr(param, 'input_size'): # If parameter has `input_size` attribute, use that. self.input_size = param.input_size - elif isinstance(param, basestring) and len(param) > 4000: + elif isinstance(param, six.string_types) and len(param) > 4000: # Mark any string param greater than 4000 characters as a CLOB. self.input_size = Database.CLOB else: @@ -824,7 +825,7 @@ def to_unicode(s): Convert strings to Unicode objects (and return all other data types unchanged). """ - if isinstance(s, basestring): + if isinstance(s, six.string_types): return force_unicode(s) return s diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 9db76a617b..9606b1b843 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -21,6 +21,7 @@ from django.utils import timezone from django.utils.translation import ugettext_lazy as _ from django.utils.encoding import smart_unicode, force_unicode from django.utils.ipv6 import clean_ipv6_address +from django.utils import six class NOT_PROVIDED: pass @@ -625,7 +626,7 @@ class CharField(Field): return "CharField" def to_python(self, value): - if isinstance(value, basestring) or value is None: + if isinstance(value, six.string_types) or value is None: return value return smart_unicode(value) @@ -864,7 +865,7 @@ class DecimalField(Field): raise exceptions.ValidationError(msg) def _format(self, value): - if isinstance(value, basestring) or value is None: + if isinstance(value, six.string_types) or value is None: return value else: return self.format_number(value) @@ -1185,7 +1186,7 @@ class TextField(Field): return "TextField" def get_prep_value(self, value): - if isinstance(value, basestring) or value is None: + if isinstance(value, six.string_types) or value is None: return value return smart_unicode(value) diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index b0dce381a6..d3f1327315 100644 --- a/django/db/models/fields/files.py +++ b/django/db/models/fields/files.py @@ -9,6 +9,7 @@ from django.core.files.storage import default_storage from django.core.files.images import ImageFile from django.db.models import signals from django.utils.encoding import force_unicode, smart_str +from django.utils import six from django.utils.translation import ugettext_lazy as _ class FieldFile(File): @@ -176,7 +177,7 @@ class FileDescriptor(object): # subclasses might also want to subclass the attribute class]. This # object understands how to convert a path to a file, and also how to # handle None. - if isinstance(file, basestring) or file is None: + if isinstance(file, six.string_types) or file is None: attr = self.field.attr_class(instance, self.field, file) instance.__dict__[self.field.name] = attr diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 96d1438282..2a2502b54f 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -10,6 +10,7 @@ from django.db.models.query import QuerySet from django.db.models.query_utils import QueryWrapper from django.db.models.deletion import CASCADE from django.utils.encoding import smart_unicode +from django.utils import six from django.utils.translation import ugettext_lazy as _, string_concat from django.utils.functional import curry, cached_property from django.core import exceptions @@ -104,7 +105,7 @@ class RelatedField(object): } other = self.rel.to - if isinstance(other, basestring) or other._meta.pk is None: + if isinstance(other, six.string_types) or other._meta.pk is None: def resolve_related_class(field, model, cls): field.rel.to = model field.do_related_class(model, cls) @@ -865,7 +866,7 @@ class ManyToOneRel(object): try: to._meta except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT - assert isinstance(to, basestring), "'to' must be either a model, a model name or the string %r" % RECURSIVE_RELATIONSHIP_CONSTANT + assert isinstance(to, six.string_types), "'to' must be either a model, a model name or the string %r" % RECURSIVE_RELATIONSHIP_CONSTANT self.to, self.field_name = to, field_name self.related_name = related_name if limit_choices_to is None: @@ -933,7 +934,7 @@ class ForeignKey(RelatedField, Field): try: to_name = to._meta.object_name.lower() except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT - assert isinstance(to, basestring), "%s(%r) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string %r" % (self.__class__.__name__, to, RECURSIVE_RELATIONSHIP_CONSTANT) + assert isinstance(to, six.string_types), "%s(%r) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string %r" % (self.__class__.__name__, to, RECURSIVE_RELATIONSHIP_CONSTANT) else: assert not to._meta.abstract, "%s cannot define a relation with abstract class %s" % (self.__class__.__name__, to._meta.object_name) # For backwards compatibility purposes, we need to *try* and set @@ -1004,7 +1005,7 @@ class ForeignKey(RelatedField, Field): def contribute_to_class(self, cls, name): super(ForeignKey, self).contribute_to_class(cls, name) setattr(cls, self.name, ReverseSingleRelatedObjectDescriptor(self)) - if isinstance(self.rel.to, basestring): + if isinstance(self.rel.to, six.string_types): target = self.rel.to else: target = self.rel.to._meta.db_table @@ -1022,7 +1023,7 @@ class ForeignKey(RelatedField, Field): def formfield(self, **kwargs): db = kwargs.pop('using', None) - if isinstance(self.rel.to, basestring): + if isinstance(self.rel.to, six.string_types): raise ValueError("Cannot create form field for %r yet, because " "its related model %r has not been loaded yet" % (self.name, self.rel.to)) @@ -1079,13 +1080,13 @@ class OneToOneField(ForeignKey): def create_many_to_many_intermediary_model(field, klass): from django.db import models managed = True - if isinstance(field.rel.to, basestring) and field.rel.to != RECURSIVE_RELATIONSHIP_CONSTANT: + if isinstance(field.rel.to, six.string_types) and field.rel.to != RECURSIVE_RELATIONSHIP_CONSTANT: to_model = field.rel.to to = to_model.split('.')[-1] def set_managed(field, model, cls): field.rel.through._meta.managed = model._meta.managed or cls._meta.managed add_lazy_relation(klass, field, to_model, set_managed) - elif isinstance(field.rel.to, basestring): + elif isinstance(field.rel.to, six.string_types): to = klass._meta.object_name to_model = klass managed = klass._meta.managed @@ -1124,7 +1125,7 @@ class ManyToManyField(RelatedField, Field): try: assert not to._meta.abstract, "%s cannot define a relation with abstract class %s" % (self.__class__.__name__, to._meta.object_name) except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT - assert isinstance(to, basestring), "%s(%r) is invalid. First parameter to ManyToManyField must be either a model, a model name, or the string %r" % (self.__class__.__name__, to, RECURSIVE_RELATIONSHIP_CONSTANT) + assert isinstance(to, six.string_types), "%s(%r) is invalid. First parameter to ManyToManyField must be either a model, a model name, or the string %r" % (self.__class__.__name__, to, RECURSIVE_RELATIONSHIP_CONSTANT) # Python 2.6 and earlier require dictionary keys to be of str type, # not unicode and class names must be ASCII (in Python 2.x), so we # forcibly coerce it here (breaks early if there's a problem). @@ -1232,12 +1233,12 @@ class ManyToManyField(RelatedField, Field): # Populate some necessary rel arguments so that cross-app relations # work correctly. - if isinstance(self.rel.through, basestring): + if isinstance(self.rel.through, six.string_types): def resolve_through_model(field, model, cls): field.rel.through = model add_lazy_relation(cls, self, self.rel.through, resolve_through_model) - if isinstance(self.rel.to, basestring): + if isinstance(self.rel.to, six.string_types): target = self.rel.to else: target = self.rel.to._meta.db_table diff --git a/django/db/models/options.py b/django/db/models/options.py index 767b625c1d..7308a15c6b 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -10,6 +10,7 @@ from django.db.models.loading import get_models, app_cache_ready from django.utils.translation import activate, deactivate_all, get_language, string_concat from django.utils.encoding import force_unicode, smart_str from django.utils.datastructures import SortedDict +from django.utils import six # Calculate the verbose_name by converting from InitialCaps to "lowercase with spaces". get_verbose_name = lambda class_name: re.sub('(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))', ' \\1', class_name).lower().strip() @@ -400,7 +401,7 @@ class Options(object): proxy_cache = cache.copy() for klass in get_models(include_auto_created=True, only_installed=False): for f in klass._meta.local_fields: - if f.rel and not isinstance(f.rel.to, basestring): + if f.rel and not isinstance(f.rel.to, six.string_types): if self == f.rel.to._meta: cache[RelatedObject(f.rel.to, klass, f)] = None proxy_cache[RelatedObject(f.rel.to, klass, f)] = None @@ -442,7 +443,7 @@ class Options(object): cache[obj] = model for klass in get_models(only_installed=False): for f in klass._meta.local_many_to_many: - if f.rel and not isinstance(f.rel.to, basestring) and self == f.rel.to._meta: + if f.rel and not isinstance(f.rel.to, six.string_types) and self == f.rel.to._meta: cache[RelatedObject(f.rel.to, klass, f)] = None if app_cache_ready(): self._related_many_to_many_cache = cache diff --git a/django/db/utils.py b/django/db/utils.py index 2b6ae2cf2e..0ce09bab70 100644 --- a/django/db/utils.py +++ b/django/db/utils.py @@ -4,6 +4,7 @@ from threading import local from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.utils.importlib import import_module +from django.utils import six DEFAULT_DB_ALIAS = 'default' @@ -108,7 +109,7 @@ class ConnectionRouter(object): def __init__(self, routers): self.routers = [] for r in routers: - if isinstance(r, basestring): + if isinstance(r, six.string_types): try: module_name, klass_name = r.rsplit('.', 1) module = import_module(module_name) diff --git a/django/forms/extras/widgets.py b/django/forms/extras/widgets.py index 6c39b25a74..4e11a4ee06 100644 --- a/django/forms/extras/widgets.py +++ b/django/forms/extras/widgets.py @@ -11,6 +11,7 @@ from django.utils import datetime_safe from django.utils.dates import MONTHS from django.utils.safestring import mark_safe from django.utils.formats import get_format +from django.utils import six from django.conf import settings __all__ = ('SelectDateWidget',) @@ -64,7 +65,7 @@ class SelectDateWidget(Widget): year_val, month_val, day_val = value.year, value.month, value.day except AttributeError: year_val = month_val = day_val = None - if isinstance(value, basestring): + if isinstance(value, six.string_types): if settings.USE_L10N: try: input_format = get_format('DATE_INPUT_FORMATS')[0] diff --git a/django/forms/fields.py b/django/forms/fields.py index 4668eade97..4c4209dddd 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -22,6 +22,7 @@ from django.forms.widgets import (TextInput, PasswordInput, HiddenInput, from django.utils import formats from django.utils.encoding import smart_unicode, force_unicode from django.utils.ipv6 import clean_ipv6_address +from django.utils import six from django.utils.translation import ugettext_lazy as _ # Provide this import for backwards compatibility. @@ -445,7 +446,7 @@ class RegexField(CharField): return self._regex def _set_regex(self, regex): - if isinstance(regex, basestring): + if isinstance(regex, six.string_types): regex = re.compile(regex, re.UNICODE) self._regex = regex if hasattr(self, '_regex_validator') and self._regex_validator in self.validators: @@ -633,7 +634,7 @@ class BooleanField(Field): # will submit for False. Also check for '0', since this is what # RadioSelect will provide. Because bool("True") == bool('1') == True, # we don't need to handle that explicitly. - if isinstance(value, basestring) and value.lower() in ('false', '0'): + if isinstance(value, six.string_types) and value.lower() in ('false', '0'): value = False else: value = bool(value) diff --git a/django/forms/widgets.py b/django/forms/widgets.py index 20fa9e973a..f2446efcdf 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -16,6 +16,7 @@ from django.utils.html import conditional_escape, format_html, format_html_join from django.utils.translation import ugettext, ugettext_lazy from django.utils.encoding import StrAndUnicode, force_unicode from django.utils.safestring import mark_safe +from django.utils import six from django.utils import datetime_safe, formats from django.utils import six @@ -522,7 +523,7 @@ class CheckboxInput(Widget): value = data.get(name) # Translate true and false strings to boolean values. values = {'true': True, 'false': False} - if isinstance(value, basestring): + if isinstance(value, six.string_types): value = values.get(value.lower(), value) return value diff --git a/django/template/base.py b/django/template/base.py index 89bc90971f..cbf6de2d40 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -18,6 +18,7 @@ from django.utils.safestring import (SafeData, EscapeData, mark_safe, from django.utils.formats import localize from django.utils.html import escape from django.utils.module_loading import module_has_submodule +from django.utils import six from django.utils.timezone import template_localtime @@ -1188,7 +1189,7 @@ class Library(object): from django.template.loader import get_template, select_template if isinstance(file_name, Template): t = file_name - elif not isinstance(file_name, basestring) and is_iterable(file_name): + elif not isinstance(file_name, six.string_types) and is_iterable(file_name): t = select_template(file_name) else: t = get_template(file_name) diff --git a/django/template/loader.py b/django/template/loader.py index b6d62cc2b0..cfffb4014e 100644 --- a/django/template/loader.py +++ b/django/template/loader.py @@ -29,6 +29,7 @@ from django.core.exceptions import ImproperlyConfigured from django.template.base import Origin, Template, Context, TemplateDoesNotExist, add_to_builtins from django.utils.importlib import import_module from django.conf import settings +from django.utils import six template_source_loaders = None @@ -89,7 +90,7 @@ def find_template_loader(loader): loader, args = loader[0], loader[1:] else: args = [] - if isinstance(loader, basestring): + if isinstance(loader, six.string_types): module, attr = loader.rsplit('.', 1) try: mod = import_module(module) diff --git a/django/template/response.py b/django/template/response.py index 286417ccdf..800e060c74 100644 --- a/django/template/response.py +++ b/django/template/response.py @@ -1,5 +1,6 @@ from django.http import HttpResponse from django.template import loader, Context, RequestContext +from django.utils import six class ContentNotRenderedError(Exception): @@ -53,7 +54,7 @@ class SimpleTemplateResponse(HttpResponse): "Accepts a template object, path-to-template or list of paths" if isinstance(template, (list, tuple)): return loader.select_template(template) - elif isinstance(template, basestring): + elif isinstance(template, six.string_types): return loader.get_template(template) else: return template diff --git a/django/templatetags/i18n.py b/django/templatetags/i18n.py index 231b723d3a..509ab6707d 100644 --- a/django/templatetags/i18n.py +++ b/django/templatetags/i18n.py @@ -5,6 +5,7 @@ from django.template import (Node, Variable, TemplateSyntaxError, TokenParser, Library, TOKEN_TEXT, TOKEN_VAR) from django.template.base import _render_value_in_context from django.template.defaulttags import token_kwargs +from django.utils import six from django.utils import translation @@ -76,7 +77,7 @@ class TranslateNode(Node): self.asvar = asvar self.message_context = message_context self.filter_expression = filter_expression - if isinstance(self.filter_expression.var, basestring): + if isinstance(self.filter_expression.var, six.string_types): self.filter_expression.var = Variable("'%s'" % self.filter_expression.var) diff --git a/django/templatetags/tz.py b/django/templatetags/tz.py index ca72ca5ec8..96210f189d 100644 --- a/django/templatetags/tz.py +++ b/django/templatetags/tz.py @@ -7,6 +7,7 @@ except ImportError: from django.template import Node from django.template import TemplateSyntaxError, Library +from django.utils import six from django.utils import timezone register = Library() @@ -64,7 +65,7 @@ def do_timezone(value, arg): # Obtain a tzinfo instance if isinstance(arg, tzinfo): tz = arg - elif isinstance(arg, basestring) and pytz is not None: + elif isinstance(arg, six.string_types) and pytz is not None: try: tz = pytz.timezone(arg) except pytz.UnknownTimeZoneError: diff --git a/django/test/_doctest.py b/django/test/_doctest.py index 4456511532..0388714094 100644 --- a/django/test/_doctest.py +++ b/django/test/_doctest.py @@ -480,7 +480,7 @@ class DocTest: Create a new DocTest containing the given examples. The DocTest's globals are initialized with a copy of `globs`. """ - assert not isinstance(examples, basestring), \ + assert not isinstance(examples, six.string_types), \ "DocTest no longer accepts str; use DocTestParser instead" self.examples = examples self.docstring = docstring @@ -906,13 +906,13 @@ class DocTestFinder: # Look for tests in a module's __test__ dictionary. if inspect.ismodule(obj) and self._recurse: for valname, val in getattr(obj, '__test__', {}).items(): - if not isinstance(valname, basestring): + if not isinstance(valname, six.string_types): raise ValueError("DocTestFinder.find: __test__ keys " "must be strings: %r" % (type(valname),)) if not (inspect.isfunction(val) or inspect.isclass(val) or inspect.ismethod(val) or inspect.ismodule(val) or - isinstance(val, basestring)): + isinstance(val, six.string_types)): raise ValueError("DocTestFinder.find: __test__ values " "must be strings, functions, methods, " "classes, or modules: %r" % @@ -945,7 +945,7 @@ class DocTestFinder: """ # Extract the object's docstring. If it doesn't have one, # then return None (no test for this object). - if isinstance(obj, basestring): + if isinstance(obj, six.string_types): docstring = obj else: try: @@ -953,7 +953,7 @@ class DocTestFinder: docstring = '' else: docstring = obj.__doc__ - if not isinstance(docstring, basestring): + if not isinstance(docstring, six.string_types): docstring = str(docstring) except (TypeError, AttributeError): docstring = '' diff --git a/django/test/client.py b/django/test/client.py index 74e11a0efd..7b6cdaa2a4 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -116,7 +116,7 @@ def encode_multipart(boundary, data): for (key, value) in data.items(): if is_file(value): lines.extend(encode_file(boundary, key, value)) - elif not isinstance(value, basestring) and is_iterable(value): + elif not isinstance(value, six.string_types) and is_iterable(value): for item in value: if is_file(item): lines.extend(encode_file(boundary, key, item)) diff --git a/django/test/html.py b/django/test/html.py index 79b198f1be..a44eb72322 100644 --- a/django/test/html.py +++ b/django/test/html.py @@ -8,6 +8,7 @@ import re from HTMLParser import HTMLParseError from django.utils.encoding import force_unicode from django.utils.html_parser import HTMLParser +from django.utils import six WHITESPACE = re.compile('\s+') @@ -24,11 +25,11 @@ class Element(object): self.children = [] def append(self, element): - if isinstance(element, basestring): + if isinstance(element, six.string_types): element = force_unicode(element) element = normalize_whitespace(element) if self.children: - if isinstance(self.children[-1], basestring): + if isinstance(self.children[-1], six.string_types): self.children[-1] += element self.children[-1] = normalize_whitespace(self.children[-1]) return @@ -36,7 +37,7 @@ class Element(object): # removing last children if it is only whitespace # this can result in incorrect dom representations since # whitespace between inline tags like is significant - if isinstance(self.children[-1], basestring): + if isinstance(self.children[-1], six.string_types): if self.children[-1].isspace(): self.children.pop() if element: @@ -45,7 +46,7 @@ class Element(object): def finalize(self): def rstrip_last_element(children): if children: - if isinstance(children[-1], basestring): + if isinstance(children[-1], six.string_types): children[-1] = children[-1].rstrip() if not children[-1]: children.pop() @@ -54,7 +55,7 @@ class Element(object): rstrip_last_element(self.children) for i, child in enumerate(self.children): - if isinstance(child, basestring): + if isinstance(child, six.string_types): self.children[i] = child.strip() elif hasattr(child, 'finalize'): child.finalize() @@ -87,15 +88,15 @@ class Element(object): return not self.__eq__(element) def _count(self, element, count=True): - if not isinstance(element, basestring): + if not isinstance(element, six.string_types): if self == element: return 1 i = 0 for child in self.children: # child is text content and element is also text content, then # make a simple "text" in "text" - if isinstance(child, basestring): - if isinstance(element, basestring): + if isinstance(child, six.string_types): + if isinstance(element, six.string_types): if count: i += child.count(element) elif element in child: @@ -219,6 +220,6 @@ def parse_html(html): document.finalize() # Removing ROOT element if it's not necessary if len(document.children) == 1: - if not isinstance(document.children[0], basestring): + if not isinstance(document.children[0], six.string_types): document = document.children[0] return document diff --git a/django/test/utils.py b/django/test/utils.py index ca4a5e7474..4b121bdfb0 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -6,6 +6,7 @@ from django.template import Template, loader, TemplateDoesNotExist from django.template.loaders import cached from django.utils.translation import deactivate from django.utils.functional import wraps +from django.utils import six __all__ = ( @@ -35,7 +36,7 @@ class ContextList(list): in a list of context objects. """ def __getitem__(self, key): - if isinstance(key, basestring): + if isinstance(key, six.string_types): for subcontext in self: if key in subcontext: return subcontext[key] diff --git a/django/utils/archive.py b/django/utils/archive.py index 70e1f9ba59..6b5d73290f 100644 --- a/django/utils/archive.py +++ b/django/utils/archive.py @@ -27,6 +27,8 @@ import sys import tarfile import zipfile +from django.utils import six + class ArchiveException(Exception): """ @@ -58,7 +60,7 @@ class Archive(object): @staticmethod def _archive_cls(file): cls = None - if isinstance(file, basestring): + if isinstance(file, six.string_types): filename = file else: try: diff --git a/django/utils/checksums.py b/django/utils/checksums.py index 970f563f38..6bbdccc58c 100644 --- a/django/utils/checksums.py +++ b/django/utils/checksums.py @@ -4,6 +4,8 @@ Common checksum routines (used in multiple localflavor/ cases, for example). __all__ = ['luhn',] +from django.utils import six + LUHN_ODD_LOOKUP = (0, 2, 4, 6, 8, 1, 3, 5, 7, 9) # sum_of_digits(index * 2) def luhn(candidate): @@ -12,7 +14,7 @@ def luhn(candidate): algorithm (used in validation of, for example, credit cards). Both numeric and string candidates are accepted. """ - if not isinstance(candidate, basestring): + if not isinstance(candidate, six.string_types): candidate = str(candidate) try: evens = sum([int(c) for c in candidate[-1::-2]]) diff --git a/django/utils/dictconfig.py b/django/utils/dictconfig.py index ae797afcc5..b4d6d66b3c 100644 --- a/django/utils/dictconfig.py +++ b/django/utils/dictconfig.py @@ -23,6 +23,8 @@ import re import sys import types +from django.utils import six + IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I) def valid_ident(s): @@ -231,7 +233,7 @@ class BaseConfigurator(object): isinstance(value, tuple): value = ConvertingTuple(value) value.configurator = self - elif isinstance(value, basestring): # str for py3k + elif isinstance(value, six.string_types): # str for py3k m = self.CONVERT_PATTERN.match(value) if m: d = m.groupdict() diff --git a/django/utils/encoding.py b/django/utils/encoding.py index 30665480f6..716d46ceff 100644 --- a/django/utils/encoding.py +++ b/django/utils/encoding.py @@ -64,7 +64,7 @@ def force_unicode(s, encoding='utf-8', strings_only=False, errors='strict'): if strings_only and is_protected_type(s): return s try: - if not isinstance(s, basestring,): + if not isinstance(s, six.string_types,): if hasattr(s, '__unicode__'): s = unicode(s) else: @@ -109,7 +109,7 @@ def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'): return s if isinstance(s, Promise): return unicode(s).encode(encoding, errors) - elif not isinstance(s, basestring): + elif not isinstance(s, six.string_types): try: return str(s) except UnicodeEncodeError: diff --git a/django/utils/formats.py b/django/utils/formats.py index d3afc72729..eae40970da 100644 --- a/django/utils/formats.py +++ b/django/utils/formats.py @@ -178,7 +178,7 @@ def sanitize_separators(value): """ if settings.USE_L10N: decimal_separator = get_format('DECIMAL_SEPARATOR') - if isinstance(value, basestring): + if isinstance(value, six.string_types): parts = [] if decimal_separator in value: value, decimals = value.split(decimal_separator, 1) diff --git a/django/utils/regex_helper.py b/django/utils/regex_helper.py index 4b8ecea721..8953a21e95 100644 --- a/django/utils/regex_helper.py +++ b/django/utils/regex_helper.py @@ -7,6 +7,8 @@ should be good enough for a large class of URLS, however. """ from __future__ import unicode_literals +from django.utils import six + # 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 # this sequence. Any missing key is mapped to itself. @@ -302,7 +304,7 @@ def flatten_result(source): result_args = [[]] pos = last = 0 for pos, elt in enumerate(source): - if isinstance(elt, basestring): + if isinstance(elt, six.string_types): continue piece = ''.join(source[last:pos]) if isinstance(elt, Group): diff --git a/django/utils/timezone.py b/django/utils/timezone.py index d9d9636023..68c214d26f 100644 --- a/django/utils/timezone.py +++ b/django/utils/timezone.py @@ -13,6 +13,7 @@ except ImportError: pytz = None from django.conf import settings +from django.utils import six __all__ = [ 'utc', 'get_default_timezone', 'get_current_timezone', @@ -107,7 +108,7 @@ def get_default_timezone(): """ global _localtime if _localtime is None: - if isinstance(settings.TIME_ZONE, basestring) and pytz is not None: + if isinstance(settings.TIME_ZONE, six.string_types) and pytz is not None: _localtime = pytz.timezone(settings.TIME_ZONE) else: _localtime = LocalTimezone() @@ -160,7 +161,7 @@ def activate(timezone): """ if isinstance(timezone, tzinfo): _active.value = timezone - elif isinstance(timezone, basestring) and pytz is not None: + elif isinstance(timezone, six.string_types) and pytz is not None: _active.value = pytz.timezone(timezone) else: raise ValueError("Invalid timezone: %r" % timezone) diff --git a/django/views/debug.py b/django/views/debug.py index 3414cb193c..65226b5ca7 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -15,6 +15,7 @@ from django.template.defaultfilters import force_escape, pprint from django.utils.html import escape from django.utils.importlib import import_module from django.utils.encoding import smart_unicode, smart_str +from django.utils import six HIDDEN_SETTINGS = re.compile('API|TOKEN|KEY|SECRET|PASS|PROFANITIES_LIST|SIGNATURE') @@ -214,7 +215,7 @@ class ExceptionReporter(object): self.loader_debug_info = None # Handle deprecated string exceptions - if isinstance(self.exc_type, basestring): + if isinstance(self.exc_type, six.string_types): self.exc_value = Exception('Deprecated String Exception: %r' % self.exc_type) self.exc_type = type(self.exc_value) diff --git a/django/views/i18n.py b/django/views/i18n.py index 5d1ecb99ea..b0f64f4902 100644 --- a/django/views/i18n.py +++ b/django/views/i18n.py @@ -8,6 +8,7 @@ from django.utils.translation import check_for_language, activate, to_locale, ge from django.utils.text import javascript_quote from django.utils.encoding import smart_unicode from django.utils.formats import get_format_modules, get_format +from django.utils import six def set_language(request): """ @@ -52,7 +53,7 @@ def get_formats(): result[attr] = get_format(attr) src = [] for k, v in result.items(): - if isinstance(v, (basestring, int)): + if isinstance(v, (six.string_types, int)): src.append("formats['%s'] = '%s';\n" % (javascript_quote(k), javascript_quote(smart_unicode(v)))) elif isinstance(v, (tuple, list)): v = [javascript_quote(smart_unicode(value)) for value in v] @@ -184,7 +185,7 @@ def javascript_catalog(request, domain='djangojs', packages=None): activate(request.GET['language']) if packages is None: packages = ['django.conf'] - if isinstance(packages, basestring): + if isinstance(packages, six.string_types): packages = packages.split('+') packages = [p for p in packages if p == 'django.conf' or p in settings.INSTALLED_APPS] default_locale = to_locale(settings.LANGUAGE_CODE) @@ -258,7 +259,7 @@ def javascript_catalog(request, domain='djangojs', packages=None): for k, v in t.items(): if k == '': continue - if isinstance(k, basestring): + if isinstance(k, six.string_types): csrc.append("catalog['%s'] = '%s';\n" % (javascript_quote(k), javascript_quote(v))) elif isinstance(k, tuple): if k[0] not in pdict: diff --git a/tests/modeltests/field_subclassing/fields.py b/tests/modeltests/field_subclassing/fields.py index b9987c0fab..553b031de3 100644 --- a/tests/modeltests/field_subclassing/fields.py +++ b/tests/modeltests/field_subclassing/fields.py @@ -4,6 +4,7 @@ import json from django.db import models from django.utils.encoding import force_unicode +from django.utils import six class Small(object): @@ -66,7 +67,7 @@ class JSONField(models.TextField): if not value: return None - if isinstance(value, basestring): + if isinstance(value, six.string_types): value = json.loads(value) return value diff --git a/tests/modeltests/serializers/tests.py b/tests/modeltests/serializers/tests.py index 13cf1e7e17..73a3aa3e7a 100644 --- a/tests/modeltests/serializers/tests.py +++ b/tests/modeltests/serializers/tests.py @@ -10,6 +10,7 @@ from django.conf import settings from django.core import serializers from django.db import transaction, connection from django.test import TestCase, TransactionTestCase, Approximate +from django.utils import six from django.utils import unittest from .models import (Category, Author, Article, AuthorProfile, Actor, Movie, @@ -461,7 +462,7 @@ else: # yaml.safe_load will return non-string objects for some # of the fields we are interested in, this ensures that # everything comes back as a string - if isinstance(field_value, basestring): + if isinstance(field_value, six.string_types): ret_list.append(field_value) else: ret_list.append(str(field_value)) diff --git a/tests/regressiontests/forms/tests/fields.py b/tests/regressiontests/forms/tests/fields.py index 12eb016c6e..feb2ade458 100644 --- a/tests/regressiontests/forms/tests/fields.py +++ b/tests/regressiontests/forms/tests/fields.py @@ -35,10 +35,11 @@ from decimal import Decimal from django.core.files.uploadedfile import SimpleUploadedFile from django.forms import * from django.test import SimpleTestCase +from django.utils import six def fix_os_paths(x): - if isinstance(x, basestring): + if isinstance(x, six.string_types): return x.replace('\\', '/') elif isinstance(x, tuple): return tuple(fix_os_paths(list(x))) diff --git a/tests/regressiontests/i18n/commands/tests.py b/tests/regressiontests/i18n/commands/tests.py index 38e8af1d0d..e00ef72d59 100644 --- a/tests/regressiontests/i18n/commands/tests.py +++ b/tests/regressiontests/i18n/commands/tests.py @@ -2,13 +2,15 @@ import os import re from subprocess import Popen, PIPE +from django.utils import six + can_run_extraction_tests = False can_run_compilation_tests = False def find_command(cmd, path=None, pathext=None): if path is None: path = os.environ.get('PATH', []).split(os.pathsep) - if isinstance(path, basestring): + if isinstance(path, six.string_types): path = [path] # check if there are funny path extensions for executables, e.g. Windows if pathext is None: diff --git a/tests/regressiontests/staticfiles_tests/tests.py b/tests/regressiontests/staticfiles_tests/tests.py index 812a80a583..e05729cf7f 100644 --- a/tests/regressiontests/staticfiles_tests/tests.py +++ b/tests/regressiontests/staticfiles_tests/tests.py @@ -20,6 +20,7 @@ from django.test.utils import override_settings from django.utils.encoding import smart_unicode from django.utils.functional import empty from django.utils._os import rmtree_errorhandler +from django.utils import six from django.contrib.staticfiles import finders, storage @@ -83,7 +84,7 @@ class BaseStaticFilesTestCase(object): self.assertRaises(IOError, self._get_file, filepath) def render_template(self, template, **kwargs): - if isinstance(template, basestring): + if isinstance(template, six.string_types): template = loader.get_template_from_string(template) return template.render(Context(kwargs)).strip()