From e9e78fbb7b361d979950cc776fcc9de87c53977d Mon Sep 17 00:00:00 2001 From: RavSinghChandan Date: Fri, 30 Oct 2026 22:05:46 +0530 Subject: [PATCH] Format NaN with the locale's symbol, without fraction digits or exponent --- babel/numbers.py | 12 +++++++++--- tests/test_numbers_format_decimal.py | 8 ++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/babel/numbers.py b/babel/numbers.py index 09e7a767f..f79bf3c10 100644 --- a/babel/numbers.py +++ b/babel/numbers.py @@ -1525,8 +1525,8 @@ def apply( if not decimal_quantization or (self.exp_prec and frac_prec == (0, 0)): frac_prec = (frac_prec[0], max([frac_prec[1], get_decimal_precision(value)])) - # Render scientific notation. - if self.exp_prec: + # Render scientific notation (NaN and infinity have no exponent). + if self.exp_prec and value.is_finite(): number = ''.join([ self._quantize_value(value, locale, frac_prec, group_separator, numbering_system=numbering_system), get_exponential_symbol(locale, numbering_system=numbering_system), @@ -1640,9 +1640,15 @@ def _quantize_value( *, numbering_system: Literal["default"] | str, ) -> str: - # If the number is +/-Infinity, we can't quantize it + # If the number is +/-Infinity or NaN, we can't quantize it if value.is_infinite(): return get_infinity_symbol(locale, numbering_system=numbering_system) + if value.is_nan(): + symbols = _get_number_symbols( + Locale.parse(locale or LC_NUMERIC), + numbering_system=numbering_system, + ) + return symbols.get('nan', 'NaN') quantum = get_decimal_quantum(frac_prec[1]) rounded = value.quantize(quantum) a, sep, b = f"{rounded:f}".partition(".") diff --git a/tests/test_numbers_format_decimal.py b/tests/test_numbers_format_decimal.py index 124c5b96d..354d919bc 100644 --- a/tests/test_numbers_format_decimal.py +++ b/tests/test_numbers_format_decimal.py @@ -111,6 +111,14 @@ def test_nan_and_infinity(): assert numbers.format_compact_decimal(decimal.Decimal('NaN'), locale='en_US', format_type="short") == 'NaN' assert numbers.format_currency(decimal.Decimal('Infinity'), 'USD', locale='en_US') == '$∞' assert numbers.format_currency(decimal.Decimal('-Infinity'), 'USD', locale='en_US') == '-$∞' + assert numbers.format_currency(decimal.Decimal('NaN'), 'USD', locale='en_US') == '$NaN' + assert numbers.format_currency(decimal.Decimal('NaN'), 'EUR', locale='de_DE') == 'NaN\xa0€' + assert numbers.format_decimal(decimal.Decimal('NaN'), '#,##0.00', locale='en_US') == 'NaN' + assert numbers.format_scientific(decimal.Decimal('NaN'), locale='en_US') == 'NaN' + assert numbers.format_scientific(decimal.Decimal('Infinity'), locale='en_US') == '∞' + # the locale's symbol for NaN is used, like for infinity + assert numbers.format_decimal(decimal.Decimal('NaN'), locale='fi_FI') == 'epäluku' + assert numbers.format_decimal(float('nan'), locale='ar_EG', numbering_system='default') == 'ليس\xa0رقمًا' def test_group_separator():