Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/humanize/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,14 @@ def intcomma(value: NumberOrString, ndigits: int | None = None) -> str:

Args:
value (int, float, str): Integer or float to convert.
ndigits (int, None): Digits of precision for rounding after the decimal point.
ndigits (int, None): Non-negative digits of precision for rounding after the
decimal point.

Returns:
str: String containing commas every three digits.

Raises:
ValueError: If a negative precision is used to format a number.
"""
import math

Expand All @@ -195,6 +199,9 @@ def intcomma(value: NumberOrString, ndigits: int | None = None) -> str:
return str(value)

if ndigits is not None:
if ndigits < 0:
msg = "ndigits must be non-negative"
raise ValueError(msg)
result = f"{value:,.{ndigits}f}"
else:
result = f"{value:,}"
Expand Down
7 changes: 7 additions & 0 deletions tests/test_number.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ def test_intcomma(
assert humanize.intcomma(*test_args) == expected


@pytest.mark.parametrize("value", [12345, 12345.111, "12345.111"])
@pytest.mark.parametrize("ndigits", [-1, -10])
def test_intcomma_negative_ndigits(value: float | str, ndigits: int) -> None:
with pytest.raises(ValueError, match="^ndigits must be non-negative$"):
humanize.intcomma(value, ndigits=ndigits)


@pytest.mark.parametrize("sign", [1, -1])
def test_intcomma_large_integer(sign: int) -> None:
value = sign * (10**400 + 123)
Expand Down