Closed olunusib closed 7 months ago
This seems to overlap with the previously (#494, #577) soft-deprecated
frac_prec
override... Would it be enough to setpattern.frac_prec = (precision, precision)
for thepattern
instead of adding the new parameter here in the bowels ofPattern
?Further, I think an exception should be raised when trying to use the mutually exclusive arguments?
@akx,
precision
is set outside the NumberPattern
class, it will be overwritten by this since decimal_quantization
is False.I was looking in a similar issue. In my case, I also wanted to use the implicit precision coming with a str
or Decimal
value, even if the least significant digits are 0.
I came up with the following function to compute the value of the force_frac
override for NumberPattern.apply
:
def _get_frac_prec(
pattern: babel.numbers.NumberPattern,
value: float | decimal.Decimal | str,
currency: str | None = None,
currency_digits: bool = True,
decimal_quantization: bool = True,
decimal_normalization: bool = True,
precision: int | None = None,
) -> tuple[int, int]:
if precision is not None:
min_prec = max_prec = precision
elif currency and currency_digits:
min_prec = max_prec = babel.numbers.get_currency_precision(currency)
else:
min_prec, max_prec = pattern.frac_prec
if decimal_quantization and (
pattern.exp_prec is None
or min_prec != 0
or max_prec != 0
):
return min_prec, max_prec
# Duplicates the beginning of NumberPattern.apply
if not isinstance(value, decimal.Decimal):
value = decimal.Decimal(str(value))
value = value.scaleb(pattern.scale)
num_prec = get_decimal_precision(value, normalized=decimal_normalization)
return max(num_prec, min_prec), max(num_prec, max_prec)
Which requires to add a new parameter to get_decimal_precision
to disable normalization:
def get_decimal_precision(number: decimal.Decimal, normalized: bool = True) -> int:
assert isinstance(number, decimal.Decimal)
if normalized:
number = number.normalize()
exponent = number.as_tuple().exponent
# Note: DecimalTuple.exponent can be 'n' (qNaN), 'N' (sNaN), or 'F' (Infinity)
if not isinstance(exponent, int) or exponent >= 0:
return 0
return abs(exponent)
When decimal_quantization
is enabled, precision
sets the exact number of digits after the decimal point. When disabled, precision
sets the minimal number of digits, but there can be more digits (with decimal_normalization
removing or keeping the non-significant 0).
@Olunusib Did you close this on purpose or just resignated? I found this PR useful and it was some functionality that would be really useful to have.
@FelixSchwarz It was inadvertently closed. I'll get it back up very soon.
Hey @Olunusib, I'm just wondering about getting this back up? Seems like some generally useful functionality and it would help me get rid of the warnings I am getting because I'm currently using force_frac
to achieve the same as this PR would allow me to do. :)
When bypassing decimal quantization, we should be able to specify precision. Fixes #893.