Skip to content

Commit 97fc008

Browse files
authored
Merge pull request #183 from hugovk/i18n-intcomma
2 parents 89b73e0 + 6ca44f7 commit 97fc008

10 files changed

Lines changed: 73 additions & 26 deletions

File tree

.pre-commit-config.yaml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@ repos:
1111
- id: black
1212
args: ["--target-version", "py36"]
1313

14+
- repo: https://github.com/PyCQA/isort
15+
rev: 5.6.4
16+
hooks:
17+
- id: isort
18+
1419
- repo: https://gitlab.com/pycqa/flake8
1520
rev: 3.8.4
1621
hooks:
1722
- id: flake8
1823
additional_dependencies: [flake8-2020, flake8-implicit-str-concat]
1924

20-
- repo: https://github.com/timothycrosley/isort
21-
rev: 5.6.4
22-
hooks:
23-
- id: isort
24-
2525
- repo: https://github.com/pre-commit/pygrep-hooks
2626
rev: v1.7.0
2727
hooks:
@@ -33,6 +33,7 @@ repos:
3333
- id: check-merge-conflict
3434
- id: check-toml
3535
- id: check-yaml
36+
- id: end-of-file-fixer
3637

3738
- repo: https://github.com/PyCQA/pydocstyle
3839
rev: 5.1.1
@@ -41,6 +42,11 @@ repos:
4142
args: ["--convention", "google"]
4243
files: "src/"
4344

45+
- repo: https://github.com/tox-dev/tox-ini-fmt
46+
rev: 0.5.0
47+
hooks:
48+
- id: tox-ini-fmt
49+
4450
- repo: https://github.com/asottile/setup-cfg-fmt
4551
rev: v1.15.1
4652
hooks:

setup.cfg

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,7 @@ max_line_length = 88
5656
convention = google
5757

5858
[tool:isort]
59-
known_third_party = freezegun,humanize,pkg_resources,pytest,setuptools
60-
force_grid_wrap = 0
61-
include_trailing_comma = True
62-
line_length = 88
63-
multi_line_output = 3
64-
use_parentheses = True
59+
profile = black
6560

6661
[tool:pytest]
6762
addopts = --color=yes

src/humanize/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
"""Main package for humanize."""
22
import pkg_resources
3+
34
from humanize.filesize import naturalsize
4-
from humanize.i18n import activate, deactivate
5+
from humanize.i18n import activate, deactivate, thousands_separator
56
from humanize.number import apnumber, fractional, intcomma, intword, ordinal, scientific
67
from humanize.time import (
78
naturaldate,
@@ -30,5 +31,6 @@
3031
"ordinal",
3132
"precisedelta",
3233
"scientific",
34+
"thousands_separator",
3335
"VERSION",
3436
]

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_filesize.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
"""Tests for filesize humanizing."""
44

5-
import humanize
65
import pytest
76

7+
import humanize
8+
89

910
@pytest.mark.parametrize(
1011
"test_args, expected",

tests/test_i18n.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import datetime as dt
22
import importlib
33

4-
import humanize
54
import pytest
65

6+
import humanize
7+
78

89
def test_i18n():
910
three_seconds = dt.timedelta(seconds=3)
@@ -26,6 +27,20 @@ def test_i18n():
2627
assert humanize.precisedelta(one_min_three_seconds) == "1 minute and 7 seconds"
2728

2829

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

tests/test_number.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
"""Number tests."""
44

5-
import humanize
65
import pytest
6+
7+
import humanize
78
from humanize import number
89

910

tests/test_time.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44

55
import datetime as dt
66

7-
import humanize
87
import pytest
98
from freezegun import freeze_time
9+
10+
import humanize
1011
from humanize import time
1112

1213
ONE_DAY_DELTA = dt.timedelta(days=1)

tox.ini

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tox]
22
envlist =
3-
py{36, 37, 38, 39, py3}
3+
py{py3, 39, 38, 37, 36}
44

55
[testenv]
66
extras =
@@ -9,14 +9,19 @@ commands =
99
{envpython} -m pytest --cov humanize --cov tests --cov-report xml {posargs}
1010

1111
[testenv:docs]
12-
deps = -r docs/requirements.txt
13-
commands = mkdocs build
12+
deps =
13+
-rdocs/requirements.txt
14+
commands =
15+
mkdocs build
1416

1517
[testenv:lint]
16-
deps = pre-commit
17-
commands = pre-commit run --all-files --show-diff-on-failure
18+
passenv =
19+
PRE_COMMIT_COLOR
1820
skip_install = true
19-
passenv = PRE_COMMIT_COLOR
21+
deps =
22+
pre-commit
23+
commands =
24+
pre-commit run --all-files --show-diff-on-failure
2025

2126
[pytest]
22-
addopts = --doctest-modules
27+
addopts = --doctest-modules

0 commit comments

Comments
 (0)