Opened 12 years ago
Closed 4 years ago
#18995 closed Cleanup/optimization (fixed)
String formatting error when passing floats as values in {% blocktrans %} tags
Reported by: | Bruno Renié | Owned by: | Jacob Walls |
---|---|---|---|
Component: | Internationalization | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
With the following template code:
{% blocktrans count counter=person.distance_in_miles|floatformat:0 %}{{ counter }} mile away{% plural %}{{ counter }} miles away{% endblocktrans %}
And a russian translation:
#, python-format msgid "%(counter)s mile away" msgid_plural "%(counter)s miles away" msgstr[0] "На расстоянии %(counter)s мили" msgstr[1] "На расстоянии %(counter)s миль" msgstr[2] "На расстоянии %(counter)s миль"
Rendering the template fails with a String formatting error: "TypeError: not all arguments converted during string formatting".
This happens because gettext string formatting fails when a float is passed. Removing the floatformat
and casting the value as int works fine.
This could be improved by either:
- Swallow
TypeError
and throw a friendlier message saying the type might not be compatible with gettext's string formatting (not a fan of swallowingTypeError
though, we need to make sure nothing else in do_translate throws such an exception) - Actively checking the type's compatibility with the string format
Change History (7)
comment:1 by , 12 years ago
Triage Stage: | Unreviewed → Accepted |
---|---|
Type: | Uncategorized → Cleanup/optimization |
comment:2 by , 11 years ago
comment:4 by , 4 years ago
Patch needs improvement: | set |
---|---|
Version: | 1.4 → master |
comment:5 by , 4 years ago
Patch needs improvement: | unset |
---|
Adjusted patch per review to allow floats and decimal.Decimal in addition to integers.
comment:6 by , 4 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
Note:
See TracTickets
for help on using tickets.
I've done some digging and found that the issue isn't to do with floats. In fact,
ungettext
will happily work with floats without raising any exceptions.The root of the problem is that
floatformat
returns a string, which conflicts with the Russian plural rules. Indeed, those rules use the modulo sign%
:If you pass a string as a value for
n
, then the%
sign will operate as string formatting instead of a modulo, therefore causing theTypeError
. The same effect can be easily reproduced as follows:I suggest making
blocktrans
raise an exception upstream if the value provided for the counter is not a number.