python-humanize / python-humanize/humanize

`naturalsize()` raises `ValueError` for custom format strings with text

Open Beginner friendly
#366 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
756
Forks
148
Avg merge
6d 1h
Merged PRs (30d)
12

Description

Environment

  • humanize 4.16.0 and current main at 42b4a1db
  • Python 3.11.15

Reproduction

import humanize

print(humanize.naturalsize(999_999, gnu=True, format="Size: %.1f"))

humanize 4.15.0 returns:

Size: 976.6K

humanize 4.16.0 and current main raise:

ValueError: could not convert string to float: 'Size: 976.6'

Expected behavior

The documented custom formatter should continue to accept text around the numeric conversion.
Since this behavior worked in 4.15.0, preserving it would avoid a backward compatibility regression.

Cause

PR #329 added unit rollover handling. The new condition formats the mantissa with the
user-provided format and passes the entire result to float():

float(format % (abs_bytes / (base**exp)))

This works for a plain numeric format such as "%.1f", but not for a general formatter
such as "Size: %.1f".

Suggested fix

It might be preferable not to require the complete user-formatted result to be parseable as a float. One
backward-compatible option is to apply rollover only when the formatted result is a
plain numeric string, and otherwise preserve the pre-4.16 behavior. A more complete
solution could derive the rounded numeric mantissa independently from surrounding text.

It might also be worth adding a regression test covering both a prefix and a suffix.

How this was found

This was found by change-directed differential testing: reviewing the recent rollover change, mapping it to the public naturalsize() API, and constructing a documented custom formatter that reaches the newly added float(format % value) expression.

Related: #329, which fixes rollover but does not discuss custom format strings.

Thanks for taking the time to review this report! I appreciate all the work that goes into maintaining this project.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the naturalsize() entry point and inspect the unit-rollover handling introduced by PR #329, especially the custom-format path described in the report. Add regression coverage for format strings with both prefixes and suffixes, then run the relevant test suite; done means these formats preserve the pre-4.16 behavior while rollover still works for plain numeric formats.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
75/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.