Skip to content

Commit 918a6db

Browse files
committed
Add docstring for naturalsize()
1 parent 79e8faf commit 918a6db

1 file changed

Lines changed: 71 additions & 51 deletions

File tree

src/humanize/filesize.py

Lines changed: 71 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -4,62 +4,82 @@
44

55
from math import log
66

7-
from humanize import i18n
8-
9-
suffixes = {
10-
"decimal": ("kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", "RB", "QB"),
11-
"binary": ("KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", "RiB", "QiB"),
12-
"gnu": "KMGTPEZYRQ",
7+
from humanize.i18n import gettext as _
8+
9+
10+
_SUFFIXES = {
11+
"decimal": (
12+
_(" kB"),
13+
_(" MB"),
14+
_(" GB"),
15+
_(" TB"),
16+
_(" PB"),
17+
_(" EB"),
18+
_(" ZB"),
19+
_(" YB"),
20+
_(" RB"),
21+
_(" QB"),
22+
),
23+
"binary": (
24+
_(" KiB"),
25+
_(" MiB"),
26+
_(" GiB"),
27+
_(" TiB"),
28+
_(" PiB"),
29+
_(" EiB"),
30+
_(" ZiB"),
31+
_(" YiB"),
32+
_(" RiB"),
33+
_(" QiB"),
34+
),
1335
}
1436

1537

16-
def _translation():
17-
"""Return active gettext translation (or None)."""
18-
try:
19-
return i18n.get_translation()
20-
except Exception:
21-
return None
22-
23-
2438
def naturalsize(
2539
value: float | str,
2640
binary: bool = False,
27-
gnu: bool = False,
2841
format: str = "%.1f",
2942
) -> str:
30-
t = _translation()
31-
_ = t.gettext if t is not None else (lambda s: s)
32-
33-
if gnu:
34-
suffix = suffixes["gnu"]
35-
elif binary:
36-
suffix = suffixes["binary"]
37-
else:
38-
suffix = suffixes["decimal"]
39-
40-
base = 1024 if (gnu or binary) else 1000
41-
bytes_ = float(value)
42-
abs_bytes = abs(bytes_)
43-
44-
if abs_bytes == 1 and not gnu:
45-
return f"{int(bytes_)} {_('Byte')}"
46-
47-
if abs_bytes < base:
48-
if gnu:
49-
return f"{int(bytes_)}B"
50-
return f"{int(bytes_)} {_('Bytes')}"
51-
52-
exp = int(min(log(abs_bytes, base), len(suffix)))
53-
number = format % (bytes_ / (base**exp))
54-
55-
# French decimal separator: use comma instead of dot
56-
if t is not None:
57-
lang = (t.info().get("language", "") or "").lower()
58-
if lang.startswith("fr"):
59-
number = number.replace(".", ",")
60-
61-
if gnu:
62-
return number + suffix[exp - 1]
63-
64-
unit = _(suffix[exp - 1])
65-
return f"{number} {unit}"
43+
"""
44+
Format a number of bytes like a human-readable file size.
45+
46+
Examples:
47+
>>> naturalsize(42)
48+
'42 Bytes'
49+
>>> naturalsize(42000)
50+
'42.0 kB'
51+
>>> naturalsize(42000000)
52+
'42.0 MB'
53+
54+
When a locale is activated via ``humanize.i18n.activate()``,
55+
the unit suffixes will be translated accordingly.
56+
57+
:param value: The number of bytes.
58+
:param binary: Use binary (powers of 1024) units instead of decimal.
59+
:param format: Numeric format string.
60+
:return: Human-readable file size.
61+
"""
62+
63+
try:
64+
bytes_value = float(value)
65+
except (TypeError, ValueError):
66+
return str(value)
67+
68+
if bytes_value == 1:
69+
return _("1 Byte")
70+
if bytes_value < 1024:
71+
return _("%d Bytes") % bytes_value
72+
73+
base = 1024 if binary else 1000
74+
exp = int(log(bytes_value, base))
75+
exp = min(exp, len(_SUFFIXES["binary"]) if binary else len(_SUFFIXES["decimal"]))
76+
77+
value = bytes_value / base**exp
78+
79+
suffix = (
80+
_SUFFIXES["binary"][exp - 1]
81+
if binary
82+
else _SUFFIXES["decimal"][exp - 1]
83+
)
84+
85+
return (format % value) + suffix

0 commit comments

Comments
 (0)