#28304: pgettext should return SafeData if both `message` and `context` are instances of SafeData ------------------------------------------------+------------------------ Reporter: Artem Polunin | Owner: nobody Type: Bug | Status: new Component: Internationalization | Version: master Severity: Normal | Keywords: Triage Stage: Unreviewed | Has patch: 0 Needs documentation: 0 | Needs tests: 0 Patch needs improvement: 0 | Easy pickings: 0 UI/UX: 0 | ------------------------------------------------+------------------------ `pgettext` always returns `str` even if both `message` and `context` are instances of `SafeData` (assuming translations exist).
If we have following translations into Ukrainian {{{ msgid "" msgstr "" "Project-Id-Version: django\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2017-06-09 14:23+0000\n" "PO-Revision-Date: 2017-06-09 10:22-0400\n" "Last-Translator: None\n" "Language-Team: Ukrainian\n" "Language: uk_UA\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" msgid "'" msgstr "' відсотків" msgctxt "percent" msgid "'" msgstr "' відсотків" }}} then {{{ >>> from django.utils.translation import activate, ugettext, pgettext >>> from django.utils.safestring import SafeText >>> >>> activate('ua') >>> >>> type(pgettext(SafeText('percent'), SafeText('''))) # Should return `SafeText` instance <class 'str'> >>> >>> type(ugettext(SafeText('''))) # This works correctly <class 'django.utils.safestring.SafeText'> }}} This causes additional escape when using `trans` with `context` in templates: {{{ >>> from django.utils.translation import activate >>> from django.template import Context, Template >>> >>> activate('ua') >>> >>> Template("{% load i18n %}{% trans ''' context 'percent' %}").render(Context()) # `&` unnecessary escaped into `&` '&#39; відсотків' >>> >>> Template("{% load i18n %}{% trans ''' %}").render(Context()) # This works correctly '' відсотків' }}} ----- The fix can be as follows: This line https://github.com/django/django/blob/master/django/utils/translation/trans_real.py#L325 in `pgettext` can be changed into: {{{ msg_with_ctxt = "%s%s%s" % (context, CONTEXT_SEPARATOR, message) if isinstance(context, SafeData) and isinstance(message, SafeData): msg_with_ctxt = mark_safe(msg_with_ctxt) }}} ----- All versions from 1.8 to master are affected. -- Ticket URL: <https://code.djangoproject.com/ticket/28304> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/049.37f31499000cca49f6a6406ec7817990%40djangoproject.com. For more options, visit https://groups.google.com/d/optout.