Code

Opened 3 years ago

Closed 5 weeks ago

Last modified 5 weeks ago

#16723 closed Bug (invalid)

Pluralize filter shouldn't pluralize decimal/float values between 1 and 2

Reported by: rfugger Owned by:
Component: Template system Version: master
Severity: Normal Keywords:
Cc: arv@…, adam@…, Odd_Bloke Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

The pluralize filter's support for floating point/decimal numbers is buggy. Its check for plurality is:

if int(value) != 1

which unfortunately catches floats 1.0 < x < 2.0 that shouldn't be pluralized in English.

Example:

pound{{ weight|pluralize:"s" }}

When weight is 1.3, this gives "1.3 pound", which is incorrect. "1.3 pounds" is the expected result.

The filter should probably also pluralize 1.0 when it is given as a floating point/decimal number, because native speakers will generally pluralize all decimal numbers. ("One-point-oh hours," not "One-point-oh hour".)

Reference:
http://www.englishforums.com/English/1119PluralOrSingular/wdvmb/post.htm#684376

Attachments (1)

django-2011-08-29-pluralize-16723.patch (1.2 KB) - added by AdamG 3 years ago.

Download all attachments as: .zip

Change History (10)

Changed 3 years ago by AdamG

comment:1 Changed 3 years ago by AdamG

  • Cc adam@… added
  • Has patch set
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

Patch to fix w/ tests attached.

I agree that it would make sense for 1.0 to also be pluralized, however, I didnt make that change in this patch for three reasons:

  • It turns this from a one-line change to something significantly more complex, since we have to treat the strings "1" and "1.0" differently
  • It could break people's existing code, if they don't realize they're passing in a float
  • Where "1.0 pounds" is desired instead of "1 pound"/"1.1 pounds", pluralize wouldn't be needed in the first place, the template would just be:
{{ weight|floatformat:1 }} pounds

With this patch, for "1 pound" & "1.1 pounds", we can do:

{{ weight|floatformat }} pound{{ weight|pluralize }}

This is consistent with the decision made in #12380.

comment:2 Changed 3 years ago by aaugustin

  • Triage Stage changed from Unreviewed to Accepted

The docs say that pluralize "returns a plural suffix if the value is not 1".

It looks like int(value) is only intended to convert a string to an int and pluralize wasn't designed to deal with float values.

An alternative fix could be to change the check to if str(value) != "1". Thus 1.0 will be pluralized and it's still a one-liner.

comment:3 Changed 16 months ago by aaugustin

  • Owner changed from nobody to aaugustin
  • Status changed from new to assigned

comment:4 Changed 16 months ago by aaugustin

  • Resolution set to invalid
  • Status changed from assigned to closed

Re-reading the original report and the first comment closely, they actually say that all floats should trigger pluralization, even 1.0.

This makes the pluralize filter unnecessary when used with floats.

comment:5 Changed 4 months ago by Odd_Bloke

  • Cc Odd_Bloke added
  • Resolution invalid deleted
  • Status changed from closed to new

This does cause a problem with DecimalField. If I do:

MyModel.objects.create(decimal_field=Decimal('1.0'))

then this comes out of the ORM as:

Decimal('1')

which the templating system will display as "1" (rather than "1.0" or another float-y representation). (This is also the case if I pass in the float 1.0.)

Therefore, I can't "hard-code" the pluralised noun, because I might end up with "1 widgets" rather than "1 widget". If I use |pluralize, then I end up with "1 widget" but also "1.2 widget".

I'm happy to be corrected, but it seems to me that this is a valid bug.

comment:6 Changed 4 months ago by aaugustin

  • Status changed from new to assigned

comment:7 Changed 4 months ago by aaugustin

  • Owner aaugustin deleted
  • Status changed from assigned to new

comment:8 Changed 5 weeks ago by aaugustin

  • Resolution set to invalid
  • Status changed from new to closed

I don't understand the last comment, Decimal('1.0') is handled by the |pluralize filter as a singular value and is displayed as 1 in the template. So everything is correct. I'm going to add a test.

comment:9 Changed 5 weeks ago by Aymeric Augustin <aymeric.augustin@…>

In 1a01e24331194a8580d9f16b02e02f8403680942:

Tested pluralization of decimals.

Refs #16723.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


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

 
Note: See TracTickets for help on using tickets.