-
Notifications
You must be signed in to change notification settings - Fork 440
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
Allow full control on Decimal behaviour #410
Conversation
Allow the rounding mode to be controlled from the currently active decimal context. This gives the caller the ability to control rounding mode, precision, exponent range and all attributes that affect decimal operations. Fixes #90
Instead of selecting individual symbols, expose only the chosen decimal module through babel._compat. This forces Babel to always use "decimal." prefix. Howver, it will simplify the code for users that need to manipulate the decimal context.
Explain how the user can control the behaviour of number rounding when formatting numeric values or currencies.
ROUND_HALF_EVEN = _RHE | ||
if sys.version_info[:2] >= (3, 3): | ||
import decimal | ||
else: |
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 file contains unused source code.
PyUnusedCodeBear, severity NORMAL, section default
.
The issue can be fixed by applying the following patch:
--- a/babel/_compat.py
+++ b/babel/_compat.py
@@ -67,4 +67,4 @@
try:
import cdecimal as decimal
except ImportError:
- import decimal
+ pass
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 file contains unused source code.
PyUnusedCodeBear, severity NORMAL, section default
.
The issue can be fixed by applying the following patch:
--- a/babel/_compat.py
+++ b/babel/_compat.py
@@ -67,4 +67,4 @@
try:
import cdecimal as decimal
except ImportError:
- import decimal
+ pass
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 seems odd, according to Codecov, babel/_compat.py
is 100% covered.
Current coverage is 89.51%
@@ master #410 diff @@
==========================================
Files 24 24
Lines 3950 3946 -4
Methods 0 0
Messages 0 0
Branches 0 0
==========================================
- Hits 3561 3532 -29
- Misses 389 414 +25
Partials 0 0
|
LGTM, but if someone else (@jtwang?) wants to give this an once-over, that'd be grand. :) |
@@ -86,6 +86,58 @@ the specification. The following table is just a relatively brief overview. | |||
+----------+-----------------------------------------------------------------+ | |||
|
|||
|
|||
Rounding Modes |
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.
+++++++
Thanks for the great docs!
Could you add a doctest or a note to the docstring for babel.numbers.format_decimal
? Same for format_currency
- especially around the interaction with custom currency formats and currency_digits
. (omg so complicated)
Thank you so much for taking this on! @sublee - does this let you do what you want? |
@jtwang No it doesn't. What I need is the precision setting for Precision to show usually depend on business logic, not specific locale. The code for determining precision should be static against dynamic locales. For example: >>> print(format_number(123456789.123456789, prec=5, locale=random.choice(locales)))
123.456.789,12346 For now, we can't separate precision from locales. Because |
The rounding performed by Babel is only triggered when formatting a numeric or monetary amount requires digit truncation. To control how many decimals you wan to display, you can always use the
Also note that you can pass instances of |
@etanol Custom The So, if I want to set a precision by the >>> format_number(123456789.123456789, locale='hi_IN')
'12,34,56,789.123'
>>> # The format is yours. The precision specified exactly but commas are wrong.
>>> format_number(123456789.123456789, format='#,##0.00##', locale='hi_IN')
'123,456,789.1235'
>>> # All is okay but the format depends on the hi_IN locale.
>>> format_number(123456789.123456789, format='#,##,##0.00##', locale='hi_IN')
'12,34,56,789.1235' As I said, it depends on locales instead of business logic. |
@sublee Right, I see what you mean. I have a couple of ideas to refactor the |
@etanol Sounds great! I'll wait your work. |
@akx - sure, I didn't spot anything worrisome. :) |
It turns out that the solution to allow the user to change the rounding mode was way simpler than expected at the beginning.
According to UTS #35 sections 3.3 and 3.7, the user is allowed to change rounding mode. But the default should be half even mode. This is already the default Python rounding mode in all decimal implementations, so the solution was to stop indicating the rounding mode on
Decimal
operations.Some documentation has been added to show how to properly change the rounding mode and other
Context
parameters.Therefore, this should fix #90