Fixed #27067 -- Deprecated string_concat() in favor of format_lazy().

This commit is contained in:
Mattias Loverot 2016-08-16 12:07:03 +02:00 committed by Tim Graham
parent 13c3e5d5a0
commit 2315114090
10 changed files with 44 additions and 20 deletions

View File

@ -507,6 +507,7 @@ answer newbie questions, and generally made Django that much better:
Matt Riggott
Matt Robenolt <m@robenolt.com>
Mattia Larentis <mattia@laretis.eu>
Mattias Loverot <mattias@stubin.se>
mattycakes@gmail.com
Max Burstein <http://maxburstein.com>
Max Derkachev <mderk@yandex.ru>

View File

@ -43,9 +43,9 @@ from django.utils.encoding import force_text, python_2_unicode_compatible
from django.utils.html import escape, format_html
from django.utils.http import urlencode, urlquote
from django.utils.safestring import mark_safe
from django.utils.text import capfirst, get_text_list
from django.utils.text import capfirst, format_lazy, get_text_list
from django.utils.translation import (
override as translation_override, string_concat, ugettext as _, ungettext,
override as translation_override, ugettext as _, ungettext,
)
from django.views.decorators.csrf import csrf_protect
from django.views.generic import RedirectView
@ -258,7 +258,7 @@ class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)):
if isinstance(form_field.widget, SelectMultiple) and not isinstance(form_field.widget, CheckboxSelectMultiple):
msg = _('Hold down "Control", or "Command" on a Mac, to select more than one.')
help_text = form_field.help_text
form_field.help_text = string_concat(help_text, ' ', msg) if help_text else msg
form_field.help_text = format_lazy('{} {}', help_text, msg) if help_text else msg
return form_field
def get_view_on_site_url(self, obj=None):

View File

@ -2,7 +2,7 @@ from __future__ import unicode_literals
from django.core.exceptions import ValidationError
from django.utils.functional import SimpleLazyObject
from django.utils.translation import string_concat
from django.utils.text import format_lazy
def prefix_validation_error(error, prefix, code, params):
@ -15,10 +15,11 @@ def prefix_validation_error(error, prefix, code, params):
return ValidationError(
# We can't simply concatenate messages since they might require
# their associated parameters to be expressed correctly which
# is not something `string_concat` does. For example, proxied
# is not something `format_lazy` does. For example, proxied
# ungettext calls require a count parameter and are converted
# to an empty string if they are missing it.
message=string_concat(
message=format_lazy(
'{}{}',
SimpleLazyObject(lambda: prefix % params),
SimpleLazyObject(lambda: error.message % error_params),
),

View File

@ -22,8 +22,8 @@ from django.utils.encoding import (
force_text, python_2_unicode_compatible, smart_text,
)
from django.utils.functional import cached_property
from django.utils.text import camel_case_to_spaces
from django.utils.translation import override, string_concat
from django.utils.text import camel_case_to_spaces, format_lazy
from django.utils.translation import override
NOT_PROVIDED = object()
@ -197,7 +197,7 @@ class Options(object):
# verbose_name_plural is a special case because it uses a 's'
# by default.
if self.verbose_name_plural is None:
self.verbose_name_plural = string_concat(self.verbose_name, 's')
self.verbose_name_plural = format_lazy('{}s', self.verbose_name)
# order_with_respect_and ordering are mutually exclusive.
self._ordering_clash = bool(self.ordering and self.order_with_respect_to)
@ -206,7 +206,7 @@ class Options(object):
if meta_attrs != {}:
raise TypeError("'class Meta' got invalid attribute(s): %s" % ','.join(meta_attrs.keys()))
else:
self.verbose_name_plural = string_concat(self.verbose_name, 's')
self.verbose_name_plural = format_lazy('{}s', self.verbose_name)
del self.meta
# If the db_table wasn't provided, use the app_label + model_name.

View File

@ -4,9 +4,11 @@ Internationalization support.
from __future__ import unicode_literals
import re
import warnings
from django.utils import six
from django.utils.decorators import ContextDecorator
from django.utils.deprecation import RemovedInDjango21Warning
from django.utils.encoding import force_text
from django.utils.functional import lazy
@ -224,6 +226,10 @@ def _string_concat(*strings):
Lazy variant of string concatenation, needed for translations that are
constructed from multiple parts.
"""
warnings.warn(
'django.utils.translate.string_concat() is deprecated in '
'favor of django.utils.text.format_lazy().',
RemovedInDjango21Warning, stacklevel=2)
return ''.join(force_text(s) for s in strings)
string_concat = lazy(_string_concat, six.text_type)

View File

@ -25,6 +25,8 @@ details on these changes.
* ``django.test.runner.setup_databases()`` will be removed.
* ``django.utils.translation.string_concat()`` will be removed.
.. _deprecation-removed-in-2.0:
2.0

View File

@ -1107,6 +1107,12 @@ For a complete discussion on the usage of the following see the
.. function:: string_concat(*strings)
.. deprecated:: 1.11
Use :meth:`django.utils.text.format_lazy` instead.
``string_concat(*strings)`` can be replaced by
``format_lazy('{}' * len(strings), *strings)``.
Lazy variant of string concatenation, needed for translations that are
constructed from multiple parts.

View File

@ -477,3 +477,7 @@ Miscellaneous
* ``django.test.runner.setup_databases()`` is moved to
:func:`django.test.utils.setup_databases`. The old location is deprecated.
* ``django.utils.translation.string_concat()`` is deprecated in
favor of :func:`django.utils.text.format_lazy`. ``string_concat(*strings)``
can be replaced by ``format_lazy('{}' * len(strings), *strings)``.

View File

@ -489,21 +489,22 @@ directly with the ``number`` argument::
raise forms.ValidationError(self.error_message % number)
Joining strings: ``string_concat()``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Formatting strings: ``format_lazy()``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Standard Python string joins (``''.join([...])``) will not work on lists
containing lazy translation objects. Instead, you can use
:func:`django.utils.translation.string_concat()`, which creates a lazy object
that concatenates its contents *and* converts them to strings only when the
result is included in a string. For example::
Python's :meth:`str.format()` method will not work when either the
``format_string`` or any of the arguments to :meth:`str.format()`
contains lazy translation objects. Instead, you can use
:func:`django.utils.text.format_lazy()`, which creates a lazy object
that runs the ``str.format()`` method only when the result is included
in a string. For example::
from django.utils.translation import string_concat
from django.utils.text import format_lazy
from django.utils.translation import ugettext_lazy
...
name = ugettext_lazy('John Lennon')
instrument = ugettext_lazy('guitar')
result = string_concat(name, ': ', instrument)
result = format_lazy('{name}: {instrument}', name=name, instrument=instrument)
In this case, the lazy translations in ``result`` will only be converted to
strings when ``result`` itself is used in a string (usually at template

View File

@ -16,10 +16,12 @@ from django.conf import settings
from django.conf.urls.i18n import i18n_patterns
from django.template import Context, Template, TemplateSyntaxError
from django.test import (
RequestFactory, SimpleTestCase, TestCase, override_settings,
RequestFactory, SimpleTestCase, TestCase, ignore_warnings,
override_settings,
)
from django.utils import six, translation
from django.utils._os import upath
from django.utils.deprecation import RemovedInDjango21Warning
from django.utils.formats import (
date_format, get_format, get_format_modules, iter_format_modules, localize,
localize_input, reset_format_cache, sanitize_separators, time_format,
@ -417,6 +419,7 @@ class TranslationTests(SimpleTestCase):
' super results{% endblocktrans %}'
)
@ignore_warnings(category=RemovedInDjango21Warning)
def test_string_concat(self):
"""
six.text_type(string_concat(...)) should not raise a TypeError - #4796