summaryrefslogtreecommitdiff
path: root/django/utils
diff options
context:
space:
mode:
authorAymeric Augustin <aymeric.augustin@m4x.org>2012-07-20 14:48:51 +0200
committerAymeric Augustin <aymeric.augustin@m4x.org>2012-07-22 09:29:54 +0200
commitbdca5ea345c548a82a80d198906818c9ccbef896 (patch)
tree5c3f5fe5ad2522175d67b96a1fce1ff1763ba125 /django/utils
parent3cb2457f46b3e40ff6b6acffcb3fd44cbea091e5 (diff)
[py3] Replaced unicode/str by six.text_type/bytes.
Diffstat (limited to 'django/utils')
-rw-r--r--django/utils/dateformat.py5
-rw-r--r--django/utils/encoding.py37
-rw-r--r--django/utils/formats.py4
-rw-r--r--django/utils/functional.py11
-rw-r--r--django/utils/html.py17
-rw-r--r--django/utils/http.py9
-rw-r--r--django/utils/numberformat.py5
-rw-r--r--django/utils/safestring.py33
-rw-r--r--django/utils/text.py25
-rw-r--r--django/utils/translation/__init__.py15
10 files changed, 91 insertions, 70 deletions
diff --git a/django/utils/dateformat.py b/django/utils/dateformat.py
index d410bce63e..c9a6138aed 100644
--- a/django/utils/dateformat.py
+++ b/django/utils/dateformat.py
@@ -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.translation import ugettext as _
from django.utils.encoding import force_unicode
+from django.utils import six
from django.utils.timezone import is_aware, is_naive
re_formatchars = re.compile(r'(?<!\\)([aAbBcdDeEfFgGhHiIjlLmMnNoOPrsStTUuwWyYzZ])')
@@ -236,7 +237,7 @@ class DateFormat(TimeFormat):
name = self.timezone and self.timezone.tzname(self.data) or None
if name is None:
name = self.format('O')
- return unicode(name)
+ return six.text_type(name)
def U(self):
"Seconds since the Unix epoch (January 1 1970 00:00:00 GMT)"
@@ -277,7 +278,7 @@ class DateFormat(TimeFormat):
def y(self):
"Year, 2 digits; e.g. '99'"
- return unicode(self.data.year)[2:]
+ return six.text_type(self.data.year)[2:]
def Y(self):
"Year, 4 digits; e.g. '1999'"
diff --git a/django/utils/encoding.py b/django/utils/encoding.py
index 716d46ceff..789e709da5 100644
--- a/django/utils/encoding.py
+++ b/django/utils/encoding.py
@@ -25,8 +25,12 @@ class StrAndUnicode(object):
Useful as a mix-in.
"""
- def __str__(self):
- return self.__unicode__().encode('utf-8')
+ if six.PY3:
+ def __str__(self):
+ return self.__unicode__()
+ else:
+ def __str__(self):
+ return self.__unicode__().encode('utf-8')
def smart_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
"""
@@ -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
# is an instance of unicode. This function gets called often in that
# setting.
- if isinstance(s, unicode):
+ if isinstance(s, six.text_type):
return s
if strings_only and is_protected_type(s):
return s
try:
- if not isinstance(s, six.string_types,):
+ if not isinstance(s, six.string_types):
if hasattr(s, '__unicode__'):
- s = unicode(s)
+ s = s.__unicode__()
else:
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:
if not isinstance(s, Exception):
raise
@@ -81,8 +91,8 @@ def force_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
# output should be.
s = ' '.join([force_unicode(arg, encoding, strings_only,
errors) for arg in s])
- elif not isinstance(s, unicode):
- # Note: We use .decode() here, instead of unicode(s, encoding,
+ elif not isinstance(s, six.text_type):
+ # 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
# SafeUnicode at the end.
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)):
return s
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):
try:
- return str(s)
+ if six.PY3:
+ return six.text_type(s).encode(encoding)
+ else:
+ return bytes(s)
except UnicodeEncodeError:
if isinstance(s, Exception):
# 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.
return ' '.join([smart_str(arg, encoding, strings_only,
errors) for arg in s])
- return unicode(s).encode(encoding, errors)
- elif isinstance(s, unicode):
+ 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)
diff --git a/django/utils/formats.py b/django/utils/formats.py
index eae40970da..2e54d792fa 100644
--- a/django/utils/formats.py
+++ b/django/utils/formats.py
@@ -89,7 +89,7 @@ def get_format(format_type, lang=None, use_l10n=None):
_format_cache[cache_key] = None
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):
"""
@@ -139,7 +139,7 @@ def localize(value, use_l10n=None):
be localized (or not), overriding the value of settings.USE_L10N.
"""
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):
return number_format(value, use_l10n=use_l10n)
elif isinstance(value, datetime.datetime):
diff --git a/django/utils/functional.py b/django/utils/functional.py
index 31466ee8b8..2dca182b99 100644
--- a/django/utils/functional.py
+++ b/django/utils/functional.py
@@ -3,6 +3,7 @@ import operator
from functools import wraps, update_wrapper
import sys
+from django.utils import six
# You can't trivially replace this `functools.partial` because this binds to
# classes and returns bound instances, whereas functools.partial (on CPython)
@@ -92,8 +93,8 @@ def lazy(func, *resultclasses):
if hasattr(cls, k):
continue
setattr(cls, k, meth)
- cls._delegate_str = str in resultclasses
- cls._delegate_unicode = unicode in resultclasses
+ cls._delegate_str = bytes 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."
if cls._delegate_unicode:
cls.__unicode__ = cls.__unicode_cast
@@ -147,7 +148,7 @@ def lazy(func, *resultclasses):
if self._delegate_str:
return str(self) % rhs
elif self._delegate_unicode:
- return unicode(self) % rhs
+ return six.text_type(self) % rhs
else:
raise AssertionError('__mod__ not supported for non-string types')
@@ -255,8 +256,8 @@ class SimpleLazyObject(LazyObject):
def _setup(self):
self._wrapped = self._setupfunc()
- __str__ = new_method_proxy(str)
- __unicode__ = new_method_proxy(unicode)
+ __str__ = new_method_proxy(bytes)
+ __unicode__ = new_method_proxy(six.text_type)
def __deepcopy__(self, memo):
if self._wrapped is empty:
diff --git a/django/utils/html.py b/django/utils/html.py
index 390c45dcec..d5881996d9 100644
--- a/django/utils/html.py
+++ b/django/utils/html.py
@@ -10,6 +10,7 @@ import urlparse
from django.utils.safestring import SafeData, mark_safe
from django.utils.encoding import smart_str, force_unicode
from django.utils.functional import allow_lazy
+from django.utils import six
from django.utils.text import normalize_newlines
# 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.
"""
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 = (
('\\', '\\u005C'),
@@ -61,7 +62,7 @@ def escapejs(value):
for bad, good in _js_escapes:
value = mark_safe(force_unicode(value).replace(bad, good))
return value
-escapejs = allow_lazy(escapejs, unicode)
+escapejs = allow_lazy(escapejs, six.text_type)
def conditional_escape(text):
"""
@@ -112,7 +113,7 @@ def linebreaks(value, autoescape=False):
else:
paras = ['<p>%s</p>' % p.replace('\n', '<br />') for p in paras]
return '\n\n'.join(paras)
-linebreaks = allow_lazy(linebreaks, unicode)
+linebreaks = allow_lazy(linebreaks, six.text_type)
def strip_tags(value):
"""Returns the given HTML with all tags stripped."""
@@ -122,17 +123,17 @@ 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))
-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):
"""Returns the given HTML with all entities (&something;) stripped."""
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):
"""Returns the given HTML with all unencoded ampersands encoded correctly."""
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):
"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:
words[i] = escape(word)
return ''.join(words)
-urlize = allow_lazy(urlize, unicode)
+urlize = allow_lazy(urlize, six.text_type)
def clean_html(text):
"""
@@ -260,4 +261,4 @@ def clean_html(text):
# of the text.
text = trailing_empty_content_re.sub('', text)
return text
-clean_html = allow_lazy(clean_html, unicode)
+clean_html = allow_lazy(clean_html, six.text_type)
diff --git a/django/utils/http.py b/django/utils/http.py
index 87db284416..ec94d62903 100644
--- a/django/utils/http.py
+++ b/django/utils/http.py
@@ -9,6 +9,7 @@ from email.utils import formatdate
from django.utils.datastructures import MultiValueDict
from django.utils.encoding import smart_str, force_unicode
from django.utils.functional import allow_lazy
+from django.utils import six
ETAG_MATCH = re.compile(r'(?:W/)?"((?:\\.|[^"])*)"')
@@ -31,7 +32,7 @@ def urlquote(url, safe='/'):
without double-quoting occurring.
"""
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=''):
"""
@@ -41,7 +42,7 @@ def urlquote_plus(url, safe=''):
iri_to_uri() call without double-quoting occurring.
"""
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):
"""
@@ -49,7 +50,7 @@ def urlunquote(quoted_url):
the result of django.utils.http.urlquote().
"""
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):
"""
@@ -57,7 +58,7 @@ def urlunquote_plus(quoted_url):
the result of django.utils.http.urlquote_plus().
"""
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):
"""
diff --git a/django/utils/numberformat.py b/django/utils/numberformat.py
index 924d06511b..d51b230823 100644
--- a/django/utils/numberformat.py
+++ b/django/utils/numberformat.py
@@ -1,5 +1,6 @@
from django.conf import settings
from django.utils.safestring import mark_safe
+from django.utils import six
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
# Make the common case fast
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
if float(number) < 0:
sign = '-'
else:
sign = ''
- str_number = unicode(number)
+ str_number = six.text_type(number)
if str_number[0] == '-':
str_number = str_number[1:]
# decimal part
diff --git a/django/utils/safestring.py b/django/utils/safestring.py
index 2e31c23676..1599fc2a66 100644
--- a/django/utils/safestring.py
+++ b/django/utils/safestring.py
@@ -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.
"""
from django.utils.functional import curry, Promise
+from django.utils import six
class EscapeData(object):
pass
-class EscapeString(str, EscapeData):
+class EscapeString(bytes, EscapeData):
"""
A string that should be HTML-escaped when output.
"""
pass
-class EscapeUnicode(unicode, EscapeData):
+class EscapeUnicode(six.text_type, EscapeData):
"""
A unicode object that should be HTML-escaped when output.
"""
@@ -24,7 +25,7 @@ class EscapeUnicode(unicode, EscapeData):
class SafeData(object):
pass
-class SafeString(str, SafeData):
+class SafeString(bytes, SafeData):
"""
A string subclass that has been specifically marked as "safe" (requires no
further escaping) for HTML output purposes.
@@ -40,7 +41,7 @@ class SafeString(str, SafeData):
elif isinstance(rhs, SafeString):
return SafeString(t)
return t
-
+
def _proxy_method(self, *args, **kwargs):
"""
Wrap a call to a normal unicode method up so that we return safe
@@ -49,14 +50,14 @@ class SafeString(str, SafeData):
"""
method = kwargs.pop('method')
data = method(self, *args, **kwargs)
- if isinstance(data, str):
+ if isinstance(data, bytes):
return SafeString(data)
else:
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
output purposes.
@@ -70,7 +71,7 @@ class SafeUnicode(unicode, SafeData):
if isinstance(rhs, SafeData):
return SafeUnicode(t)
return t
-
+
def _proxy_method(self, *args, **kwargs):
"""
Wrap a call to a normal unicode method up so that we return safe
@@ -79,12 +80,12 @@ class SafeUnicode(unicode, SafeData):
"""
method = kwargs.pop('method')
data = method(self, *args, **kwargs)
- if isinstance(data, str):
+ if isinstance(data, bytes):
return SafeString(data)
else:
return SafeUnicode(data)
- encode = curry(_proxy_method, method = unicode.encode)
+ encode = curry(_proxy_method, method=six.text_type.encode)
def mark_safe(s):
"""
@@ -95,11 +96,11 @@ def mark_safe(s):
"""
if isinstance(s, SafeData):
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)
- if isinstance(s, (unicode, Promise)):
+ if isinstance(s, (six.text_type, Promise)):
return SafeUnicode(s)
- return SafeString(str(s))
+ return SafeString(bytes(s))
def mark_for_escaping(s):
"""
@@ -111,9 +112,9 @@ def mark_for_escaping(s):
"""
if isinstance(s, (SafeData, EscapeData)):
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)
- if isinstance(s, (unicode, Promise)):
+ if isinstance(s, (six.text_type, Promise)):
return EscapeUnicode(s)
- return EscapeString(str(s))
+ return EscapeString(bytes(s))
diff --git a/django/utils/text.py b/django/utils/text.py
index 2546f770b5..9f773ad41b 100644
--- a/django/utils/text.py
+++ b/django/utils/text.py
@@ -9,11 +9,12 @@ from io import BytesIO
from django.utils.encoding import force_unicode
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 = allow_lazy(capfirst, unicode)
+capfirst = allow_lazy(capfirst, six.text_type)
# Set up regular expressions
re_words = re.compile(r'&.*?;|<.*?>|(\w[\w-]*)', re.U|re.S)
@@ -46,7 +47,7 @@ def wrap(text, width):
pos = len(lines[-1])
yield word
return ''.join(_generator())
-wrap = allow_lazy(wrap, unicode)
+wrap = allow_lazy(wrap, six.text_type)
class Truncator(SimpleLazyObject):
@@ -207,14 +208,14 @@ def truncate_words(s, num, end_text='...'):
'in django.utils.text instead.', category=DeprecationWarning)
truncate = end_text and ' %s' % end_text or ''
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='...'):
warnings.warn('This function has been deprecated. Use the Truncator class '
'in django.utils.text instead.', category=DeprecationWarning)
truncate = end_text and ' %s' % end_text or ''
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):
"""
@@ -227,7 +228,7 @@ def get_valid_filename(s):
"""
s = force_unicode(s).strip().replace(' ', '_')
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')):
"""
@@ -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
_(', ').join([force_unicode(i) for i in 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):
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):
"Recapitalizes text, placing caps after end-of-sentence punctuation."
@@ -288,9 +289,9 @@ def javascript_quote(s, quote_double_quotes=False):
def fix(match):
return b"\u%04x" % ord(match.group(1))
- if type(s) == str:
+ if type(s) == bytes:
s = s.decode('utf-8')
- elif type(s) != unicode:
+ elif type(s) != six.text_type:
raise TypeError(s)
s = s.replace('\\', '\\\\')
s = s.replace('\r', '\\r')
@@ -300,7 +301,7 @@ def javascript_quote(s, quote_double_quotes=False):
if quote_double_quotes:
s = s.replace('"', '&quot;')
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
# for single-quoted strings).
@@ -332,7 +333,7 @@ def smart_split(text):
text = force_unicode(text)
for bit in smart_split_re.finditer(text):
yield bit.group(0)
-smart_split = allow_lazy(smart_split, unicode)
+smart_split = allow_lazy(smart_split, six.text_type)
def _replace_entity(match):
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):
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):
r"""
diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py
index 0f1f28e5c4..d31a7aebf1 100644
--- a/django/utils/translation/__init__.py
+++ b/django/utils/translation/__init__.py
@@ -5,6 +5,7 @@ from __future__ import unicode_literals
from django.utils.encoding import force_unicode
from django.utils.functional import lazy
+from django.utils import six
__all__ = [
@@ -78,12 +79,12 @@ def pgettext(context, message):
def npgettext(context, singular, plural, number):
return _trans.npgettext(context, singular, plural, number)
-ngettext_lazy = lazy(ngettext, str)
-gettext_lazy = lazy(gettext, str)
-ungettext_lazy = lazy(ungettext, unicode)
-ugettext_lazy = lazy(ugettext, unicode)
-pgettext_lazy = lazy(pgettext, unicode)
-npgettext_lazy = lazy(npgettext, unicode)
+ngettext_lazy = lazy(ngettext, bytes)
+gettext_lazy = lazy(gettext, bytes)
+ungettext_lazy = lazy(ungettext, six.text_type)
+ugettext_lazy = lazy(ugettext, six.text_type)
+pgettext_lazy = lazy(pgettext, six.text_type)
+npgettext_lazy = lazy(npgettext, six.text_type)
def activate(language):
return _trans.activate(language)
@@ -139,7 +140,7 @@ def _string_concat(*strings):
constructed from multiple parts.
"""
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):
from django.conf.locale import LANG_INFO