TL;DR
num2words2 is an actively-maintained drop-in fork of num2words that addresses 79 open issues on this repo (including this one if you're reading this on a closed/stale ticket). Released on PyPI as num2words2 and on AUR as python-num2words2. Latest: v1.0.9 (2026-05-01).
pip install num2words2 # or: yay -S python-num2words2
from num2words2 import num2words
num2words(123, lang="en") # 'one hundred and twenty-three'
The public API is identical to num2words — the only change you make is the import.
Why a fork
Upstream merge velocity has slowed substantially: many bug fixes and locale additions have sat in PRs / issues for years. The fork's goal is to keep shipping. None of this is meant as a dig at the upstream maintainers — num2words is the work that made all of it possible. This issue is just a pointer for users who land here from search and need a working release today.
Issues addressed in num2words2
The 79 open upstream issues below are all resolved (or have explicit support added) in v1.0.9. Each issue already has an individual comment from me with a code sample reproducing the fix; this top-level summary is just for discovery.
Language correctness fixes — Arabic ordinals + dual case rules (#403, #516, #557), Turkish bir insertion + spacing (#486, #487, #564, #621), French ordinal -ième/-s elision (#409), Belgian/Swiss French (#169, #485), Norwegian neuter ett (#485), Catalan decimal coma (#631), Dutch year/spacing (#519, #628), Italian 18/21 (#418, #552), Portuguese dezenove (#546), Spanish un apocopation (#515), Polish negatives + twenties (#71, #277, #362), Croatian (#180), Greek (#320), Serbian Cyrl/Latn split (#332, #336), Ukrainian gender (#560), Korean ordinals (#555), Czech/Danish ISO codes (#431, #458), Brazilian . vs , parsing (#300), Hindi (#226), Persian (#378), Tamil (#423, #558), Filipino (#381), Breton (#447), Kyrgyz (#217), Nepalese (#547), Chinese (#649), Swedish triple consonant (#572, #573), German eine/spacing/capitalization (#148, #357, #462, #514).
Currency / formatting fixes — fractional cents (#190), 12 → "twelve euro, zero cents" (#426), Russian Zloty currency (#566), Nigerian decimal currency (#172), additional currency codes SGD/CHF/AED/JPY/etc. (#590), to='currency' wrong currency (#483), style='us' (#562), cents='omit' (#554), style='terse' ordinal mode (#535), 100020 currency (#553).
Numeric / API fixes — large numbers ES/PT (#501), unconventional large-number names (#514), Num2Word_ID.str_to_number (#476), Num2Word_FA.str_to_number (#522), Num2Word_AR.str_to_number (#527), Num2Word_DK.ordflag (#425), python -m num2words2 (#348), mixed text input (#281), separator parsing (#265), 24,120.10 conversion (#319), localized strings (#318), year format with decimals (#316), en_IN currency (#313), precision= override (#580), MAXVAL per language (#582), Windows test compat (#401), -1..0 negative handling (#402, #644), float vs int truncation (#414), Armenian hundreds (#599), Amharic infinite loop / 1802 (#591, #639), invalid US ordinal (#147), Arabic str_to_number (#456), Spanish ES_AR (#257), Improve Turkish overall (#534).
Full list (79): #71 #147 #148 #169 #172 #180 #190 #217 #226 #257 #265 #277 #281 #300 #313 #316 #318 #319 #320 #332 #336 #348 #357 #362 #378 #381 #401 #402 #403 #409 #414 #418 #423 #425 #426 #431 #447 #456 #458 #462 #476 #483 #485 #486 #487 #501 #514 #515 #516 #519 #522 #527 #534 #535 #546 #547 #552 #553 #554 #555 #557 #558 #560 #562 #564 #566 #572 #573 #580 #582 #590 #591 #599 #621 #628 #631 #639 #644 #649.
Releases timeline
- v1.0.4 — initial wave: Arabic ordinals + case, Turkish bir, French ordinal -ième, Norwegian neuter ett, Catalan decimal, German DEM/INR
- v1.0.5 — Turkish 121100 spacing, Spanish big-number depth (10⁵⁷),
Num2Word_ID.str_to_number
- v1.0.6 —
style='us', cents='omit', precision= kwarg
- v1.0.7 — Turkish
spaced=, decimal_word= kwargs, Serbian Cyrl/Latn split, Indian lakh/crore/arab/...
- v1.0.8 —
style='terse' ordinal mode, en_IN MAXVAL, Czech decimal strip, French/Belgian merge corrections
- v1.0.9 — CI/test hygiene; same library code as v1.0.8
Full changelog: https://github.com/jqueguiner/num2words2/releases
Trying it on your case
If your specific case isn't right in v1.0.9, open an issue at jqueguiner/num2words2/issues — I respond.
— Maintainer of jqueguiner/num2words2
TL;DR
num2words2 is an actively-maintained drop-in fork of
num2wordsthat addresses 79 open issues on this repo (including this one if you're reading this on a closed/stale ticket). Released on PyPI asnum2words2and on AUR aspython-num2words2. Latest: v1.0.9 (2026-05-01).pip install num2words2 # or: yay -S python-num2words2The public API is identical to
num2words— the only change you make is the import.Why a fork
Upstream merge velocity has slowed substantially: many bug fixes and locale additions have sat in PRs / issues for years. The fork's goal is to keep shipping. None of this is meant as a dig at the upstream maintainers —
num2wordsis the work that made all of it possible. This issue is just a pointer for users who land here from search and need a working release today.Issues addressed in num2words2
The 79 open upstream issues below are all resolved (or have explicit support added) in v1.0.9. Each issue already has an individual comment from me with a code sample reproducing the fix; this top-level summary is just for discovery.
Language correctness fixes — Arabic ordinals + dual case rules (#403, #516, #557), Turkish
birinsertion + spacing (#486, #487, #564, #621), French ordinal-ième/-selision (#409), Belgian/Swiss French (#169, #485), Norwegian neuterett(#485), Catalan decimal coma (#631), Dutch year/spacing (#519, #628), Italian 18/21 (#418, #552), Portuguesedezenove(#546), Spanishunapocopation (#515), Polish negatives + twenties (#71, #277, #362), Croatian (#180), Greek (#320), Serbian Cyrl/Latn split (#332, #336), Ukrainian gender (#560), Korean ordinals (#555), Czech/Danish ISO codes (#431, #458), Brazilian.vs,parsing (#300), Hindi (#226), Persian (#378), Tamil (#423, #558), Filipino (#381), Breton (#447), Kyrgyz (#217), Nepalese (#547), Chinese (#649), Swedish triple consonant (#572, #573), Germaneine/spacing/capitalization (#148, #357, #462, #514).Currency / formatting fixes — fractional cents (#190), 12 → "twelve euro, zero cents" (#426), Russian Zloty currency (#566), Nigerian decimal currency (#172), additional currency codes SGD/CHF/AED/JPY/etc. (#590),
to='currency'wrong currency (#483),style='us'(#562),cents='omit'(#554),style='terse'ordinal mode (#535), 100020 currency (#553).Numeric / API fixes — large numbers ES/PT (#501), unconventional large-number names (#514),
Num2Word_ID.str_to_number(#476),Num2Word_FA.str_to_number(#522),Num2Word_AR.str_to_number(#527),Num2Word_DK.ordflag(#425),python -m num2words2(#348), mixed text input (#281), separator parsing (#265), 24,120.10 conversion (#319), localized strings (#318), year format with decimals (#316), en_IN currency (#313),precision=override (#580),MAXVALper language (#582), Windows test compat (#401), -1..0 negative handling (#402, #644), float vs int truncation (#414), Armenian hundreds (#599), Amharic infinite loop / 1802 (#591, #639), invalid US ordinal (#147), Arabicstr_to_number(#456), Spanish ES_AR (#257), Improve Turkish overall (#534).Full list (79): #71 #147 #148 #169 #172 #180 #190 #217 #226 #257 #265 #277 #281 #300 #313 #316 #318 #319 #320 #332 #336 #348 #357 #362 #378 #381 #401 #402 #403 #409 #414 #418 #423 #425 #426 #431 #447 #456 #458 #462 #476 #483 #485 #486 #487 #501 #514 #515 #516 #519 #522 #527 #534 #535 #546 #547 #552 #553 #554 #555 #557 #558 #560 #562 #564 #566 #572 #573 #580 #582 #590 #591 #599 #621 #628 #631 #639 #644 #649.
Releases timeline
Num2Word_ID.str_to_numberstyle='us',cents='omit',precision=kwargspaced=,decimal_word=kwargs, Serbian Cyrl/Latn split, Indianlakh/crore/arab/...style='terse'ordinal mode, en_IN MAXVAL, Czech decimal strip, French/Belgian merge correctionsFull changelog: https://github.com/jqueguiner/num2words2/releases
Trying it on your case
If your specific case isn't right in v1.0.9, open an issue at jqueguiner/num2words2/issues — I respond.
— Maintainer of jqueguiner/num2words2