1
0
mirror of https://github.com/django/django.git synced 2025-11-07 07:15:35 +00:00

Fixed #18269 -- Applied unicode_literals for Python 3 compatibility.

Thanks Vinay Sajip for the support of his django3 branch and
Jannis Leidel for the review.
This commit is contained in:
Claude Paroz
2012-06-07 18:08:47 +02:00
parent 706fd9adc0
commit 4a103086d5
401 changed files with 6647 additions and 6157 deletions

View File

@@ -9,6 +9,7 @@ RequestContext.
from django.conf import settings
from django.middleware.csrf import get_token
from django.utils.encoding import smart_str
from django.utils.functional import lazy
def csrf(request):
@@ -24,7 +25,7 @@ def csrf(request):
# instead of returning an empty dict.
return b'NOTPROVIDED'
else:
return token
return smart_str(token)
_get_val = lazy(_get_val, str)
return {'csrf_token': _get_val() }

View File

@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os
from io import BytesIO
@@ -19,7 +21,7 @@ class File(FileProxyMixin):
return smart_str(self.name or '')
def __unicode__(self):
return smart_unicode(self.name or u'')
return smart_unicode(self.name or '')
def __repr__(self):
return "<%s: %s>" % (self.__class__.__name__, self or "None")

View File

@@ -2,6 +2,8 @@
Base file upload handler classes, and the built-in concrete subclasses
"""
from __future__ import unicode_literals
from io import BytesIO
from django.conf import settings
@@ -33,9 +35,9 @@ class StopUpload(UploadFileException):
def __unicode__(self):
if self.connection_reset:
return u'StopUpload: Halt current upload.'
return 'StopUpload: Halt current upload.'
else:
return u'StopUpload: Consume request data, then halt.'
return 'StopUpload: Consume request data, then halt.'
class SkipFile(UploadFileException):
"""

View File

@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import sys
from django import http
@@ -254,9 +256,9 @@ def get_script_name(environ):
# rewrites. Unfortunately not every Web server (lighttpd!) passes this
# information through all the time, so FORCE_SCRIPT_NAME, above, is still
# needed.
script_url = environ.get('SCRIPT_URL', u'')
script_url = environ.get('SCRIPT_URL', '')
if not script_url:
script_url = environ.get('REDIRECT_URL', u'')
script_url = environ.get('REDIRECT_URL', '')
if script_url:
return force_unicode(script_url[:-len(environ.get('PATH_INFO', ''))])
return force_unicode(environ.get('SCRIPT_NAME', u''))
return force_unicode(environ.get('SCRIPT_NAME', ''))

View File

@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import sys
from io import BytesIO
from threading import Lock
@@ -7,7 +9,7 @@ from django.core import signals
from django.core.handlers import base
from django.core.urlresolvers import set_script_prefix
from django.utils import datastructures
from django.utils.encoding import force_unicode, iri_to_uri
from django.utils.encoding import force_unicode, smart_str, iri_to_uri
from django.utils.log import getLogger
logger = getLogger('django.request')
@@ -125,7 +127,7 @@ class LimitedStream(object):
class WSGIRequest(http.HttpRequest):
def __init__(self, environ):
script_name = base.get_script_name(environ)
path_info = force_unicode(environ.get('PATH_INFO', u'/'))
path_info = force_unicode(environ.get('PATH_INFO', '/'))
if not path_info or path_info == script_name:
# Sometimes PATH_INFO exists, but is empty (e.g. accessing
# the SCRIPT_NAME URL without a trailing slash). We really need to
@@ -134,7 +136,7 @@ class WSGIRequest(http.HttpRequest):
#
# (The comparison of path_info to script_name is to work around an
# apparent bug in flup 1.0.1. See Django ticket #8490).
path_info = u'/'
path_info = '/'
self.environ = environ
self.path_info = path_info
self.path = '%s%s' % (script_name, path_info)
@@ -246,6 +248,6 @@ class WSGIHandler(base.BaseHandler):
status = '%s %s' % (response.status_code, status_text)
response_headers = [(str(k), str(v)) for k, v in response.items()]
for c in response.cookies.values():
response_headers.append(('Set-Cookie', str(c.output(header=''))))
start_response(status, response_headers)
response_headers.append((b'Set-Cookie', str(c.output(header=''))))
start_response(smart_str(status), response_headers)
return response

View File

@@ -1,6 +1,7 @@
"""
Tools for sending email.
"""
from __future__ import unicode_literals
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
@@ -89,7 +90,7 @@ def mail_admins(subject, message, fail_silently=False, connection=None,
"""Sends a message to the admins, as defined by the ADMINS setting."""
if not settings.ADMINS:
return
mail = EmailMultiAlternatives(u'%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject),
mail = EmailMultiAlternatives('%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject),
message, settings.SERVER_EMAIL, [a[1] for a in settings.ADMINS],
connection=connection)
if html_message:
@@ -102,7 +103,7 @@ def mail_managers(subject, message, fail_silently=False, connection=None,
"""Sends a message to the managers, as defined by the MANAGERS setting."""
if not settings.MANAGERS:
return
mail = EmailMultiAlternatives(u'%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject),
mail = EmailMultiAlternatives('%s%s' % (settings.EMAIL_SUBJECT_PREFIX, subject),
message, settings.SERVER_EMAIL, [a[1] for a in settings.MANAGERS],
connection=connection)
if html_message:

View File

@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import mimetypes
import os
import random
@@ -90,7 +92,7 @@ def forbid_multi_line_headers(name, val, encoding):
else:
if name.lower() == 'subject':
val = Header(val)
return name, val
return smart_str(name), val
def sanitize_address(addr, encoding):
@@ -101,8 +103,8 @@ def sanitize_address(addr, encoding):
try:
addr = addr.encode('ascii')
except UnicodeEncodeError: # IDN
if u'@' in addr:
localpart, domain = addr.split(u'@', 1)
if '@' in addr:
localpart, domain = addr.split('@', 1)
localpart = str(Header(localpart, encoding))
domain = domain.encode('idna')
addr = '@'.join([localpart, domain])

View File

@@ -4,6 +4,8 @@ from django.core.cache.backends.db import BaseDatabaseCache
from django.core.management.base import LabelCommand, CommandError
from django.db import connections, router, transaction, models, DEFAULT_DB_ALIAS
from django.db.utils import DatabaseError
from django.utils.encoding import force_unicode
class Command(LabelCommand):
help = "Creates the table needed to use the SQL cache backend."
@@ -58,7 +60,7 @@ class Command(LabelCommand):
transaction.rollback_unless_managed(using=db)
raise CommandError(
"Cache table '%s' could not be created.\nThe error was: %s." %
(tablename, e))
(tablename, force_unicode(e)))
for statement in index_output:
curs.execute(statement)
transaction.commit_unless_managed(using=db)

View File

@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import sys
import os
import gzip
@@ -12,6 +14,7 @@ from django.core.management.color import no_style
from django.db import (connections, router, transaction, DEFAULT_DB_ALIAS,
IntegrityError, DatabaseError)
from django.db.models import get_apps
from django.utils.encoding import force_unicode
from itertools import product
try:
@@ -186,7 +189,7 @@ class Command(BaseCommand):
'app_label': obj.object._meta.app_label,
'object_name': obj.object._meta.object_name,
'pk': obj.object.pk,
'error_msg': e
'error_msg': force_unicode(e)
},)
raise

View File

@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from optparse import make_option
from django.core.management.base import AppCommand
@@ -16,4 +18,4 @@ class Command(AppCommand):
output_transaction = True
def handle_app(self, app, **options):
return u'\n'.join(sql_create(app, self.style, connections[options.get('database')])).encode('utf-8')
return '\n'.join(sql_create(app, self.style, connections[options.get('database')]))

View File

@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from optparse import make_option
from django.core.management.base import AppCommand
@@ -16,4 +18,4 @@ class Command(AppCommand):
output_transaction = True
def handle_app(self, app, **options):
return u'\n'.join(sql_all(app, self.style, connections[options.get('database')])).encode('utf-8')
return '\n'.join(sql_all(app, self.style, connections[options.get('database')]))

View File

@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from optparse import make_option
from django.core.management.base import AppCommand
@@ -16,4 +18,4 @@ class Command(AppCommand):
output_transaction = True
def handle_app(self, app, **options):
return u'\n'.join(sql_delete(app, self.style, connections[options.get('database')])).encode('utf-8')
return '\n'.join(sql_delete(app, self.style, connections[options.get('database')]))

View File

@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from optparse import make_option
from django.core.management.base import AppCommand
@@ -16,4 +18,4 @@ class Command(AppCommand):
output_transaction = True
def handle_app(self, app, **options):
return u'\n'.join(sql_custom(app, self.style, connections[options.get('database')])).encode('utf-8')
return '\n'.join(sql_custom(app, self.style, connections[options.get('database')]))

View File

@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from optparse import make_option
from django.core.management.base import NoArgsCommand
@@ -16,4 +18,4 @@ class Command(NoArgsCommand):
output_transaction = True
def handle_noargs(self, **options):
return u'\n'.join(sql_flush(self.style, connections[options.get('database')], only_django=True)).encode('utf-8')
return '\n'.join(sql_flush(self.style, connections[options.get('database')], only_django=True))

View File

@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from optparse import make_option
from django.core.management.base import AppCommand
@@ -17,4 +19,4 @@ class Command(AppCommand):
output_transaction = True
def handle_app(self, app, **options):
return u'\n'.join(sql_indexes(app, self.style, connections[options.get('database')])).encode('utf-8')
return '\n'.join(sql_indexes(app, self.style, connections[options.get('database')]))

View File

@@ -1,3 +1,5 @@
from __future__ import unicode_literals
from optparse import make_option
from django.core.management.base import AppCommand
@@ -17,4 +19,4 @@ class Command(AppCommand):
def handle_app(self, app, **options):
connection = connections[options.get('database')]
return u'\n'.join(connection.ops.sequence_reset_sql(self.style, models.get_models(app, include_auto_created=True))).encode('utf-8')
return '\n'.join(connection.ops.sequence_reset_sql(self.style, models.get_models(app, include_auto_created=True)))

View File

@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import os
import re
@@ -160,9 +162,9 @@ def custom_sql_for_model(model, style, connection):
with open(sql_file, 'U') as fp:
for statement in statements.split(fp.read().decode(settings.FILE_CHARSET)):
# Remove any comments from the file
statement = re.sub(ur"--.*([\n\Z]|$)", "", statement)
statement = re.sub(r"--.*([\n\Z]|$)", "", statement)
if statement.strip():
output.append(statement + u";")
output.append(statement + ";")
return output

View File

@@ -1,6 +1,7 @@
import sys
from django.core.management.color import color_style
from django.utils.encoding import smart_str
from django.utils.itercompat import is_iterable
class ModelErrorCollection:
@@ -11,7 +12,7 @@ class ModelErrorCollection:
def add(self, context, error):
self.errors.append((context, error))
self.outfile.write(self.style.ERROR("%s: %s\n" % (context, error)))
self.outfile.write(self.style.ERROR(smart_str("%s: %s\n" % (context, error))))
def get_validation_errors(outfile, app=None):
"""

View File

@@ -13,6 +13,7 @@ from io import BytesIO
from django.core.serializers.base import DeserializationError
from django.core.serializers.python import Serializer as PythonSerializer
from django.core.serializers.python import Deserializer as PythonDeserializer
from django.utils.encoding import smart_str
from django.utils.timezone import is_aware
class Serializer(PythonSerializer):
@@ -61,8 +62,10 @@ def Deserializer(stream_or_string, **options):
"""
Deserialize a stream or string of JSON data.
"""
if isinstance(stream_or_string, basestring):
if isinstance(stream_or_string, bytes):
stream = BytesIO(stream_or_string)
elif isinstance(stream_or_string, unicode):
stream = BytesIO(smart_str(stream_or_string))
else:
stream = stream_or_string
try:

View File

@@ -3,6 +3,7 @@ A Python "serializer". Doesn't do much serializing per se -- just converts to
and from basic Python data types (lists, dicts, strings, etc.). Useful as a basis for
other serializers.
"""
from __future__ import unicode_literals
from django.conf import settings
from django.core.serializers import base
@@ -138,5 +139,5 @@ def _get_model(model_identifier):
except TypeError:
Model = None
if Model is None:
raise base.DeserializationError(u"Invalid model identifier: '%s'" % model_identifier)
raise base.DeserializationError("Invalid model identifier: '%s'" % model_identifier)
return Model

View File

@@ -2,6 +2,8 @@
XML serializer.
"""
from __future__ import unicode_literals
from django.conf import settings
from django.core.serializers import base
from django.db import models, DEFAULT_DB_ALIAS
@@ -289,4 +291,4 @@ def getInnerText(node):
inner_text.extend(getInnerText(child))
else:
pass
return u"".join(inner_text)
return "".join(inner_text)

View File

@@ -6,6 +6,7 @@ a string) and returns a tuple in this format:
(view_function, function_args, function_kwargs)
"""
from __future__ import unicode_literals
import re
from threading import local
@@ -182,7 +183,7 @@ class RegexURLPattern(LocaleRegexProvider):
self.name = name
def __repr__(self):
return smart_str(u'<%s %s %s>' % (self.__class__.__name__, self.name, self.regex.pattern))
return smart_str('<%s %s %s>' % (self.__class__.__name__, self.name, self.regex.pattern))
def add_prefix(self, prefix):
"""
@@ -232,7 +233,7 @@ class RegexURLResolver(LocaleRegexProvider):
self._app_dict = {}
def __repr__(self):
return smart_str(u'<%s %s (%s:%s) %s>' % (self.__class__.__name__, self.urlconf_name, self.app_name, self.namespace, self.regex.pattern))
return smart_str('<%s %s (%s:%s) %s>' % (self.__class__.__name__, self.urlconf_name, self.app_name, self.namespace, self.regex.pattern))
def _populate(self):
lookups = MultiValueDict()
@@ -379,7 +380,7 @@ class RegexURLResolver(LocaleRegexProvider):
continue
unicode_kwargs = dict([(k, force_unicode(v)) for (k, v) in kwargs.items()])
candidate = (prefix_norm + result) % unicode_kwargs
if re.search(u'^%s%s' % (_prefix, pattern), candidate, re.UNICODE):
if re.search('^%s%s' % (_prefix, pattern), candidate, re.UNICODE):
return candidate
# lookup_view can be URL label, or dotted path, or callable, Any of
# these can be passed in at the top, but callables are not friendly in
@@ -497,7 +498,7 @@ def get_script_prefix():
wishes to construct their own URLs manually (although accessing the request
instance is normally going to be a lot cleaner).
"""
return getattr(_prefixes, "value", u'/')
return getattr(_prefixes, "value", '/')
def set_urlconf(urlconf_name):
"""

View File

@@ -1,3 +1,5 @@
from __future__ import unicode_literals
import re
import urlparse
@@ -11,7 +13,7 @@ EMPTY_VALUES = (None, '', [], (), {})
class RegexValidator(object):
regex = ''
message = _(u'Enter a valid value.')
message = _('Enter a valid value.')
code = 'invalid'
def __init__(self, regex=None, message=None, code=None):
@@ -75,13 +77,13 @@ class EmailValidator(RegexValidator):
super(EmailValidator, self).__call__(value)
except ValidationError as e:
# Trivial case failed. Try for possible IDN domain-part
if value and u'@' in value:
parts = value.split(u'@')
if value and '@' in value:
parts = value.split('@')
try:
parts[-1] = parts[-1].encode('idna')
except UnicodeError:
raise e
super(EmailValidator, self).__call__(u'@'.join(parts))
super(EmailValidator, self).__call__('@'.join(parts))
else:
raise
@@ -91,17 +93,17 @@ email_re = re.compile(
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"'
r')@((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$)' # domain
r'|\[(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\]$', re.IGNORECASE) # literal form, ipv4 address (SMTP 4.1.3)
validate_email = EmailValidator(email_re, _(u'Enter a valid e-mail address.'), 'invalid')
validate_email = EmailValidator(email_re, _('Enter a valid e-mail address.'), 'invalid')
slug_re = re.compile(r'^[-\w]+$')
validate_slug = RegexValidator(slug_re, _(u"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."), 'invalid')
validate_slug = RegexValidator(slug_re, _("Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."), 'invalid')
ipv4_re = re.compile(r'^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$')
validate_ipv4_address = RegexValidator(ipv4_re, _(u'Enter a valid IPv4 address.'), 'invalid')
validate_ipv4_address = RegexValidator(ipv4_re, _('Enter a valid IPv4 address.'), 'invalid')
def validate_ipv6_address(value):
if not is_valid_ipv6_address(value):
raise ValidationError(_(u'Enter a valid IPv6 address.'), code='invalid')
raise ValidationError(_('Enter a valid IPv6 address.'), code='invalid')
def validate_ipv46_address(value):
try:
@@ -110,7 +112,7 @@ def validate_ipv46_address(value):
try:
validate_ipv6_address(value)
except ValidationError:
raise ValidationError(_(u'Enter a valid IPv4 or IPv6 address.'), code='invalid')
raise ValidationError(_('Enter a valid IPv4 or IPv6 address.'), code='invalid')
ip_address_validator_map = {
'both': ([validate_ipv46_address], _('Enter a valid IPv4 or IPv6 address.')),
@@ -135,13 +137,13 @@ def ip_address_validators(protocol, unpack_ipv4):
% (protocol, ip_address_validator_map.keys()))
comma_separated_int_list_re = re.compile('^[\d,]+$')
validate_comma_separated_integer_list = RegexValidator(comma_separated_int_list_re, _(u'Enter only digits separated by commas.'), 'invalid')
validate_comma_separated_integer_list = RegexValidator(comma_separated_int_list_re, _('Enter only digits separated by commas.'), 'invalid')
class BaseValidator(object):
compare = lambda self, a, b: a is not b
clean = lambda self, x: x
message = _(u'Ensure this value is %(limit_value)s (it is %(show_value)s).')
message = _('Ensure this value is %(limit_value)s (it is %(show_value)s).')
code = 'limit_value'
def __init__(self, limit_value):
@@ -159,23 +161,23 @@ class BaseValidator(object):
class MaxValueValidator(BaseValidator):
compare = lambda self, a, b: a > b
message = _(u'Ensure this value is less than or equal to %(limit_value)s.')
message = _('Ensure this value is less than or equal to %(limit_value)s.')
code = 'max_value'
class MinValueValidator(BaseValidator):
compare = lambda self, a, b: a < b
message = _(u'Ensure this value is greater than or equal to %(limit_value)s.')
message = _('Ensure this value is greater than or equal to %(limit_value)s.')
code = 'min_value'
class MinLengthValidator(BaseValidator):
compare = lambda self, a, b: a < b
clean = lambda self, x: len(x)
message = _(u'Ensure this value has at least %(limit_value)d characters (it has %(show_value)d).')
message = _('Ensure this value has at least %(limit_value)d characters (it has %(show_value)d).')
code = 'min_length'
class MaxLengthValidator(BaseValidator):
compare = lambda self, a, b: a > b
clean = lambda self, x: len(x)
message = _(u'Ensure this value has at most %(limit_value)d characters (it has %(show_value)d).')
message = _('Ensure this value has at most %(limit_value)d characters (it has %(show_value)d).')
code = 'max_length'