Code

Opened 5 months ago

Last modified 5 months ago

#21408 new Bug

Fallback to timesince produces erroneous translations in naturaltime

Reported by: 676c7473@… Owned by: nobody
Component: Internationalization Version: master
Severity: Normal Keywords: i18n l10n translation
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

The naturaltime filter in django.contrib.humanize composes strings for days, weeks, months, and years from the words "ago" and "in" and the output of the built-in timesince filter. See here, where delta is to be supplied by timesince:

#: templatetags/humanize.py:190
#, python-format
msgctxt "naturaltime"
msgid "%(delta)s ago"
msgstr "vor %(delta)s"

This produces erroneous translations in German (and probably other inflectional languages, too).

"3 days, 12 hours ago" is translated by Django as

vor 3 Tage, 12 Stunden

but the correct translation is (with dative inflection)

vor 3 Tagen, 12 Stunden

"3 Tage" is correct for timesince, but for naturaltime it must become "3 Tagen". Unfortunately, the assumption that these translations can simply be pieced together from translated bits in timesince.py is mistaken.

I apologise if this isn't the right channel. I'd be glad to help, but so far I haven't seen a good way to avoid duplicating translations.

Attachments (0)

Change History (5)

comment:1 Changed 5 months ago by claudep

  • Component changed from Translations to Internationalization
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted
  • Version changed from 1.6 to master

Surely, this will need duplication of translatable strings. One solution would be to make the django.utils.timesince utility to accept a new optional argument containing a set of translatable strings. Then, naturaltime will be able to provide its own set of npgettext_lazy (with context) strings.

comment:2 Changed 5 months ago by 676c7473@…

Thank you for your answer. Slightly off-topic: I noticed a minor error in the docs for npgettext_lazy and have fixed it in https://github.com/django/django/pull/1895.

comment:3 Changed 5 months ago by 676c7473@…

I'm running into some difficulties with the code and the translations. Could it be that the .po files are out of sync with the code?

in humanize.py, line 204, there are bits like this one:

    return ungettext(
        # Translators: \\u00a0 is non-breaking space
        'a second ago', '%(count)s\u00a0seconds ago', delta.seconds
    ) % {'count': delta.seconds}

There is a corresponding entry in the "en" locale, but in the "de" locale it looks different:

#. Translators: \\u00a0 is non-breaking space
#: templatetags/humanize.py:198
#, python-format
msgid "a second ago"
msgid_plural "%(count)s\\u00a0seconds ago"
msgstr[0] ""
msgstr[1] ""
#: templatetags/humanize.py:196
#, python-format
msgid "a second ago"
msgid_plural "%(count)s seconds ago"
msgstr[0] "vor einer Sekunde"
msgstr[1] "vor %(count)s Sekunden"

I guess the translation is still found because the msgid is the same, but the German translation doesn't have the non-breaking space.

Also, these gettext messages in timesince.py, line 24,

    chunks = (
        (60 * 60 * 24 * 365, ungettext_lazy('%d year', '%d years')),
        (60 * 60 * 24 * 30, ungettext_lazy('%d month', '%d months')),
        ...

don't exist in the "de" translations. As far as I can tell, the msgid "year" will not match "%d year".

#: utils/timesince.py:23
#, python-format
msgid "%d year"
msgid_plural "%d years"
msgstr[0] ""
msgstr[1] ""
#: utils/timesince.py:22
msgid "year"
msgid_plural "years"
msgstr[0] "Jahr"
msgstr[1] "Jahre"

I'm not sure what's happening here. I'll experiment some more, maybe things will become clearer soon. If you want to share some advice, please do! Thanks.

comment:4 Changed 5 months ago by claudep

You might find more up-to-date translations in the 1.6.x branch. We've still not updated master with the more recent translations.

comment:5 Changed 5 months ago by 676c7473@…

Yes, @claudep, thank you, unfortunately there are no unit tests for those, and consequently the bug they introduced was overlooked: ticket:21415 Sorry for not noticing this earlier.

David

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as new
The owner will be changed from nobody to anonymous. Next status will be 'assigned'
as The resolution will be set. Next status will be 'closed'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.