diff --git a/src/humanize/filesize.py b/src/humanize/filesize.py index ca4d468..996506e 100644 --- a/src/humanize/filesize.py +++ b/src/humanize/filesize.py @@ -3,9 +3,31 @@ from __future__ import annotations suffixes = { - "decimal": (" kB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB"), - "binary": (" KiB", " MiB", " GiB", " TiB", " PiB", " EiB", " ZiB", " YiB"), - "gnu": "KMGTPEZY", + "decimal": ( + " kB", + " MB", + " GB", + " TB", + " PB", + " EB", + " ZB", + " YB", + " RB", + " QB", + ), + "binary": ( + " KiB", + " MiB", + " GiB", + " TiB", + " PiB", + " EiB", + " ZiB", + " YiB", + " RiB", + " QiB", + ), + "gnu": "KMGTPEZYRQ", } @@ -34,7 +56,9 @@ def naturalsize( >>> naturalsize(3000, True) '2.9 KiB' >>> naturalsize(10**28) - '10000.0 YB' + '10.0 RB' + >>> naturalsize(10**34 * 3) + '30000.0 QB' >>> naturalsize(-4096, True) '-4.0 KiB' @@ -65,15 +89,11 @@ def naturalsize( if abs_bytes == 1 and not gnu: return "%d Byte" % bytes_ - if abs_bytes < base and not gnu: - return "%d Bytes" % bytes_ - - if abs_bytes < base and gnu: - return "%dB" % bytes_ - - for i, s in enumerate(suffix): - unit = base ** (i + 2) + if abs_bytes < base: + return ("%dB" if gnu else "%d Bytes") % bytes_ + for i, s in enumerate(suffix, 2): + unit = base**i if abs_bytes < unit: break diff --git a/tests/test_filesize.py b/tests/test_filesize.py index 0119d58..416cbf1 100644 --- a/tests/test_filesize.py +++ b/tests/test_filesize.py @@ -12,25 +12,56 @@ "test_args, expected", [ ([300], "300 Bytes"), - ([3000], "3.0 kB"), - ([3000000], "3.0 MB"), - ([3000000000], "3.0 GB"), - ([3000000000000], "3.0 TB"), + ([1000**1 * 31], "31.0 kB"), + ([1000**2 * 32], "32.0 MB"), + ([1000**3 * 33], "33.0 GB"), + ([1000**4 * 34], "34.0 TB"), + ([1000**5 * 35], "35.0 PB"), + ([1000**6 * 36], "36.0 EB"), + ([1000**7 * 37], "37.0 ZB"), + ([1000**8 * 38], "38.0 YB"), + ([1000**9 * 39], "39.0 RB"), + ([1000**10 * 40], "40.0 QB"), ([300, True], "300 Bytes"), - ([3000, True], "2.9 KiB"), - ([3000000, True], "2.9 MiB"), + ([1024**1 * 31, True], "31.0 KiB"), + ([1024**2 * 32, True], "32.0 MiB"), + ([1024**3 * 33, True], "33.0 GiB"), + ([1024**4 * 34, True], "34.0 TiB"), + ([1024**5 * 35, True], "35.0 PiB"), + ([1024**6 * 36, True], "36.0 EiB"), + ([1024**7 * 37, True], "37.0 ZiB"), + ([1024**8 * 38, True], "38.0 YiB"), + ([1024**9 * 39, True], "39.0 RiB"), + ([1024**10 * 40, True], "40.0 QiB"), + ([1000**1 * 31, True], "30.3 KiB"), + ([1000**2 * 32, True], "30.5 MiB"), + ([1000**3 * 33, True], "30.7 GiB"), + ([1000**4 * 34, True], "30.9 TiB"), + ([1000**5 * 35, True], "31.1 PiB"), + ([1000**6 * 36, True], "31.2 EiB"), + ([1000**7 * 37, True], "31.3 ZiB"), + ([1000**8 * 38, True], "31.4 YiB"), + ([1000**9 * 39, True], "31.5 RiB"), + ([1000**10 * 40, True], "31.6 QiB"), + ([1000**1 * 31, False, True], "30.3K"), + ([1000**2 * 32, False, True], "30.5M"), + ([1000**3 * 33, False, True], "30.7G"), + ([1000**4 * 34, False, True], "30.9T"), + ([1000**5 * 35, False, True], "31.1P"), + ([1000**6 * 36, False, True], "31.2E"), + ([1000**7 * 37, False, True], "31.3Z"), + ([1000**8 * 38, False, True], "31.4Y"), + ([1000**9 * 39, False, True], "31.5R"), + ([1000**10 * 40, False, True], "31.6Q"), ([300, False, True], "300B"), ([3000, False, True], "2.9K"), ([3000000, False, True], "2.9M"), ([1024, False, True], "1.0K"), - ([10**26 * 30, False, True], "2481.5Y"), - ([10**26 * 30, True], "2481.5 YiB"), - ([10**26 * 30], "3000.0 YB"), ([1, False, False], "1 Byte"), ([3141592, False, False, "%.2f"], "3.14 MB"), ([3000, False, True, "%.3f"], "2.930K"), ([3000000000, False, True, "%.0f"], "3G"), - ([10**26 * 30, True, False, "%.3f"], "2481.542 YiB"), + ([10**26 * 30, True, False, "%.3f"], "2.423 RiB"), ], ) def test_naturalsize(test_args: list[int] | list[int | bool], expected: str) -> None: