fix(number, lists): correct negative ordinal suffixes and support general iterables with oxford_comma - #376
Conversation
for more information, see https://pre-commit.ci
Mukller
left a comment
There was a problem hiding this comment.
Verified locally on the PR branch vs release 4.16.0 (Python 3.13):
The negative-ordinal fix is real and correct — Python's modulo makes the old code produce wrong suffixes:
| input | release | branch |
|---|---|---|
ordinal(-1) |
-1th |
-1st |
ordinal(-2) |
-2th |
-2nd |
ordinal(-11) / (-111) |
-11th / -111th |
same (11/12/13 rule preserved via abs % 100) |
natural_list improvements verified too: plain generators now work (release raises TypeError), oxford_comma=True yields "a, b, and three"-style output while default stays byte-identical, two-item lists ignore the flag correctly.
pytest tests/test_lists.py tests/test_number.py — 243 passed.
One request before merge, on an unrelated bundled hunk: the __version__ fallback hardcodes "4.12.2.dev0" when _version.py is missing. That misreports the actual version in exactly the broken environments where accurate versions matter most (bug reports from source checkouts would claim 4.12.2). Suggest either dropping that hunk from this PR (it's orthogonal to both fixes here) or using a neutral placeholder via importlib.metadata.version("humanize") with a fallback of "unknown".
Everything else: approve-worthy.
|
Thanks for the review @Mukller! I have dropped the |
Summary
This PR resolves two key issues and enhances developer ergonomics:
Negative Integer Ordinal Suffix Calculation (
src/humanize/number.py):ordinal()for negative integers (e.g.-21previously returned'-21th'due to Python's modulo behavior on negative numbers). Usingabs(value)ensures correct suffixes (e.g.,-1st,-2nd,-3rd,-11th,-21st).Iterable & Oxford Comma Support in
natural_list(src/humanize/lists.py):natural_listto accept any generalIterable(such as generators, tuples, sets) instead of strictly requiringlist.oxford_comma: bool = Falseparameter to format lists as'one, two, and three'.Source Import & Test Resilience (
src/humanize/__init__.py,tests/):try...except ImportErrorfallback for_version.pyin__init__.pyso importing directly from source without build artifacts works smoothly.pytest.importorskipfor optional test dependencies (freezegun,pytest-codspeed) to prevent test crashes in minimal development environments.Empirical Test Verification
Ran
pytest: