[py3] Replaced unicode/str by six.text_type/bytes.

This commit is contained in:
Aymeric Augustin 2012-07-20 14:48:51 +02:00
parent 3cb2457f46
commit bdca5ea345
96 changed files with 376 additions and 294 deletions

View File

@ -189,7 +189,7 @@ class AdminReadonlyField(object):
if value is None: if value is None:
result_repr = EMPTY_CHANGELIST_VALUE result_repr = EMPTY_CHANGELIST_VALUE
elif isinstance(f.rel, ManyToManyRel): elif isinstance(f.rel, ManyToManyRel):
result_repr = ", ".join(map(unicode, value.all())) result_repr = ", ".join(map(six.text_type, value.all()))
else: else:
result_repr = display_for_field(value, f) result_repr = display_for_field(value, f)
return conditional_escape(result_repr) return conditional_escape(result_repr)

View File

@ -275,10 +275,10 @@ def label_for_field(name, model, model_admin=None, return_attr=False):
except models.FieldDoesNotExist: except models.FieldDoesNotExist:
if name == "__unicode__": if name == "__unicode__":
label = force_unicode(model._meta.verbose_name) label = force_unicode(model._meta.verbose_name)
attr = unicode attr = six.text_type
elif name == "__str__": elif name == "__str__":
label = smart_str(model._meta.verbose_name) label = smart_str(model._meta.verbose_name)
attr = str attr = bytes
else: else:
if callable(name): if callable(name):
attr = name attr = name

View File

@ -15,6 +15,7 @@ from django.utils.text import Truncator
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.encoding import force_unicode from django.utils.encoding import force_unicode
from django.utils import six
class FilteredSelectMultiple(forms.SelectMultiple): class FilteredSelectMultiple(forms.SelectMultiple):
@ -121,7 +122,7 @@ def url_params_from_lookup_dict(lookups):
# See django.db.fields.BooleanField.get_prep_lookup # See django.db.fields.BooleanField.get_prep_lookup
v = ('0', '1')[v] v = ('0', '1')[v]
else: else:
v = unicode(v) v = six.text_type(v)
items.append((k, v)) items.append((k, v))
params.update(dict(items)) params.update(dict(items))
return params return params

View File

@ -8,6 +8,7 @@ from django.db import models
from django.db.models.manager import EmptyManager from django.db.models.manager import EmptyManager
from django.utils.crypto import get_random_string from django.utils.crypto import get_random_string
from django.utils.encoding import smart_str from django.utils.encoding import smart_str
from django.utils import six
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils import timezone from django.utils import timezone
@ -79,9 +80,9 @@ class Permission(models.Model):
def __unicode__(self): def __unicode__(self):
return "%s | %s | %s" % ( return "%s | %s | %s" % (
unicode(self.content_type.app_label), six.text_type(self.content_type.app_label),
unicode(self.content_type), six.text_type(self.content_type),
unicode(self.name)) six.text_type(self.name))
def natural_key(self): def natural_key(self):
return (self.codename,) + self.content_type.natural_key() return (self.codename,) + self.content_type.natural_key()
@ -421,7 +422,7 @@ class AnonymousUser(object):
return 'AnonymousUser' return 'AnonymousUser'
def __str__(self): def __str__(self):
return unicode(self).encode('utf-8') return six.text_type(self).encode('utf-8')
def __eq__(self, other): def __eq__(self, other):
return isinstance(other, self.__class__) return isinstance(other, self.__class__)

View File

@ -2,6 +2,7 @@ from datetime import date
from django.conf import settings from django.conf import settings
from django.utils.http import int_to_base36, base36_to_int from django.utils.http import int_to_base36, base36_to_int
from django.utils.crypto import constant_time_compare, salted_hmac from django.utils.crypto import constant_time_compare, salted_hmac
from django.utils import six
class PasswordResetTokenGenerator(object): class PasswordResetTokenGenerator(object):
""" """
@ -56,8 +57,8 @@ class PasswordResetTokenGenerator(object):
# Ensure results are consistent across DB backends # Ensure results are consistent across DB backends
login_timestamp = user.last_login.replace(microsecond=0, tzinfo=None) login_timestamp = user.last_login.replace(microsecond=0, tzinfo=None)
value = (unicode(user.id) + user.password + value = (six.text_type(user.id) + user.password +
unicode(login_timestamp) + unicode(timestamp)) six.text_type(login_timestamp) + six.text_type(timestamp))
hash = salted_hmac(key_salt, value).hexdigest()[::2] hash = salted_hmac(key_salt, value).hexdigest()[::2]
return "%s-%s" % (ts_b36, hash) return "%s-%s" % (ts_b36, hash)

View File

@ -9,6 +9,7 @@ from django.contrib.sites.models import Site
from django.http import HttpRequest, Http404 from django.http import HttpRequest, Http404
from django.test import TestCase from django.test import TestCase
from django.utils.encoding import smart_str from django.utils.encoding import smart_str
from django.utils import six
class ConcreteModel(models.Model): class ConcreteModel(models.Model):
@ -271,4 +272,4 @@ class ContentTypesTests(TestCase):
app_label = 'contenttypes', app_label = 'contenttypes',
model = 'OldModel', model = 'OldModel',
) )
self.assertEqual(unicode(ct), 'Old model') self.assertEqual(six.text_type(ct), 'Old model')

View File

@ -7,6 +7,7 @@ from django.forms import formsets, ValidationError
from django.views.generic import TemplateView from django.views.generic import TemplateView
from django.utils.datastructures import SortedDict from django.utils.datastructures import SortedDict
from django.utils.decorators import classonlymethod from django.utils.decorators import classonlymethod
from django.utils import six
from django.contrib.formtools.wizard.storage import get_storage from django.contrib.formtools.wizard.storage import get_storage
from django.contrib.formtools.wizard.storage.exceptions import NoFileStorageConfigured from django.contrib.formtools.wizard.storage.exceptions import NoFileStorageConfigured
@ -157,10 +158,10 @@ class WizardView(TemplateView):
if isinstance(form, (list, tuple)): if isinstance(form, (list, tuple)):
# if the element is a tuple, add the tuple to the new created # if the element is a tuple, add the tuple to the new created
# sorted dictionary. # sorted dictionary.
init_form_list[unicode(form[0])] = form[1] init_form_list[six.text_type(form[0])] = form[1]
else: else:
# if not, add the form with a zero based counter as unicode # if not, add the form with a zero based counter as unicode
init_form_list[unicode(i)] = form init_form_list[six.text_type(i)] = form
# walk through the new created list of forms # walk through the new created list of forms
for form in init_form_list.itervalues(): for form in init_form_list.itervalues():

View File

@ -4,6 +4,7 @@ Base/mixin classes for the spatial backend database operations and the
""" """
import re import re
from django.contrib.gis import gdal from django.contrib.gis import gdal
from django.utils import six
class BaseSpatialOperations(object): class BaseSpatialOperations(object):
""" """
@ -88,7 +89,7 @@ class BaseSpatialOperations(object):
# For quoting column values, rather than columns. # For quoting column values, rather than columns.
def geo_quote_name(self, name): def geo_quote_name(self, name):
if isinstance(name, unicode): if isinstance(name, six.text_type):
name = name.encode('ascii') name = name.encode('ascii')
return "'%s'" % name return "'%s'" % name
@ -330,6 +331,6 @@ class SpatialRefSysMixin(object):
it will be 'pretty' OGC WKT. it will be 'pretty' OGC WKT.
""" """
try: try:
return unicode(self.srs) return six.text_type(self.srs)
except: except:
return unicode(self.wkt) return six.text_type(self.wkt)

View File

@ -12,7 +12,7 @@ def gqn(val):
backend quotename function). backend quotename function).
""" """
if isinstance(val, six.string_types): if isinstance(val, six.string_types):
if isinstance(val, unicode): val = val.encode('ascii') if isinstance(val, six.text_type): val = val.encode('ascii')
return "'%s'" % val return "'%s'" % val
else: else:
return str(val) return str(val)

View File

@ -81,7 +81,7 @@ class OGRGeometry(GDALBase):
# Constructing the geometry, # Constructing the geometry,
if str_instance: if str_instance:
# Checking if unicode # Checking if unicode
if isinstance(geom_input, unicode): if isinstance(geom_input, six.text_type):
# Encoding to ASCII, WKT or HEX doesn't need any more. # Encoding to ASCII, WKT or HEX doesn't need any more.
geom_input = geom_input.encode('ascii') geom_input = geom_input.encode('ascii')

View File

@ -56,7 +56,7 @@ class SpatialReference(GDALBase):
if isinstance(srs_input, six.string_types): if isinstance(srs_input, six.string_types):
# Encoding to ASCII if unicode passed in. # Encoding to ASCII if unicode passed in.
if isinstance(srs_input, unicode): if isinstance(srs_input, six.text_type):
srs_input = srs_input.encode('ascii') srs_input = srs_input.encode('ascii')
try: try:
# If SRID is a string, e.g., '4326', then make acceptable # If SRID is a string, e.g., '4326', then make acceptable

View File

@ -55,7 +55,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
(SRID) number for this Geometry. If not set, the SRID will be None. (SRID) number for this Geometry. If not set, the SRID will be None.
""" """
if isinstance(geo_input, six.string_types): if isinstance(geo_input, six.string_types):
if isinstance(geo_input, unicode): if isinstance(geo_input, six.text_type):
# Encoding to ASCII, WKT or HEXEWKB doesn't need any more. # Encoding to ASCII, WKT or HEXEWKB doesn't need any more.
geo_input = geo_input.encode('ascii') geo_input = geo_input.encode('ascii')

View File

@ -13,7 +13,7 @@ class GEOSIOTest(unittest.TestCase):
# read() should return a GEOSGeometry # read() should return a GEOSGeometry
ref = GEOSGeometry(wkt) ref = GEOSGeometry(wkt)
g1 = wkt_r.read(wkt) g1 = wkt_r.read(wkt)
g2 = wkt_r.read(unicode(wkt)) g2 = wkt_r.read(six.text_type(wkt))
for geom in (g1, g2): for geom in (g1, g2):
self.assertEqual(ref, geom) self.assertEqual(ref, geom)

View File

@ -11,6 +11,7 @@ from django.contrib.gis.tests.utils import (
no_mysql, no_oracle, no_spatialite, no_mysql, no_oracle, no_spatialite,
mysql, oracle, postgis, spatialite) mysql, oracle, postgis, spatialite)
from django.test import TestCase from django.test import TestCase
from django.utils import six
from .models import Country, City, PennsylvaniaCity, State, Track from .models import Country, City, PennsylvaniaCity, State, Track
@ -663,7 +664,7 @@ class GeoModelTest(TestCase):
# Let's try and break snap_to_grid() with bad combinations of arguments. # Let's try and break snap_to_grid() with bad combinations of arguments.
for bad_args in ((), range(3), range(5)): for bad_args in ((), range(3), range(5)):
self.assertRaises(ValueError, Country.objects.snap_to_grid, *bad_args) self.assertRaises(ValueError, Country.objects.snap_to_grid, *bad_args)
for bad_args in (('1.0',), (1.0, None), tuple(map(unicode, range(4)))): for bad_args in (('1.0',), (1.0, None), tuple(map(six.text_type, range(4)))):
self.assertRaises(TypeError, Country.objects.snap_to_grid, *bad_args) self.assertRaises(TypeError, Country.objects.snap_to_grid, *bad_args)
# Boundary for San Marino, courtesy of Bjorn Sandvik of thematicmapping.org # Boundary for San Marino, courtesy of Bjorn Sandvik of thematicmapping.org

View File

@ -330,7 +330,7 @@ class LayerMapping(object):
if self.encoding: if self.encoding:
# The encoding for OGR data sources may be specified here # The encoding for OGR data sources may be specified here
# (e.g., 'cp437' for Census Bureau boundary files). # (e.g., 'cp437' for Census Bureau boundary files).
val = unicode(ogr_field.value, self.encoding) val = six.text_type(ogr_field.value, self.encoding)
else: else:
val = ogr_field.value val = ogr_field.value
if model_field.max_length and len(val) > model_field.max_length: if model_field.max_length and len(val) > model_field.max_length:

View File

@ -7,6 +7,7 @@ import re
from django.forms import ValidationError from django.forms import ValidationError
from django.forms.fields import Select, RegexField from django.forms.fields import Select, RegexField
from django.utils import six
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.validators import EMPTY_VALUES from django.core.validators import EMPTY_VALUES
from django.contrib.localflavor.mx.mx_states import STATE_CHOICES from django.contrib.localflavor.mx.mx_states import STATE_CHOICES
@ -155,7 +156,7 @@ class MXRFCField(RegexField):
elif checksum == 11: elif checksum == 11:
return '0' return '0'
return unicode(checksum) return six.text_type(checksum)
def _has_inconvenient_word(self, rfc): def _has_inconvenient_word(self, rfc):
first_four = rfc[:4] first_four = rfc[:4]
@ -219,7 +220,7 @@ class MXCURPField(RegexField):
if checksum == 10: if checksum == 10:
return '0' return '0'
return unicode(checksum) return six.text_type(checksum)
def _has_inconvenient_word(self, curp): def _has_inconvenient_word(self, curp):
first_four = curp[:4] first_four = curp[:4]

View File

@ -1,4 +1,5 @@
import datetime import datetime
from django.utils import six
def id_number_checksum(gd): def id_number_checksum(gd):
""" """
@ -65,7 +66,7 @@ def validate_id_birthday(gd, fix_coordination_number_day=True):
def format_personal_id_number(birth_day, gd): def format_personal_id_number(birth_day, gd):
# birth_day.strftime cannot be used, since it does not support dates < 1900 # birth_day.strftime cannot be used, since it does not support dates < 1900
return unicode(str(birth_day.year) + gd['month'] + gd['day'] + gd['serial'] + gd['checksum']) return six.text_type(str(birth_day.year) + gd['month'] + gd['day'] + gd['serial'] + gd['checksum'])
def format_organisation_number(gd): def format_organisation_number(gd):
if gd['century'] is None: if gd['century'] is None:
@ -73,7 +74,7 @@ def format_organisation_number(gd):
else: else:
century = gd['century'] century = gd['century']
return unicode(century + gd['year'] + gd['month'] + gd['day'] + gd['serial'] + gd['checksum']) return six.text_type(century + gd['year'] + gd['month'] + gd['day'] + gd['serial'] + gd['checksum'])
def valid_organisation(gd): def valid_organisation(gd):
return gd['century'] in (None, 16) and \ return gd['century'] in (None, 16) and \

View File

@ -3,6 +3,7 @@ from optparse import make_option
from django.core.management.base import NoArgsCommand, CommandError from django.core.management.base import NoArgsCommand, CommandError
from django.db import connections, DEFAULT_DB_ALIAS from django.db import connections, DEFAULT_DB_ALIAS
from django.utils import six
class Command(NoArgsCommand): class Command(NoArgsCommand):
help = "Introspects the database tables in the given database and outputs a Django model module." help = "Introspects the database tables in the given database and outputs a Django model module."
@ -115,7 +116,7 @@ class Command(NoArgsCommand):
if att_name[0].isdigit(): if att_name[0].isdigit():
att_name = 'number_%s' % att_name att_name = 'number_%s' % att_name
extra_params['db_column'] = unicode(column_name) extra_params['db_column'] = six.text_type(column_name)
comment_notes.append("Field renamed because it wasn't a " comment_notes.append("Field renamed because it wasn't a "
"valid Python identifier.") "valid Python identifier.")

View File

@ -120,7 +120,7 @@ def get_validation_errors(outfile, app=None):
e.add(opts, "'%s' has a relation with model %s, which has either not been installed or is abstract." % (f.name, f.rel.to)) e.add(opts, "'%s' has a relation with model %s, which has either not been installed or is abstract." % (f.name, f.rel.to))
# it is a string and we could not find the model it refers to # it is a string and we could not find the model it refers to
# so skip the next section # so skip the next section
if isinstance(f.rel.to, (str, unicode)): if isinstance(f.rel.to, six.string_types):
continue continue
# Make sure the related field specified by a ForeignKey is unique # Make sure the related field specified by a ForeignKey is unique
@ -162,7 +162,7 @@ def get_validation_errors(outfile, app=None):
e.add(opts, "'%s' has an m2m relation with model %s, which has either not been installed or is abstract." % (f.name, f.rel.to)) e.add(opts, "'%s' has an m2m relation with model %s, which has either not been installed or is abstract." % (f.name, f.rel.to))
# it is a string and we could not find the model it refers to # it is a string and we could not find the model it refers to
# so skip the next section # so skip the next section
if isinstance(f.rel.to, (str, unicode)): if isinstance(f.rel.to, six.string_types):
continue continue
# Check that the field is not set to unique. ManyToManyFields do not support unique. # Check that the field is not set to unique. ManyToManyFields do not support unique.

View File

@ -169,7 +169,7 @@ class LocaleRegexProvider(object):
except re.error as e: except re.error as e:
raise ImproperlyConfigured( raise ImproperlyConfigured(
'"%s" is not a valid regular expression: %s' % '"%s" is not a valid regular expression: %s' %
(regex, unicode(e))) (regex, six.text_type(e)))
self._regex_dict[language_code] = compiled_regex self._regex_dict[language_code] = compiled_regex
return self._regex_dict[language_code] return self._regex_dict[language_code]

View File

@ -12,6 +12,7 @@ from django.db.backends import util
from django.db.transaction import TransactionManagementError from django.db.transaction import TransactionManagementError
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.importlib import import_module from django.utils.importlib import import_module
from django.utils import six
from django.utils.timezone import is_aware from django.utils.timezone import is_aware
@ -808,7 +809,7 @@ class BaseDatabaseOperations(object):
""" """
if value is None: if value is None:
return None return None
return unicode(value) return six.text_type(value)
def value_to_db_datetime(self, value): def value_to_db_datetime(self, value):
""" """
@ -817,7 +818,7 @@ class BaseDatabaseOperations(object):
""" """
if value is None: if value is None:
return None return None
return unicode(value) return six.text_type(value)
def value_to_db_time(self, value): def value_to_db_time(self, value):
""" """
@ -828,7 +829,7 @@ class BaseDatabaseOperations(object):
return None return None
if is_aware(value): if is_aware(value):
raise ValueError("Django does not support timezone-aware times.") raise ValueError("Django does not support timezone-aware times.")
return unicode(value) return six.text_type(value)
def value_to_db_decimal(self, value, max_digits, decimal_places): def value_to_db_decimal(self, value, max_digits, decimal_places):
""" """

View File

@ -297,7 +297,7 @@ class DatabaseOperations(BaseDatabaseOperations):
raise ValueError("MySQL backend does not support timezone-aware datetimes when USE_TZ is False.") raise ValueError("MySQL backend does not support timezone-aware datetimes when USE_TZ is False.")
# MySQL doesn't support microseconds # MySQL doesn't support microseconds
return unicode(value.replace(microsecond=0)) return six.text_type(value.replace(microsecond=0))
def value_to_db_time(self, value): def value_to_db_time(self, value):
if value is None: if value is None:
@ -308,7 +308,7 @@ class DatabaseOperations(BaseDatabaseOperations):
raise ValueError("MySQL backend does not support timezone-aware times.") raise ValueError("MySQL backend does not support timezone-aware times.")
# MySQL doesn't support microseconds # MySQL doesn't support microseconds
return unicode(value.replace(microsecond=0)) return six.text_type(value.replace(microsecond=0))
def year_lookup_bounds(self, value): def year_lookup_bounds(self, value):
# Again, no microseconds # Again, no microseconds
@ -399,8 +399,8 @@ class DatabaseWrapper(BaseDatabaseWrapper):
kwargs['client_flag'] = CLIENT.FOUND_ROWS kwargs['client_flag'] = CLIENT.FOUND_ROWS
kwargs.update(settings_dict['OPTIONS']) kwargs.update(settings_dict['OPTIONS'])
self.connection = Database.connect(**kwargs) self.connection = Database.connect(**kwargs)
self.connection.encoders[SafeUnicode] = self.connection.encoders[unicode] self.connection.encoders[SafeUnicode] = self.connection.encoders[six.text_type]
self.connection.encoders[SafeString] = self.connection.encoders[str] self.connection.encoders[SafeString] = self.connection.encoders[bytes]
connection_created.send(sender=self.__class__, connection=self) connection_created.send(sender=self.__class__, connection=self)
cursor = self.connection.cursor() cursor = self.connection.cursor()
if new_connection: if new_connection:

View File

@ -356,7 +356,7 @@ WHEN (new.%(col_name)s IS NULL)
else: else:
raise ValueError("Oracle backend does not support timezone-aware datetimes when USE_TZ is False.") raise ValueError("Oracle backend does not support timezone-aware datetimes when USE_TZ is False.")
return unicode(value) return six.text_type(value)
def value_to_db_time(self, value): def value_to_db_time(self, value):
if value is None: if value is None:

View File

@ -177,7 +177,7 @@ class DatabaseOperations(BaseDatabaseOperations):
else: else:
raise ValueError("SQLite backend does not support timezone-aware datetimes when USE_TZ is False.") raise ValueError("SQLite backend does not support timezone-aware datetimes when USE_TZ is False.")
return unicode(value) return six.text_type(value)
def value_to_db_time(self, value): def value_to_db_time(self, value):
if value is None: if value is None:
@ -187,7 +187,7 @@ class DatabaseOperations(BaseDatabaseOperations):
if timezone.is_aware(value): if timezone.is_aware(value):
raise ValueError("SQLite backend does not support timezone-aware times.") raise ValueError("SQLite backend does not support timezone-aware times.")
return unicode(value) return six.text_type(value)
def year_lookup_bounds(self, value): def year_lookup_bounds(self, value):
first = '%s-01-01' first = '%s-01-01'

View File

@ -375,7 +375,7 @@ class ModelWithoutMeta(object):
def __repr__(self): def __repr__(self):
try: try:
u = unicode(self) u = six.text_type(self)
except (UnicodeEncodeError, UnicodeDecodeError): except (UnicodeEncodeError, UnicodeDecodeError):
u = '[Bad Unicode data]' u = '[Bad Unicode data]'
return smart_str('<%s: %s>' % (self.__class__.__name__, u)) return smart_str('<%s: %s>' % (self.__class__.__name__, u))
@ -790,8 +790,8 @@ class ModelWithoutMeta(object):
def date_error_message(self, lookup_type, field, unique_for): def date_error_message(self, lookup_type, field, unique_for):
opts = self._meta opts = self._meta
return _("%(field_name)s must be unique for %(date_field)s %(lookup)s.") % { return _("%(field_name)s must be unique for %(date_field)s %(lookup)s.") % {
'field_name': unicode(capfirst(opts.get_field(field).verbose_name)), 'field_name': six.text_type(capfirst(opts.get_field(field).verbose_name)),
'date_field': unicode(capfirst(opts.get_field(unique_for).verbose_name)), 'date_field': six.text_type(capfirst(opts.get_field(unique_for).verbose_name)),
'lookup': lookup_type, 'lookup': lookup_type,
} }
@ -806,16 +806,16 @@ class ModelWithoutMeta(object):
field_label = capfirst(field.verbose_name) field_label = capfirst(field.verbose_name)
# Insert the error into the error dict, very sneaky # Insert the error into the error dict, very sneaky
return field.error_messages['unique'] % { return field.error_messages['unique'] % {
'model_name': unicode(model_name), 'model_name': six.text_type(model_name),
'field_label': unicode(field_label) 'field_label': six.text_type(field_label)
} }
# unique_together # unique_together
else: else:
field_labels = map(lambda f: capfirst(opts.get_field(f).verbose_name), unique_check) field_labels = map(lambda f: capfirst(opts.get_field(f).verbose_name), unique_check)
field_labels = get_text_list(field_labels, _('and')) field_labels = get_text_list(field_labels, _('and'))
return _("%(model_name)s with this %(field_label)s already exists.") % { return _("%(model_name)s with this %(field_label)s already exists.") % {
'model_name': unicode(model_name), 'model_name': six.text_type(model_name),
'field_label': unicode(field_labels) 'field_label': six.text_type(field_labels)
} }
def full_clean(self, exclude=None): def full_clean(self, exclude=None):

View File

@ -265,7 +265,7 @@ class FileField(Field):
# Need to convert File objects provided via a form to unicode for database insertion # Need to convert File objects provided via a form to unicode for database insertion
if value is None: if value is None:
return None return None
return unicode(value) return six.text_type(value)
def pre_save(self, model_instance, add): def pre_save(self, model_instance, add):
"Returns field's value just before saving." "Returns field's value just before saving."

View File

@ -331,10 +331,10 @@ class BaseTemporalField(Field):
def to_python(self, value): def to_python(self, value):
# Try to coerce the value to unicode. # Try to coerce the value to unicode.
unicode_value = force_unicode(value, strings_only=True) unicode_value = force_unicode(value, strings_only=True)
if isinstance(unicode_value, unicode): if isinstance(unicode_value, six.text_type):
value = unicode_value.strip() value = unicode_value.strip()
# If unicode, try to strptime against each input format. # If unicode, try to strptime against each input format.
if isinstance(value, unicode): if isinstance(value, six.text_type):
for format in self.input_formats: for format in self.input_formats:
try: try:
return self.strptime(value, format) return self.strptime(value, format)

View File

@ -151,7 +151,7 @@ class BaseForm(StrAndUnicode):
if bf.is_hidden: if bf.is_hidden:
if bf_errors: if bf_errors:
top_errors.extend(['(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors]) top_errors.extend(['(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors])
hidden_fields.append(unicode(bf)) hidden_fields.append(six.text_type(bf))
else: else:
# Create a 'class="..."' atribute if the row should have any # Create a 'class="..."' atribute if the row should have any
# CSS classes applied. # CSS classes applied.
@ -181,7 +181,7 @@ class BaseForm(StrAndUnicode):
output.append(normal_row % { output.append(normal_row % {
'errors': force_unicode(bf_errors), 'errors': force_unicode(bf_errors),
'label': force_unicode(label), 'label': force_unicode(label),
'field': unicode(bf), 'field': six.text_type(bf),
'help_text': help_text, 'help_text': help_text,
'html_class_attr': html_class_attr 'html_class_attr': html_class_attr
}) })

View File

@ -7,6 +7,7 @@ from django.forms.util import ErrorList
from django.forms.widgets import Media, HiddenInput from django.forms.widgets import Media, HiddenInput
from django.utils.encoding import StrAndUnicode from django.utils.encoding import StrAndUnicode
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils import six
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
@ -345,17 +346,17 @@ class BaseFormSet(StrAndUnicode):
# probably should be. It might make sense to render each form as a # probably should be. It might make sense to render each form as a
# table row with each field as a td. # table row with each field as a td.
forms = ' '.join([form.as_table() for form in self]) forms = ' '.join([form.as_table() for form in self])
return mark_safe('\n'.join([unicode(self.management_form), forms])) return mark_safe('\n'.join([six.text_type(self.management_form), forms]))
def as_p(self): def as_p(self):
"Returns this formset rendered as HTML <p>s." "Returns this formset rendered as HTML <p>s."
forms = ' '.join([form.as_p() for form in self]) forms = ' '.join([form.as_p() for form in self])
return mark_safe('\n'.join([unicode(self.management_form), forms])) return mark_safe('\n'.join([six.text_type(self.management_form), forms]))
def as_ul(self): def as_ul(self):
"Returns this formset rendered as HTML <li>s." "Returns this formset rendered as HTML <li>s."
forms = ' '.join([form.as_ul() for form in self]) forms = ' '.join([form.as_ul() for form in self])
return mark_safe('\n'.join([unicode(self.management_form), forms])) return mark_safe('\n'.join([six.text_type(self.management_form), forms]))
def formset_factory(form, formset=BaseFormSet, extra=1, can_order=False, def formset_factory(form, formset=BaseFormSet, extra=1, can_order=False,
can_delete=False, max_num=None): can_delete=False, max_num=None):

View File

@ -576,7 +576,7 @@ class BaseModelFormSet(BaseFormSet):
else: else:
return ugettext("Please correct the duplicate data for %(field)s, " return ugettext("Please correct the duplicate data for %(field)s, "
"which must be unique.") % { "which must be unique.") % {
"field": get_text_list(unique_check, unicode(_("and"))), "field": get_text_list(unique_check, six.text_type(_("and"))),
} }
def get_date_error_message(self, date_check): def get_date_error_message(self, date_check):
@ -584,7 +584,7 @@ class BaseModelFormSet(BaseFormSet):
"which must be unique for the %(lookup)s in %(date_field)s.") % { "which must be unique for the %(lookup)s in %(date_field)s.") % {
'field_name': date_check[2], 'field_name': date_check[2],
'date_field': date_check[3], 'date_field': date_check[3],
'lookup': unicode(date_check[1]), 'lookup': six.text_type(date_check[1]),
} }
def get_form_error(self): def get_form_error(self):

View File

@ -137,10 +137,10 @@ def build_request_repr(request, path_override=None, GET_override=None,
return smart_str('<%s\npath:%s,\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' % return smart_str('<%s\npath:%s,\nGET:%s,\nPOST:%s,\nCOOKIES:%s,\nMETA:%s>' %
(request.__class__.__name__, (request.__class__.__name__,
path, path,
unicode(get), six.text_type(get),
unicode(post), six.text_type(post),
unicode(cookies), six.text_type(cookies),
unicode(meta))) six.text_type(meta)))
class UnreadablePostError(IOError): class UnreadablePostError(IOError):
pass pass
@ -544,7 +544,7 @@ class HttpResponse(object):
def _convert_to_ascii(self, *values): def _convert_to_ascii(self, *values):
"""Converts all values to ascii strings.""" """Converts all values to ascii strings."""
for value in values: for value in values:
if isinstance(value, unicode): if isinstance(value, six.text_type):
try: try:
value = value.encode('us-ascii') value = value.encode('us-ascii')
except UnicodeError as e: except UnicodeError as e:
@ -663,7 +663,7 @@ class HttpResponse(object):
def next(self): def next(self):
chunk = next(self._iterator) chunk = next(self._iterator)
if isinstance(chunk, unicode): if isinstance(chunk, six.text_type):
chunk = chunk.encode(self._charset) chunk = chunk.encode(self._charset)
return str(chunk) return str(chunk)
@ -740,8 +740,8 @@ def str_to_unicode(s, encoding):
Returns any non-basestring objects without change. Returns any non-basestring objects without change.
""" """
if isinstance(s, str): if isinstance(s, bytes):
return unicode(s, encoding, 'replace') return six.text_type(s, encoding, 'replace')
else: else:
return s return s

View File

@ -11,6 +11,7 @@ from django.conf import settings
from django.core.exceptions import SuspiciousOperation from django.core.exceptions import SuspiciousOperation
from django.utils.datastructures import MultiValueDict from django.utils.datastructures import MultiValueDict
from django.utils.encoding import force_unicode from django.utils.encoding import force_unicode
from django.utils import six
from django.utils.text import unescape_entities from django.utils.text import unescape_entities
from django.core.files.uploadhandler import StopUpload, SkipFile, StopFutureHandlers from django.core.files.uploadhandler import StopUpload, SkipFile, StopFutureHandlers
@ -77,7 +78,7 @@ class MultiPartParser(object):
# This means we shouldn't continue...raise an error. # This means we shouldn't continue...raise an error.
raise MultiPartParserError("Invalid content length: %r" % content_length) raise MultiPartParserError("Invalid content length: %r" % content_length)
if isinstance(boundary, unicode): if isinstance(boundary, six.text_type):
boundary = boundary.encode('ascii') boundary = boundary.encode('ascii')
self._boundary = boundary self._boundary = boundary
self._input_data = input_data self._input_data = input_data

View File

@ -86,7 +86,7 @@ class VariableDoesNotExist(Exception):
self.params = params self.params = params
def __str__(self): def __str__(self):
return unicode(self).encode('utf-8') return six.text_type(self).encode('utf-8')
def __unicode__(self): def __unicode__(self):
return self.msg % tuple([force_unicode(p, errors='replace') return self.msg % tuple([force_unicode(p, errors='replace')

View File

@ -18,6 +18,7 @@ from django.utils.html import (conditional_escape, escapejs, fix_ampersands,
from django.utils.http import urlquote from django.utils.http import urlquote
from django.utils.text import Truncator, wrap, phone2numeric from django.utils.text import Truncator, wrap, phone2numeric
from django.utils.safestring import mark_safe, SafeData, mark_for_escaping from django.utils.safestring import mark_safe, SafeData, mark_for_escaping
from django.utils import six
from django.utils.timesince import timesince, timeuntil from django.utils.timesince import timesince, timeuntil
from django.utils.translation import ugettext, ungettext from django.utils.translation import ugettext, ungettext
from django.utils.text import normalize_newlines from django.utils.text import normalize_newlines
@ -176,7 +177,7 @@ def floatformat(text, arg=-1):
# and `exponent` from `Decimal.as_tuple()` directly. # and `exponent` from `Decimal.as_tuple()` directly.
sign, digits, exponent = d.quantize(exp, ROUND_HALF_UP, sign, digits, exponent = d.quantize(exp, ROUND_HALF_UP,
Context(prec=prec)).as_tuple() Context(prec=prec)).as_tuple()
digits = [unicode(digit) for digit in reversed(digits)] digits = [six.text_type(digit) for digit in reversed(digits)]
while len(digits) <= abs(exponent): while len(digits) <= abs(exponent):
digits.append('0') digits.append('0')
digits.insert(-exponent, '.') digits.insert(-exponent, '.')
@ -200,7 +201,7 @@ def linenumbers(value, autoescape=None):
lines = value.split('\n') lines = value.split('\n')
# Find the maximum width of the line count, for use with zero padding # Find the maximum width of the line count, for use with zero padding
# string format command # string format command
width = unicode(len(unicode(len(lines)))) width = six.text_type(len(six.text_type(len(lines))))
if not autoescape or isinstance(value, SafeData): if not autoescape or isinstance(value, SafeData):
for i, line in enumerate(lines): for i, line in enumerate(lines):
lines[i] = ("%0" + width + "d. %s") % (i + 1, line) lines[i] = ("%0" + width + "d. %s") % (i + 1, line)
@ -234,7 +235,7 @@ def slugify(value):
and converts spaces to hyphens. and converts spaces to hyphens.
""" """
value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore') value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
value = unicode(re.sub('[^\w\s-]', '', value).strip().lower()) value = six.text_type(re.sub('[^\w\s-]', '', value).strip().lower())
return mark_safe(re.sub('[-\s]+', '-', value)) return mark_safe(re.sub('[-\s]+', '-', value))
@register.filter(is_safe=True) @register.filter(is_safe=True)
@ -249,7 +250,7 @@ def stringformat(value, arg):
of Python string formatting of Python string formatting
""" """
try: try:
return ("%" + unicode(arg)) % value return ("%" + six.text_type(arg)) % value
except (ValueError, TypeError): except (ValueError, TypeError):
return "" return ""

View File

@ -211,7 +211,7 @@ def _normalize_module(module, depth=2):
""" """
if inspect.ismodule(module): if inspect.ismodule(module):
return module return module
elif isinstance(module, (str, unicode)): elif isinstance(module, six.string_types):
return __import__(module, globals(), locals(), ["*"]) return __import__(module, globals(), locals(), ["*"])
elif module is None: elif module is None:
return sys.modules[sys._getframe(depth).f_globals['__name__']] return sys.modules[sys._getframe(depth).f_globals['__name__']]

View File

@ -125,14 +125,14 @@ class Element(object):
output += ' %s' % key output += ' %s' % key
if self.children: if self.children:
output += '>\n' output += '>\n'
output += ''.join(unicode(c) for c in self.children) output += ''.join(six.text_type(c) for c in self.children)
output += '\n</%s>' % self.name output += '\n</%s>' % self.name
else: else:
output += ' />' output += ' />'
return output return output
def __repr__(self): def __repr__(self):
return unicode(self) return six.text_type(self)
class RootElement(Element): class RootElement(Element):
@ -140,7 +140,7 @@ class RootElement(Element):
super(RootElement, self).__init__(None, ()) super(RootElement, self).__init__(None, ())
def __unicode__(self): def __unicode__(self):
return ''.join(unicode(c) for c in self.children) return ''.join(six.text_type(c) for c in self.children)
class Parser(HTMLParser): class Parser(HTMLParser):

View File

@ -38,6 +38,7 @@ from django.test.utils import (get_warnings_state, restore_warnings_state,
from django.test.utils import ContextList from django.test.utils import ContextList
from django.utils import unittest as ut2 from django.utils import unittest as ut2
from django.utils.encoding import smart_str, force_unicode from django.utils.encoding import smart_str, force_unicode
from django.utils import six
from django.utils.unittest.util import safe_repr from django.utils.unittest.util import safe_repr
from django.views.static import serve from django.views.static import serve
@ -421,8 +422,8 @@ class SimpleTestCase(ut2.TestCase):
standardMsg = '%s != %s' % ( standardMsg = '%s != %s' % (
safe_repr(dom1, True), safe_repr(dom2, True)) safe_repr(dom1, True), safe_repr(dom2, True))
diff = ('\n' + '\n'.join(difflib.ndiff( diff = ('\n' + '\n'.join(difflib.ndiff(
unicode(dom1).splitlines(), six.text_type(dom1).splitlines(),
unicode(dom2).splitlines()))) six.text_type(dom2).splitlines())))
standardMsg = self._truncateMessage(standardMsg, diff) standardMsg = self._truncateMessage(standardMsg, diff)
self.fail(self._formatMessage(msg, standardMsg)) self.fail(self._formatMessage(msg, standardMsg))

View File

@ -21,6 +21,7 @@ from django.utils.dates import MONTHS, MONTHS_3, MONTHS_ALT, MONTHS_AP, WEEKDAYS
from django.utils.tzinfo import LocalTimezone from django.utils.tzinfo import LocalTimezone
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils.encoding import force_unicode from django.utils.encoding import force_unicode
from django.utils import six
from django.utils.timezone import is_aware, is_naive from django.utils.timezone import is_aware, is_naive
re_formatchars = re.compile(r'(?<!\\)([aAbBcdDeEfFgGhHiIjlLmMnNoOPrsStTUuwWyYzZ])') re_formatchars = re.compile(r'(?<!\\)([aAbBcdDeEfFgGhHiIjlLmMnNoOPrsStTUuwWyYzZ])')
@ -236,7 +237,7 @@ class DateFormat(TimeFormat):
name = self.timezone and self.timezone.tzname(self.data) or None name = self.timezone and self.timezone.tzname(self.data) or None
if name is None: if name is None:
name = self.format('O') name = self.format('O')
return unicode(name) return six.text_type(name)
def U(self): def U(self):
"Seconds since the Unix epoch (January 1 1970 00:00:00 GMT)" "Seconds since the Unix epoch (January 1 1970 00:00:00 GMT)"
@ -277,7 +278,7 @@ class DateFormat(TimeFormat):
def y(self): def y(self):
"Year, 2 digits; e.g. '99'" "Year, 2 digits; e.g. '99'"
return unicode(self.data.year)[2:] return six.text_type(self.data.year)[2:]
def Y(self): def Y(self):
"Year, 4 digits; e.g. '1999'" "Year, 4 digits; e.g. '1999'"

View File

@ -25,6 +25,10 @@ class StrAndUnicode(object):
Useful as a mix-in. Useful as a mix-in.
""" """
if six.PY3:
def __str__(self):
return self.__unicode__()
else:
def __str__(self): def __str__(self):
return self.__unicode__().encode('utf-8') return self.__unicode__().encode('utf-8')
@ -59,17 +63,23 @@ def force_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
# Handle the common case first, saves 30-40% in performance when s # Handle the common case first, saves 30-40% in performance when s
# is an instance of unicode. This function gets called often in that # is an instance of unicode. This function gets called often in that
# setting. # setting.
if isinstance(s, unicode): if isinstance(s, six.text_type):
return s return s
if strings_only and is_protected_type(s): if strings_only and is_protected_type(s):
return s return s
try: try:
if not isinstance(s, six.string_types,): if not isinstance(s, six.string_types):
if hasattr(s, '__unicode__'): if hasattr(s, '__unicode__'):
s = unicode(s) s = s.__unicode__()
else: else:
try: try:
s = unicode(str(s), encoding, errors) if six.PY3:
if isinstance(s, bytes):
s = six.text_type(s, encoding, errors)
else:
s = six.text_type(s)
else:
s = six.text_type(bytes(s), encoding, errors)
except UnicodeEncodeError: except UnicodeEncodeError:
if not isinstance(s, Exception): if not isinstance(s, Exception):
raise raise
@ -81,8 +91,8 @@ def force_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
# output should be. # output should be.
s = ' '.join([force_unicode(arg, encoding, strings_only, s = ' '.join([force_unicode(arg, encoding, strings_only,
errors) for arg in s]) errors) for arg in s])
elif not isinstance(s, unicode): elif not isinstance(s, six.text_type):
# Note: We use .decode() here, instead of unicode(s, encoding, # Note: We use .decode() here, instead of six.text_type(s, encoding,
# errors), so that if s is a SafeString, it ends up being a # errors), so that if s is a SafeString, it ends up being a
# SafeUnicode at the end. # SafeUnicode at the end.
s = s.decode(encoding, errors) s = s.decode(encoding, errors)
@ -108,10 +118,13 @@ def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'):
if strings_only and (s is None or isinstance(s, int)): if strings_only and (s is None or isinstance(s, int)):
return s return s
if isinstance(s, Promise): if isinstance(s, Promise):
return unicode(s).encode(encoding, errors) return six.text_type(s).encode(encoding, errors)
elif not isinstance(s, six.string_types): elif not isinstance(s, six.string_types):
try: try:
return str(s) if six.PY3:
return six.text_type(s).encode(encoding)
else:
return bytes(s)
except UnicodeEncodeError: except UnicodeEncodeError:
if isinstance(s, Exception): if isinstance(s, Exception):
# An Exception subclass containing non-ASCII data that doesn't # An Exception subclass containing non-ASCII data that doesn't
@ -119,8 +132,8 @@ def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'):
# further exception. # further exception.
return ' '.join([smart_str(arg, encoding, strings_only, return ' '.join([smart_str(arg, encoding, strings_only,
errors) for arg in s]) errors) for arg in s])
return unicode(s).encode(encoding, errors) return six.text_type(s).encode(encoding, errors)
elif isinstance(s, unicode): elif isinstance(s, six.text_type):
return s.encode(encoding, errors) return s.encode(encoding, errors)
elif s and encoding != 'utf-8': elif s and encoding != 'utf-8':
return s.decode('utf-8', errors).encode(encoding, errors) return s.decode('utf-8', errors).encode(encoding, errors)

View File

@ -89,7 +89,7 @@ def get_format(format_type, lang=None, use_l10n=None):
_format_cache[cache_key] = None _format_cache[cache_key] = None
return getattr(settings, format_type) return getattr(settings, format_type)
get_format_lazy = lazy(get_format, unicode, list, tuple) get_format_lazy = lazy(get_format, six.text_type, list, tuple)
def date_format(value, format=None, use_l10n=None): def date_format(value, format=None, use_l10n=None):
""" """
@ -139,7 +139,7 @@ def localize(value, use_l10n=None):
be localized (or not), overriding the value of settings.USE_L10N. be localized (or not), overriding the value of settings.USE_L10N.
""" """
if isinstance(value, bool): if isinstance(value, bool):
return mark_safe(unicode(value)) return mark_safe(six.text_type(value))
elif isinstance(value, (decimal.Decimal, float) + six.integer_types): elif isinstance(value, (decimal.Decimal, float) + six.integer_types):
return number_format(value, use_l10n=use_l10n) return number_format(value, use_l10n=use_l10n)
elif isinstance(value, datetime.datetime): elif isinstance(value, datetime.datetime):

View File

@ -3,6 +3,7 @@ import operator
from functools import wraps, update_wrapper from functools import wraps, update_wrapper
import sys import sys
from django.utils import six
# You can't trivially replace this `functools.partial` because this binds to # You can't trivially replace this `functools.partial` because this binds to
# classes and returns bound instances, whereas functools.partial (on CPython) # classes and returns bound instances, whereas functools.partial (on CPython)
@ -92,8 +93,8 @@ def lazy(func, *resultclasses):
if hasattr(cls, k): if hasattr(cls, k):
continue continue
setattr(cls, k, meth) setattr(cls, k, meth)
cls._delegate_str = str in resultclasses cls._delegate_str = bytes in resultclasses
cls._delegate_unicode = unicode in resultclasses cls._delegate_unicode = six.text_type in resultclasses
assert not (cls._delegate_str and cls._delegate_unicode), "Cannot call lazy() with both str and unicode return types." assert not (cls._delegate_str and cls._delegate_unicode), "Cannot call lazy() with both str and unicode return types."
if cls._delegate_unicode: if cls._delegate_unicode:
cls.__unicode__ = cls.__unicode_cast cls.__unicode__ = cls.__unicode_cast
@ -147,7 +148,7 @@ def lazy(func, *resultclasses):
if self._delegate_str: if self._delegate_str:
return str(self) % rhs return str(self) % rhs
elif self._delegate_unicode: elif self._delegate_unicode:
return unicode(self) % rhs return six.text_type(self) % rhs
else: else:
raise AssertionError('__mod__ not supported for non-string types') raise AssertionError('__mod__ not supported for non-string types')
@ -255,8 +256,8 @@ class SimpleLazyObject(LazyObject):
def _setup(self): def _setup(self):
self._wrapped = self._setupfunc() self._wrapped = self._setupfunc()
__str__ = new_method_proxy(str) __str__ = new_method_proxy(bytes)
__unicode__ = new_method_proxy(unicode) __unicode__ = new_method_proxy(six.text_type)
def __deepcopy__(self, memo): def __deepcopy__(self, memo):
if self._wrapped is empty: if self._wrapped is empty:

View File

@ -10,6 +10,7 @@ import urlparse
from django.utils.safestring import SafeData, mark_safe from django.utils.safestring import SafeData, mark_safe
from django.utils.encoding import smart_str, force_unicode from django.utils.encoding import smart_str, force_unicode
from django.utils.functional import allow_lazy from django.utils.functional import allow_lazy
from django.utils import six
from django.utils.text import normalize_newlines from django.utils.text import normalize_newlines
# Configuration for urlize() function. # Configuration for urlize() function.
@ -36,7 +37,7 @@ def escape(text):
Returns the given text with ampersands, quotes and angle brackets encoded for use in HTML. Returns the given text with ampersands, quotes and angle brackets encoded for use in HTML.
""" """
return mark_safe(force_unicode(text).replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;')) return mark_safe(force_unicode(text).replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;'))
escape = allow_lazy(escape, unicode) escape = allow_lazy(escape, six.text_type)
_base_js_escapes = ( _base_js_escapes = (
('\\', '\\u005C'), ('\\', '\\u005C'),
@ -61,7 +62,7 @@ def escapejs(value):
for bad, good in _js_escapes: for bad, good in _js_escapes:
value = mark_safe(force_unicode(value).replace(bad, good)) value = mark_safe(force_unicode(value).replace(bad, good))
return value return value
escapejs = allow_lazy(escapejs, unicode) escapejs = allow_lazy(escapejs, six.text_type)
def conditional_escape(text): def conditional_escape(text):
""" """
@ -112,7 +113,7 @@ def linebreaks(value, autoescape=False):
else: else:
paras = ['<p>%s</p>' % p.replace('\n', '<br />') for p in paras] paras = ['<p>%s</p>' % p.replace('\n', '<br />') for p in paras]
return '\n\n'.join(paras) return '\n\n'.join(paras)
linebreaks = allow_lazy(linebreaks, unicode) linebreaks = allow_lazy(linebreaks, six.text_type)
def strip_tags(value): def strip_tags(value):
"""Returns the given HTML with all tags stripped.""" """Returns the given HTML with all tags stripped."""
@ -122,17 +123,17 @@ strip_tags = allow_lazy(strip_tags)
def strip_spaces_between_tags(value): def strip_spaces_between_tags(value):
"""Returns the given HTML with spaces between tags removed.""" """Returns the given HTML with spaces between tags removed."""
return re.sub(r'>\s+<', '><', force_unicode(value)) return re.sub(r'>\s+<', '><', force_unicode(value))
strip_spaces_between_tags = allow_lazy(strip_spaces_between_tags, unicode) strip_spaces_between_tags = allow_lazy(strip_spaces_between_tags, six.text_type)
def strip_entities(value): def strip_entities(value):
"""Returns the given HTML with all entities (&something;) stripped.""" """Returns the given HTML with all entities (&something;) stripped."""
return re.sub(r'&(?:\w+|#\d+);', '', force_unicode(value)) return re.sub(r'&(?:\w+|#\d+);', '', force_unicode(value))
strip_entities = allow_lazy(strip_entities, unicode) strip_entities = allow_lazy(strip_entities, six.text_type)
def fix_ampersands(value): def fix_ampersands(value):
"""Returns the given HTML with all unencoded ampersands encoded correctly.""" """Returns the given HTML with all unencoded ampersands encoded correctly."""
return unencoded_ampersands_re.sub('&amp;', force_unicode(value)) return unencoded_ampersands_re.sub('&amp;', force_unicode(value))
fix_ampersands = allow_lazy(fix_ampersands, unicode) fix_ampersands = allow_lazy(fix_ampersands, six.text_type)
def smart_urlquote(url): def smart_urlquote(url):
"Quotes a URL if it isn't already quoted." "Quotes a URL if it isn't already quoted."
@ -226,7 +227,7 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
elif autoescape: elif autoescape:
words[i] = escape(word) words[i] = escape(word)
return ''.join(words) return ''.join(words)
urlize = allow_lazy(urlize, unicode) urlize = allow_lazy(urlize, six.text_type)
def clean_html(text): def clean_html(text):
""" """
@ -260,4 +261,4 @@ def clean_html(text):
# of the text. # of the text.
text = trailing_empty_content_re.sub('', text) text = trailing_empty_content_re.sub('', text)
return text return text
clean_html = allow_lazy(clean_html, unicode) clean_html = allow_lazy(clean_html, six.text_type)

View File

@ -9,6 +9,7 @@ from email.utils import formatdate
from django.utils.datastructures import MultiValueDict from django.utils.datastructures import MultiValueDict
from django.utils.encoding import smart_str, force_unicode from django.utils.encoding import smart_str, force_unicode
from django.utils.functional import allow_lazy from django.utils.functional import allow_lazy
from django.utils import six
ETAG_MATCH = re.compile(r'(?:W/)?"((?:\\.|[^"])*)"') ETAG_MATCH = re.compile(r'(?:W/)?"((?:\\.|[^"])*)"')
@ -31,7 +32,7 @@ def urlquote(url, safe='/'):
without double-quoting occurring. without double-quoting occurring.
""" """
return force_unicode(urllib.quote(smart_str(url), smart_str(safe))) return force_unicode(urllib.quote(smart_str(url), smart_str(safe)))
urlquote = allow_lazy(urlquote, unicode) urlquote = allow_lazy(urlquote, six.text_type)
def urlquote_plus(url, safe=''): def urlquote_plus(url, safe=''):
""" """
@ -41,7 +42,7 @@ def urlquote_plus(url, safe=''):
iri_to_uri() call without double-quoting occurring. iri_to_uri() call without double-quoting occurring.
""" """
return force_unicode(urllib.quote_plus(smart_str(url), smart_str(safe))) return force_unicode(urllib.quote_plus(smart_str(url), smart_str(safe)))
urlquote_plus = allow_lazy(urlquote_plus, unicode) urlquote_plus = allow_lazy(urlquote_plus, six.text_type)
def urlunquote(quoted_url): def urlunquote(quoted_url):
""" """
@ -49,7 +50,7 @@ def urlunquote(quoted_url):
the result of django.utils.http.urlquote(). the result of django.utils.http.urlquote().
""" """
return force_unicode(urllib.unquote(smart_str(quoted_url))) return force_unicode(urllib.unquote(smart_str(quoted_url)))
urlunquote = allow_lazy(urlunquote, unicode) urlunquote = allow_lazy(urlunquote, six.text_type)
def urlunquote_plus(quoted_url): def urlunquote_plus(quoted_url):
""" """
@ -57,7 +58,7 @@ def urlunquote_plus(quoted_url):
the result of django.utils.http.urlquote_plus(). the result of django.utils.http.urlquote_plus().
""" """
return force_unicode(urllib.unquote_plus(smart_str(quoted_url))) return force_unicode(urllib.unquote_plus(smart_str(quoted_url)))
urlunquote_plus = allow_lazy(urlunquote_plus, unicode) urlunquote_plus = allow_lazy(urlunquote_plus, six.text_type)
def urlencode(query, doseq=0): def urlencode(query, doseq=0):
""" """

View File

@ -1,5 +1,6 @@
from django.conf import settings from django.conf import settings
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils import six
def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='', def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='',
@ -18,13 +19,13 @@ def format(number, decimal_sep, decimal_pos=None, grouping=0, thousand_sep='',
use_grouping = use_grouping and grouping > 0 use_grouping = use_grouping and grouping > 0
# Make the common case fast # Make the common case fast
if isinstance(number, int) and not use_grouping and not decimal_pos: if isinstance(number, int) and not use_grouping and not decimal_pos:
return mark_safe(unicode(number)) return mark_safe(six.text_type(number))
# sign # sign
if float(number) < 0: if float(number) < 0:
sign = '-' sign = '-'
else: else:
sign = '' sign = ''
str_number = unicode(number) str_number = six.text_type(number)
if str_number[0] == '-': if str_number[0] == '-':
str_number = str_number[1:] str_number = str_number[1:]
# decimal part # decimal part

View File

@ -5,17 +5,18 @@ that the producer of the string has already turned characters that should not
be interpreted by the HTML engine (e.g. '<') into the appropriate entities. be interpreted by the HTML engine (e.g. '<') into the appropriate entities.
""" """
from django.utils.functional import curry, Promise from django.utils.functional import curry, Promise
from django.utils import six
class EscapeData(object): class EscapeData(object):
pass pass
class EscapeString(str, EscapeData): class EscapeString(bytes, EscapeData):
""" """
A string that should be HTML-escaped when output. A string that should be HTML-escaped when output.
""" """
pass pass
class EscapeUnicode(unicode, EscapeData): class EscapeUnicode(six.text_type, EscapeData):
""" """
A unicode object that should be HTML-escaped when output. A unicode object that should be HTML-escaped when output.
""" """
@ -24,7 +25,7 @@ class EscapeUnicode(unicode, EscapeData):
class SafeData(object): class SafeData(object):
pass pass
class SafeString(str, SafeData): class SafeString(bytes, SafeData):
""" """
A string subclass that has been specifically marked as "safe" (requires no A string subclass that has been specifically marked as "safe" (requires no
further escaping) for HTML output purposes. further escaping) for HTML output purposes.
@ -49,14 +50,14 @@ class SafeString(str, SafeData):
""" """
method = kwargs.pop('method') method = kwargs.pop('method')
data = method(self, *args, **kwargs) data = method(self, *args, **kwargs)
if isinstance(data, str): if isinstance(data, bytes):
return SafeString(data) return SafeString(data)
else: else:
return SafeUnicode(data) return SafeUnicode(data)
decode = curry(_proxy_method, method = str.decode) decode = curry(_proxy_method, method=bytes.decode)
class SafeUnicode(unicode, SafeData): class SafeUnicode(six.text_type, SafeData):
""" """
A unicode subclass that has been specifically marked as "safe" for HTML A unicode subclass that has been specifically marked as "safe" for HTML
output purposes. output purposes.
@ -79,12 +80,12 @@ class SafeUnicode(unicode, SafeData):
""" """
method = kwargs.pop('method') method = kwargs.pop('method')
data = method(self, *args, **kwargs) data = method(self, *args, **kwargs)
if isinstance(data, str): if isinstance(data, bytes):
return SafeString(data) return SafeString(data)
else: else:
return SafeUnicode(data) return SafeUnicode(data)
encode = curry(_proxy_method, method = unicode.encode) encode = curry(_proxy_method, method=six.text_type.encode)
def mark_safe(s): def mark_safe(s):
""" """
@ -95,11 +96,11 @@ def mark_safe(s):
""" """
if isinstance(s, SafeData): if isinstance(s, SafeData):
return s return s
if isinstance(s, str) or (isinstance(s, Promise) and s._delegate_str): if isinstance(s, bytes) or (isinstance(s, Promise) and s._delegate_str):
return SafeString(s) return SafeString(s)
if isinstance(s, (unicode, Promise)): if isinstance(s, (six.text_type, Promise)):
return SafeUnicode(s) return SafeUnicode(s)
return SafeString(str(s)) return SafeString(bytes(s))
def mark_for_escaping(s): def mark_for_escaping(s):
""" """
@ -111,9 +112,9 @@ def mark_for_escaping(s):
""" """
if isinstance(s, (SafeData, EscapeData)): if isinstance(s, (SafeData, EscapeData)):
return s return s
if isinstance(s, str) or (isinstance(s, Promise) and s._delegate_str): if isinstance(s, bytes) or (isinstance(s, Promise) and s._delegate_str):
return EscapeString(s) return EscapeString(s)
if isinstance(s, (unicode, Promise)): if isinstance(s, (six.text_type, Promise)):
return EscapeUnicode(s) return EscapeUnicode(s)
return EscapeString(str(s)) return EscapeString(bytes(s))

View File

@ -9,11 +9,12 @@ from io import BytesIO
from django.utils.encoding import force_unicode from django.utils.encoding import force_unicode
from django.utils.functional import allow_lazy, SimpleLazyObject from django.utils.functional import allow_lazy, SimpleLazyObject
from django.utils import six
from django.utils.translation import ugettext_lazy, ugettext as _, pgettext from django.utils.translation import ugettext_lazy, ugettext as _, pgettext
# Capitalizes the first letter of a string. # Capitalizes the first letter of a string.
capfirst = lambda x: x and force_unicode(x)[0].upper() + force_unicode(x)[1:] capfirst = lambda x: x and force_unicode(x)[0].upper() + force_unicode(x)[1:]
capfirst = allow_lazy(capfirst, unicode) capfirst = allow_lazy(capfirst, six.text_type)
# Set up regular expressions # Set up regular expressions
re_words = re.compile(r'&.*?;|<.*?>|(\w[\w-]*)', re.U|re.S) re_words = re.compile(r'&.*?;|<.*?>|(\w[\w-]*)', re.U|re.S)
@ -46,7 +47,7 @@ def wrap(text, width):
pos = len(lines[-1]) pos = len(lines[-1])
yield word yield word
return ''.join(_generator()) return ''.join(_generator())
wrap = allow_lazy(wrap, unicode) wrap = allow_lazy(wrap, six.text_type)
class Truncator(SimpleLazyObject): class Truncator(SimpleLazyObject):
@ -207,14 +208,14 @@ def truncate_words(s, num, end_text='...'):
'in django.utils.text instead.', category=DeprecationWarning) 'in django.utils.text instead.', category=DeprecationWarning)
truncate = end_text and ' %s' % end_text or '' truncate = end_text and ' %s' % end_text or ''
return Truncator(s).words(num, truncate=truncate) return Truncator(s).words(num, truncate=truncate)
truncate_words = allow_lazy(truncate_words, unicode) truncate_words = allow_lazy(truncate_words, six.text_type)
def truncate_html_words(s, num, end_text='...'): def truncate_html_words(s, num, end_text='...'):
warnings.warn('This function has been deprecated. Use the Truncator class ' warnings.warn('This function has been deprecated. Use the Truncator class '
'in django.utils.text instead.', category=DeprecationWarning) 'in django.utils.text instead.', category=DeprecationWarning)
truncate = end_text and ' %s' % end_text or '' truncate = end_text and ' %s' % end_text or ''
return Truncator(s).words(num, truncate=truncate, html=True) return Truncator(s).words(num, truncate=truncate, html=True)
truncate_html_words = allow_lazy(truncate_html_words, unicode) truncate_html_words = allow_lazy(truncate_html_words, six.text_type)
def get_valid_filename(s): def get_valid_filename(s):
""" """
@ -227,7 +228,7 @@ def get_valid_filename(s):
""" """
s = force_unicode(s).strip().replace(' ', '_') s = force_unicode(s).strip().replace(' ', '_')
return re.sub(r'(?u)[^-\w.]', '', s) return re.sub(r'(?u)[^-\w.]', '', s)
get_valid_filename = allow_lazy(get_valid_filename, unicode) get_valid_filename = allow_lazy(get_valid_filename, six.text_type)
def get_text_list(list_, last_word=ugettext_lazy('or')): def get_text_list(list_, last_word=ugettext_lazy('or')):
""" """
@ -248,11 +249,11 @@ def get_text_list(list_, last_word=ugettext_lazy('or')):
# Translators: This string is used as a separator between list elements # Translators: This string is used as a separator between list elements
_(', ').join([force_unicode(i) for i in list_][:-1]), _(', ').join([force_unicode(i) for i in list_][:-1]),
force_unicode(last_word), force_unicode(list_[-1])) force_unicode(last_word), force_unicode(list_[-1]))
get_text_list = allow_lazy(get_text_list, unicode) get_text_list = allow_lazy(get_text_list, six.text_type)
def normalize_newlines(text): def normalize_newlines(text):
return force_unicode(re.sub(r'\r\n|\r|\n', '\n', text)) return force_unicode(re.sub(r'\r\n|\r|\n', '\n', text))
normalize_newlines = allow_lazy(normalize_newlines, unicode) normalize_newlines = allow_lazy(normalize_newlines, six.text_type)
def recapitalize(text): def recapitalize(text):
"Recapitalizes text, placing caps after end-of-sentence punctuation." "Recapitalizes text, placing caps after end-of-sentence punctuation."
@ -288,9 +289,9 @@ def javascript_quote(s, quote_double_quotes=False):
def fix(match): def fix(match):
return b"\u%04x" % ord(match.group(1)) return b"\u%04x" % ord(match.group(1))
if type(s) == str: if type(s) == bytes:
s = s.decode('utf-8') s = s.decode('utf-8')
elif type(s) != unicode: elif type(s) != six.text_type:
raise TypeError(s) raise TypeError(s)
s = s.replace('\\', '\\\\') s = s.replace('\\', '\\\\')
s = s.replace('\r', '\\r') s = s.replace('\r', '\\r')
@ -300,7 +301,7 @@ def javascript_quote(s, quote_double_quotes=False):
if quote_double_quotes: if quote_double_quotes:
s = s.replace('"', '&quot;') s = s.replace('"', '&quot;')
return str(ustring_re.sub(fix, s)) return str(ustring_re.sub(fix, s))
javascript_quote = allow_lazy(javascript_quote, unicode) javascript_quote = allow_lazy(javascript_quote, six.text_type)
# Expression to match some_token and some_token="with spaces" (and similarly # Expression to match some_token and some_token="with spaces" (and similarly
# for single-quoted strings). # for single-quoted strings).
@ -332,7 +333,7 @@ def smart_split(text):
text = force_unicode(text) text = force_unicode(text)
for bit in smart_split_re.finditer(text): for bit in smart_split_re.finditer(text):
yield bit.group(0) yield bit.group(0)
smart_split = allow_lazy(smart_split, unicode) smart_split = allow_lazy(smart_split, six.text_type)
def _replace_entity(match): def _replace_entity(match):
text = match.group(1) text = match.group(1)
@ -356,7 +357,7 @@ _entity_re = re.compile(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));")
def unescape_entities(text): def unescape_entities(text):
return _entity_re.sub(_replace_entity, text) return _entity_re.sub(_replace_entity, text)
unescape_entities = allow_lazy(unescape_entities, unicode) unescape_entities = allow_lazy(unescape_entities, six.text_type)
def unescape_string_literal(s): def unescape_string_literal(s):
r""" r"""

View File

@ -5,6 +5,7 @@ from __future__ import unicode_literals
from django.utils.encoding import force_unicode from django.utils.encoding import force_unicode
from django.utils.functional import lazy from django.utils.functional import lazy
from django.utils import six
__all__ = [ __all__ = [
@ -78,12 +79,12 @@ def pgettext(context, message):
def npgettext(context, singular, plural, number): def npgettext(context, singular, plural, number):
return _trans.npgettext(context, singular, plural, number) return _trans.npgettext(context, singular, plural, number)
ngettext_lazy = lazy(ngettext, str) ngettext_lazy = lazy(ngettext, bytes)
gettext_lazy = lazy(gettext, str) gettext_lazy = lazy(gettext, bytes)
ungettext_lazy = lazy(ungettext, unicode) ungettext_lazy = lazy(ungettext, six.text_type)
ugettext_lazy = lazy(ugettext, unicode) ugettext_lazy = lazy(ugettext, six.text_type)
pgettext_lazy = lazy(pgettext, unicode) pgettext_lazy = lazy(pgettext, six.text_type)
npgettext_lazy = lazy(npgettext, unicode) npgettext_lazy = lazy(npgettext, six.text_type)
def activate(language): def activate(language):
return _trans.activate(language) return _trans.activate(language)
@ -139,7 +140,7 @@ def _string_concat(*strings):
constructed from multiple parts. constructed from multiple parts.
""" """
return ''.join([force_unicode(s) for s in strings]) return ''.join([force_unicode(s) for s in strings])
string_concat = lazy(_string_concat, unicode) string_concat = lazy(_string_concat, six.text_type)
def get_language_info(lang_code): def get_language_info(lang_code):
from django.conf.locale import LANG_INFO from django.conf.locale import LANG_INFO

View File

@ -362,7 +362,7 @@ class ExceptionReporter(object):
if match: if match:
encoding = match.group(1) encoding = match.group(1)
break break
source = [unicode(sline, encoding, 'replace') for sline in source] source = [six.text_type(sline, encoding, 'replace') for sline in source]
lower_bound = max(0, lineno - context_lines) lower_bound = max(0, lineno - context_lines)
upper_bound = lineno + context_lines upper_bound = lineno + context_lines

View File

@ -2,6 +2,7 @@ from __future__ import absolute_import
from django.core.exceptions import FieldError from django.core.exceptions import FieldError
from django.test import TestCase from django.test import TestCase
from django.utils import six
from .models import Author, Article from .models import Author, Article
@ -22,13 +23,13 @@ class CustomColumnsTests(TestCase):
Author.objects.all(), [ Author.objects.all(), [
"Peter Jones", "John Smith", "Peter Jones", "John Smith",
], ],
unicode six.text_type
) )
self.assertQuerysetEqual( self.assertQuerysetEqual(
Author.objects.filter(first_name__exact="John"), [ Author.objects.filter(first_name__exact="John"), [
"John Smith", "John Smith",
], ],
unicode six.text_type
) )
self.assertEqual( self.assertEqual(
Author.objects.get(first_name__exact="John"), Author.objects.get(first_name__exact="John"),
@ -55,7 +56,7 @@ class CustomColumnsTests(TestCase):
"Peter Jones", "Peter Jones",
"John Smith", "John Smith",
], ],
unicode six.text_type
) )
# Get the articles for an author # Get the articles for an author
self.assertQuerysetEqual( self.assertQuerysetEqual(
@ -69,5 +70,5 @@ class CustomColumnsTests(TestCase):
art.authors.filter(last_name='Jones'), [ art.authors.filter(last_name='Jones'), [
"Peter Jones" "Peter Jones"
], ],
unicode six.text_type
) )

View File

@ -1,6 +1,7 @@
from __future__ import absolute_import from __future__ import absolute_import
from django.test import TestCase from django.test import TestCase
from django.utils import six
from .models import Person, Book, Car, PersonManager, PublishedBookManager from .models import Person, Book, Car, PersonManager, PublishedBookManager
@ -14,7 +15,7 @@ class CustomManagerTests(TestCase):
Person.objects.get_fun_people(), [ Person.objects.get_fun_people(), [
"Bugs Bunny" "Bugs Bunny"
], ],
unicode six.text_type
) )
# The RelatedManager used on the 'books' descriptor extends the default # The RelatedManager used on the 'books' descriptor extends the default
# manager # manager

View File

@ -2,6 +2,7 @@ import random
import string import string
from django.db import models from django.db import models
from django.utils import six
class MyWrapper(object): class MyWrapper(object):
@ -44,12 +45,12 @@ class MyAutoField(models.CharField):
if not value: if not value:
return return
if isinstance(value, MyWrapper): if isinstance(value, MyWrapper):
return unicode(value) return six.text_type(value)
return value return value
def get_db_prep_value(self, value, connection, prepared=False): def get_db_prep_value(self, value, connection, prepared=False):
if not value: if not value:
return return
if isinstance(value, MyWrapper): if isinstance(value, MyWrapper):
return unicode(value) return six.text_type(value)
return value return value

View File

@ -3,6 +3,7 @@ from __future__ import absolute_import, unicode_literals
from django.db import transaction, IntegrityError from django.db import transaction, IntegrityError
from django.test import TestCase, skipIfDBFeature from django.test import TestCase, skipIfDBFeature
from django.utils import six
from .models import Employee, Business, Bar, Foo from .models import Employee, Business, Bar, Foo
@ -16,7 +17,7 @@ class CustomPKTests(TestCase):
Employee.objects.all(), [ Employee.objects.all(), [
"Dan Jones", "Dan Jones",
], ],
unicode six.text_type
) )
fran = Employee.objects.create( fran = Employee.objects.create(
@ -27,7 +28,7 @@ class CustomPKTests(TestCase):
"Fran Bones", "Fran Bones",
"Dan Jones", "Dan Jones",
], ],
unicode six.text_type
) )
self.assertEqual(Employee.objects.get(pk=123), dan) self.assertEqual(Employee.objects.get(pk=123), dan)
@ -45,7 +46,7 @@ class CustomPKTests(TestCase):
"Fran Bones", "Fran Bones",
"Dan Jones", "Dan Jones",
], ],
unicode six.text_type
) )
# The primary key can be accessed via the pk property on the model. # The primary key can be accessed via the pk property on the model.
e = Employee.objects.get(pk=123) e = Employee.objects.get(pk=123)
@ -63,7 +64,7 @@ class CustomPKTests(TestCase):
"Dan Jones", "Dan Jones",
"Fran Jones", "Fran Jones",
], ],
unicode six.text_type
) )
emps = Employee.objects.in_bulk([123, 456]) emps = Employee.objects.in_bulk([123, 456])
@ -76,7 +77,7 @@ class CustomPKTests(TestCase):
"Dan Jones", "Dan Jones",
"Fran Jones", "Fran Jones",
], ],
unicode six.text_type
) )
self.assertQuerysetEqual( self.assertQuerysetEqual(
fran.business_set.all(), [ fran.business_set.all(), [
@ -108,14 +109,14 @@ class CustomPKTests(TestCase):
"Dan Jones", "Dan Jones",
"Fran Jones", "Fran Jones",
], ],
unicode, six.text_type,
) )
self.assertQuerysetEqual( self.assertQuerysetEqual(
Employee.objects.filter(business__pk="Sears"), [ Employee.objects.filter(business__pk="Sears"), [
"Dan Jones", "Dan Jones",
"Fran Jones", "Fran Jones",
], ],
unicode, six.text_type,
) )
self.assertQuerysetEqual( self.assertQuerysetEqual(

View File

@ -3,6 +3,7 @@ from __future__ import absolute_import, unicode_literals
from django.core.exceptions import FieldError from django.core.exceptions import FieldError
from django.db.models import F from django.db.models import F
from django.test import TestCase from django.test import TestCase
from django.utils import six
from .models import Company, Employee from .models import Company, Employee
@ -156,7 +157,7 @@ class ExpressionsTests(TestCase):
"Frank Meyer", "Frank Meyer",
"Max Mustermann", "Max Mustermann",
], ],
lambda c: unicode(c.point_of_contact), lambda c: six.text_type(c.point_of_contact),
) )
c = Company.objects.all()[0] c = Company.objects.all()[0]

View File

@ -19,7 +19,7 @@ class Small(object):
return '%s%s' % (force_unicode(self.first), force_unicode(self.second)) return '%s%s' % (force_unicode(self.first), force_unicode(self.second))
def __str__(self): def __str__(self):
return unicode(self).encode('utf-8') return six.text_type(self).encode('utf-8')
class SmallField(models.Field): class SmallField(models.Field):
""" """
@ -42,7 +42,7 @@ class SmallField(models.Field):
return Small(value[0], value[1]) return Small(value[0], value[1])
def get_db_prep_save(self, value, connection): def get_db_prep_save(self, value, connection):
return unicode(value) return six.text_type(value)
def get_prep_lookup(self, lookup_type, value): def get_prep_lookup(self, lookup_type, value):
if lookup_type == 'exact': if lookup_type == 'exact':

View File

@ -7,6 +7,7 @@ This demonstrates features of the database API.
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models from django.db import models
from django.utils import six
class Author(models.Model): class Author(models.Model):
@ -35,7 +36,7 @@ class Season(models.Model):
gt = models.IntegerField(null=True, blank=True) gt = models.IntegerField(null=True, blank=True)
def __unicode__(self): def __unicode__(self):
return unicode(self.year) return six.text_type(self.year)
class Game(models.Model): class Game(models.Model):
season = models.ForeignKey(Season, related_name='games') season = models.ForeignKey(Season, related_name='games')

View File

@ -6,6 +6,7 @@ Make sure to set ``related_name`` if you use relationships to the same table.
from __future__ import unicode_literals from __future__ import unicode_literals
from django.db import models from django.db import models
from django.utils import six
class User(models.Model): class User(models.Model):
@ -17,7 +18,7 @@ class Issue(models.Model):
client = models.ForeignKey(User, related_name='test_issue_client') client = models.ForeignKey(User, related_name='test_issue_client')
def __unicode__(self): def __unicode__(self):
return unicode(self.num) return six.text_type(self.num)
class Meta: class Meta:
ordering = ('num',) ordering = ('num',)

View File

@ -3,6 +3,7 @@ from __future__ import absolute_import
from datetime import datetime from datetime import datetime
from django.test import TestCase from django.test import TestCase
from django.utils import six
from .models import Reporter, Article, Writer from .models import Reporter, Article, Writer
@ -24,7 +25,7 @@ class M2MIntermediaryTests(TestCase):
("John Smith", "Main writer"), ("John Smith", "Main writer"),
("Jane Doe", "Contributor"), ("Jane Doe", "Contributor"),
], ],
lambda w: (unicode(w.reporter), w.position) lambda w: (six.text_type(w.reporter), w.position)
) )
self.assertEqual(w1.reporter, r1) self.assertEqual(w1.reporter, r1)
self.assertEqual(w2.reporter, r2) self.assertEqual(w2.reporter, r2)
@ -36,5 +37,5 @@ class M2MIntermediaryTests(TestCase):
r1.writer_set.all(), [ r1.writer_set.all(), [
("John Smith", "Main writer") ("John Smith", "Main writer")
], ],
lambda w: (unicode(w.reporter), w.position) lambda w: (six.text_type(w.reporter), w.position)
) )

View File

@ -5,6 +5,7 @@ from datetime import datetime
from django.core.exceptions import MultipleObjectsReturned, FieldError from django.core.exceptions import MultipleObjectsReturned, FieldError
from django.test import TestCase from django.test import TestCase
from django.utils import six
from django.utils.translation import ugettext_lazy from django.utils.translation import ugettext_lazy
from .models import Article, Reporter from .models import Article, Reporter
@ -421,7 +422,7 @@ class ManyToOneTests(TestCase):
lazy = ugettext_lazy('test') lazy = ugettext_lazy('test')
reporter.article_set.create(headline=lazy, reporter.article_set.create(headline=lazy,
pub_date=datetime(2011, 6, 10)) pub_date=datetime(2011, 6, 10))
notlazy = unicode(lazy) notlazy = six.text_type(lazy)
article = reporter.article_set.get() article = reporter.article_set.get()
self.assertEqual(article.headline, notlazy) self.assertEqual(article.headline, notlazy)

View File

@ -13,6 +13,7 @@ import tempfile
from django.core.files.storage import FileSystemStorage from django.core.files.storage import FileSystemStorage
from django.db import models from django.db import models
from django.utils import six
temp_storage_dir = tempfile.mkdtemp(dir=os.environ['DJANGO_TEST_TEMP_DIR']) temp_storage_dir = tempfile.mkdtemp(dir=os.environ['DJANGO_TEST_TEMP_DIR'])
@ -226,7 +227,7 @@ class BigInt(models.Model):
biggie = models.BigIntegerField() biggie = models.BigIntegerField()
def __unicode__(self): def __unicode__(self):
return unicode(self.biggie) return six.text_type(self.biggie)
class MarkupField(models.CharField): class MarkupField(models.CharField):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):

View File

@ -11,6 +11,7 @@ from django.db import connection
from django.forms.models import model_to_dict from django.forms.models import model_to_dict
from django.utils.unittest import skipUnless from django.utils.unittest import skipUnless
from django.test import TestCase from django.test import TestCase
from django.utils import six
from .models import (Article, ArticleStatus, BetterWriter, BigInt, Book, from .models import (Article, ArticleStatus, BetterWriter, BigInt, Book,
Category, CommaSeparatedInteger, CustomFieldForExclusionModel, DerivedBook, Category, CommaSeparatedInteger, CustomFieldForExclusionModel, DerivedBook,
@ -653,7 +654,7 @@ class OldFormForXTests(TestCase):
# ManyToManyFields are represented by a MultipleChoiceField, ForeignKeys and any # ManyToManyFields are represented by a MultipleChoiceField, ForeignKeys and any
# fields with the 'choices' attribute are represented by a ChoiceField. # fields with the 'choices' attribute are represented by a ChoiceField.
f = ArticleForm(auto_id=False) f = ArticleForm(auto_id=False)
self.assertHTMLEqual(unicode(f), '''<tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr> self.assertHTMLEqual(six.text_type(f), '''<tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr>
<tr><th>Slug:</th><td><input type="text" name="slug" maxlength="50" /></td></tr> <tr><th>Slug:</th><td><input type="text" name="slug" maxlength="50" /></td></tr>
<tr><th>Pub date:</th><td><input type="text" name="pub_date" /></td></tr> <tr><th>Pub date:</th><td><input type="text" name="pub_date" /></td></tr>
<tr><th>Writer:</th><td><select name="writer"> <tr><th>Writer:</th><td><select name="writer">
@ -681,14 +682,14 @@ class OldFormForXTests(TestCase):
# a value of None. If a field isn't specified on a form, the object created # a value of None. If a field isn't specified on a form, the object created
# from the form can't provide a value for that field! # from the form can't provide a value for that field!
f = PartialArticleForm(auto_id=False) f = PartialArticleForm(auto_id=False)
self.assertHTMLEqual(unicode(f), '''<tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr> self.assertHTMLEqual(six.text_type(f), '''<tr><th>Headline:</th><td><input type="text" name="headline" maxlength="50" /></td></tr>
<tr><th>Pub date:</th><td><input type="text" name="pub_date" /></td></tr>''') <tr><th>Pub date:</th><td><input type="text" name="pub_date" /></td></tr>''')
# When the ModelForm is passed an instance, that instance's current values are # When the ModelForm is passed an instance, that instance's current values are
# inserted as 'initial' data in each Field. # inserted as 'initial' data in each Field.
w = Writer.objects.get(name='Mike Royko') w = Writer.objects.get(name='Mike Royko')
f = RoykoForm(auto_id=False, instance=w) f = RoykoForm(auto_id=False, instance=w)
self.assertHTMLEqual(unicode(f), '''<tr><th>Name:</th><td><input type="text" name="name" value="Mike Royko" maxlength="50" /><br /><span class="helptext">Use both first and last names.</span></td></tr>''') self.assertHTMLEqual(six.text_type(f), '''<tr><th>Name:</th><td><input type="text" name="name" value="Mike Royko" maxlength="50" /><br /><span class="helptext">Use both first and last names.</span></td></tr>''')
art = Article( art = Article(
headline='Test article', headline='Test article',
@ -725,7 +726,7 @@ class OldFormForXTests(TestCase):
'headline': 'Test headline', 'headline': 'Test headline',
'slug': 'test-headline', 'slug': 'test-headline',
'pub_date': '1984-02-06', 'pub_date': '1984-02-06',
'writer': unicode(w_royko.pk), 'writer': six.text_type(w_royko.pk),
'article': 'Hello.' 'article': 'Hello.'
}, instance=art) }, instance=art)
self.assertEqual(f.errors, {}) self.assertEqual(f.errors, {})
@ -808,9 +809,9 @@ class OldFormForXTests(TestCase):
'headline': 'New headline', 'headline': 'New headline',
'slug': 'new-headline', 'slug': 'new-headline',
'pub_date': '1988-01-04', 'pub_date': '1988-01-04',
'writer': unicode(w_royko.pk), 'writer': six.text_type(w_royko.pk),
'article': 'Hello.', 'article': 'Hello.',
'categories': [unicode(c1.id), unicode(c2.id)] 'categories': [six.text_type(c1.id), six.text_type(c2.id)]
}, instance=new_art) }, instance=new_art)
new_art = f.save() new_art = f.save()
self.assertEqual(new_art.id == art_id_1, True) self.assertEqual(new_art.id == art_id_1, True)
@ -820,7 +821,7 @@ class OldFormForXTests(TestCase):
# Now, submit form data with no categories. This deletes the existing categories. # Now, submit form data with no categories. This deletes the existing categories.
f = TestArticleForm({'headline': 'New headline', 'slug': 'new-headline', 'pub_date': '1988-01-04', f = TestArticleForm({'headline': 'New headline', 'slug': 'new-headline', 'pub_date': '1988-01-04',
'writer': unicode(w_royko.pk), 'article': 'Hello.'}, instance=new_art) 'writer': six.text_type(w_royko.pk), 'article': 'Hello.'}, instance=new_art)
new_art = f.save() new_art = f.save()
self.assertEqual(new_art.id == art_id_1, True) self.assertEqual(new_art.id == art_id_1, True)
new_art = Article.objects.get(id=art_id_1) new_art = Article.objects.get(id=art_id_1)
@ -828,7 +829,7 @@ class OldFormForXTests(TestCase):
# Create a new article, with categories, via the form. # Create a new article, with categories, via the form.
f = ArticleForm({'headline': 'The walrus was Paul', 'slug': 'walrus-was-paul', 'pub_date': '1967-11-01', f = ArticleForm({'headline': 'The walrus was Paul', 'slug': 'walrus-was-paul', 'pub_date': '1967-11-01',
'writer': unicode(w_royko.pk), 'article': 'Test.', 'categories': [unicode(c1.id), unicode(c2.id)]}) 'writer': six.text_type(w_royko.pk), 'article': 'Test.', 'categories': [six.text_type(c1.id), six.text_type(c2.id)]})
new_art = f.save() new_art = f.save()
art_id_2 = new_art.id art_id_2 = new_art.id
self.assertEqual(art_id_2 not in (None, art_id_1), True) self.assertEqual(art_id_2 not in (None, art_id_1), True)
@ -837,7 +838,7 @@ class OldFormForXTests(TestCase):
# Create a new article, with no categories, via the form. # Create a new article, with no categories, via the form.
f = ArticleForm({'headline': 'The walrus was Paul', 'slug': 'walrus-was-paul', 'pub_date': '1967-11-01', f = ArticleForm({'headline': 'The walrus was Paul', 'slug': 'walrus-was-paul', 'pub_date': '1967-11-01',
'writer': unicode(w_royko.pk), 'article': 'Test.'}) 'writer': six.text_type(w_royko.pk), 'article': 'Test.'})
new_art = f.save() new_art = f.save()
art_id_3 = new_art.id art_id_3 = new_art.id
self.assertEqual(art_id_3 not in (None, art_id_1, art_id_2), True) self.assertEqual(art_id_3 not in (None, art_id_1, art_id_2), True)
@ -847,7 +848,7 @@ class OldFormForXTests(TestCase):
# Create a new article, with categories, via the form, but use commit=False. # Create a new article, with categories, via the form, but use commit=False.
# The m2m data won't be saved until save_m2m() is invoked on the form. # The m2m data won't be saved until save_m2m() is invoked on the form.
f = ArticleForm({'headline': 'The walrus was Paul', 'slug': 'walrus-was-paul', 'pub_date': '1967-11-01', f = ArticleForm({'headline': 'The walrus was Paul', 'slug': 'walrus-was-paul', 'pub_date': '1967-11-01',
'writer': unicode(w_royko.pk), 'article': 'Test.', 'categories': [unicode(c1.id), unicode(c2.id)]}) 'writer': six.text_type(w_royko.pk), 'article': 'Test.', 'categories': [six.text_type(c1.id), six.text_type(c2.id)]})
new_art = f.save(commit=False) new_art = f.save(commit=False)
# Manually save the instance # Manually save the instance
@ -1091,12 +1092,12 @@ class OldFormForXTests(TestCase):
<p><label for="id_age">Age:</label> <input type="text" name="age" id="id_age" /></p>''' % (w_woodward.pk, w_bernstein.pk, bw.pk, w_royko.pk)) <p><label for="id_age">Age:</label> <input type="text" name="age" id="id_age" /></p>''' % (w_woodward.pk, w_bernstein.pk, bw.pk, w_royko.pk))
data = { data = {
'writer': unicode(w_woodward.pk), 'writer': six.text_type(w_woodward.pk),
'age': '65', 'age': '65',
} }
form = WriterProfileForm(data) form = WriterProfileForm(data)
instance = form.save() instance = form.save()
self.assertEqual(unicode(instance), 'Bob Woodward is 65') self.assertEqual(six.text_type(instance), 'Bob Woodward is 65')
form = WriterProfileForm(instance=instance) form = WriterProfileForm(instance=instance)
self.assertHTMLEqual(form.as_p(), '''<p><label for="id_writer">Writer:</label> <select name="writer" id="id_writer"> self.assertHTMLEqual(form.as_p(), '''<p><label for="id_writer">Writer:</label> <select name="writer" id="id_writer">
@ -1376,7 +1377,7 @@ class OldFormForXTests(TestCase):
# Similar to a regular Form class you can define custom media to be used on # Similar to a regular Form class you can define custom media to be used on
# the ModelForm. # the ModelForm.
f = ModelFormWithMedia() f = ModelFormWithMedia()
self.assertHTMLEqual(unicode(f.media), '''<link href="/some/form/css" type="text/css" media="all" rel="stylesheet" /> self.assertHTMLEqual(six.text_type(f.media), '''<link href="/some/form/css" type="text/css" media="all" rel="stylesheet" />
<script type="text/javascript" src="/some/form/javascript"></script>''') <script type="text/javascript" src="/some/form/javascript"></script>''')
f = CommaSeparatedIntegerForm({'field': '1,2,3'}) f = CommaSeparatedIntegerForm({'field': '1,2,3'})
@ -1445,7 +1446,7 @@ class OldFormForXTests(TestCase):
(22, 'Pear'))) (22, 'Pear')))
form = InventoryForm(instance=core) form = InventoryForm(instance=core)
self.assertHTMLEqual(unicode(form['parent']), '''<select name="parent" id="id_parent"> self.assertHTMLEqual(six.text_type(form['parent']), '''<select name="parent" id="id_parent">
<option value="">---------</option> <option value="">---------</option>
<option value="86" selected="selected">Apple</option> <option value="86" selected="selected">Apple</option>
<option value="87">Core</option> <option value="87">Core</option>
@ -1466,7 +1467,7 @@ class OldFormForXTests(TestCase):
self.assertEqual(CategoryForm.base_fields.keys(), self.assertEqual(CategoryForm.base_fields.keys(),
['description', 'url']) ['description', 'url'])
self.assertHTMLEqual(unicode(CategoryForm()), '''<tr><th><label for="id_description">Description:</label></th><td><input type="text" name="description" id="id_description" /></td></tr> self.assertHTMLEqual(six.text_type(CategoryForm()), '''<tr><th><label for="id_description">Description:</label></th><td><input type="text" name="description" id="id_description" /></td></tr>
<tr><th><label for="id_url">The URL:</label></th><td><input id="id_url" type="text" name="url" maxlength="40" /></td></tr>''') <tr><th><label for="id_url">The URL:</label></th><td><input id="id_url" type="text" name="url" maxlength="40" /></td></tr>''')
# to_field_name should also work on ModelMultipleChoiceField ################## # to_field_name should also work on ModelMultipleChoiceField ##################
@ -1481,5 +1482,5 @@ class OldFormForXTests(TestCase):
def test_model_field_that_returns_none_to_exclude_itself_with_explicit_fields(self): def test_model_field_that_returns_none_to_exclude_itself_with_explicit_fields(self):
self.assertEqual(CustomFieldForExclusionForm.base_fields.keys(), ['name']) self.assertEqual(CustomFieldForExclusionForm.base_fields.keys(), ['name'])
self.assertHTMLEqual(unicode(CustomFieldForExclusionForm()), self.assertHTMLEqual(six.text_type(CustomFieldForExclusionForm()),
'''<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="10" /></td></tr>''') '''<tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="10" /></td></tr>''')

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
import datetime import datetime
from django.db import models from django.db import models
from django.utils import six
class Author(models.Model): class Author(models.Model):
@ -149,7 +150,7 @@ class Revision(models.Model):
unique_together = (("repository", "revision"),) unique_together = (("repository", "revision"),)
def __unicode__(self): def __unicode__(self):
return "%s (%s)" % (self.revision, unicode(self.repository)) return "%s (%s)" % (self.revision, six.text_type(self.repository))
# models for testing callable defaults (see bug #7975). If you define a model # models for testing callable defaults (see bug #7975). If you define a model
# with a callable default value, you cannot rely on the initial value in a # with a callable default value, you cannot rely on the initial value in a

View File

@ -10,6 +10,7 @@ from django.db import models
from django.forms.models import (_get_foreign_key, inlineformset_factory, from django.forms.models import (_get_foreign_key, inlineformset_factory,
modelformset_factory) modelformset_factory)
from django.test import TestCase, skipUnlessDBFeature from django.test import TestCase, skipUnlessDBFeature
from django.utils import six
from .models import (Author, BetterAuthor, Book, BookWithCustomPK, from .models import (Author, BetterAuthor, Book, BookWithCustomPK,
BookWithOptionalAltEditor, AlternateBook, AuthorMeeting, CustomPrimaryKey, BookWithOptionalAltEditor, AlternateBook, AuthorMeeting, CustomPrimaryKey,
@ -72,7 +73,7 @@ class DeletionTests(TestCase):
'form-TOTAL_FORMS': '1', 'form-TOTAL_FORMS': '1',
'form-INITIAL_FORMS': '1', 'form-INITIAL_FORMS': '1',
'form-MAX_NUM_FORMS': '0', 'form-MAX_NUM_FORMS': '0',
'form-0-id': unicode(poet.id), 'form-0-id': six.text_type(poet.id),
'form-0-name': 'x' * 1000, 'form-0-name': 'x' * 1000,
} }
formset = PoetFormSet(data, queryset=Poet.objects.all()) formset = PoetFormSet(data, queryset=Poet.objects.all())
@ -772,7 +773,7 @@ class ModelFormsetTest(TestCase):
'owner_set-TOTAL_FORMS': '3', 'owner_set-TOTAL_FORMS': '3',
'owner_set-INITIAL_FORMS': '1', 'owner_set-INITIAL_FORMS': '1',
'owner_set-MAX_NUM_FORMS': '', 'owner_set-MAX_NUM_FORMS': '',
'owner_set-0-auto_id': unicode(owner1.auto_id), 'owner_set-0-auto_id': six.text_type(owner1.auto_id),
'owner_set-0-name': 'Joe Perry', 'owner_set-0-name': 'Joe Perry',
'owner_set-1-auto_id': '', 'owner_set-1-auto_id': '',
'owner_set-1-name': 'Jack Berry', 'owner_set-1-name': 'Jack Berry',
@ -835,7 +836,7 @@ class ModelFormsetTest(TestCase):
'ownerprofile-TOTAL_FORMS': '1', 'ownerprofile-TOTAL_FORMS': '1',
'ownerprofile-INITIAL_FORMS': '1', 'ownerprofile-INITIAL_FORMS': '1',
'ownerprofile-MAX_NUM_FORMS': '1', 'ownerprofile-MAX_NUM_FORMS': '1',
'ownerprofile-0-owner': unicode(owner1.auto_id), 'ownerprofile-0-owner': six.text_type(owner1.auto_id),
'ownerprofile-0-age': '55', 'ownerprofile-0-age': '55',
} }
formset = FormSet(data, instance=owner1) formset = FormSet(data, instance=owner1)
@ -993,8 +994,8 @@ class ModelFormsetTest(TestCase):
'membership_set-TOTAL_FORMS': '1', 'membership_set-TOTAL_FORMS': '1',
'membership_set-INITIAL_FORMS': '0', 'membership_set-INITIAL_FORMS': '0',
'membership_set-MAX_NUM_FORMS': '', 'membership_set-MAX_NUM_FORMS': '',
'membership_set-0-date_joined': unicode(now.strftime('%Y-%m-%d %H:%M:%S')), 'membership_set-0-date_joined': six.text_type(now.strftime('%Y-%m-%d %H:%M:%S')),
'initial-membership_set-0-date_joined': unicode(now.strftime('%Y-%m-%d %H:%M:%S')), 'initial-membership_set-0-date_joined': six.text_type(now.strftime('%Y-%m-%d %H:%M:%S')),
'membership_set-0-karma': '', 'membership_set-0-karma': '',
} }
formset = FormSet(data, instance=person) formset = FormSet(data, instance=person)
@ -1007,8 +1008,8 @@ class ModelFormsetTest(TestCase):
'membership_set-TOTAL_FORMS': '1', 'membership_set-TOTAL_FORMS': '1',
'membership_set-INITIAL_FORMS': '0', 'membership_set-INITIAL_FORMS': '0',
'membership_set-MAX_NUM_FORMS': '', 'membership_set-MAX_NUM_FORMS': '',
'membership_set-0-date_joined': unicode(one_day_later.strftime('%Y-%m-%d %H:%M:%S')), 'membership_set-0-date_joined': six.text_type(one_day_later.strftime('%Y-%m-%d %H:%M:%S')),
'initial-membership_set-0-date_joined': unicode(now.strftime('%Y-%m-%d %H:%M:%S')), 'initial-membership_set-0-date_joined': six.text_type(now.strftime('%Y-%m-%d %H:%M:%S')),
'membership_set-0-karma': '', 'membership_set-0-karma': '',
} }
formset = FormSet(filled_data, instance=person) formset = FormSet(filled_data, instance=person)
@ -1029,9 +1030,9 @@ class ModelFormsetTest(TestCase):
'membership_set-TOTAL_FORMS': '1', 'membership_set-TOTAL_FORMS': '1',
'membership_set-INITIAL_FORMS': '0', 'membership_set-INITIAL_FORMS': '0',
'membership_set-MAX_NUM_FORMS': '', 'membership_set-MAX_NUM_FORMS': '',
'membership_set-0-date_joined_0': unicode(now.strftime('%Y-%m-%d')), 'membership_set-0-date_joined_0': six.text_type(now.strftime('%Y-%m-%d')),
'membership_set-0-date_joined_1': unicode(now.strftime('%H:%M:%S')), 'membership_set-0-date_joined_1': six.text_type(now.strftime('%H:%M:%S')),
'initial-membership_set-0-date_joined': unicode(now.strftime('%Y-%m-%d %H:%M:%S')), 'initial-membership_set-0-date_joined': six.text_type(now.strftime('%Y-%m-%d %H:%M:%S')),
'membership_set-0-karma': '', 'membership_set-0-karma': '',
} }
formset = FormSet(data, instance=person) formset = FormSet(data, instance=person)

View File

@ -4,6 +4,7 @@ from operator import attrgetter
from django.core.exceptions import FieldError from django.core.exceptions import FieldError
from django.test import TestCase from django.test import TestCase
from django.utils import six
from .models import (Chef, CommonInfo, ItalianRestaurant, ParkingLot, Place, from .models import (Chef, CommonInfo, ItalianRestaurant, ParkingLot, Place,
Post, Restaurant, Student, StudentWorker, Supplier, Worker, MixinModel) Post, Restaurant, Student, StudentWorker, Supplier, Worker, MixinModel)
@ -21,8 +22,8 @@ class ModelInheritanceTests(TestCase):
s = Student.objects.create(name="Pebbles", age=5, school_class="1B") s = Student.objects.create(name="Pebbles", age=5, school_class="1B")
self.assertEqual(unicode(w1), "Worker Fred") self.assertEqual(six.text_type(w1), "Worker Fred")
self.assertEqual(unicode(s), "Student Pebbles") self.assertEqual(six.text_type(s), "Student Pebbles")
# The children inherit the Meta class of their parents (if they don't # The children inherit the Meta class of their parents (if they don't
# specify their own). # specify their own).

View File

@ -3,6 +3,7 @@ Tests for the order_with_respect_to Meta attribute.
""" """
from django.db import models from django.db import models
from django.utils import six
class Question(models.Model): class Question(models.Model):
@ -16,7 +17,7 @@ class Answer(models.Model):
order_with_respect_to = 'question' order_with_respect_to = 'question'
def __unicode__(self): def __unicode__(self):
return unicode(self.text) return six.text_type(self.text)
class Post(models.Model): class Post(models.Model):
title = models.CharField(max_length=200) title = models.CharField(max_length=200)

View File

@ -4,6 +4,7 @@ from datetime import datetime
from django.core.paginator import Paginator, InvalidPage, EmptyPage from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.test import TestCase from django.test import TestCase
from django.utils import six
from .models import Article from .models import Article
@ -32,7 +33,7 @@ class PaginationTests(TestCase):
def test_first_page(self): def test_first_page(self):
paginator = Paginator(Article.objects.all(), 5) paginator = Paginator(Article.objects.all(), 5)
p = paginator.page(1) p = paginator.page(1)
self.assertEqual("<Page 1 of 2>", unicode(p)) self.assertEqual("<Page 1 of 2>", six.text_type(p))
self.assertQuerysetEqual(p.object_list, [ self.assertQuerysetEqual(p.object_list, [
"<Article: Article 1>", "<Article: Article 1>",
"<Article: Article 2>", "<Article: Article 2>",
@ -52,7 +53,7 @@ class PaginationTests(TestCase):
def test_last_page(self): def test_last_page(self):
paginator = Paginator(Article.objects.all(), 5) paginator = Paginator(Article.objects.all(), 5)
p = paginator.page(2) p = paginator.page(2)
self.assertEqual("<Page 2 of 2>", unicode(p)) self.assertEqual("<Page 2 of 2>", six.text_type(p))
self.assertQuerysetEqual(p.object_list, [ self.assertQuerysetEqual(p.object_list, [
"<Article: Article 6>", "<Article: Article 6>",
"<Article: Article 7>", "<Article: Article 7>",
@ -109,7 +110,7 @@ class PaginationTests(TestCase):
self.assertEqual(3, paginator.num_pages) self.assertEqual(3, paginator.num_pages)
self.assertEqual([1, 2, 3], paginator.page_range) self.assertEqual([1, 2, 3], paginator.page_range)
p = paginator.page(2) p = paginator.page(2)
self.assertEqual("<Page 2 of 3>", unicode(p)) self.assertEqual("<Page 2 of 3>", six.text_type(p))
self.assertEqual([4, 5, 6], p.object_list) self.assertEqual([4, 5, 6], p.object_list)
self.assertTrue(p.has_next()) self.assertTrue(p.has_next())
self.assertTrue(p.has_previous()) self.assertTrue(p.has_previous())

View File

@ -4,6 +4,7 @@ from django.contrib.contenttypes.models import ContentType
from django.db import connection from django.db import connection
from django.test import TestCase from django.test import TestCase
from django.test.utils import override_settings from django.test.utils import override_settings
from django.utils import six
from .models import (Author, Book, Reader, Qualification, Teacher, Department, from .models import (Author, Book, Reader, Qualification, Teacher, Department,
TaggedItem, Bookmark, AuthorAddress, FavoriteAuthors, AuthorWithAge, TaggedItem, Bookmark, AuthorAddress, FavoriteAuthors, AuthorWithAge,
@ -120,7 +121,7 @@ class PrefetchRelatedTests(TestCase):
""" """
with self.assertNumQueries(3): with self.assertNumQueries(3):
qs = Author.objects.prefetch_related('books__read_by') qs = Author.objects.prefetch_related('books__read_by')
lists = [[[unicode(r) for r in b.read_by.all()] lists = [[[six.text_type(r) for r in b.read_by.all()]
for b in a.books.all()] for b in a.books.all()]
for a in qs] for a in qs]
self.assertEqual(lists, self.assertEqual(lists,
@ -134,7 +135,7 @@ class PrefetchRelatedTests(TestCase):
def test_overriding_prefetch(self): def test_overriding_prefetch(self):
with self.assertNumQueries(3): with self.assertNumQueries(3):
qs = Author.objects.prefetch_related('books', 'books__read_by') qs = Author.objects.prefetch_related('books', 'books__read_by')
lists = [[[unicode(r) for r in b.read_by.all()] lists = [[[six.text_type(r) for r in b.read_by.all()]
for b in a.books.all()] for b in a.books.all()]
for a in qs] for a in qs]
self.assertEqual(lists, self.assertEqual(lists,
@ -146,7 +147,7 @@ class PrefetchRelatedTests(TestCase):
]) ])
with self.assertNumQueries(3): with self.assertNumQueries(3):
qs = Author.objects.prefetch_related('books__read_by', 'books') qs = Author.objects.prefetch_related('books__read_by', 'books')
lists = [[[unicode(r) for r in b.read_by.all()] lists = [[[six.text_type(r) for r in b.read_by.all()]
for b in a.books.all()] for b in a.books.all()]
for a in qs] for a in qs]
self.assertEqual(lists, self.assertEqual(lists,
@ -164,7 +165,7 @@ class PrefetchRelatedTests(TestCase):
# Need a double # Need a double
with self.assertNumQueries(3): with self.assertNumQueries(3):
author = Author.objects.prefetch_related('books__read_by').get(name="Charlotte") author = Author.objects.prefetch_related('books__read_by').get(name="Charlotte")
lists = [[unicode(r) for r in b.read_by.all()] lists = [[six.text_type(r) for r in b.read_by.all()]
for b in author.books.all()] for b in author.books.all()]
self.assertEqual(lists, [["Amy"], ["Belinda"]]) # Poems, Jane Eyre self.assertEqual(lists, [["Amy"], ["Belinda"]]) # Poems, Jane Eyre
@ -175,7 +176,7 @@ class PrefetchRelatedTests(TestCase):
""" """
with self.assertNumQueries(2): with self.assertNumQueries(2):
qs = Author.objects.select_related('first_book').prefetch_related('first_book__read_by') qs = Author.objects.select_related('first_book').prefetch_related('first_book__read_by')
lists = [[unicode(r) for r in a.first_book.read_by.all()] lists = [[six.text_type(r) for r in a.first_book.read_by.all()]
for a in qs] for a in qs]
self.assertEqual(lists, [["Amy"], self.assertEqual(lists, [["Amy"],
["Amy"], ["Amy"],
@ -227,7 +228,7 @@ class DefaultManagerTests(TestCase):
# qualifications, since this will do one query per teacher. # qualifications, since this will do one query per teacher.
qs = Department.objects.prefetch_related('teachers') qs = Department.objects.prefetch_related('teachers')
depts = "".join(["%s department: %s\n" % depts = "".join(["%s department: %s\n" %
(dept.name, ", ".join(unicode(t) for t in dept.teachers.all())) (dept.name, ", ".join(six.text_type(t) for t in dept.teachers.all()))
for dept in qs]) for dept in qs])
self.assertEqual(depts, self.assertEqual(depts,
@ -343,9 +344,9 @@ class MultiTableInheritanceTest(TestCase):
def test_foreignkey(self): def test_foreignkey(self):
with self.assertNumQueries(2): with self.assertNumQueries(2):
qs = AuthorWithAge.objects.prefetch_related('addresses') qs = AuthorWithAge.objects.prefetch_related('addresses')
addresses = [[unicode(address) for address in obj.addresses.all()] addresses = [[six.text_type(address) for address in obj.addresses.all()]
for obj in qs] for obj in qs]
self.assertEqual(addresses, [[unicode(self.authorAddress)], [], []]) self.assertEqual(addresses, [[six.text_type(self.authorAddress)], [], []])
def test_foreignkey_to_inherited(self): def test_foreignkey_to_inherited(self):
with self.assertNumQueries(2): with self.assertNumQueries(2):
@ -356,19 +357,19 @@ class MultiTableInheritanceTest(TestCase):
def test_m2m_to_inheriting_model(self): def test_m2m_to_inheriting_model(self):
qs = AuthorWithAge.objects.prefetch_related('books_with_year') qs = AuthorWithAge.objects.prefetch_related('books_with_year')
with self.assertNumQueries(2): with self.assertNumQueries(2):
lst = [[unicode(book) for book in author.books_with_year.all()] lst = [[six.text_type(book) for book in author.books_with_year.all()]
for author in qs] for author in qs]
qs = AuthorWithAge.objects.all() qs = AuthorWithAge.objects.all()
lst2 = [[unicode(book) for book in author.books_with_year.all()] lst2 = [[six.text_type(book) for book in author.books_with_year.all()]
for author in qs] for author in qs]
self.assertEqual(lst, lst2) self.assertEqual(lst, lst2)
qs = BookWithYear.objects.prefetch_related('aged_authors') qs = BookWithYear.objects.prefetch_related('aged_authors')
with self.assertNumQueries(2): with self.assertNumQueries(2):
lst = [[unicode(author) for author in book.aged_authors.all()] lst = [[six.text_type(author) for author in book.aged_authors.all()]
for book in qs] for book in qs]
qs = BookWithYear.objects.all() qs = BookWithYear.objects.all()
lst2 = [[unicode(author) for author in book.aged_authors.all()] lst2 = [[six.text_type(author) for author in book.aged_authors.all()]
for book in qs] for book in qs]
self.assertEqual(lst, lst2) self.assertEqual(lst, lst2)
@ -410,23 +411,23 @@ class ForeignKeyToFieldTest(TestCase):
def test_foreignkey(self): def test_foreignkey(self):
with self.assertNumQueries(2): with self.assertNumQueries(2):
qs = Author.objects.prefetch_related('addresses') qs = Author.objects.prefetch_related('addresses')
addresses = [[unicode(address) for address in obj.addresses.all()] addresses = [[six.text_type(address) for address in obj.addresses.all()]
for obj in qs] for obj in qs]
self.assertEqual(addresses, [[unicode(self.authorAddress)], [], []]) self.assertEqual(addresses, [[six.text_type(self.authorAddress)], [], []])
def test_m2m(self): def test_m2m(self):
with self.assertNumQueries(3): with self.assertNumQueries(3):
qs = Author.objects.all().prefetch_related('favorite_authors', 'favors_me') qs = Author.objects.all().prefetch_related('favorite_authors', 'favors_me')
favorites = [( favorites = [(
[unicode(i_like) for i_like in author.favorite_authors.all()], [six.text_type(i_like) for i_like in author.favorite_authors.all()],
[unicode(likes_me) for likes_me in author.favors_me.all()] [six.text_type(likes_me) for likes_me in author.favors_me.all()]
) for author in qs] ) for author in qs]
self.assertEqual( self.assertEqual(
favorites, favorites,
[ [
([unicode(self.author2)],[unicode(self.author3)]), ([six.text_type(self.author2)],[six.text_type(self.author3)]),
([unicode(self.author3)],[unicode(self.author1)]), ([six.text_type(self.author3)],[six.text_type(self.author1)]),
([unicode(self.author1)],[unicode(self.author2)]) ([six.text_type(self.author1)],[six.text_type(self.author2)])
] ]
) )

View File

@ -1,6 +1,7 @@
from __future__ import absolute_import from __future__ import absolute_import
from django.test import TestCase from django.test import TestCase
from django.utils import six
from .models import Person from .models import Person
@ -19,7 +20,7 @@ class SaveDeleteHookTests(TestCase):
Person.objects.all(), [ Person.objects.all(), [
"John Smith", "John Smith",
], ],
unicode six.text_type
) )
p.delete() p.delete()

View File

@ -10,6 +10,7 @@ from __future__ import unicode_literals
from decimal import Decimal from decimal import Decimal
from django.db import models from django.db import models
from django.utils import six
class Category(models.Model): class Category(models.Model):
@ -100,7 +101,7 @@ class TeamField(models.CharField):
super(TeamField, self).__init__(max_length=100) super(TeamField, self).__init__(max_length=100)
def get_db_prep_save(self, value, connection): def get_db_prep_save(self, value, connection):
return unicode(value.title) return six.text_type(value.title)
def to_python(self, value): def to_python(self, value):
if isinstance(value, Team): if isinstance(value, Team):

View File

@ -296,7 +296,7 @@ class XmlSerializerTestCase(SerializersTestBase, TestCase):
def _comparison_value(value): def _comparison_value(value):
# The XML serializer handles everything as strings, so comparisons # The XML serializer handles everything as strings, so comparisons
# need to be performed on the stringified value # need to be performed on the stringified value
return unicode(value) return six.text_type(value)
@staticmethod @staticmethod
def _validate_output(serial_str): def _validate_output(serial_str):

View File

@ -3,6 +3,7 @@ from __future__ import absolute_import
from django.db.models import signals from django.db.models import signals
from django.dispatch import receiver from django.dispatch import receiver
from django.test import TestCase from django.test import TestCase
from django.utils import six
from .models import Person, Car from .models import Person, Car
@ -144,7 +145,7 @@ class SignalTests(TestCase):
Person.objects.all(), [ Person.objects.all(), [
"James Jones", "James Jones",
], ],
unicode six.text_type
) )
signals.post_delete.disconnect(post_delete_test) signals.post_delete.disconnect(post_delete_test)

View File

@ -4,6 +4,7 @@ updates.
""" """
from django.db import models from django.db import models
from django.utils import six
class DataPoint(models.Model): class DataPoint(models.Model):
@ -12,14 +13,14 @@ class DataPoint(models.Model):
another_value = models.CharField(max_length=20, blank=True) another_value = models.CharField(max_length=20, blank=True)
def __unicode__(self): def __unicode__(self):
return unicode(self.name) return six.text_type(self.name)
class RelatedPoint(models.Model): class RelatedPoint(models.Model):
name = models.CharField(max_length=20) name = models.CharField(max_length=20)
data = models.ForeignKey(DataPoint) data = models.ForeignKey(DataPoint)
def __unicode__(self): def __unicode__(self):
return unicode(self.name) return six.text_type(self.name)
class A(models.Model): class A(models.Model):

View File

@ -10,6 +10,7 @@ from django.template import Context, Template
from django.test import TestCase from django.test import TestCase
from django.test.client import RequestFactory from django.test.client import RequestFactory
from django.utils import formats from django.utils import formats
from django.utils import six
from .admin import (ChildAdmin, QuartetAdmin, BandAdmin, ChordsBandAdmin, from .admin import (ChildAdmin, QuartetAdmin, BandAdmin, ChordsBandAdmin,
GroupAdmin, ParentAdmin, DynamicListDisplayChildAdmin, GroupAdmin, ParentAdmin, DynamicListDisplayChildAdmin,
@ -339,7 +340,7 @@ class ChangeListTests(TestCase):
event = Event.objects.create(date=datetime.date.today()) event = Event.objects.create(date=datetime.date.today())
response = self.client.get('/admin/admin_changelist/event/') response = self.client.get('/admin/admin_changelist/event/')
self.assertContains(response, formats.localize(event.date)) self.assertContains(response, formats.localize(event.date))
self.assertNotContains(response, unicode(event.date)) self.assertNotContains(response, six.text_type(event.date))
def test_dynamic_list_display(self): def test_dynamic_list_display(self):
""" """
@ -443,9 +444,9 @@ class ChangeListTests(TestCase):
request = self._mocked_authenticated_request('/swallow/', superuser) request = self._mocked_authenticated_request('/swallow/', superuser)
response = model_admin.changelist_view(request) response = model_admin.changelist_view(request)
# just want to ensure it doesn't blow up during rendering # just want to ensure it doesn't blow up during rendering
self.assertContains(response, unicode(swallow.origin)) self.assertContains(response, six.text_type(swallow.origin))
self.assertContains(response, unicode(swallow.load)) self.assertContains(response, six.text_type(swallow.load))
self.assertContains(response, unicode(swallow.speed)) self.assertContains(response, six.text_type(swallow.speed))
def test_deterministic_order_for_unordered_model(self): def test_deterministic_order_for_unordered_model(self):
""" """

View File

@ -1,4 +1,5 @@
from django.db import models from django.db import models
from django.utils import six
class Article(models.Model): class Article(models.Model):
@ -22,7 +23,7 @@ class Count(models.Model):
parent = models.ForeignKey('self', null=True) parent = models.ForeignKey('self', null=True)
def __unicode__(self): def __unicode__(self):
return unicode(self.num) return six.text_type(self.num)
class Event(models.Model): class Event(models.Model):
date = models.DateTimeField(auto_now_add=True) date = models.DateTimeField(auto_now_add=True)

View File

@ -15,6 +15,7 @@ from django.test import TestCase
from django.utils import unittest from django.utils import unittest
from django.utils.formats import localize from django.utils.formats import localize
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils import six
from .models import Article, Count, Event, Location from .models import Article, Count, Event, Location
@ -249,17 +250,17 @@ class UtilTests(unittest.TestCase):
log_entry.action_flag = admin.models.ADDITION log_entry.action_flag = admin.models.ADDITION
self.assertTrue( self.assertTrue(
unicode(log_entry).startswith('Added ') six.text_type(log_entry).startswith('Added ')
) )
log_entry.action_flag = admin.models.CHANGE log_entry.action_flag = admin.models.CHANGE
self.assertTrue( self.assertTrue(
unicode(log_entry).startswith('Changed ') six.text_type(log_entry).startswith('Changed ')
) )
log_entry.action_flag = admin.models.DELETION log_entry.action_flag = admin.models.DELETION
self.assertTrue( self.assertTrue(
unicode(log_entry).startswith('Deleted ') six.text_type(log_entry).startswith('Deleted ')
) )
def test_safestring_in_field_label(self): def test_safestring_in_field_label(self):

View File

@ -30,6 +30,7 @@ from django.utils.cache import get_max_age
from django.utils.encoding import iri_to_uri from django.utils.encoding import iri_to_uri
from django.utils.html import escape from django.utils.html import escape
from django.utils.http import urlencode from django.utils.http import urlencode
from django.utils import six
from django.test.utils import override_settings from django.test.utils import override_settings
# local test models # local test models
@ -2478,7 +2479,7 @@ class AdminCustomQuerysetTest(TestCase):
response = self.client.post('/test_admin/admin/admin_views/paper/%s/' % p.pk, response = self.client.post('/test_admin/admin/admin_views/paper/%s/' % p.pk,
post_data, follow=True) post_data, follow=True)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
# Message should contain non-ugly model name. Instance representation is set by unicode() (ugly) # Message should contain non-ugly model name. Instance representation is set by six.text_type() (ugly)
self.assertContains(response, '<li class="info">The paper &quot;Paper_Deferred_author object&quot; was changed successfully.</li>', html=True) self.assertContains(response, '<li class="info">The paper &quot;Paper_Deferred_author object&quot; was changed successfully.</li>', html=True)
# defer() is used in ModelAdmin.queryset() # defer() is used in ModelAdmin.queryset()
@ -2530,8 +2531,8 @@ class AdminInlineFileUploadTest(TestCase):
"pictures-TOTAL_FORMS": "2", "pictures-TOTAL_FORMS": "2",
"pictures-INITIAL_FORMS": "1", "pictures-INITIAL_FORMS": "1",
"pictures-MAX_NUM_FORMS": "0", "pictures-MAX_NUM_FORMS": "0",
"pictures-0-id": unicode(self.picture.id), "pictures-0-id": six.text_type(self.picture.id),
"pictures-0-gallery": unicode(self.gallery.id), "pictures-0-gallery": six.text_type(self.gallery.id),
"pictures-0-name": "Test Picture", "pictures-0-name": "Test Picture",
"pictures-0-image": "", "pictures-0-image": "",
"pictures-1-id": "", "pictures-1-id": "",

View File

@ -16,6 +16,7 @@ from django.db.utils import ConnectionHandler, DatabaseError, load_backend
from django.test import (TestCase, skipUnlessDBFeature, skipIfDBFeature, from django.test import (TestCase, skipUnlessDBFeature, skipIfDBFeature,
TransactionTestCase) TransactionTestCase)
from django.test.utils import override_settings from django.test.utils import override_settings
from django.utils import six
from django.utils import unittest from django.utils import unittest
from . import models from . import models
@ -50,7 +51,7 @@ class OracleChecks(unittest.TestCase):
# than 4000 chars and read it properly # than 4000 chars and read it properly
c = connection.cursor() c = connection.cursor()
c.execute('CREATE TABLE ltext ("TEXT" NCLOB)') c.execute('CREATE TABLE ltext ("TEXT" NCLOB)')
long_str = ''.join([unicode(x) for x in xrange(4000)]) long_str = ''.join([six.text_type(x) for x in xrange(4000)])
c.execute('INSERT INTO ltext VALUES (%s)',[long_str]) c.execute('INSERT INTO ltext VALUES (%s)',[long_str])
c.execute('SELECT text FROM ltext') c.execute('SELECT text FROM ltext')
row = c.fetchone() row = c.fetchone()
@ -154,7 +155,7 @@ class LastExecutedQueryTest(TestCase):
sql, params = tags.query.sql_with_params() sql, params = tags.query.sql_with_params()
cursor = tags.query.get_compiler('default').execute_sql(None) cursor = tags.query.get_compiler('default').execute_sql(None)
last_sql = cursor.db.ops.last_executed_query(cursor, sql, params) last_sql = cursor.db.ops.last_executed_query(cursor, sql, params)
self.assertTrue(isinstance(last_sql, unicode)) self.assertTrue(isinstance(last_sql, six.text_type))
class ParameterHandlingTest(TestCase): class ParameterHandlingTest(TestCase):

View File

@ -3,6 +3,7 @@ from __future__ import absolute_import, unicode_literals
import datetime import datetime
from django.test import TestCase, skipIfDBFeature from django.test import TestCase, skipIfDBFeature
from django.utils import six
from django.utils.timezone import utc from django.utils.timezone import utc
from .models import Donut, RumBaba from .models import Donut, RumBaba
@ -73,7 +74,7 @@ class DataTypesTestCase(TestCase):
database should be unicode.""" database should be unicode."""
d = Donut.objects.create(name='Jelly Donut', review='Outstanding') d = Donut.objects.create(name='Jelly Donut', review='Outstanding')
newd = Donut.objects.get(id=d.id) newd = Donut.objects.get(id=d.id)
self.assertTrue(isinstance(newd.review, unicode)) self.assertTrue(isinstance(newd.review, six.text_type))
@skipIfDBFeature('supports_timezones') @skipIfDBFeature('supports_timezones')
def test_error_on_timezone(self): def test_error_on_timezone(self):

View File

@ -6,6 +6,7 @@ import decimal
from django.template.defaultfilters import * from django.template.defaultfilters import *
from django.test import TestCase from django.test import TestCase
from django.utils import six
from django.utils import unittest, translation from django.utils import unittest, translation
from django.utils.safestring import SafeData from django.utils.safestring import SafeData
@ -48,13 +49,13 @@ class DefaultFiltersTests(TestCase):
'0.00000000000000000002') '0.00000000000000000002')
pos_inf = float(1e30000) pos_inf = float(1e30000)
self.assertEqual(floatformat(pos_inf), unicode(pos_inf)) self.assertEqual(floatformat(pos_inf), six.text_type(pos_inf))
neg_inf = float(-1e30000) neg_inf = float(-1e30000)
self.assertEqual(floatformat(neg_inf), unicode(neg_inf)) self.assertEqual(floatformat(neg_inf), six.text_type(neg_inf))
nan = pos_inf / pos_inf nan = pos_inf / pos_inf
self.assertEqual(floatformat(nan), unicode(nan)) self.assertEqual(floatformat(nan), six.text_type(nan))
class FloatWrapper(object): class FloatWrapper(object):
def __init__(self, value): def __init__(self, value):

View File

@ -6,6 +6,7 @@ import os
from django.core.files.uploadedfile import UploadedFile from django.core.files.uploadedfile import UploadedFile
from django.http import HttpResponse, HttpResponseServerError from django.http import HttpResponse, HttpResponseServerError
from django.utils import six
from .models import FileModel, UPLOAD_TO from .models import FileModel, UPLOAD_TO
from .tests import UNICODE_FILENAME from .tests import UNICODE_FILENAME
@ -19,7 +20,7 @@ def file_upload_view(request):
""" """
form_data = request.POST.copy() form_data = request.POST.copy()
form_data.update(request.FILES) form_data.update(request.FILES)
if isinstance(form_data.get('file_field'), UploadedFile) and isinstance(form_data['name'], unicode): if isinstance(form_data.get('file_field'), UploadedFile) and isinstance(form_data['name'], six.text_type):
# If a file is posted, the dummy client should only post the file name, # If a file is posted, the dummy client should only post the file name,
# not the full path. # not the full path.
if os.path.dirname(form_data['file_field'].name) != '': if os.path.dirname(form_data['file_field'].name) != '':

View File

@ -2,6 +2,7 @@ from __future__ import absolute_import, unicode_literals
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db import models from django.db import models
from django.utils import six
class Animal(models.Model): class Animal(models.Model):
@ -29,7 +30,7 @@ class Stuff(models.Model):
owner = models.ForeignKey(User, null=True) owner = models.ForeignKey(User, null=True)
def __unicode__(self): def __unicode__(self):
return unicode(self.name) + ' is owned by ' + unicode(self.owner) return six.text_type(self.name) + ' is owned by ' + six.text_type(self.owner)
class Absolute(models.Model): class Absolute(models.Model):

View File

@ -8,6 +8,7 @@ from django.db import models
from django.forms import Form, ModelForm, FileField, ModelChoiceField from django.forms import Form, ModelForm, FileField, ModelChoiceField
from django.forms.models import ModelFormMetaclass from django.forms.models import ModelFormMetaclass
from django.test import TestCase from django.test import TestCase
from django.utils import six
from ..models import (ChoiceOptionModel, ChoiceFieldModel, FileModel, Group, from ..models import (ChoiceOptionModel, ChoiceFieldModel, FileModel, Group,
BoundaryModel, Defaults) BoundaryModel, Defaults)
@ -40,7 +41,7 @@ class ModelFormCallableModelDefault(TestCase):
choices = list(ChoiceFieldForm().fields['choice'].choices) choices = list(ChoiceFieldForm().fields['choice'].choices)
self.assertEqual(len(choices), 1) self.assertEqual(len(choices), 1)
self.assertEqual(choices[0], (option.pk, unicode(option))) self.assertEqual(choices[0], (option.pk, six.text_type(option)))
def test_callable_initial_value(self): def test_callable_initial_value(self):
"The initial value for a callable default returning a queryset is the pk (refs #13769)" "The initial value for a callable default returning a queryset is the pk (refs #13769)"

View File

@ -5,6 +5,7 @@ from django.core.exceptions import ValidationError
from django.forms.util import flatatt, ErrorDict, ErrorList from django.forms.util import flatatt, ErrorDict, ErrorList
from django.test import TestCase from django.test import TestCase
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils import six
from django.utils.translation import ugettext_lazy from django.utils.translation import ugettext_lazy
@ -30,7 +31,7 @@ class FormsUtilTestCase(TestCase):
'<ul class="errorlist"><li>There was an error.</li></ul>') '<ul class="errorlist"><li>There was an error.</li></ul>')
# Can take a unicode string. # Can take a unicode string.
self.assertHTMLEqual(unicode(ErrorList(ValidationError("Not \u03C0.").messages)), self.assertHTMLEqual(six.text_type(ErrorList(ValidationError("Not \u03C0.").messages)),
'<ul class="errorlist"><li>Not π.</li></ul>') '<ul class="errorlist"><li>Not π.</li></ul>')
# Can take a lazy string. # Can take a lazy string.

View File

@ -10,6 +10,7 @@ from django.forms import *
from django.forms.widgets import RadioFieldRenderer from django.forms.widgets import RadioFieldRenderer
from django.utils import formats from django.utils import formats
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils import six
from django.utils.translation import activate, deactivate from django.utils.translation import activate, deactivate
from django.test import TestCase from django.test import TestCase
@ -676,7 +677,7 @@ beatle J R Ringo False""")
# You can create your own custom renderers for RadioSelect to use. # You can create your own custom renderers for RadioSelect to use.
class MyRenderer(RadioFieldRenderer): class MyRenderer(RadioFieldRenderer):
def render(self): def render(self):
return '<br />\n'.join([unicode(choice) for choice in self]) return '<br />\n'.join([six.text_type(choice) for choice in self])
w = RadioSelect(renderer=MyRenderer) w = RadioSelect(renderer=MyRenderer)
self.assertHTMLEqual(w.render('beatle', 'G', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<label><input type="radio" name="beatle" value="J" /> John</label><br /> self.assertHTMLEqual(w.render('beatle', 'G', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<label><input type="radio" name="beatle" value="J" /> John</label><br />
<label><input type="radio" name="beatle" value="P" /> Paul</label><br /> <label><input type="radio" name="beatle" value="P" /> Paul</label><br />
@ -716,7 +717,7 @@ beatle J R Ringo False""")
# Unicode choices are correctly rendered as HTML # Unicode choices are correctly rendered as HTML
w = RadioSelect() w = RadioSelect()
self.assertHTMLEqual(unicode(w.render('email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')])), '<ul>\n<li><label><input checked="checked" type="radio" name="email" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /> \u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</label></li>\n<li><label><input type="radio" name="email" value="\u0107\u017e\u0161\u0111" /> abc\u0107\u017e\u0161\u0111</label></li>\n</ul>') self.assertHTMLEqual(six.text_type(w.render('email', 'ŠĐĆŽćžšđ', choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')])), '<ul>\n<li><label><input checked="checked" type="radio" name="email" value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" /> \u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</label></li>\n<li><label><input type="radio" name="email" value="\u0107\u017e\u0161\u0111" /> abc\u0107\u017e\u0161\u0111</label></li>\n</ul>')
# Attributes provided at instantiation are passed to the constituent inputs # Attributes provided at instantiation are passed to the constituent inputs
w = RadioSelect(attrs={'id':'foo'}) w = RadioSelect(attrs={'id':'foo'})
@ -1135,7 +1136,7 @@ class ClearableFileInputTests(TestCase):
output = widget.render('my<div>file', field) output = widget.render('my<div>file', field)
self.assertFalse(field.url in output) self.assertFalse(field.url in output)
self.assertTrue('href="something?chapter=1&amp;sect=2&amp;copy=3&amp;lang=en"' in output) self.assertTrue('href="something?chapter=1&amp;sect=2&amp;copy=3&amp;lang=en"' in output)
self.assertFalse(unicode(field) in output) self.assertFalse(six.text_type(field) in output)
self.assertTrue('something&lt;div onclick=&quot;alert(&#39;oops&#39;)&quot;&gt;.jpg' in output) self.assertTrue('something&lt;div onclick=&quot;alert(&#39;oops&#39;)&quot;&gt;.jpg' in output)
self.assertTrue('my&lt;div&gt;file' in output) self.assertTrue('my&lt;div&gt;file' in output)
self.assertFalse('my<div>file' in output) self.assertFalse('my<div>file' in output)

View File

@ -6,6 +6,7 @@ import os
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.test import TestCase from django.test import TestCase
from django.test.utils import override_settings from django.test.utils import override_settings
from django.utils import six
from django.utils import translation from django.utils import translation
@ -24,11 +25,11 @@ class ContentTypeTests(TestCase):
def test_verbose_name(self): def test_verbose_name(self):
company_type = ContentType.objects.get(app_label='i18n', model='company') company_type = ContentType.objects.get(app_label='i18n', model='company')
with translation.override('en'): with translation.override('en'):
self.assertEqual(unicode(company_type), 'Company') self.assertEqual(six.text_type(company_type), 'Company')
with translation.override('fr'): with translation.override('fr'):
self.assertEqual(unicode(company_type), 'Société') self.assertEqual(six.text_type(company_type), 'Société')
def test_field_override(self): def test_field_override(self):
company_type = ContentType.objects.get(app_label='i18n', model='company') company_type = ContentType.objects.get(app_label='i18n', model='company')
company_type.name = 'Other' company_type.name = 'Other'
self.assertEqual(unicode(company_type), 'Other') self.assertEqual(six.text_type(company_type), 'Other')

View File

@ -19,6 +19,7 @@ from django.utils.formats import (get_format, date_format, time_format,
from django.utils.importlib import import_module from django.utils.importlib import import_module
from django.utils.numberformat import format as nformat from django.utils.numberformat import format as nformat
from django.utils.safestring import mark_safe, SafeString, SafeUnicode from django.utils.safestring import mark_safe, SafeString, SafeUnicode
from django.utils import six
from django.utils.six import PY3 from django.utils.six import PY3
from django.utils.translation import (ugettext, ugettext_lazy, activate, from django.utils.translation import (ugettext, ugettext_lazy, activate,
deactivate, gettext_lazy, pgettext, npgettext, to_locale, deactivate, gettext_lazy, pgettext, npgettext, to_locale,
@ -81,9 +82,9 @@ class TranslationTests(TestCase):
def test_lazy_pickle(self): def test_lazy_pickle(self):
s1 = ugettext_lazy("test") s1 = ugettext_lazy("test")
self.assertEqual(unicode(s1), "test") self.assertEqual(six.text_type(s1), "test")
s2 = pickle.loads(pickle.dumps(s1)) s2 = pickle.loads(pickle.dumps(s1))
self.assertEqual(unicode(s2), "test") self.assertEqual(six.text_type(s2), "test")
def test_pgettext(self): def test_pgettext(self):
# Reset translation catalog to include other/locale/de # Reset translation catalog to include other/locale/de
@ -222,10 +223,10 @@ class TranslationTests(TestCase):
def test_string_concat(self): def test_string_concat(self):
""" """
unicode(string_concat(...)) should not raise a TypeError - #4796 six.text_type(string_concat(...)) should not raise a TypeError - #4796
""" """
import django.utils.translation import django.utils.translation
self.assertEqual('django', unicode(django.utils.translation.string_concat("dja", "ngo"))) self.assertEqual('django', six.text_type(django.utils.translation.string_concat("dja", "ngo")))
def test_safe_status(self): def test_safe_status(self):
""" """

View File

@ -2,6 +2,7 @@ from __future__ import absolute_import, unicode_literals
from django.forms.models import inlineformset_factory from django.forms.models import inlineformset_factory
from django.test import TestCase from django.test import TestCase
from django.utils import six
from .models import Poet, Poem, School, Parent, Child from .models import Poet, Poem, School, Parent, Child
@ -66,8 +67,8 @@ class DeletionTests(TestCase):
'poem_set-TOTAL_FORMS': '1', 'poem_set-TOTAL_FORMS': '1',
'poem_set-INITIAL_FORMS': '1', 'poem_set-INITIAL_FORMS': '1',
'poem_set-MAX_NUM_FORMS': '0', 'poem_set-MAX_NUM_FORMS': '0',
'poem_set-0-id': unicode(poem.id), 'poem_set-0-id': six.text_type(poem.id),
'poem_set-0-poem': unicode(poem.id), 'poem_set-0-poem': six.text_type(poem.id),
'poem_set-0-name': 'x' * 1000, 'poem_set-0-name': 'x' * 1000,
} }
formset = PoemFormSet(data, instance=poet) formset = PoemFormSet(data, instance=poet)

View File

@ -7,6 +7,7 @@ from django.core.exceptions import FieldError, ValidationError
from django.core.files.uploadedfile import SimpleUploadedFile from django.core.files.uploadedfile import SimpleUploadedFile
from django.forms.models import (modelform_factory, ModelChoiceField, from django.forms.models import (modelform_factory, ModelChoiceField,
fields_for_model, construct_instance, ModelFormMetaclass) fields_for_model, construct_instance, ModelFormMetaclass)
from django.utils import six
from django.utils import unittest from django.utils import unittest
from django.test import TestCase from django.test import TestCase
@ -392,14 +393,14 @@ class FileFieldTests(unittest.TestCase):
""" """
form = DocumentForm() form = DocumentForm()
self.assertTrue('name="myfile"' in unicode(form)) self.assertTrue('name="myfile"' in six.text_type(form))
self.assertTrue('myfile-clear' not in unicode(form)) self.assertTrue('myfile-clear' not in six.text_type(form))
form = DocumentForm(files={'myfile': SimpleUploadedFile('something.txt', b'content')}) form = DocumentForm(files={'myfile': SimpleUploadedFile('something.txt', b'content')})
self.assertTrue(form.is_valid()) self.assertTrue(form.is_valid())
doc = form.save(commit=False) doc = form.save(commit=False)
self.assertEqual(doc.myfile.name, 'something.txt') self.assertEqual(doc.myfile.name, 'something.txt')
form = DocumentForm(instance=doc) form = DocumentForm(instance=doc)
self.assertTrue('myfile-clear' in unicode(form)) self.assertTrue('myfile-clear' in six.text_type(form))
form = DocumentForm(instance=doc, data={'myfile-clear': 'true'}) form = DocumentForm(instance=doc, data={'myfile-clear': 'true'})
doc = form.save(commit=False) doc = form.save(commit=False)
self.assertEqual(bool(doc.myfile), False) self.assertEqual(bool(doc.myfile), False)
@ -420,7 +421,7 @@ class FileFieldTests(unittest.TestCase):
self.assertTrue(not form.is_valid()) self.assertTrue(not form.is_valid())
self.assertEqual(form.errors['myfile'], self.assertEqual(form.errors['myfile'],
['Please either submit a file or check the clear checkbox, not both.']) ['Please either submit a file or check the clear checkbox, not both.'])
rendered = unicode(form) rendered = six.text_type(form)
self.assertTrue('something.txt' in rendered) self.assertTrue('something.txt' in rendered)
self.assertTrue('myfile-clear' in rendered) self.assertTrue('myfile-clear' in rendered)

View File

@ -5,6 +5,7 @@ from django.forms.formsets import BaseFormSet, DELETION_FIELD_NAME
from django.forms.util import ErrorDict, ErrorList from django.forms.util import ErrorDict, ErrorList
from django.forms.models import modelform_factory, inlineformset_factory, modelformset_factory, BaseModelFormSet from django.forms.models import modelform_factory, inlineformset_factory, modelformset_factory, BaseModelFormSet
from django.test import TestCase from django.test import TestCase
from django.utils import six
from .models import User, UserSite, Restaurant, Manager, Network, Host from .models import User, UserSite, Restaurant, Manager, Network, Host
@ -51,7 +52,7 @@ class InlineFormsetTests(TestCase):
'usersite_set-TOTAL_FORMS': '1', 'usersite_set-TOTAL_FORMS': '1',
'usersite_set-INITIAL_FORMS': '1', 'usersite_set-INITIAL_FORMS': '1',
'usersite_set-MAX_NUM_FORMS': '0', 'usersite_set-MAX_NUM_FORMS': '0',
'usersite_set-0-id': unicode(usersite[0]['id']), 'usersite_set-0-id': six.text_type(usersite[0]['id']),
'usersite_set-0-data': '11', 'usersite_set-0-data': '11',
'usersite_set-0-user': 'apollo13' 'usersite_set-0-user': 'apollo13'
} }
@ -69,7 +70,7 @@ class InlineFormsetTests(TestCase):
'usersite_set-TOTAL_FORMS': '2', 'usersite_set-TOTAL_FORMS': '2',
'usersite_set-INITIAL_FORMS': '1', 'usersite_set-INITIAL_FORMS': '1',
'usersite_set-MAX_NUM_FORMS': '0', 'usersite_set-MAX_NUM_FORMS': '0',
'usersite_set-0-id': unicode(usersite[0]['id']), 'usersite_set-0-id': six.text_type(usersite[0]['id']),
'usersite_set-0-data': '11', 'usersite_set-0-data': '11',
'usersite_set-0-user': 'apollo13', 'usersite_set-0-user': 'apollo13',
'usersite_set-1-data': '42', 'usersite_set-1-data': '42',
@ -124,7 +125,7 @@ class InlineFormsetTests(TestCase):
'manager_set-TOTAL_FORMS': '1', 'manager_set-TOTAL_FORMS': '1',
'manager_set-INITIAL_FORMS': '1', 'manager_set-INITIAL_FORMS': '1',
'manager_set-MAX_NUM_FORMS': '0', 'manager_set-MAX_NUM_FORMS': '0',
'manager_set-0-id': unicode(manager[0]['id']), 'manager_set-0-id': six.text_type(manager[0]['id']),
'manager_set-0-name': 'Terry Gilliam' 'manager_set-0-name': 'Terry Gilliam'
} }
form_set = FormSet(data, instance=restaurant) form_set = FormSet(data, instance=restaurant)
@ -140,7 +141,7 @@ class InlineFormsetTests(TestCase):
'manager_set-TOTAL_FORMS': '2', 'manager_set-TOTAL_FORMS': '2',
'manager_set-INITIAL_FORMS': '1', 'manager_set-INITIAL_FORMS': '1',
'manager_set-MAX_NUM_FORMS': '0', 'manager_set-MAX_NUM_FORMS': '0',
'manager_set-0-id': unicode(manager[0]['id']), 'manager_set-0-id': six.text_type(manager[0]['id']),
'manager_set-0-name': 'Terry Gilliam', 'manager_set-0-name': 'Terry Gilliam',
'manager_set-1-name': 'John Cleese' 'manager_set-1-name': 'John Cleese'
} }
@ -188,7 +189,7 @@ class InlineFormsetTests(TestCase):
'host_set-TOTAL_FORMS': '2', 'host_set-TOTAL_FORMS': '2',
'host_set-INITIAL_FORMS': '1', 'host_set-INITIAL_FORMS': '1',
'host_set-MAX_NUM_FORMS': '0', 'host_set-MAX_NUM_FORMS': '0',
'host_set-0-id': unicode(host1.id), 'host_set-0-id': six.text_type(host1.id),
'host_set-0-hostname': 'tranquility.hub.dal.net', 'host_set-0-hostname': 'tranquility.hub.dal.net',
'host_set-1-hostname': 'matrix.de.eu.dal.net' 'host_set-1-hostname': 'matrix.de.eu.dal.net'
} }

View File

@ -5,6 +5,7 @@ from operator import attrgetter
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.test import TestCase, skipUnlessDBFeature from django.test import TestCase, skipUnlessDBFeature
from django.utils import six
from django.utils import tzinfo from django.utils import tzinfo
from .models import (Worker, Article, Party, Event, Department, from .models import (Worker, Article, Party, Event, Department,
@ -38,7 +39,7 @@ class ModelTests(TestCase):
# Empty strings should be returned as Unicode # Empty strings should be returned as Unicode
a = Article.objects.get(pk=a.pk) a = Article.objects.get(pk=a.pk)
self.assertEqual(a.misc_data, '') self.assertEqual(a.misc_data, '')
self.assertIs(type(a.misc_data), unicode) self.assertIs(type(a.misc_data), six.text_type)
def test_long_textfield(self): def test_long_textfield(self):
# TextFields can hold more than 4000 characters (this was broken in # TextFields can hold more than 4000 characters (this was broken in
@ -138,7 +139,7 @@ class ModelTests(TestCase):
# Check Department and Worker (non-default PK type) # Check Department and Worker (non-default PK type)
d = Department.objects.create(id=10, name="IT") d = Department.objects.create(id=10, name="IT")
w = Worker.objects.create(department=d, name="Full-time") w = Worker.objects.create(department=d, name="Full-time")
self.assertEqual(unicode(w), "Full-time") self.assertEqual(six.text_type(w), "Full-time")
def test_broken_unicode(self): def test_broken_unicode(self):
# Models with broken unicode methods should still have a printable repr # Models with broken unicode methods should still have a printable repr

View File

@ -6,6 +6,7 @@ from __future__ import unicode_literals
import threading import threading
from django.db import models from django.db import models
from django.utils import six
class DumbCategory(models.Model): class DumbCategory(models.Model):
@ -122,7 +123,7 @@ class Number(models.Model):
num = models.IntegerField() num = models.IntegerField()
def __unicode__(self): def __unicode__(self):
return unicode(self.num) return six.text_type(self.num)
# Symmetrical m2m field with a normal field using the reverse accesor name # Symmetrical m2m field with a normal field using the reverse accesor name
# ("valid"). # ("valid").

View File

@ -1,6 +1,7 @@
from __future__ import absolute_import, unicode_literals from __future__ import absolute_import, unicode_literals
from django.test import TestCase from django.test import TestCase
from django.utils import six
from .models import (Building, Child, Device, Port, Item, Country, Connection, from .models import (Building, Child, Device, Port, Item, Country, Connection,
ClientStatus, State, Client, SpecialClient, TUser, Person, Student, ClientStatus, State, Client, SpecialClient, TUser, Person, Student,
@ -33,11 +34,11 @@ class SelectRelatedRegressTests(TestCase):
c2=Connection.objects.create(start=port2, end=port3) c2=Connection.objects.create(start=port2, end=port3)
connections=Connection.objects.filter(start__device__building=b, end__device__building=b).order_by('id') connections=Connection.objects.filter(start__device__building=b, end__device__building=b).order_by('id')
self.assertEqual([(c.id, unicode(c.start), unicode(c.end)) for c in connections], self.assertEqual([(c.id, six.text_type(c.start), six.text_type(c.end)) for c in connections],
[(c1.id, 'router/4', 'switch/7'), (c2.id, 'switch/7', 'server/1')]) [(c1.id, 'router/4', 'switch/7'), (c2.id, 'switch/7', 'server/1')])
connections=Connection.objects.filter(start__device__building=b, end__device__building=b).select_related().order_by('id') connections=Connection.objects.filter(start__device__building=b, end__device__building=b).select_related().order_by('id')
self.assertEqual([(c.id, unicode(c.start), unicode(c.end)) for c in connections], self.assertEqual([(c.id, six.text_type(c.start), six.text_type(c.end)) for c in connections],
[(c1.id, 'router/4', 'switch/7'), (c2.id, 'switch/7', 'server/1')]) [(c1.id, 'router/4', 'switch/7'), (c2.id, 'switch/7', 'server/1')])
# This final query should only have seven tables (port, device and building # This final query should only have seven tables (port, device and building

View File

@ -3,6 +3,7 @@ import operator
from django import template from django import template
from django.template.defaultfilters import stringfilter from django.template.defaultfilters import stringfilter
from django.template.loader import get_template from django.template.loader import get_template
from django.utils import six
register = template.Library() register = template.Library()
@ -56,13 +57,13 @@ simple_one_default.anything = "Expected simple_one_default __dict__"
@register.simple_tag @register.simple_tag
def simple_unlimited_args(one, two='hi', *args): def simple_unlimited_args(one, two='hi', *args):
"""Expected simple_unlimited_args __doc__""" """Expected simple_unlimited_args __doc__"""
return "simple_unlimited_args - Expected result: %s" % (', '.join([unicode(arg) for arg in [one, two] + list(args)])) return "simple_unlimited_args - Expected result: %s" % (', '.join([six.text_type(arg) for arg in [one, two] + list(args)]))
simple_unlimited_args.anything = "Expected simple_unlimited_args __dict__" simple_unlimited_args.anything = "Expected simple_unlimited_args __dict__"
@register.simple_tag @register.simple_tag
def simple_only_unlimited_args(*args): def simple_only_unlimited_args(*args):
"""Expected simple_only_unlimited_args __doc__""" """Expected simple_only_unlimited_args __doc__"""
return "simple_only_unlimited_args - Expected result: %s" % ', '.join([unicode(arg) for arg in args]) return "simple_only_unlimited_args - Expected result: %s" % ', '.join([six.text_type(arg) for arg in args])
simple_only_unlimited_args.anything = "Expected simple_only_unlimited_args __dict__" simple_only_unlimited_args.anything = "Expected simple_only_unlimited_args __dict__"
@register.simple_tag @register.simple_tag
@ -71,7 +72,7 @@ def simple_unlimited_args_kwargs(one, two='hi', *args, **kwargs):
# Sort the dictionary by key to guarantee the order for testing. # Sort the dictionary by key to guarantee the order for testing.
sorted_kwarg = sorted(kwargs.iteritems(), key=operator.itemgetter(0)) sorted_kwarg = sorted(kwargs.iteritems(), key=operator.itemgetter(0))
return "simple_unlimited_args_kwargs - Expected result: %s / %s" % ( return "simple_unlimited_args_kwargs - Expected result: %s / %s" % (
', '.join([unicode(arg) for arg in [one, two] + list(args)]), ', '.join([six.text_type(arg) for arg in [one, two] + list(args)]),
', '.join(['%s=%s' % (k, v) for (k, v) in sorted_kwarg]) ', '.join(['%s=%s' % (k, v) for (k, v) in sorted_kwarg])
) )
simple_unlimited_args_kwargs.anything = "Expected simple_unlimited_args_kwargs __dict__" simple_unlimited_args_kwargs.anything = "Expected simple_unlimited_args_kwargs __dict__"
@ -183,25 +184,25 @@ inclusion_one_default_from_template.anything = "Expected inclusion_one_default_f
@register.inclusion_tag('inclusion.html') @register.inclusion_tag('inclusion.html')
def inclusion_unlimited_args(one, two='hi', *args): def inclusion_unlimited_args(one, two='hi', *args):
"""Expected inclusion_unlimited_args __doc__""" """Expected inclusion_unlimited_args __doc__"""
return {"result": "inclusion_unlimited_args - Expected result: %s" % (', '.join([unicode(arg) for arg in [one, two] + list(args)]))} return {"result": "inclusion_unlimited_args - Expected result: %s" % (', '.join([six.text_type(arg) for arg in [one, two] + list(args)]))}
inclusion_unlimited_args.anything = "Expected inclusion_unlimited_args __dict__" inclusion_unlimited_args.anything = "Expected inclusion_unlimited_args __dict__"
@register.inclusion_tag(get_template('inclusion.html')) @register.inclusion_tag(get_template('inclusion.html'))
def inclusion_unlimited_args_from_template(one, two='hi', *args): def inclusion_unlimited_args_from_template(one, two='hi', *args):
"""Expected inclusion_unlimited_args_from_template __doc__""" """Expected inclusion_unlimited_args_from_template __doc__"""
return {"result": "inclusion_unlimited_args_from_template - Expected result: %s" % (', '.join([unicode(arg) for arg in [one, two] + list(args)]))} return {"result": "inclusion_unlimited_args_from_template - Expected result: %s" % (', '.join([six.text_type(arg) for arg in [one, two] + list(args)]))}
inclusion_unlimited_args_from_template.anything = "Expected inclusion_unlimited_args_from_template __dict__" inclusion_unlimited_args_from_template.anything = "Expected inclusion_unlimited_args_from_template __dict__"
@register.inclusion_tag('inclusion.html') @register.inclusion_tag('inclusion.html')
def inclusion_only_unlimited_args(*args): def inclusion_only_unlimited_args(*args):
"""Expected inclusion_only_unlimited_args __doc__""" """Expected inclusion_only_unlimited_args __doc__"""
return {"result": "inclusion_only_unlimited_args - Expected result: %s" % (', '.join([unicode(arg) for arg in args]))} return {"result": "inclusion_only_unlimited_args - Expected result: %s" % (', '.join([six.text_type(arg) for arg in args]))}
inclusion_only_unlimited_args.anything = "Expected inclusion_only_unlimited_args __dict__" inclusion_only_unlimited_args.anything = "Expected inclusion_only_unlimited_args __dict__"
@register.inclusion_tag(get_template('inclusion.html')) @register.inclusion_tag(get_template('inclusion.html'))
def inclusion_only_unlimited_args_from_template(*args): def inclusion_only_unlimited_args_from_template(*args):
"""Expected inclusion_only_unlimited_args_from_template __doc__""" """Expected inclusion_only_unlimited_args_from_template __doc__"""
return {"result": "inclusion_only_unlimited_args_from_template - Expected result: %s" % (', '.join([unicode(arg) for arg in args]))} return {"result": "inclusion_only_unlimited_args_from_template - Expected result: %s" % (', '.join([six.text_type(arg) for arg in args]))}
inclusion_only_unlimited_args_from_template.anything = "Expected inclusion_only_unlimited_args_from_template __dict__" inclusion_only_unlimited_args_from_template.anything = "Expected inclusion_only_unlimited_args_from_template __dict__"
@register.inclusion_tag('test_incl_tag_current_app.html', takes_context=True) @register.inclusion_tag('test_incl_tag_current_app.html', takes_context=True)
@ -222,7 +223,7 @@ def inclusion_unlimited_args_kwargs(one, two='hi', *args, **kwargs):
# Sort the dictionary by key to guarantee the order for testing. # Sort the dictionary by key to guarantee the order for testing.
sorted_kwarg = sorted(kwargs.iteritems(), key=operator.itemgetter(0)) sorted_kwarg = sorted(kwargs.iteritems(), key=operator.itemgetter(0))
return {"result": "inclusion_unlimited_args_kwargs - Expected result: %s / %s" % ( return {"result": "inclusion_unlimited_args_kwargs - Expected result: %s / %s" % (
', '.join([unicode(arg) for arg in [one, two] + list(args)]), ', '.join([six.text_type(arg) for arg in [one, two] + list(args)]),
', '.join(['%s=%s' % (k, v) for (k, v) in sorted_kwarg]) ', '.join(['%s=%s' % (k, v) for (k, v) in sorted_kwarg])
)} )}
inclusion_unlimited_args_kwargs.anything = "Expected inclusion_unlimited_args_kwargs __dict__" inclusion_unlimited_args_kwargs.anything = "Expected inclusion_unlimited_args_kwargs __dict__"
@ -278,13 +279,13 @@ assignment_one_default.anything = "Expected assignment_one_default __dict__"
@register.assignment_tag @register.assignment_tag
def assignment_unlimited_args(one, two='hi', *args): def assignment_unlimited_args(one, two='hi', *args):
"""Expected assignment_unlimited_args __doc__""" """Expected assignment_unlimited_args __doc__"""
return "assignment_unlimited_args - Expected result: %s" % (', '.join([unicode(arg) for arg in [one, two] + list(args)])) return "assignment_unlimited_args - Expected result: %s" % (', '.join([six.text_type(arg) for arg in [one, two] + list(args)]))
assignment_unlimited_args.anything = "Expected assignment_unlimited_args __dict__" assignment_unlimited_args.anything = "Expected assignment_unlimited_args __dict__"
@register.assignment_tag @register.assignment_tag
def assignment_only_unlimited_args(*args): def assignment_only_unlimited_args(*args):
"""Expected assignment_only_unlimited_args __doc__""" """Expected assignment_only_unlimited_args __doc__"""
return "assignment_only_unlimited_args - Expected result: %s" % ', '.join([unicode(arg) for arg in args]) return "assignment_only_unlimited_args - Expected result: %s" % ', '.join([six.text_type(arg) for arg in args])
assignment_only_unlimited_args.anything = "Expected assignment_only_unlimited_args __dict__" assignment_only_unlimited_args.anything = "Expected assignment_only_unlimited_args __dict__"
@register.assignment_tag @register.assignment_tag
@ -293,7 +294,7 @@ def assignment_unlimited_args_kwargs(one, two='hi', *args, **kwargs):
# Sort the dictionary by key to guarantee the order for testing. # Sort the dictionary by key to guarantee the order for testing.
sorted_kwarg = sorted(kwargs.iteritems(), key=operator.itemgetter(0)) sorted_kwarg = sorted(kwargs.iteritems(), key=operator.itemgetter(0))
return "assignment_unlimited_args_kwargs - Expected result: %s / %s" % ( return "assignment_unlimited_args_kwargs - Expected result: %s / %s" % (
', '.join([unicode(arg) for arg in [one, two] + list(args)]), ', '.join([six.text_type(arg) for arg in [one, two] + list(args)]),
', '.join(['%s=%s' % (k, v) for (k, v) in sorted_kwarg]) ', '.join(['%s=%s' % (k, v) for (k, v) in sorted_kwarg])
) )
assignment_unlimited_args_kwargs.anything = "Expected assignment_unlimited_args_kwargs __dict__" assignment_unlimited_args_kwargs.anything = "Expected assignment_unlimited_args_kwargs __dict__"

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.template import Template, TemplateEncodingError, Context from django.template import Template, TemplateEncodingError, Context
from django.utils.safestring import SafeData from django.utils.safestring import SafeData
from django.utils import six
from django.utils.unittest import TestCase from django.utils.unittest import TestCase
@ -27,5 +28,5 @@ class UnicodeTests(TestCase):
# they all render the same (and are returned as unicode objects and # they all render the same (and are returned as unicode objects and
# "safe" objects as well, for auto-escaping purposes). # "safe" objects as well, for auto-escaping purposes).
self.assertEqual(t1.render(c3), t2.render(c3)) self.assertEqual(t1.render(c3), t2.render(c3))
self.assertIsInstance(t1.render(c3), unicode) self.assertIsInstance(t1.render(c3), six.text_type)
self.assertIsInstance(t1.render(c3), SafeData) self.assertIsInstance(t1.render(c3), SafeData)

View File

@ -4,6 +4,7 @@ import copy
import pickle import pickle
from django.test.utils import str_prefix from django.test.utils import str_prefix
from django.utils import six
from django.utils.unittest import TestCase from django.utils.unittest import TestCase
from django.utils.functional import SimpleLazyObject, empty from django.utils.functional import SimpleLazyObject, empty
@ -22,7 +23,7 @@ class _ComplexObject(object):
return "I am _ComplexObject(%r)" % self.name return "I am _ComplexObject(%r)" % self.name
def __unicode__(self): def __unicode__(self):
return unicode(self.name) return six.text_type(self.name)
def __repr__(self): def __repr__(self):
return "_ComplexObject(%r)" % self.name return "_ComplexObject(%r)" % self.name
@ -58,7 +59,7 @@ class TestUtilsSimpleLazyObject(TestCase):
str(SimpleLazyObject(complex_object))) str(SimpleLazyObject(complex_object)))
def test_unicode(self): def test_unicode(self):
self.assertEqual("joe", unicode(SimpleLazyObject(complex_object))) self.assertEqual("joe", six.text_type(SimpleLazyObject(complex_object)))
def test_class(self): def test_class(self):
# This is important for classes that use __class__ in things like # This is important for classes that use __class__ in things like
@ -108,5 +109,5 @@ class TestUtilsSimpleLazyObject(TestCase):
pickled = pickle.dumps(x) pickled = pickle.dumps(x)
unpickled = pickle.loads(pickled) unpickled = pickle.loads(pickled)
self.assertEqual(unpickled, x) self.assertEqual(unpickled, x)
self.assertEqual(unicode(unpickled), unicode(x)) self.assertEqual(six.text_type(unpickled), six.text_type(x))
self.assertEqual(unpickled.name, x.name) self.assertEqual(unpickled.name, x.name)

View File

@ -6,6 +6,7 @@ from django.core.wsgi import get_wsgi_application
from django.test import TestCase from django.test import TestCase
from django.test.client import RequestFactory from django.test.client import RequestFactory
from django.test.utils import override_settings from django.test.utils import override_settings
from django.utils import six
from django.utils import unittest from django.utils import unittest
@ -39,7 +40,7 @@ class WSGITest(TestCase):
response_data["headers"], response_data["headers"],
[('Content-Type', 'text/html; charset=utf-8')]) [('Content-Type', 'text/html; charset=utf-8')])
self.assertEqual( self.assertEqual(
unicode(response), six.text_type(response),
"Content-Type: text/html; charset=utf-8\n\nHello World!") "Content-Type: text/html; charset=utf-8\n\nHello World!")

View File

@ -7,6 +7,7 @@ import tempfile
import warnings import warnings
from django import contrib from django import contrib
from django.utils import six
# databrowse is deprecated, but we still want to run its tests # databrowse is deprecated, but we still want to run its tests
warnings.filterwarnings('ignore', "The Databrowse contrib app is deprecated", warnings.filterwarnings('ignore', "The Databrowse contrib app is deprecated",
@ -142,7 +143,7 @@ def teardown(state):
# so that it will successfully remove temp trees containing # so that it will successfully remove temp trees containing
# non-ASCII filenames on Windows. (We're assuming the temp dir # non-ASCII filenames on Windows. (We're assuming the temp dir
# name itself does not contain non-ASCII characters.) # name itself does not contain non-ASCII characters.)
shutil.rmtree(unicode(TEMP_DIR)) shutil.rmtree(six.text_type(TEMP_DIR))
# Restore the old settings. # Restore the old settings.
for key, value in state.items(): for key, value in state.items():
setattr(settings, key, value) setattr(settings, key, value)