Skip to main content
PyPI version Python versions License Monthly downloads AUR version CI status Lint status Coverage

num2words2 converts numbers like 42 to words like forty-two across 120+ languages and 170+ locale codes (see REFERENCE.md for the full table), producing cardinals, ordinals, currency, year, fractions, bank-cheque format, and aviation/ICAO digit-by-digit phraseology.

It is a Rust port of the num2words conversion engine with a thin Python binder. Every conversion runs in a compiled Rust core (PyO3/abi3); Python only normalises the arguments and shapes the result. The output is byte-for-byte identical to the original pure-Python library — validated against a frozen ~150,000-case corpus — while running typically 4–12× faster, and up to 26× on some languages and 150× on string parsing (see Performance).

The project is hosted on GitHub, and the full documentation is available in the Wiki. Contributions are welcome.

Performance

Because the conversion engine is compiled Rust, num2words2 is several times faster than the original pure-Python num2words. Benchmarked against num2words 0.5.14, Apple M-series, nanoseconds per call:

Operation

original

num2words2

speedup

int → cardinal (8765)

24,384 ns

2,099 ns

11.6×

float → cardinal (1234.56)

33,107 ns

3,367 ns

9.8×

ordinal

24,969 ns

2,407 ns

10.4×

currency

32,518 ns

3,345 ns

9.7×

year

13,484 ns

1,434 ns

9.4×

string input ("1234")

335,862 ns

2,200 ns

152.6×

French cardinal

61,046 ns

2,359 ns

25.9×

German cardinal

63,046 ns

2,386 ns

26.4×

Russian cardinal

4,781 ns

1,001 ns

4.8×

The speedup is largest where the original does heavy Python-level parsing (string inputs) or deep recursion (French, German); it never comes at the cost of accuracy — output is byte-for-byte identical to the original across a frozen ~150,000-case corpus of cardinals, ordinals, currency, years, fractions, floats and strings.

Installation

Install from PyPI — the wheels bundle the Python binder and the compiled Rust extension, built per platform:

pip install num2words2

Wheels for every version are also attached to the GitHub Releases page; the compiled extension is distributed only through those release wheels (it is not committed to the repository).

To build from source you need a stable Rust toolchain and maturin:

maturin build --release

Development Setup

The project uses pre-commit hooks to ensure code quality. To set up your development environment:

# Install pre-commit
pip install pre-commit

# Install the git hook scripts
pre-commit install

# Run hooks on all files (optional, useful for initial setup)
pre-commit run --all-files

This will automatically format and lint your code before each commit using:

  • autopep8 - PEP 8 formatting

  • autoflake - removes unused imports and variables

  • isort - sorts imports

  • flake8 - style and quality checks

  • trailing-whitespace removal

  • end-of-file fixing

Testing

The library uses pytest for testing. First, install the development dependencies:

make dev-install

Then, you can run the test suite using several methods:

  • Run basic tests: This runs tests with your current Python environment.

    make test
  • Run with Tox: This runs tests against all supported Python versions, which is the standard for CI.

    tox

Generating End-to-End Tests with LLMs

The repository includes a powerful script to generate high-quality, realistic test cases using Large Language Models (LLMs). This helps ensure accuracy across multiple languages and complex scenarios.

What it does: The tests/scripts/generate_llm_tests.py script uses an LLM (like GPT-4o) to create sentences containing numbers, dates, and currencies, and then generates the expected word-for-word conversion.

Requirements:

  • An OpenAI API key. You must set it as an environment variable: export OPENAI_API_KEY='your-key-here'

How to Use:

To generate 10 new test sentences for French and Spanish, you can run:

python tests/scripts/generate_llm_tests.py --languages fr,es --samples 10

The new tests will be appended to tests/data/e2e_test_sentences.csv.

Key Options:

  • --languages: Comma-separated list of language codes (e.g., en_IN,de,it).

  • --samples: Number of samples to generate per language.

  • --mode: Use sentences for full sentences or numbers for direct number-to-word conversions.

  • --model: The OpenAI model to use (e.g., gpt-4o, gpt-4o-mini).

  • --output: Specify a different output file.

  • --overwrite: Overwrite the output file instead of appending.

This tool is essential for expanding test coverage and ensuring the library’s robustness.

Usage

Command line:

$ num2words2 10001
ten thousand and one
$ num2words2 24,120.10
twenty-four thousand, one hundred and twenty point one
$ num2words2 24,120.10 -l es
veinticuatro mil ciento veinte punto uno
$ num2words2 2.14 -l es --to currency
dos euros con catorce céntimos

In code there’s only one function to use:

>>> from num2words2 import num2words
>>> num2words(42)
forty-two
>>> num2words(42, to='ordinal')
forty-second
>>> num2words(42, lang='fr')
quarante-deux

Besides the numerical argument, there are two main optional arguments, to: and lang:

to: The converter to use. Supported values are:

  • cardinal (default)

  • ordinal

  • ordinal_num

  • year

  • currency

lang: The language in which to convert the number. Supported values are:

  • en (English, default)

  • am (Amharic)

  • ar (Arabic)

  • az (Azerbaijani)

  • be (Belarusian)

  • bn (Bangladeshi)

  • ca (Catalan)

  • ce (Chechen)

  • cs (Czech)

  • cy (Welsh)

  • da (Danish)

  • de (German)

  • en_GB (English - Great Britain)

  • en_IN (English - India)

  • en_NG (English - Nigeria)

  • es (Spanish)

  • es_CO (Spanish - Colombia)

  • es_CR (Spanish - Costa Rica)

  • es_GT (Spanish - Guatemala)

  • es_VE (Spanish - Venezuela)

  • eu (EURO)

  • fa (Farsi)

  • fi (Finnish)

  • fr (French)

  • fr_BE (French - Belgium)

  • fr_CH (French - Switzerland)

  • fr_DZ (French - Algeria)

  • he (Hebrew)

  • hi (Hindi)

  • hu (Hungarian)

  • hy (Armenian)

  • id (Indonesian)

  • is (Icelandic)

  • it (Italian)

  • ja (Japanese)

  • kn (Kannada)

  • ko (Korean)

  • kz (Kazakh)

  • mn (Mongolian)

  • lt (Lithuanian)

  • lv (Latvian)

  • nl (Dutch)

  • no (Norwegian)

  • pl (Polish)

  • pt (Portuguese)

  • pt_BR (Portuguese - Brazilian)

  • ro (Romanian)

  • ru (Russian)

  • sl (Slovene)

  • sk (Slovak)

  • sr (Serbian)

  • sv (Swedish)

  • te (Telugu)

  • tet (Tetum)

  • tg (Tajik)

  • tr (Turkish)

  • th (Thai)

  • uk (Ukrainian)

  • vi (Vietnamese)

  • zh (Chinese - Traditional)

  • zh_CN (Chinese - Simplified / Mainland China)

  • zh_TW (Chinese - Traditional / Taiwan)

  • zh_HK (Chinese - Traditional / Hong Kong)

You can supply values like fr_FR; if the country doesn’t exist but the language does, the code will fall back to the base language (i.e. fr). If you supply an unsupported language, NotImplementedError is raised. Therefore, if you want to call num2words with a fallback, you can do:

try:
    return num2words(42, lang=mylang)
except NotImplementedError:
    return num2words(42, lang='en')

Additionally, some converters and languages support other optional arguments that are needed to make the converter useful in practice.

Wiki

For the full documentation, including installation, API details, CLI usage, supported locales, sentence conversion, currency handling, and migration guidance, please check the Wiki. Feel free to propose wiki enhancements.

History

num2words is based on an old library, pynum2word, created by Taro Ogawa in 2003. Unfortunately, the library stopped being maintained and the author can’t be reached. There was another developer, Marius Grigaitis, who in 2011 added Lithuanian support, but didn’t take over maintenance of the project.

Virgil Dupras from Savoir-faire Linux based himself on Marius Grigaitis’ improvements and re-published pynum2word as num2words.

Relationship to num2words

num2words2 is not a divergent fork. It is a Rust port of the num2words conversion engine with a Python binder, kept output-compatible with the original.

The original project’s issues and pull requests are actively monitored. Valid, relevant fixes and features are reviewed and then ported into this project’s Rust core, with byte-parity re-verified against the frozen corpus. num2words2 therefore tracks upstream improvements while delivering them natively — and several times faster.

Jean-Louis Queguiner

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

num2words2-1.0.18.tar.gz (2.3 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

num2words2-1.0.18-cp38-abi3-win_amd64.whl (3.1 MB view details)

Uploaded CPython 3.8+Windows x86-64

num2words2-1.0.18-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.1 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

num2words2-1.0.18-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.0 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

num2words2-1.0.18-cp38-abi3-macosx_11_0_arm64.whl (2.7 MB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

File details

Details for the file num2words2-1.0.18.tar.gz.

File metadata

  • Download URL: num2words2-1.0.18.tar.gz
  • Upload date:
  • Size: 2.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for num2words2-1.0.18.tar.gz
Algorithm Hash digest
SHA256 0c03d6e2057820c13f497d5e2a7c1e98c7f43238e99de1093a6982a8e87e0e54
MD5 1cc29ac0dd8efecc18e0d0663cef5ca4
BLAKE2b-256 a73f3aca6139ccc1dc0c2f486498a988e8853202dee1d2c2c9c9c68b4f31eaac

See more details on using hashes here.

File details

Details for the file num2words2-1.0.18-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: num2words2-1.0.18-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 3.1 MB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for num2words2-1.0.18-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 3b6207b77c023ce40ebba7b3c5432f62c7fcf1c2a4ddfac6bc055ee7f3401d83
MD5 d0bd2a921c25d9c67b6f81e570eda6f1
BLAKE2b-256 f4ea096ecae3a07299561f5faaa5f1372d03ac12b4389452143ab7c76071938a

See more details on using hashes here.

File details

Details for the file num2words2-1.0.18-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for num2words2-1.0.18-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 06de5ecb09fdc73191f0e348eae32595c89e6a3f7f82793f2d74931836be65a7
MD5 34a13398c28672ef5eb153a8ef65d3a3
BLAKE2b-256 a1411ba4aa5c3107bcc7110cbbf1769c20cb5ad75b7b3d3a6b719072fe30d557

See more details on using hashes here.

File details

Details for the file num2words2-1.0.18-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for num2words2-1.0.18-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e8ccdedb7ca418d411e26538870c3c2cb54935abe226a0fada16f43b0041c301
MD5 0a2a209f7efd51c48b39aa93d037ca28
BLAKE2b-256 7daa969210eb295b747700aad5bfcfa58c685671e6584a7080e6afc1a9854e9b

See more details on using hashes here.

File details

Details for the file num2words2-1.0.18-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for num2words2-1.0.18-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 52cf41dc0f208e0eac44ac28b794d8f8ff2fb22418aafb49adbfc1fa52011e04
MD5 f02839cca90d2523035070abea97c22e
BLAKE2b-256 cadd62a3722b8ac96aa5ef865b541a23656d7afc14f72c4bccf2feadde8e57d8

See more details on using hashes here.

Release history Release notifications | RSS feed

1.0.20

6 files

1.0.19

6 files

This release

1.0.18 This release

5 files

1.0.17

2 files

1.0.16

2 files

1.0.15

2 files

1.0.14

2 files

1.0.13

2 files

1.0.12

2 files

1.0.11

2 files

1.0.10

2 files

1.0.9

2 files

1.0.8

2 files

1.0.7

2 files

1.0.6

2 files

1.0.5

2 files

1.0.4

2 files

1.0.3

2 files

1.0.2

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page