Skip to content

Commit cb0ac59

Browse files
committed
Internationalise intcomma
1 parent 0cbd1ab commit cb0ac59

4 files changed

Lines changed: 40 additions & 4 deletions

File tree

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
import pkg_resources
33
from humanize.filesize import naturalsize
4-
from humanize.i18n import activate, deactivate
4+
from humanize.i18n import activate, deactivate, thousands_separator
55
from humanize.number import apnumber, fractional, intcomma, intword, ordinal, scientific
66
from humanize.time import (
77
naturaldate,
@@ -30,5 +30,6 @@
3030
"ordinal",
3131
"precisedelta",
3232
"scientific",
33+
"thousands_separator",
3334
"VERSION",
3435
]

src/humanize/i18n.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@
33
import os.path
44
from threading import local
55

6-
__all__ = ["activate", "deactivate", "gettext", "ngettext"]
6+
__all__ = ["activate", "deactivate", "gettext", "ngettext", "thousands_separator"]
77

88
_TRANSLATIONS = {None: gettext_module.NullTranslations()}
99
_CURRENT = local()
1010

1111

12+
# Mapping of locale to thousands separator
13+
_THOUSANDS_SEPARATOR = {
14+
"fr_FR": " ",
15+
}
16+
17+
1218
def _get_default_locale_path():
1319
try:
1420
if __file__ is None:
@@ -129,3 +135,16 @@ def num_name(n):
129135
str: Original text, unchanged.
130136
"""
131137
return message
138+
139+
140+
def thousands_separator() -> str:
141+
"""Return the thousands separator for a locale, default to comma.
142+
143+
Returns:
144+
str: Thousands separator.
145+
"""
146+
try:
147+
sep = _THOUSANDS_SEPARATOR[_CURRENT.locale]
148+
except (AttributeError, KeyError):
149+
sep = ","
150+
return sep

src/humanize/number.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from .i18n import gettext as _
99
from .i18n import gettext_noop as N_
1010
from .i18n import pgettext as P_
11+
from .i18n import thousands_separator
1112

1213

1314
def ordinal(value):
@@ -97,9 +98,10 @@ def intcomma(value, ndigits=None):
9798
Returns:
9899
str: string containing commas every three digits.
99100
"""
101+
sep = thousands_separator()
100102
try:
101103
if isinstance(value, str):
102-
float(value.replace(",", ""))
104+
float(value.replace(sep, ""))
103105
else:
104106
float(value)
105107
except (TypeError, ValueError):
@@ -110,7 +112,7 @@ def intcomma(value, ndigits=None):
110112
else:
111113
orig = str(value)
112114

113-
new = re.sub(r"^(-?\d+)(\d{3})", r"\g<1>,\g<2>", orig)
115+
new = re.sub(r"^(-?\d+)(\d{3})", fr"\g<1>{sep}\g<2>", orig)
114116
if orig == new:
115117
return new
116118
else:

tests/test_i18n.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,20 @@ def test_i18n():
2626
assert humanize.precisedelta(one_min_three_seconds) == "1 minute and 7 seconds"
2727

2828

29+
def test_intcomma():
30+
number = 10_000_000
31+
32+
assert humanize.intcomma(number) == "10,000,000"
33+
34+
try:
35+
humanize.i18n.activate("fr_FR")
36+
assert humanize.intcomma(number) == "10 000 000"
37+
38+
finally:
39+
humanize.i18n.deactivate()
40+
assert humanize.intcomma(number) == "10,000,000"
41+
42+
2943
def test_default_locale_path_defined__file__():
3044
i18n = importlib.import_module("humanize.i18n")
3145
assert i18n._get_default_locale_path() is not None

0 commit comments

Comments
 (0)