Loading AUTHORS +2 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ answer newbie questions, and generally made Django that much better: Alex Hill <alex@hill.net.au> Alex Ogier <alex.ogier@gmail.com> Alex Robbins <alexander.j.robbins@gmail.com> Alexey Boriskin <alex@boriskin.me> Aljosa Mohorovic <aljosa.mohorovic@gmail.com> Amit Chakradeo <http://amit.chakradeo.net/> Amit Ramon <amit.ramon@gmail.com> Loading Loading @@ -287,6 +288,7 @@ answer newbie questions, and generally made Django that much better: Honza Král <honza.kral@gmail.com> Horst Gutmann <zerok@zerokspot.com> Hyun Mi Ae Iacopo Spalletti <i.spalletti@nephila.it> Ian A Wilson <http://ianawilson.com> Ian Clelland <clelland@gmail.com> Ian G. Kelly <ian.g.kelly@gmail.com> Loading django/utils/functional.py +40 −10 Original line number Diff line number Diff line import copy import operator import warnings from functools import total_ordering, wraps from django.utils import six from django.utils.deprecation import RemovedInDjango20Warning # You can't trivially replace this with `functools.partial` because this binds Loading Loading @@ -176,24 +178,52 @@ def _lazy_proxy_unpickle(func, args, kwargs, *resultclasses): return lazy(func, *resultclasses)(*args, **kwargs) def lazystr(text): """ Shortcut for the common case of a lazy callable that returns str. """ from django.utils.encoding import force_text # Avoid circular import return lazy(force_text, six.text_type)(text) def allow_lazy(func, *resultclasses): warnings.warn( "django.utils.functional.allow_lazy() is deprecated in favor of " "django.utils.functional.keep_lazy()", RemovedInDjango20Warning, 2) return keep_lazy(*resultclasses)(func) def keep_lazy(*resultclasses): """ A decorator that allows a function to be called with one or more lazy arguments. If none of the args are lazy, the function is evaluated immediately, otherwise a __proxy__ is returned that will evaluate the function when needed. """ if not resultclasses: raise TypeError("You must pass at least one argument to keep_lazy().") def decorator(func): lazy_func = lazy(func, *resultclasses) @wraps(func) def wrapper(*args, **kwargs): for arg in list(args) + list(kwargs.values()): for arg in list(args) + list(six.itervalues(kwargs)): if isinstance(arg, Promise): break else: return func(*args, **kwargs) return lazy_func(*args, **kwargs) return wrapper return decorator def keep_lazy_text(func): """ A decorator for functions that accept lazy arguments and return text. """ return keep_lazy(six.text_type)(func) empty = object() Loading django/utils/html.py +9 −8 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ import re from django.utils import six from django.utils.encoding import force_str, force_text from django.utils.functional import allow_lazy from django.utils.functional import keep_lazy, keep_lazy_text from django.utils.http import RFC3986_GENDELIMS, RFC3986_SUBDELIMS from django.utils.safestring import SafeData, SafeText, mark_safe from django.utils.six.moves.urllib.parse import ( Loading Loading @@ -38,6 +38,7 @@ hard_coded_bullets_re = re.compile( trailing_empty_content_re = re.compile(r'(?:<p>(?: |\s|<br \/>)*?</p>\s*)+\Z') @keep_lazy(six.text_type, SafeText) def escape(text): """ Returns the given text with ampersands, quotes and angle brackets encoded Loading @@ -49,7 +50,6 @@ def escape(text): """ return mark_safe(force_text(text).replace('&', '&').replace('<', '<') .replace('>', '>').replace('"', '"').replace("'", ''')) escape = allow_lazy(escape, six.text_type, SafeText) _js_escapes = { ord('\\'): '\\u005C', Loading @@ -69,10 +69,10 @@ _js_escapes = { _js_escapes.update((ord('%c' % z), '\\u%04X' % z) for z in range(32)) @keep_lazy(six.text_type, SafeText) def escapejs(value): """Hex encodes characters for use in JavaScript strings.""" return mark_safe(force_text(value).translate(_js_escapes)) escapejs = allow_lazy(escapejs, six.text_type, SafeText) def conditional_escape(text): Loading Loading @@ -118,16 +118,16 @@ def format_html_join(sep, format_string, args_generator): for args in args_generator)) @keep_lazy_text def linebreaks(value, autoescape=False): """Converts newlines into <p> and <br />s.""" value = normalize_newlines(value) value = normalize_newlines(force_text(value)) paras = re.split('\n{2,}', value) if autoescape: paras = ['<p>%s</p>' % escape(p).replace('\n', '<br />') for p in paras] else: paras = ['<p>%s</p>' % p.replace('\n', '<br />') for p in paras] return '\n\n'.join(paras) linebreaks = allow_lazy(linebreaks, six.text_type) class MLStripper(HTMLParser): Loading Loading @@ -166,10 +166,12 @@ def _strip_once(value): return s.get_data() @keep_lazy_text def strip_tags(value): """Returns the given HTML with all tags stripped.""" # Note: in typical case this loop executes _strip_once once. Loop condition # is redundant, but helps to reduce number of executions of _strip_once. value = force_text(value) while '<' in value and '>' in value: new_value = _strip_once(value) if len(new_value) >= len(value): Loading @@ -179,13 +181,12 @@ def strip_tags(value): break value = new_value return value strip_tags = allow_lazy(strip_tags) @keep_lazy_text def strip_spaces_between_tags(value): """Returns the given HTML with spaces between tags removed.""" return re.sub(r'>\s+<', '><', force_text(value)) strip_spaces_between_tags = allow_lazy(strip_spaces_between_tags, six.text_type) def smart_urlquote(url): Loading Loading @@ -224,6 +225,7 @@ def smart_urlquote(url): return urlunsplit((scheme, netloc, path, query, fragment)) @keep_lazy_text def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): """ Converts any URLs in text into clickable links. Loading Loading @@ -321,7 +323,6 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): elif autoescape: words[i] = escape(word) return ''.join(words) urlize = allow_lazy(urlize, six.text_type) def avoid_wrapping(value): Loading django/utils/http.py +5 −5 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ from email.utils import formatdate from django.utils import six from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_bytes, force_str, force_text from django.utils.functional import allow_lazy from django.utils.functional import keep_lazy_text from django.utils.six.moves.urllib.parse import ( quote, quote_plus, unquote, unquote_plus, urlencode as original_urlencode, urlparse, Loading Loading @@ -40,6 +40,7 @@ PROTOCOL_TO_PORT = { } @keep_lazy_text def urlquote(url, safe='/'): """ A version of Python's urllib.quote() function that can operate on unicode Loading @@ -48,9 +49,9 @@ def urlquote(url, safe='/'): without double-quoting occurring. """ return force_text(quote(force_str(url), force_str(safe))) urlquote = allow_lazy(urlquote, six.text_type) @keep_lazy_text def urlquote_plus(url, safe=''): """ A version of Python's urllib.quote_plus() function that can operate on Loading @@ -59,25 +60,24 @@ def urlquote_plus(url, safe=''): iri_to_uri() call without double-quoting occurring. """ return force_text(quote_plus(force_str(url), force_str(safe))) urlquote_plus = allow_lazy(urlquote_plus, six.text_type) @keep_lazy_text 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_text(unquote(force_str(quoted_url))) urlunquote = allow_lazy(urlunquote, six.text_type) @keep_lazy_text 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_text(unquote_plus(force_str(quoted_url))) urlunquote_plus = allow_lazy(urlunquote_plus, six.text_type) def urlencode(query, doseq=0): Loading django/utils/text.py +13 −13 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ from io import BytesIO from django.utils import six from django.utils.encoding import force_text from django.utils.functional import SimpleLazyObject, allow_lazy from django.utils.functional import SimpleLazyObject, keep_lazy, keep_lazy_text from django.utils.safestring import SafeText, mark_safe from django.utils.six.moves import html_entities from django.utils.translation import pgettext, ugettext as _, ugettext_lazy Loading @@ -20,7 +20,7 @@ if six.PY2: # Capitalizes the first letter of a string. capfirst = lambda x: x and force_text(x)[0].upper() + force_text(x)[1:] capfirst = allow_lazy(capfirst, six.text_type) capfirst = keep_lazy_text(capfirst) # Set up regular expressions re_words = re.compile(r'<.*?>|((?:\w[-\w]*|&.*?;)+)', re.U | re.S) Loading @@ -30,6 +30,7 @@ re_newlines = re.compile(r'\r\n|\r') # Used in normalize_newlines re_camel_case = re.compile(r'(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))') @keep_lazy_text def wrap(text, width): """ A word-wrap function that preserves existing line breaks. Expects that Loading Loading @@ -60,7 +61,6 @@ def wrap(text, width): if line: yield line return ''.join(_generator()) wrap = allow_lazy(wrap, six.text_type) class Truncator(SimpleLazyObject): Loading Loading @@ -95,6 +95,7 @@ class Truncator(SimpleLazyObject): string has been truncated, defaulting to a translatable string of an ellipsis (...). """ self._setup() length = int(num) text = unicodedata.normalize('NFC', self._wrapped) Loading @@ -108,7 +109,6 @@ class Truncator(SimpleLazyObject): if html: return self._truncate_html(length, truncate, text, truncate_len, False) return self._text_chars(length, truncate, text, truncate_len) chars = allow_lazy(chars) def _text_chars(self, length, truncate, text, truncate_len): """ Loading Loading @@ -138,11 +138,11 @@ class Truncator(SimpleLazyObject): argument of what should be used to notify that the string has been truncated, defaulting to ellipsis (...). """ self._setup() length = int(num) if html: return self._truncate_html(length, truncate, self._wrapped, length, True) return self._text_words(length, truncate) words = allow_lazy(words) def _text_words(self, length, truncate): """ Loading Loading @@ -229,6 +229,7 @@ class Truncator(SimpleLazyObject): return out @keep_lazy_text def get_valid_filename(s): """ Returns the given string converted to a string that can be used for a clean Loading @@ -240,9 +241,9 @@ def get_valid_filename(s): """ s = force_text(s).strip().replace(' ', '_') return re.sub(r'(?u)[^-\w.]', '', s) get_valid_filename = allow_lazy(get_valid_filename, six.text_type) @keep_lazy_text def get_text_list(list_, last_word=ugettext_lazy('or')): """ >>> get_text_list(['a', 'b', 'c', 'd']) Loading @@ -264,16 +265,16 @@ def get_text_list(list_, last_word=ugettext_lazy('or')): # Translators: This string is used as a separator between list elements _(', ').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) @keep_lazy_text def normalize_newlines(text): """Normalizes CRLF and CR newlines to just LF.""" text = force_text(text) return re_newlines.sub('\n', text) normalize_newlines = allow_lazy(normalize_newlines, six.text_type) @keep_lazy_text def phone2numeric(phone): """Converts a phone number with letters into its numeric equivalent.""" char2number = {'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3', 'f': '3', Loading @@ -281,7 +282,6 @@ def phone2numeric(phone): 'n': '6', 'o': '6', 'p': '7', 'q': '7', 'r': '7', 's': '7', 't': '8', 'u': '8', 'v': '8', 'w': '9', 'x': '9', 'y': '9', 'z': '9'} return ''.join(char2number.get(c, c) for c in phone.lower()) phone2numeric = allow_lazy(phone2numeric) # From http://www.xhaus.com/alan/python/httpcomp.html#gzip Loading Loading @@ -384,11 +384,12 @@ def _replace_entity(match): _entity_re = re.compile(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));") @keep_lazy_text def unescape_entities(text): return _entity_re.sub(_replace_entity, text) unescape_entities = allow_lazy(unescape_entities, six.text_type) return _entity_re.sub(_replace_entity, force_text(text)) @keep_lazy_text def unescape_string_literal(s): r""" Convert quoted string literals to unquoted strings with escaped quotes and Loading @@ -407,9 +408,9 @@ def unescape_string_literal(s): raise ValueError("Not a string literal: %r" % s) quote = s[0] return s[1:-1].replace(r'\%s' % quote, quote).replace(r'\\', '\\') unescape_string_literal = allow_lazy(unescape_string_literal) @keep_lazy(six.text_type, SafeText) def slugify(value, allow_unicode=False): """ Convert to ASCII if 'allow_unicode' is False. Convert spaces to hyphens. Loading @@ -424,7 +425,6 @@ def slugify(value, allow_unicode=False): value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii') value = re.sub('[^\w\s-]', '', value).strip().lower() return mark_safe(re.sub('[-\s]+', '-', value)) slugify = allow_lazy(slugify, six.text_type, SafeText) def camel_case_to_spaces(value): Loading Loading
AUTHORS +2 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ answer newbie questions, and generally made Django that much better: Alex Hill <alex@hill.net.au> Alex Ogier <alex.ogier@gmail.com> Alex Robbins <alexander.j.robbins@gmail.com> Alexey Boriskin <alex@boriskin.me> Aljosa Mohorovic <aljosa.mohorovic@gmail.com> Amit Chakradeo <http://amit.chakradeo.net/> Amit Ramon <amit.ramon@gmail.com> Loading Loading @@ -287,6 +288,7 @@ answer newbie questions, and generally made Django that much better: Honza Král <honza.kral@gmail.com> Horst Gutmann <zerok@zerokspot.com> Hyun Mi Ae Iacopo Spalletti <i.spalletti@nephila.it> Ian A Wilson <http://ianawilson.com> Ian Clelland <clelland@gmail.com> Ian G. Kelly <ian.g.kelly@gmail.com> Loading
django/utils/functional.py +40 −10 Original line number Diff line number Diff line import copy import operator import warnings from functools import total_ordering, wraps from django.utils import six from django.utils.deprecation import RemovedInDjango20Warning # You can't trivially replace this with `functools.partial` because this binds Loading Loading @@ -176,24 +178,52 @@ def _lazy_proxy_unpickle(func, args, kwargs, *resultclasses): return lazy(func, *resultclasses)(*args, **kwargs) def lazystr(text): """ Shortcut for the common case of a lazy callable that returns str. """ from django.utils.encoding import force_text # Avoid circular import return lazy(force_text, six.text_type)(text) def allow_lazy(func, *resultclasses): warnings.warn( "django.utils.functional.allow_lazy() is deprecated in favor of " "django.utils.functional.keep_lazy()", RemovedInDjango20Warning, 2) return keep_lazy(*resultclasses)(func) def keep_lazy(*resultclasses): """ A decorator that allows a function to be called with one or more lazy arguments. If none of the args are lazy, the function is evaluated immediately, otherwise a __proxy__ is returned that will evaluate the function when needed. """ if not resultclasses: raise TypeError("You must pass at least one argument to keep_lazy().") def decorator(func): lazy_func = lazy(func, *resultclasses) @wraps(func) def wrapper(*args, **kwargs): for arg in list(args) + list(kwargs.values()): for arg in list(args) + list(six.itervalues(kwargs)): if isinstance(arg, Promise): break else: return func(*args, **kwargs) return lazy_func(*args, **kwargs) return wrapper return decorator def keep_lazy_text(func): """ A decorator for functions that accept lazy arguments and return text. """ return keep_lazy(six.text_type)(func) empty = object() Loading
django/utils/html.py +9 −8 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ import re from django.utils import six from django.utils.encoding import force_str, force_text from django.utils.functional import allow_lazy from django.utils.functional import keep_lazy, keep_lazy_text from django.utils.http import RFC3986_GENDELIMS, RFC3986_SUBDELIMS from django.utils.safestring import SafeData, SafeText, mark_safe from django.utils.six.moves.urllib.parse import ( Loading Loading @@ -38,6 +38,7 @@ hard_coded_bullets_re = re.compile( trailing_empty_content_re = re.compile(r'(?:<p>(?: |\s|<br \/>)*?</p>\s*)+\Z') @keep_lazy(six.text_type, SafeText) def escape(text): """ Returns the given text with ampersands, quotes and angle brackets encoded Loading @@ -49,7 +50,6 @@ def escape(text): """ return mark_safe(force_text(text).replace('&', '&').replace('<', '<') .replace('>', '>').replace('"', '"').replace("'", ''')) escape = allow_lazy(escape, six.text_type, SafeText) _js_escapes = { ord('\\'): '\\u005C', Loading @@ -69,10 +69,10 @@ _js_escapes = { _js_escapes.update((ord('%c' % z), '\\u%04X' % z) for z in range(32)) @keep_lazy(six.text_type, SafeText) def escapejs(value): """Hex encodes characters for use in JavaScript strings.""" return mark_safe(force_text(value).translate(_js_escapes)) escapejs = allow_lazy(escapejs, six.text_type, SafeText) def conditional_escape(text): Loading Loading @@ -118,16 +118,16 @@ def format_html_join(sep, format_string, args_generator): for args in args_generator)) @keep_lazy_text def linebreaks(value, autoescape=False): """Converts newlines into <p> and <br />s.""" value = normalize_newlines(value) value = normalize_newlines(force_text(value)) paras = re.split('\n{2,}', value) if autoescape: paras = ['<p>%s</p>' % escape(p).replace('\n', '<br />') for p in paras] else: paras = ['<p>%s</p>' % p.replace('\n', '<br />') for p in paras] return '\n\n'.join(paras) linebreaks = allow_lazy(linebreaks, six.text_type) class MLStripper(HTMLParser): Loading Loading @@ -166,10 +166,12 @@ def _strip_once(value): return s.get_data() @keep_lazy_text def strip_tags(value): """Returns the given HTML with all tags stripped.""" # Note: in typical case this loop executes _strip_once once. Loop condition # is redundant, but helps to reduce number of executions of _strip_once. value = force_text(value) while '<' in value and '>' in value: new_value = _strip_once(value) if len(new_value) >= len(value): Loading @@ -179,13 +181,12 @@ def strip_tags(value): break value = new_value return value strip_tags = allow_lazy(strip_tags) @keep_lazy_text def strip_spaces_between_tags(value): """Returns the given HTML with spaces between tags removed.""" return re.sub(r'>\s+<', '><', force_text(value)) strip_spaces_between_tags = allow_lazy(strip_spaces_between_tags, six.text_type) def smart_urlquote(url): Loading Loading @@ -224,6 +225,7 @@ def smart_urlquote(url): return urlunsplit((scheme, netloc, path, query, fragment)) @keep_lazy_text def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): """ Converts any URLs in text into clickable links. Loading Loading @@ -321,7 +323,6 @@ def urlize(text, trim_url_limit=None, nofollow=False, autoescape=False): elif autoescape: words[i] = escape(word) return ''.join(words) urlize = allow_lazy(urlize, six.text_type) def avoid_wrapping(value): Loading
django/utils/http.py +5 −5 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ from email.utils import formatdate from django.utils import six from django.utils.datastructures import MultiValueDict from django.utils.encoding import force_bytes, force_str, force_text from django.utils.functional import allow_lazy from django.utils.functional import keep_lazy_text from django.utils.six.moves.urllib.parse import ( quote, quote_plus, unquote, unquote_plus, urlencode as original_urlencode, urlparse, Loading Loading @@ -40,6 +40,7 @@ PROTOCOL_TO_PORT = { } @keep_lazy_text def urlquote(url, safe='/'): """ A version of Python's urllib.quote() function that can operate on unicode Loading @@ -48,9 +49,9 @@ def urlquote(url, safe='/'): without double-quoting occurring. """ return force_text(quote(force_str(url), force_str(safe))) urlquote = allow_lazy(urlquote, six.text_type) @keep_lazy_text def urlquote_plus(url, safe=''): """ A version of Python's urllib.quote_plus() function that can operate on Loading @@ -59,25 +60,24 @@ def urlquote_plus(url, safe=''): iri_to_uri() call without double-quoting occurring. """ return force_text(quote_plus(force_str(url), force_str(safe))) urlquote_plus = allow_lazy(urlquote_plus, six.text_type) @keep_lazy_text 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_text(unquote(force_str(quoted_url))) urlunquote = allow_lazy(urlunquote, six.text_type) @keep_lazy_text 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_text(unquote_plus(force_str(quoted_url))) urlunquote_plus = allow_lazy(urlunquote_plus, six.text_type) def urlencode(query, doseq=0): Loading
django/utils/text.py +13 −13 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ from io import BytesIO from django.utils import six from django.utils.encoding import force_text from django.utils.functional import SimpleLazyObject, allow_lazy from django.utils.functional import SimpleLazyObject, keep_lazy, keep_lazy_text from django.utils.safestring import SafeText, mark_safe from django.utils.six.moves import html_entities from django.utils.translation import pgettext, ugettext as _, ugettext_lazy Loading @@ -20,7 +20,7 @@ if six.PY2: # Capitalizes the first letter of a string. capfirst = lambda x: x and force_text(x)[0].upper() + force_text(x)[1:] capfirst = allow_lazy(capfirst, six.text_type) capfirst = keep_lazy_text(capfirst) # Set up regular expressions re_words = re.compile(r'<.*?>|((?:\w[-\w]*|&.*?;)+)', re.U | re.S) Loading @@ -30,6 +30,7 @@ re_newlines = re.compile(r'\r\n|\r') # Used in normalize_newlines re_camel_case = re.compile(r'(((?<=[a-z])[A-Z])|([A-Z](?![A-Z]|$)))') @keep_lazy_text def wrap(text, width): """ A word-wrap function that preserves existing line breaks. Expects that Loading Loading @@ -60,7 +61,6 @@ def wrap(text, width): if line: yield line return ''.join(_generator()) wrap = allow_lazy(wrap, six.text_type) class Truncator(SimpleLazyObject): Loading Loading @@ -95,6 +95,7 @@ class Truncator(SimpleLazyObject): string has been truncated, defaulting to a translatable string of an ellipsis (...). """ self._setup() length = int(num) text = unicodedata.normalize('NFC', self._wrapped) Loading @@ -108,7 +109,6 @@ class Truncator(SimpleLazyObject): if html: return self._truncate_html(length, truncate, text, truncate_len, False) return self._text_chars(length, truncate, text, truncate_len) chars = allow_lazy(chars) def _text_chars(self, length, truncate, text, truncate_len): """ Loading Loading @@ -138,11 +138,11 @@ class Truncator(SimpleLazyObject): argument of what should be used to notify that the string has been truncated, defaulting to ellipsis (...). """ self._setup() length = int(num) if html: return self._truncate_html(length, truncate, self._wrapped, length, True) return self._text_words(length, truncate) words = allow_lazy(words) def _text_words(self, length, truncate): """ Loading Loading @@ -229,6 +229,7 @@ class Truncator(SimpleLazyObject): return out @keep_lazy_text def get_valid_filename(s): """ Returns the given string converted to a string that can be used for a clean Loading @@ -240,9 +241,9 @@ def get_valid_filename(s): """ s = force_text(s).strip().replace(' ', '_') return re.sub(r'(?u)[^-\w.]', '', s) get_valid_filename = allow_lazy(get_valid_filename, six.text_type) @keep_lazy_text def get_text_list(list_, last_word=ugettext_lazy('or')): """ >>> get_text_list(['a', 'b', 'c', 'd']) Loading @@ -264,16 +265,16 @@ def get_text_list(list_, last_word=ugettext_lazy('or')): # Translators: This string is used as a separator between list elements _(', ').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) @keep_lazy_text def normalize_newlines(text): """Normalizes CRLF and CR newlines to just LF.""" text = force_text(text) return re_newlines.sub('\n', text) normalize_newlines = allow_lazy(normalize_newlines, six.text_type) @keep_lazy_text def phone2numeric(phone): """Converts a phone number with letters into its numeric equivalent.""" char2number = {'a': '2', 'b': '2', 'c': '2', 'd': '3', 'e': '3', 'f': '3', Loading @@ -281,7 +282,6 @@ def phone2numeric(phone): 'n': '6', 'o': '6', 'p': '7', 'q': '7', 'r': '7', 's': '7', 't': '8', 'u': '8', 'v': '8', 'w': '9', 'x': '9', 'y': '9', 'z': '9'} return ''.join(char2number.get(c, c) for c in phone.lower()) phone2numeric = allow_lazy(phone2numeric) # From http://www.xhaus.com/alan/python/httpcomp.html#gzip Loading Loading @@ -384,11 +384,12 @@ def _replace_entity(match): _entity_re = re.compile(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));") @keep_lazy_text def unescape_entities(text): return _entity_re.sub(_replace_entity, text) unescape_entities = allow_lazy(unescape_entities, six.text_type) return _entity_re.sub(_replace_entity, force_text(text)) @keep_lazy_text def unescape_string_literal(s): r""" Convert quoted string literals to unquoted strings with escaped quotes and Loading @@ -407,9 +408,9 @@ def unescape_string_literal(s): raise ValueError("Not a string literal: %r" % s) quote = s[0] return s[1:-1].replace(r'\%s' % quote, quote).replace(r'\\', '\\') unescape_string_literal = allow_lazy(unescape_string_literal) @keep_lazy(six.text_type, SafeText) def slugify(value, allow_unicode=False): """ Convert to ASCII if 'allow_unicode' is False. Convert spaces to hyphens. Loading @@ -424,7 +425,6 @@ def slugify(value, allow_unicode=False): value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii') value = re.sub('[^\w\s-]', '', value).strip().lower() return mark_safe(re.sub('[-\s]+', '-', value)) slugify = allow_lazy(slugify, six.text_type, SafeText) def camel_case_to_spaces(value): Loading