-
Notifications
You must be signed in to change notification settings - Fork 444
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cast number to Decimal in _get_compact_format #930
Cast number to Decimal in _get_compact_format #930
Conversation
Codecov Report
@@ Coverage Diff @@
## master #930 +/- ##
=======================================
Coverage 91.59% 91.60%
=======================================
Files 21 21
Lines 4238 4240 +2
=======================================
+ Hits 3882 3884 +2
Misses 356 356
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
Initial pre-review thought: I'm pretty hesitant about the possible loss of precision w/ casting to |
As far as I can tell, in compact format, the fractional part never even shows up in any of the formats, so I think even truncating it to an int would be fine (although not necessary). The method only really needs to support int (and possibly int as a string), but float and Decimal might be nice to make it consistent with the other number formatters. |
I think we could use index 8baf110b8..907ae23f6 100644
--- a/babel/numbers.py
+++ b/babel/numbers.py
@@ -465,7 +465,7 @@ def _get_compact_format(number, compact_format, locale, fraction_digits=0):
break
# otherwise, we need to divide the number by the magnitude but remove zeros
# equal to the number of 0's in the pattern minus 1
- number = number / (magnitude / (10 ** (pattern.count("0") - 1)))
+ number = number / (magnitude // (10 ** (pattern.count("0") - 1)))
# round to the number of fraction digits requested
number = round(number, fraction_digits)
# if the remaining number is singular, use the singular format |
I noticed the index 8baf110b8..6c9ab24b0 100644
--- a/babel/numbers.py
+++ b/babel/numbers.py
@@ -426,7 +426,7 @@ def format_compact_decimal(number, *, format_type="short", locale=LC_NUMERIC, fr
>>> format_compact_decimal(12345, format_type="long", locale='en_US')
u'12 thousand'
>>> format_compact_decimal(12345, format_type="short", locale='en_US', fraction_digits=2)
- u'12.35K'
+ u'12.34K'
>>> format_compact_decimal(1234567, format_type="short", locale="ja_JP")
u'123万'
>>> format_compact_decimal(2345678, format_type="long", locale="mk")
@@ -454,6 +454,8 @@ def _get_compact_format(number, compact_format, locale, fraction_digits=0):
The algorithm is described here:
https://www.unicode.org/reports/tr35/tr35-45/tr35-numbers.html#Compact_Number_Formats.
"""
+ if not isinstance(number, decimal.Decimal):
+ number = decimal.Decimal(str(number))
format = None
for magnitude in sorted([int(m) for m in compact_format["other"]], reverse=True):
if abs(number) >= magnitude: |
Thanks for taking a look! Suggestions applied 👍 |
I found other issue in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good stuff!
>>> format_compact_decimal(12345, format_type="short", locale='en_US', fraction_digits=2) | ||
u'12.35K' | ||
u'12.34K' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changing probably depends on the ambient decimal context. But that's okay 👍
Fixes #929
Division does not work with decimal.Decimal. This uses
//
so integer division is performed instead.abs
andround
don't work with strings. This converts the number to a Decimal so that_get_compact_format
won't raise a ValueError as long as the number supports Decimal conversion. Also has a fix for how rounding modes are treated.This adds support for
decimal.Decimal
andstr
types to the number parameter offormat_compact_*
functions.