Skip to content

Commit

Permalink
Merge pull request #122 from hugovk/79-negative-filesize
Browse files Browse the repository at this point in the history
Show more than bytes for negative file sizes
  • Loading branch information
hugovk authored Mar 9, 2020
2 parents 1f43d30 + 8c56ba7 commit 705ff99
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 13 deletions.
33 changes: 21 additions & 12 deletions src/humanize/filesize.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,20 @@


def naturalsize(value, binary=False, gnu=False, format="%.1f"):
"""Format a number of byteslike a human readable filesize (eg. 10 kB). By
default, decimal suffixes (kB, MB) are used. Passing binary=true will use
binary suffixes (KiB, MiB) are used and the base will be 2**10 instead of
10**3. If ``gnu`` is True, the binary argument is ignored and GNU-style
(ls -sh style) prefixes are used (K, M) with the 2**10 definition.
Non-gnu modes are compatible with jinja2's ``filesizeformat`` filter."""
"""Format a number of bytes like a human readable filesize (eg. 10 kB).
By default, decimal suffixes (kB, MB) are used.
Non-gnu modes are compatible with jinja2's ``filesizeformat`` filter.
Args:
value (int, float, string): Integer to convert.
binary (Boolean): If `True`, uses binary suffixes (KiB, MiB) with base 2**10
instead of 10**3.
gnu (Boolean): If `True`, the binary argument is ignored and GNU-style
(`ls -sh` style) prefixes are used (K, M) with the 2**10 definition.
format (str): Custom formatter.
"""
if gnu:
suffix = suffixes["gnu"]
elif binary:
Expand All @@ -25,19 +33,20 @@ def naturalsize(value, binary=False, gnu=False, format="%.1f"):

base = 1024 if (gnu or binary) else 1000
bytes = float(value)
abs_bytes = abs(bytes)

if bytes == 1 and not gnu:
return "1 Byte"
elif bytes < base and not gnu:
if abs_bytes == 1 and not gnu:
return "%d Byte" % bytes
elif abs_bytes < base and not gnu:
return "%d Bytes" % bytes
elif bytes < base and gnu:
elif abs_bytes < base and gnu:
return "%dB" % bytes

for i, s in enumerate(suffix):
unit = base ** (i + 2)
if bytes < unit and not gnu:
if abs_bytes < unit and not gnu:
return (format + " %s") % ((base * bytes / unit), s)
elif bytes < unit and gnu:
elif abs_bytes < unit and gnu:
return (format + "%s") % ((base * bytes / unit), s)
if gnu:
return (format + "%s") % ((base * bytes / unit), s)
Expand Down
6 changes: 5 additions & 1 deletion tests/test_filesize.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,9 @@
([10 ** 26 * 30, True, False, "%.3f"], "2481.542 YiB"),
],
)
def test_naturaltime_minimum_unit_default(test_args, expected):
def test_naturalsize(test_args, expected):
assert humanize.naturalsize(*test_args) == expected

args_with_negative = test_args
args_with_negative[0] *= -1
assert humanize.naturalsize(*args_with_negative) == "-" + expected

0 comments on commit 705ff99

Please sign in to comment.