Skip to content

Commit 72d3ef4

Browse files
authored
Merge pull request #53 from Luflosi/implement-decimal-sep-i18n
2 parents d8e2739 + 862748a commit 72d3ef4

File tree

4 files changed

+33
-6
lines changed

4 files changed

+33
-6
lines changed

src/humanize/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Main package for humanize."""
22

33
from humanize.filesize import naturalsize
4-
from humanize.i18n import activate, deactivate, thousands_separator
4+
from humanize.i18n import activate, deactivate, decimal_separator, thousands_separator
55
from humanize.number import (
66
apnumber,
77
clamp,
@@ -36,6 +36,7 @@
3636
"apnumber",
3737
"clamp",
3838
"deactivate",
39+
"decimal_separator",
3940
"fractional",
4041
"intcomma",
4142
"intword",

src/humanize/i18n.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import os.path
66
from threading import local
77

8-
__all__ = ["activate", "deactivate", "thousands_separator"]
8+
__all__ = ["activate", "deactivate", "decimal_separator", "thousands_separator"]
99

1010
_TRANSLATIONS: dict[str | None, gettext_module.NullTranslations] = {
1111
None: gettext_module.NullTranslations()
@@ -19,6 +19,11 @@
1919
"fr_FR": " ",
2020
}
2121

22+
# Mapping of locale to decimal separator
23+
_DECIMAL_SEPARATOR = {
24+
"de_DE": ",",
25+
}
26+
2227

2328
def _get_default_locale_path() -> str | None:
2429
try:
@@ -173,3 +178,16 @@ def thousands_separator() -> str:
173178
except (AttributeError, KeyError):
174179
sep = ","
175180
return sep
181+
182+
183+
def decimal_separator() -> str:
184+
"""Return the decimal separator for a locale, default to dot.
185+
186+
Returns:
187+
str: Decimal separator.
188+
"""
189+
try:
190+
sep = _DECIMAL_SEPARATOR[_CURRENT.locale]
191+
except (AttributeError, KeyError):
192+
sep = "."
193+
return sep

src/humanize/number.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from .i18n import _ngettext
1414
from .i18n import _ngettext_noop as NS_
1515
from .i18n import _pgettext as P_
16-
from .i18n import thousands_separator
16+
from .i18n import decimal_separator, thousands_separator
1717

1818
if TYPE_CHECKING:
1919
if sys.version_info >= (3, 10):
@@ -130,10 +130,11 @@ def intcomma(value: NumberOrString, ndigits: int | None = None) -> str:
130130
Returns:
131131
str: String containing commas every three digits.
132132
"""
133-
sep = thousands_separator()
133+
thousands_sep = thousands_separator()
134+
decimal_sep = decimal_separator()
134135
try:
135136
if isinstance(value, str):
136-
value = value.replace(sep, "")
137+
value = value.replace(thousands_sep, "").replace(decimal_sep, ".")
137138
if "." in value:
138139
value = float(value)
139140
else:
@@ -147,8 +148,9 @@ def intcomma(value: NumberOrString, ndigits: int | None = None) -> str:
147148
orig = "{0:.{1}f}".format(value, ndigits)
148149
else:
149150
orig = str(value)
151+
orig = orig.replace(".", decimal_sep)
150152
while True:
151-
new = re.sub(r"^(-?\d+)(\d{3})", rf"\g<1>{sep}\g<2>", orig)
153+
new = re.sub(r"^(-?\d+)(\d{3})", rf"\g<1>{thousands_sep}\g<2>", orig)
152154
if orig == new:
153155
return new
154156
orig = new

tests/test_i18n.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ def test_intcomma() -> None:
4444
try:
4545
humanize.i18n.activate("de_DE")
4646
assert humanize.intcomma(number) == "10.000.000"
47+
assert humanize.intcomma(1_234_567.8901) == "1.234.567,8901"
48+
assert humanize.intcomma(1_234_567.89) == "1.234.567,89"
49+
assert humanize.intcomma("1234567,89") == "1.234.567,89"
50+
assert humanize.intcomma("1.234.567,89") == "1.234.567,89"
51+
assert humanize.intcomma("1.234.567,8") == "1.234.567,8"
52+
4753
humanize.i18n.activate("fr_FR")
4854
assert humanize.intcomma(number) == "10 000 000"
4955

0 commit comments

Comments
 (0)