Skip to content

Commit

Permalink
Merge pull request #692 from zwimer/fix/691-file_size_formatting
Browse files Browse the repository at this point in the history
Add small_formatting argument to file_size
  • Loading branch information
staticdev authored Dec 30, 2024
2 parents 2113c2c + 2b28dcf commit 34fb04e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 16 deletions.
20 changes: 14 additions & 6 deletions src/human_readable/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@


def file_size(
value: int, binary: bool = False, gnu: bool = False, formatting: str = ".1f"
value: int,
binary: bool = False,
gnu: bool = False,
formatting: str = ".1f",
small_formatting: str = "",
) -> str:
"""Return human-readable file size.
Expand All @@ -12,12 +16,16 @@ def file_size(
`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.
small_formatting is used instead of formatting when the number of bytes
is small enough that the applied suffix is B / Byte / Bytes, since files
cannot have a decimal number of bytes in a file size
Args:
value: size number.
binary: binary format. Defaults to False.
gnu: GNU format. Defaults to False.
formatting: format pattern. Defaults to ".1f".
formatting: format pattern (applied to a float). Defaults to ".1f".
small_formatting: format pattern for small values (applied to an int). Defaults to "".
Returns:
str: file size in natural language.
Expand All @@ -27,16 +35,16 @@ def file_size(
elif binary:
suffixes = (" KiB", " MiB", " GiB", " TiB", " PiB", " EiB", " ZiB", " YiB")
else:
suffixes = (" kB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB")
suffixes = (" KB", " MB", " GB", " TB", " PB", " EB", " ZB", " YB")

base = 1024 if (gnu or binary) else 1000

if value == 1 and not gnu:
return f"{1:{formatting}} Byte"
return f"{1:{small_formatting}} Byte"
if value < base and not gnu:
return f"{value:{formatting}} Bytes"
return f"{value:{small_formatting}} Bytes"
if value < base and gnu:
return f"{value:{formatting}}B"
return f"{value:{small_formatting}}B"

byte_size = float(value)
suffix = ""
Expand Down
25 changes: 15 additions & 10 deletions tests/unit/test_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

import pytest

import human_readable.files as files
from human_readable import files


@pytest.mark.parametrize(
"params, expected",
[
(1, "1.0 Byte"), # unit number
(300, "300.0 Bytes"), # hundreds number
(1, "1 Byte"), # unit number
(300, "300 Bytes"), # hundreds number
(2900000, "2.9 MB"), # millions number
(2000000000, "2.0 GB"), # billions number
(10**26 * 30, "3000.0 YB"), # giant number
Expand All @@ -24,8 +24,8 @@ def test_file_size(params: int, expected: str) -> None:
@pytest.mark.parametrize(
"params, expected",
[
((1, True), "1.0 Byte"), # unit number
((300, True), "300.0 Bytes"), # hundreds number
((1, True), "1 Byte"), # unit number
((300, True), "300 Bytes"), # hundreds number
((2900000, True), "2.8 MiB"), # millions number
((2000000000, True), "1.9 GiB"), # billions number
((10**26 * 30, True), "2481.5 YiB"), # giant number
Expand All @@ -39,8 +39,8 @@ def test_file_size_binary(params: tuple[int, bool], expected: str) -> None:
@pytest.mark.parametrize(
"params, expected",
[
((1, False, True), "1.0B"), # unit number
((300, False, True), "300.0B"), # hundreds number
((1, False, True), "1B"), # unit number
((300, False, True), "300B"), # hundreds number
((2900000, False, True), "2.8M"), # millions number
((2000000000, False, True), "1.9G"), # billions number
((10**26 * 30, False, True), "2481.5Y"), # giant number
Expand All @@ -54,9 +54,14 @@ def test_file_size_gnu(params: tuple[int, bool, bool], expected: str) -> None:
@pytest.mark.parametrize(
"params, expected",
[
((1, False, True, ".0f"), "1B"), # unit number
((300, True, False, ".2f"), "300.00 Bytes"), # hundreds number
((2900000, False, True, ".3f"), "2.766M"), # millions number
((1, False, True, ".3f", ".1f"), "1.0B"), # unit number (small formatting)
((999, False, False, ".3f", ".1f"), "999.0 Bytes"), # hundreds number (small formatting)
((1000, False, False, ".3f", ".1f"), "1.000 KB"), # hundreds number (small formatting boundary)
((1023, False, True, ".3f", ".1f"), "1023.0B"), # hundreds number (small formatting boundary)
((1024, False, True, ".3f", ".1f"), "1.000K"), # hundreds number (small formatting boundary)
((1023, True, False, ".3f", ".1f"), "1023.0 Bytes"), # hundreds number (small formatting boundary)
((1024, True, False, ".3f", ".1f"), "1.000 KiB"), # hundreds number (small formatting boundary)
((2900000, False, True, ".3f"), "2.766M"), # millions number (large formatting)
(
(2000000000, True, False, ".3f"),
"1.863 GiB",
Expand Down

0 comments on commit 34fb04e

Please sign in to comment.