Skip to content

Commit 6cc366f

Browse files
committed
Preserve large integer strings in intcomma
1 parent 392aef7 commit 6cc366f

3 files changed

Lines changed: 32 additions & 5 deletions

File tree

‎src/humanize/number.py‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,12 +181,18 @@ def intcomma(value: NumberOrString, ndigits: int | None = None) -> str:
181181
try:
182182
if isinstance(value, str):
183183
value = value.replace(thousands_sep, "").replace(decimal_sep, ".")
184-
if not math.isfinite(float(value)):
184+
if ndigits is not None and not math.isfinite(float(value)):
185185
return _format_not_finite(float(value))
186-
if "." in value:
186+
try:
187+
integer_value = int(value)
188+
except ValueError:
189+
if not math.isfinite(float(value)):
190+
return _format_not_finite(float(value))
191+
if "." not in value:
192+
raise
187193
value = float(value)
188194
else:
189-
value = int(value)
195+
value = integer_value
190196
elif not isinstance(value, int):
191197
if not math.isfinite(float(value)):
192198
return _format_not_finite(float(value))

‎tests/test_i18n.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def test_i18n() -> None:
104104

105105
def test_intcomma() -> None:
106106
number = 10_000_000
107+
large_number = str(10**400 + 123)
107108

108109
assert humanize.intcomma(number) == "10,000,000"
109110

@@ -115,11 +116,17 @@ def test_intcomma() -> None:
115116
assert humanize.intcomma("1234567,89") == "1.234.567,89"
116117
assert humanize.intcomma("1.234.567,89") == "1.234.567,89"
117118
assert humanize.intcomma("1.234.567,8") == "1.234.567,8"
119+
large_expected = "10" + ".000" * 132 + ".123"
120+
assert humanize.intcomma(large_number) == large_expected
121+
assert humanize.intcomma(large_expected) == large_expected
118122

119123
humanize.i18n.activate("fr_FR")
120124
assert humanize.intcomma(number) == "10 000 000"
121125
assert humanize.intcomma(1_234_567.89) == "1 234 567,89"
122126
assert humanize.intcomma("1 234 567,89") == "1 234 567,89"
127+
large_expected = "10" + " 000" * 132 + " 123"
128+
assert humanize.intcomma(large_number) == large_expected
129+
assert humanize.intcomma(large_expected) == large_expected
123130

124131
humanize.i18n.activate("pt_BR")
125132
assert humanize.intcomma(number) == "10.000.000"

‎tests/test_number.py‎

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@ def test_ordinal(test_input: str, expected: str) -> None:
7575
([-math.inf], "-Inf"),
7676
(["nan"], "NaN"),
7777
(["-inf"], "-Inf"),
78+
(["inf"], "+Inf"),
79+
(["1e400"], "+Inf"),
80+
(["1.0e400"], "+Inf"),
81+
(["1e3"], "1e3"),
82+
(["1.0e3"], "1,000.0"),
83+
(["not a number"], "not a number"),
84+
([str(10**400 + 123), 2], "+Inf"),
85+
([str(-(10**400 + 123)), 2], "-Inf"),
7886
],
7987
)
8088
def test_intcomma(
@@ -84,10 +92,16 @@ def test_intcomma(
8492

8593

8694
@pytest.mark.parametrize("sign", [1, -1])
87-
def test_intcomma_large_integer(sign: int) -> None:
95+
@pytest.mark.parametrize("representation", ["integer", "string", "grouped_string"])
96+
def test_intcomma_large_integer(sign: int, representation: str) -> None:
8897
value = sign * (10**400 + 123)
8998
expected = ("-" if sign < 0 else "") + "10" + ",000" * 132 + ",123"
90-
assert humanize.intcomma(value) == expected
99+
argument = (
100+
str(value)
101+
if representation == "string"
102+
else expected if representation == "grouped_string" else value
103+
)
104+
assert humanize.intcomma(argument) == expected
91105

92106

93107
def test_intword_powers() -> None:

0 commit comments

Comments
 (0)