Conversation
tenfn's teen branch (tens == 1) indexed the mill table directly with mill[mindex] rather than through millfn, which performs the range check. For numbers requiring a magnitude index beyond the largest scale word (roughly 10**37 and above), this leaked an uncaught IndexError instead of the documented NumOutOfRangeError that number_to_words advertises. Route the lookup through millfn so the teen branch raises the same documented error as every other path. Adds a regression test at both the tenfn and number_to_words levels, plus a news fragment. Fixes jaraco#242.
CAOShurong
left a comment
There was a problem hiding this comment.
Verified independently (no run, no claim). I cloned the repo and checked out the PR head 3db76f5d (3db76f5dbfe1526fbc0cb05b251b3abc3b9b5d77).
Root cause matches the PR description exactly: the teen branch of tenfn indexed mill[mindex] directly instead of routing through millfn() (which is the only path that raises the documented NumOutOfRangeError). So inputs whose magnitude index exceeds len(mill) - 1 leaked an uncaught IndexError instead of the advertised error type.
Reproduction (RED on base 262a247d):
inflect.engine().number_to_words(10**40)raisesIndexError: list index out of rangeatinflect/__init__.py:3699(themill[mindex]line).- New
tests/test_numwords.py::test_issue_242FAILS on base with that sameIndexError.
GREEN at the PR head:
git checkout 3db76f5d→tests/test_numwords.py::test_issue_242and thetests/test_pwd.pytenfnassertion both pass.- Full suite via
uv run --with pytest --with more-itertools python -m pytest tests/: 172 passed, 16 xfailed, no regressions (the newtest_issue_242+test_pwdadditions included).
The fix is a 1-line change that routes the lookup through self.millfn(mindex), consistent with every other scale-word path, and it adds a newsfragments/242.bugfix.rst changelog entry. Small, correct, and well-tested. Approved.
(AI assistance used to collect verification evidence; the fix and tests are the author's.)
Fixes #242.
Problem
number_to_wordsdocuments (and imports/advertises)NumOutOfRangeErrorfor out-of-range inputs, but for numbers requiring a magnitude index beyond the largest scale word it leaks an uncaughtIndexErrorinstead:10**36raisesNumOutOfRangeErrorcorrectly;10**40and above do not.Root cause
millfnperforms the bounds check and raisesNumOutOfRangeError:Every scale-word lookup goes through it — except the teen branch of
tenfn(tens == 1), which indexed the table directly:so an out-of-range
mindexraisedIndexErrorfrom that line rather than the documented error.Fix
Route the lookup through
millfn, matching every other path:Tests
test_tenfn: the teen branch now raisesNumOutOfRangeErrorfor an out-of-range magnitude.test_issue_242:number_to_words(10**36 / 10**40 / 10**100)all raiseNumOutOfRangeError, andnumber_to_words(10**33)still returns"one decillion".Adds a
newsfragments/242.bugfix.rst.Verification (local, Python 3.11)
IndexErrorat thetenfnline; with the fix they pass.pytest— 215 passed, 16 xfailed, no regressions.ruffintroduces no new findings on the changed line.