diff --git a/src/humanize/filesize.py b/src/humanize/filesize.py index fb675fdc..40ba26b8 100644 --- a/src/humanize/filesize.py +++ b/src/humanize/filesize.py @@ -103,8 +103,14 @@ def naturalsize( # mantissa afterward; rounding can push it up to `base` (e.g. 999999 is # 999.999 kB, which formats to "1000.0 kB"). When that happens and a larger # suffix is available, step up one suffix so the result reads "1.0 MB". - if exp < len(suffix) and abs(float(format % (abs_bytes / (base**exp)))) >= base: - exp += 1 + if exp < len(suffix): + mantissa_text = format % (abs_bytes / (base**exp)) + try: + mantissa = float(mantissa_text) + except ValueError: + mantissa = None + if mantissa is not None and abs(mantissa) >= base: + exp += 1 space = "" if gnu else " " ret: str = format % (bytes_ / (base**exp)) + space + _(suffix[exp - 1]) return ret diff --git a/tests/test_filesize.py b/tests/test_filesize.py index e6956399..2e2bd516 100644 --- a/tests/test_filesize.py +++ b/tests/test_filesize.py @@ -103,3 +103,14 @@ def test_naturalsize(test_args: list[int] | list[int | bool], expected: str) -> test_args[0] = f"-{test_args[0]}" assert humanize.naturalsize(*test_args) == "-" + expected + + +def test_naturalsize_custom_format_with_text() -> None: + # regression: custom format strings with surrounding text must not crash + # https://github.com/python-humanize/humanize/issues/366 + assert ( + humanize.naturalsize(999_999, gnu=True, format="Size: %.1f") == "Size: 976.6K" + ) + assert ( + humanize.naturalsize(999_999, gnu=True, format="%.1f bytes") == "976.6 bytesK" + )