summaryrefslogtreecommitdiff
path: root/django/utils
diff options
context:
space:
mode:
authorAymeric Augustin <aymeric.augustin@m4x.org>2012-07-21 10:00:10 +0200
committerAymeric Augustin <aymeric.augustin@m4x.org>2012-08-07 12:00:22 +0200
commitc5ef65bcf324f4c90b53be90f4aec069a68e8c59 (patch)
treebb9a4988fbae4e7366cc578ca845c49003cdcd64 /django/utils
parentee191715eae73362768184aa95206cf61bac5d38 (diff)
[py3] Ported django.utils.encoding.
* Renamed smart_unicode to smart_text (but kept the old name under Python 2 for backwards compatibility). * Renamed smart_str to smart_bytes. * Re-introduced smart_str as an alias for smart_text under Python 3 and smart_bytes under Python 2 (which is backwards compatible). Thus smart_str always returns a str objects. * Used the new smart_str in a few places where both Python 2 and 3 want a str.
Diffstat (limited to 'django/utils')
-rw-r--r--django/utils/_os.py6
-rw-r--r--django/utils/cache.py4
-rw-r--r--django/utils/crypto.py8
-rw-r--r--django/utils/dateformat.py6
-rw-r--r--django/utils/encoding.py66
-rw-r--r--django/utils/feedgenerator.py12
-rw-r--r--django/utils/html.py22
-rw-r--r--django/utils/http.py10
-rw-r--r--django/utils/text.py24
-rw-r--r--django/utils/translation/__init__.py4
-rw-r--r--django/utils/translation/trans_null.py6
-rw-r--r--django/utils/tzinfo.py6
12 files changed, 96 insertions, 78 deletions
diff --git a/django/utils/_os.py b/django/utils/_os.py
index 884689fefc..82dccd0efe 100644
--- a/django/utils/_os.py
+++ b/django/utils/_os.py
@@ -1,7 +1,7 @@
import os
import stat
from os.path import join, normcase, normpath, abspath, isabs, sep
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
try:
WindowsError = WindowsError
@@ -37,8 +37,8 @@ def safe_join(base, *paths):
The final path must be located inside of the base path component (otherwise
a ValueError is raised).
"""
- base = force_unicode(base)
- paths = [force_unicode(p) for p in paths]
+ base = force_text(base)
+ paths = [force_text(p) for p in paths]
final_path = abspathu(join(base, *paths))
base_path = abspathu(base)
base_path_len = len(base_path)
diff --git a/django/utils/cache.py b/django/utils/cache.py
index 8b81a2ffa2..42b0de4ce6 100644
--- a/django/utils/cache.py
+++ b/django/utils/cache.py
@@ -23,7 +23,7 @@ import time
from django.conf import settings
from django.core.cache import get_cache
-from django.utils.encoding import iri_to_uri, force_unicode
+from django.utils.encoding import iri_to_uri, force_text
from django.utils.http import http_date
from django.utils.timezone import get_current_timezone_name
from django.utils.translation import get_language
@@ -169,7 +169,7 @@ def _i18n_cache_key_suffix(request, cache_key):
# Windows is known to use non-standard, locale-dependant names.
# User-defined tzinfo classes may return absolutely anything.
# Hence this paranoid conversion to create a valid cache key.
- tz_name = force_unicode(get_current_timezone_name(), errors='ignore')
+ tz_name = force_text(get_current_timezone_name(), errors='ignore')
cache_key += '.%s' % tz_name.encode('ascii', 'ignore').replace(' ', '_')
return cache_key
diff --git a/django/utils/crypto.py b/django/utils/crypto.py
index 9d46bdd793..1edbb43eb3 100644
--- a/django/utils/crypto.py
+++ b/django/utils/crypto.py
@@ -23,7 +23,7 @@ except NotImplementedError:
using_sysrandom = False
from django.conf import settings
-from django.utils.encoding import smart_str
+from django.utils.encoding import smart_bytes
from django.utils.six.moves import xrange
@@ -115,7 +115,7 @@ def _fast_hmac(key, msg, digest):
A trimmed down version of Python's HMAC implementation
"""
dig1, dig2 = digest(), digest()
- key = smart_str(key)
+ key = smart_bytes(key)
if len(key) > dig1.block_size:
key = digest(key).digest()
key += chr(0) * (dig1.block_size - len(key))
@@ -141,8 +141,8 @@ def pbkdf2(password, salt, iterations, dklen=0, digest=None):
assert iterations > 0
if not digest:
digest = hashlib.sha256
- password = smart_str(password)
- salt = smart_str(salt)
+ password = smart_bytes(password)
+ salt = smart_bytes(salt)
hlen = digest().digest_size
if not dklen:
dklen = hlen
diff --git a/django/utils/dateformat.py b/django/utils/dateformat.py
index c9a6138aed..6a91a370e5 100644
--- a/django/utils/dateformat.py
+++ b/django/utils/dateformat.py
@@ -20,7 +20,7 @@ import datetime
from django.utils.dates import MONTHS, MONTHS_3, MONTHS_ALT, MONTHS_AP, WEEKDAYS, WEEKDAYS_ABBR
from django.utils.tzinfo import LocalTimezone
from django.utils.translation import ugettext as _
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
from django.utils import six
from django.utils.timezone import is_aware, is_naive
@@ -30,9 +30,9 @@ re_escaped = re.compile(r'\\(.)')
class Formatter(object):
def format(self, formatstr):
pieces = []
- for i, piece in enumerate(re_formatchars.split(force_unicode(formatstr))):
+ for i, piece in enumerate(re_formatchars.split(force_text(formatstr))):
if i % 2:
- pieces.append(force_unicode(getattr(self, piece)()))
+ pieces.append(force_text(getattr(self, piece)()))
elif piece:
pieces.append(re_escaped.sub(r'\1', piece))
return ''.join(pieces)
diff --git a/django/utils/encoding.py b/django/utils/encoding.py
index b5f4b76507..eb60cfde8b 100644
--- a/django/utils/encoding.py
+++ b/django/utils/encoding.py
@@ -24,9 +24,13 @@ class DjangoUnicodeDecodeError(UnicodeDecodeError):
class StrAndUnicode(object):
"""
- A class whose __str__ returns its __unicode__ as a UTF-8 bytestring.
+ A class that derives __str__ from __unicode__.
- Useful as a mix-in.
+ On Python 2, __str__ returns the output of __unicode__ encoded as a UTF-8
+ bytestring. On Python 3, __str__ returns the output of __unicode__.
+
+ Useful as a mix-in. If you support Python 2 and 3 with a single code base,
+ you can inherit this mix-in and just define __unicode__.
"""
if six.PY3:
def __str__(self):
@@ -35,37 +39,36 @@ class StrAndUnicode(object):
def __str__(self):
return self.__unicode__().encode('utf-8')
-def smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
+def smart_text(s, encoding='utf-8', strings_only=False, errors='strict'):
"""
- Returns a unicode object representing 's'. Treats bytestrings using the
- 'encoding' codec.
+ Returns a text object representing 's' -- unicode on Python 2 and str on
+ Python 3. Treats bytestrings using the 'encoding' codec.
If strings_only is True, don't convert (some) non-string-like objects.
"""
if isinstance(s, Promise):
# The input is the result of a gettext_lazy() call.
return s
- return force_unicode(s, encoding, strings_only, errors)
+ return force_text(s, encoding, strings_only, errors)
def is_protected_type(obj):
"""Determine if the object instance is of a protected type.
Objects of protected types are preserved as-is when passed to
- force_unicode(strings_only=True).
+ force_text(strings_only=True).
"""
return isinstance(obj, six.integer_types + (type(None), float, Decimal,
datetime.datetime, datetime.date, datetime.time))
-def force_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
+def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
"""
- Similar to smart_unicode, except that lazy instances are resolved to
+ Similar to smart_text, except that lazy instances are resolved to
strings, rather than kept as lazy objects.
If strings_only is True, don't convert (some) non-string-like objects.
"""
- # Handle the common case first, saves 30-40% in performance when s
- # is an instance of unicode. This function gets called often in that
- # setting.
+ # Handle the common case first, saves 30-40% when s is an instance of
+ # six.text_type. This function gets called often in that setting.
if isinstance(s, six.text_type):
return s
if strings_only and is_protected_type(s):
@@ -92,7 +95,7 @@ def force_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
# without raising a further exception. We do an
# approximation to what the Exception's standard str()
# output should be.
- s = ' '.join([force_unicode(arg, encoding, strings_only,
+ s = ' '.join([force_text(arg, encoding, strings_only,
errors) for arg in s])
else:
# Note: We use .decode() here, instead of six.text_type(s, encoding,
@@ -108,21 +111,26 @@ def force_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
# working unicode method. Try to handle this without raising a
# further exception by individually forcing the exception args
# to unicode.
- s = ' '.join([force_unicode(arg, encoding, strings_only,
+ s = ' '.join([force_text(arg, encoding, strings_only,
errors) for arg in s])
return s
-def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'):
+def smart_bytes(s, encoding='utf-8', strings_only=False, errors='strict'):
"""
Returns a bytestring version of 's', encoded as specified in 'encoding'.
If strings_only is True, don't convert (some) non-string-like objects.
"""
+ if isinstance(s, bytes):
+ if encoding == 'utf-8':
+ return s
+ else:
+ return s.decode('utf-8', errors).encode(encoding, errors)
if strings_only and (s is None or isinstance(s, int)):
return s
if isinstance(s, Promise):
return six.text_type(s).encode(encoding, errors)
- elif not isinstance(s, six.string_types):
+ if not isinstance(s, six.string_types):
try:
if six.PY3:
return six.text_type(s).encode(encoding)
@@ -133,15 +141,25 @@ def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'):
# An Exception subclass containing non-ASCII data that doesn't
# know how to print itself properly. We shouldn't raise a
# further exception.
- return ' '.join([smart_str(arg, encoding, strings_only,
+ return ' '.join([smart_bytes(arg, encoding, strings_only,
errors) for arg in s])
return six.text_type(s).encode(encoding, errors)
- elif isinstance(s, six.text_type):
- return s.encode(encoding, errors)
- elif s and encoding != 'utf-8':
- return s.decode('utf-8', errors).encode(encoding, errors)
else:
- return s
+ return s.encode(encoding, errors)
+
+if six.PY3:
+ smart_str = smart_text
+else:
+ smart_str = smart_bytes
+ # backwards compatibility for Python 2
+ smart_unicode = smart_text
+ force_unicode = force_text
+
+smart_str.__doc__ = """\
+Apply smart_text in Python 3 and smart_bytes in Python 2.
+
+This is suitable for writing to sys.stdout (for instance).
+"""
def iri_to_uri(iri):
"""
@@ -168,7 +186,7 @@ def iri_to_uri(iri):
# converted.
if iri is None:
return iri
- return quote(smart_str(iri), safe=b"/#%[]=:;$&()+,!?*@'~")
+ return quote(smart_bytes(iri), safe=b"/#%[]=:;$&()+,!?*@'~")
def filepath_to_uri(path):
"""Convert an file system path to a URI portion that is suitable for
@@ -187,7 +205,7 @@ def filepath_to_uri(path):
return path
# I know about `os.sep` and `os.altsep` but I want to leave
# some flexibility for hardcoding separators.
- return quote(smart_str(path).replace("\\", "/"), safe=b"/~!*()'")
+ return quote(smart_bytes(path).replace("\\", "/"), safe=b"/~!*()'")
# The encoding of the default system locale but falls back to the
# given fallback encoding if the encoding is unsupported by python or could
diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py
index 6498aaf57c..1bf43bf0a7 100644
--- a/django/utils/feedgenerator.py
+++ b/django/utils/feedgenerator.py
@@ -29,7 +29,7 @@ try:
except ImportError: # Python 2
from urlparse import urlparse
from django.utils.xmlutils import SimplerXMLGenerator
-from django.utils.encoding import force_unicode, iri_to_uri
+from django.utils.encoding import force_text, iri_to_uri
from django.utils import datetime_safe
from django.utils.timezone import is_aware
@@ -81,12 +81,12 @@ class SyndicationFeed(object):
def __init__(self, title, link, description, language=None, author_email=None,
author_name=None, author_link=None, subtitle=None, categories=None,
feed_url=None, feed_copyright=None, feed_guid=None, ttl=None, **kwargs):
- to_unicode = lambda s: force_unicode(s, strings_only=True)
+ to_unicode = lambda s: force_text(s, strings_only=True)
if categories:
- categories = [force_unicode(c) for c in categories]
+ categories = [force_text(c) for c in categories]
if ttl is not None:
# Force ints to unicode
- ttl = force_unicode(ttl)
+ ttl = force_text(ttl)
self.feed = {
'title': to_unicode(title),
'link': iri_to_uri(link),
@@ -114,12 +114,12 @@ class SyndicationFeed(object):
objects except pubdate, which is a datetime.datetime object, and
enclosure, which is an instance of the Enclosure class.
"""
- to_unicode = lambda s: force_unicode(s, strings_only=True)
+ to_unicode = lambda s: force_text(s, strings_only=True)
if categories:
categories = [to_unicode(c) for c in categories]
if ttl is not None:
# Force ints to unicode
- ttl = force_unicode(ttl)
+ ttl = force_text(ttl)
item = {
'title': to_unicode(title),
'link': iri_to_uri(link),
diff --git a/django/utils/html.py b/django/utils/html.py
index 4e888fc59b..7dd53a1353 100644
--- a/django/utils/html.py
+++ b/django/utils/html.py
@@ -11,7 +11,7 @@ except ImportError: # Python 2
from urlparse import urlsplit, urlunsplit
from django.utils.safestring import SafeData, mark_safe
-from django.utils.encoding import smart_str, force_unicode
+from django.utils.encoding import smart_bytes, force_text
from django.utils.functional import allow_lazy
from django.utils import six
from django.utils.text import normalize_newlines
@@ -39,7 +39,7 @@ def escape(text):
"""
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_text(text).replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;'))
escape = allow_lazy(escape, six.text_type)
_base_js_escapes = (
@@ -63,7 +63,7 @@ _js_escapes = (_base_js_escapes +
def escapejs(value):
"""Hex encodes characters for use in JavaScript strings."""
for bad, good in _js_escapes:
- value = mark_safe(force_unicode(value).replace(bad, good))
+ value = mark_safe(force_text(value).replace(bad, good))
return value
escapejs = allow_lazy(escapejs, six.text_type)
@@ -120,22 +120,22 @@ linebreaks = allow_lazy(linebreaks, six.text_type)
def strip_tags(value):
"""Returns the given HTML with all tags stripped."""
- return re.sub(r'<[^>]*?>', '', force_unicode(value))
+ return re.sub(r'<[^>]*?>', '', force_text(value))
strip_tags = allow_lazy(strip_tags)
def strip_spaces_between_tags(value):
"""Returns the given HTML with spaces between tags removed."""
- return re.sub(r'>\s+<', '><', force_unicode(value))
+ return re.sub(r'>\s+<', '><', force_text(value))
strip_spaces_between_tags = allow_lazy(strip_spaces_between_tags, six.text_type)
def strip_entities(value):
"""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_text(value))
strip_entities = allow_lazy(strip_entities, six.text_type)
def fix_ampersands(value):
"""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_text(value))
fix_ampersands = allow_lazy(fix_ampersands, six.text_type)
def smart_urlquote(url):
@@ -153,9 +153,9 @@ def smart_urlquote(url):
# contains a % not followed by two hexadecimal digits. See #9655.
if '%' not in url or unquoted_percents_re.search(url):
# See http://bugs.python.org/issue2637
- url = quote(smart_str(url), safe=b'!*\'();:@&=+$,/?#[]~')
+ url = quote(smart_bytes(url), safe=b'!*\'();:@&=+$,/?#[]~')
- return force_unicode(url)
+ return force_text(url)
def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
"""
@@ -176,7 +176,7 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False):
"""
trim_url = lambda x, limit=trim_url_limit: limit is not None and (len(x) > limit and ('%s...' % x[:max(0, limit - 3)])) or x
safe_input = isinstance(text, SafeData)
- words = word_split_re.split(force_unicode(text))
+ words = word_split_re.split(force_text(text))
for i, word in enumerate(words):
match = None
if '.' in word or '@' in word or ':' in word:
@@ -245,7 +245,7 @@ def clean_html(text):
bottom of the text.
"""
from django.utils.text import normalize_newlines
- text = normalize_newlines(force_unicode(text))
+ text = normalize_newlines(force_text(text))
text = re.sub(r'<(/?)\s*b\s*>', '<\\1strong>', text)
text = re.sub(r'<(/?)\s*i\s*>', '<\\1em>', text)
text = fix_ampersands(text)
diff --git a/django/utils/http.py b/django/utils/http.py
index 272e73f190..22e81a33d7 100644
--- a/django/utils/http.py
+++ b/django/utils/http.py
@@ -13,7 +13,7 @@ except ImportError: # Python 2
from email.utils import formatdate
from django.utils.datastructures import MultiValueDict
-from django.utils.encoding import smart_str, force_unicode
+from django.utils.encoding import force_text, smart_str
from django.utils.functional import allow_lazy
from django.utils import six
@@ -37,7 +37,7 @@ def urlquote(url, safe='/'):
can safely be used as part of an argument to a subsequent iri_to_uri() call
without double-quoting occurring.
"""
- return force_unicode(urllib_parse.quote(smart_str(url), smart_str(safe)))
+ return force_text(urllib_parse.quote(smart_str(url), smart_str(safe)))
urlquote = allow_lazy(urlquote, six.text_type)
def urlquote_plus(url, safe=''):
@@ -47,7 +47,7 @@ def urlquote_plus(url, safe=''):
returned string can safely be used as part of an argument to a subsequent
iri_to_uri() call without double-quoting occurring.
"""
- return force_unicode(urllib_parse.quote_plus(smart_str(url), smart_str(safe)))
+ return force_text(urllib_parse.quote_plus(smart_str(url), smart_str(safe)))
urlquote_plus = allow_lazy(urlquote_plus, six.text_type)
def urlunquote(quoted_url):
@@ -55,7 +55,7 @@ def urlunquote(quoted_url):
A wrapper for Python's urllib.unquote() function that can operate on
the result of django.utils.http.urlquote().
"""
- return force_unicode(urllib_parse.unquote(smart_str(quoted_url)))
+ return force_text(urllib_parse.unquote(smart_str(quoted_url)))
urlunquote = allow_lazy(urlunquote, six.text_type)
def urlunquote_plus(quoted_url):
@@ -63,7 +63,7 @@ def urlunquote_plus(quoted_url):
A wrapper for Python's urllib.unquote_plus() function that can operate on
the result of django.utils.http.urlquote_plus().
"""
- return force_unicode(urllib_parse.unquote_plus(smart_str(quoted_url)))
+ return force_text(urllib_parse.unquote_plus(smart_str(quoted_url)))
urlunquote_plus = allow_lazy(urlunquote_plus, six.text_type)
def urlencode(query, doseq=0):
diff --git a/django/utils/text.py b/django/utils/text.py
index 43056aa634..0838d79c65 100644
--- a/django/utils/text.py
+++ b/django/utils/text.py
@@ -7,13 +7,13 @@ from gzip import GzipFile
from django.utils.six.moves import html_entities
from io import BytesIO
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
from django.utils.functional import allow_lazy, SimpleLazyObject
from django.utils import six
from django.utils.translation import ugettext_lazy, ugettext as _, pgettext
# 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_text(x)[0].upper() + force_text(x)[1:]
capfirst = allow_lazy(capfirst, six.text_type)
# Set up regular expressions
@@ -26,7 +26,7 @@ def wrap(text, width):
A word-wrap function that preserves existing line breaks and most spaces in
the text. Expects that existing line breaks are posix newlines.
"""
- text = force_unicode(text)
+ text = force_text(text)
def _generator():
it = iter(text.split(' '))
word = next(it)
@@ -55,14 +55,14 @@ class Truncator(SimpleLazyObject):
An object used to truncate text, either by characters or words.
"""
def __init__(self, text):
- super(Truncator, self).__init__(lambda: force_unicode(text))
+ super(Truncator, self).__init__(lambda: force_text(text))
def add_truncation_text(self, text, truncate=None):
if truncate is None:
truncate = pgettext(
'String to return when truncating text',
'%(truncated_text)s...')
- truncate = force_unicode(truncate)
+ truncate = force_text(truncate)
if '%(truncated_text)s' in truncate:
return truncate % {'truncated_text': text}
# The truncation text didn't contain the %(truncated_text)s string
@@ -226,7 +226,7 @@ def get_valid_filename(s):
>>> get_valid_filename("john's portrait in 2004.jpg")
'johns_portrait_in_2004.jpg'
"""
- s = force_unicode(s).strip().replace(' ', '_')
+ s = force_text(s).strip().replace(' ', '_')
return re.sub(r'(?u)[^-\w.]', '', s)
get_valid_filename = allow_lazy(get_valid_filename, six.text_type)
@@ -244,20 +244,20 @@ def get_text_list(list_, last_word=ugettext_lazy('or')):
''
"""
if len(list_) == 0: return ''
- if len(list_) == 1: return force_unicode(list_[0])
+ if len(list_) == 1: return force_text(list_[0])
return '%s %s %s' % (
# Translators: This string is used as a separator between list elements
- _(', ').join([force_unicode(i) for i in list_][:-1]),
- force_unicode(last_word), force_unicode(list_[-1]))
+ _(', ').join([force_text(i) for i in list_][:-1]),
+ force_text(last_word), force_text(list_[-1]))
get_text_list = allow_lazy(get_text_list, six.text_type)
def normalize_newlines(text):
- return force_unicode(re.sub(r'\r\n|\r|\n', '\n', text))
+ return force_text(re.sub(r'\r\n|\r|\n', '\n', text))
normalize_newlines = allow_lazy(normalize_newlines, six.text_type)
def recapitalize(text):
"Recapitalizes text, placing caps after end-of-sentence punctuation."
- text = force_unicode(text).lower()
+ text = force_text(text).lower()
capsRE = re.compile(r'(?:^|(?<=[\.\?\!] ))([a-z])')
text = capsRE.sub(lambda x: x.group(1).upper(), text)
return text
@@ -330,7 +330,7 @@ def smart_split(text):
>>> list(smart_split(r'A "\"funky\" style" test.'))
['A', '"\\"funky\\" style"', 'test.']
"""
- text = force_unicode(text)
+ text = force_text(text)
for bit in smart_split_re.finditer(text):
yield bit.group(0)
smart_split = allow_lazy(smart_split, six.text_type)
diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py
index d31a7aebf1..febde404a5 100644
--- a/django/utils/translation/__init__.py
+++ b/django/utils/translation/__init__.py
@@ -3,7 +3,7 @@ Internationalization support.
"""
from __future__ import unicode_literals
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
from django.utils.functional import lazy
from django.utils import six
@@ -139,7 +139,7 @@ def _string_concat(*strings):
Lazy variant of string concatenation, needed for translations that are
constructed from multiple parts.
"""
- return ''.join([force_unicode(s) for s in strings])
+ return ''.join([force_text(s) for s in strings])
string_concat = lazy(_string_concat, six.text_type)
def get_language_info(lang_code):
diff --git a/django/utils/translation/trans_null.py b/django/utils/translation/trans_null.py
index 0fabc707ce..5c51468204 100644
--- a/django/utils/translation/trans_null.py
+++ b/django/utils/translation/trans_null.py
@@ -3,7 +3,7 @@
# settings.USE_I18N = False can use this module rather than trans_real.py.
from django.conf import settings
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
from django.utils.safestring import mark_safe, SafeData
def ngettext(singular, plural, number):
@@ -12,7 +12,7 @@ def ngettext(singular, plural, number):
ngettext_lazy = ngettext
def ungettext(singular, plural, number):
- return force_unicode(ngettext(singular, plural, number))
+ return force_text(ngettext(singular, plural, number))
def pgettext(context, message):
return ugettext(message)
@@ -44,7 +44,7 @@ def gettext(message):
return result
def ugettext(message):
- return force_unicode(gettext(message))
+ return force_text(gettext(message))
gettext_noop = gettext_lazy = _ = gettext
diff --git a/django/utils/tzinfo.py b/django/utils/tzinfo.py
index 05f4aa6d2f..c40b430411 100644
--- a/django/utils/tzinfo.py
+++ b/django/utils/tzinfo.py
@@ -5,7 +5,7 @@ from __future__ import unicode_literals
import time
from datetime import timedelta, tzinfo
-from django.utils.encoding import smart_unicode, smart_str, DEFAULT_LOCALE_ENCODING
+from django.utils.encoding import smart_text, smart_bytes, DEFAULT_LOCALE_ENCODING
# Python's doc say: "A tzinfo subclass must have an __init__() method that can
# be called with no arguments". FixedOffset and LocalTimezone don't honor this
@@ -53,7 +53,7 @@ class LocalTimezone(tzinfo):
self._tzname = self.tzname(dt)
def __repr__(self):
- return smart_str(self._tzname)
+ return smart_bytes(self._tzname)
def __getinitargs__(self):
return self.__dt,
@@ -72,7 +72,7 @@ class LocalTimezone(tzinfo):
def tzname(self, dt):
try:
- return smart_unicode(time.tzname[self._isdst(dt)],
+ return smart_text(time.tzname[self._isdst(dt)],
DEFAULT_LOCALE_ENCODING)
except UnicodeDecodeError:
return None