words2num2 0.3.0.dev1__tar.gz → 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {words2num2-0.3.0.dev1 → words2num2-0.3.1}/PKG-INFO +86 -28
- words2num2-0.3.0.dev1/words2num2.egg-info/PKG-INFO → words2num2-0.3.1/README.rst +72 -44
- words2num2-0.3.1/pyproject.toml +94 -0
- words2num2-0.3.1/rust/Cargo.lock +287 -0
- words2num2-0.3.1/rust/Cargo.toml +16 -0
- words2num2-0.3.1/rust/words2num2-core/Cargo.toml +18 -0
- words2num2-0.3.1/rust/words2num2-core/src/lib.rs +242 -0
- words2num2-0.3.1/rust/words2num2-core/src/w2n_formats.rs +1056 -0
- words2num2-0.3.1/rust/words2num2-core/src/w2n_lang_en.rs +1011 -0
- words2num2-0.3.1/rust/words2num2-core/src/w2n_sentence.rs +2336 -0
- words2num2-0.3.1/rust/words2num2-py/Cargo.toml +14 -0
- words2num2-0.3.1/rust/words2num2-py/src/lib.rs +312 -0
- words2num2-0.3.1/words2num2/__init__.py +140 -0
- words2num2-0.3.1/words2num2/_version.py +5 -0
- words2num2-0.3.1/words2num2/base.py +19 -0
- words2num2-0.3.1/words2num2/converters/auto.py +43 -0
- words2num2-0.3.0.dev1/.flake8 +0 -11
- words2num2-0.3.0.dev1/.github/workflows/aur-publish.yml +0 -104
- words2num2-0.3.0.dev1/.github/workflows/ci.yml +0 -68
- words2num2-0.3.0.dev1/.github/workflows/codeql-analysis.yml +0 -38
- words2num2-0.3.0.dev1/.github/workflows/e2e-tests.yml +0 -73
- words2num2-0.3.0.dev1/.github/workflows/lint.yml +0 -47
- words2num2-0.3.0.dev1/.github/workflows/manual-publish.yml +0 -66
- words2num2-0.3.0.dev1/.github/workflows/manual-release.yml +0 -81
- words2num2-0.3.0.dev1/.github/workflows/pr-size.yml +0 -67
- words2num2-0.3.0.dev1/.github/workflows/publish-pypi.yml +0 -76
- words2num2-0.3.0.dev1/.github/workflows/python-publish.yml +0 -61
- words2num2-0.3.0.dev1/.github/workflows/release.yml +0 -166
- words2num2-0.3.0.dev1/.github/workflows/scheduled-test.yml +0 -44
- words2num2-0.3.0.dev1/.gitignore +0 -18
- words2num2-0.3.0.dev1/CHANGELOG.md +0 -139
- words2num2-0.3.0.dev1/CONTRIBUTING.md +0 -123
- words2num2-0.3.0.dev1/LOCAL_TESTING.md +0 -173
- words2num2-0.3.0.dev1/MANIFEST.in +0 -5
- words2num2-0.3.0.dev1/Makefile +0 -50
- words2num2-0.3.0.dev1/README.rst +0 -351
- words2num2-0.3.0.dev1/REFERENCE.md +0 -450
- words2num2-0.3.0.dev1/bin/words2num2 +0 -28
- words2num2-0.3.0.dev1/packaging/aur/python-words2num2/.SRCINFO +0 -20
- words2num2-0.3.0.dev1/packaging/aur/python-words2num2/PKGBUILD +0 -33
- words2num2-0.3.0.dev1/packaging/aur/python-words2num2/README.md +0 -88
- words2num2-0.3.0.dev1/pyproject.toml +0 -87
- words2num2-0.3.0.dev1/setup.cfg +0 -4
- words2num2-0.3.0.dev1/setup.py +0 -58
- words2num2-0.3.0.dev1/tests/__init__.py +0 -0
- words2num2-0.3.0.dev1/tests/test_auto_parse.py +0 -252
- words2num2-0.3.0.dev1/tests/test_dispatch.py +0 -28
- words2num2-0.3.0.dev1/tests/test_lang_EN.py +0 -113
- words2num2-0.3.0.dev1/tests/test_multilang.py +0 -49
- words2num2-0.3.0.dev1/words2num2/__init__.py +0 -360
- words2num2-0.3.0.dev1/words2num2/_version.py +0 -3
- words2num2-0.3.0.dev1/words2num2/base.py +0 -155
- words2num2-0.3.0.dev1/words2num2/compat.py +0 -9
- words2num2-0.3.0.dev1/words2num2/converters/auto.py +0 -586
- words2num2-0.3.0.dev1/words2num2/converters/sentence.py +0 -116
- words2num2-0.3.0.dev1/words2num2/formats.py +0 -212
- words2num2-0.3.0.dev1/words2num2/lang_AF.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_AM.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_AR.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_AS.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_AZ.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_BA.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_BE.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_BG.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_BN.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_BO.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_BR.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_BS.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_CA.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_CE.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_CS.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_CY.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_DA.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_DE.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_EL.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_EN.py +0 -242
- words2num2-0.3.0.dev1/words2num2/lang_EN_IN.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_EN_NG.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_EO.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_ES.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_ES_CO.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_ES_CR.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_ES_GT.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_ES_NI.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_ES_VE.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_ET.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_EU.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_FA.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_FI.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_FO.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_FR.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_FR_BE.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_FR_CH.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_FR_DZ.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_GL.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_GU.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_HA.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_HAW.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_HE.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_HI.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_HR.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_HT.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_HU.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_HY.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_ID.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_IS.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_IT.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_JA.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_JW.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_KA.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_KK.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_KM.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_KN.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_KO.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_KZ.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_LA.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_LB.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_LN.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_LO.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_LT.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_LV.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_MG.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_MI.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_MK.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_ML.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_MN.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_MR.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_MS.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_MT.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_MY.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_NE.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_NL.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_NN.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_NO.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_OC.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_PA.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_PL.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_PS.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_PT.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_PT_BR.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_RO.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_RU.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_SA.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_SD.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_SI.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_SK.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_SL.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_SN.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_SO.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_SQ.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_SR.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_SU.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_SV.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_SW.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_TA.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_TE.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_TET.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_TG.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_TH.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_TK.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_TL.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_TR.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_TT.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_UK.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_UR.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_UZ.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_VI.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_WO.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_YI.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_YO.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_ZH.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_ZH_CN.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_ZH_HK.py +0 -15
- words2num2-0.3.0.dev1/words2num2/lang_ZH_TW.py +0 -15
- words2num2-0.3.0.dev1/words2num2/utils.py +0 -23
- words2num2-0.3.0.dev1/words2num2.egg-info/SOURCES.txt +0 -167
- words2num2-0.3.0.dev1/words2num2.egg-info/dependency_links.txt +0 -1
- words2num2-0.3.0.dev1/words2num2.egg-info/entry_points.txt +0 -2
- words2num2-0.3.0.dev1/words2num2.egg-info/requires.txt +0 -2
- words2num2-0.3.0.dev1/words2num2.egg-info/top_level.txt +0 -1
- {words2num2-0.3.0.dev1 → words2num2-0.3.1}/COPYING +0 -0
- {words2num2-0.3.0.dev1 → words2num2-0.3.1}/words2num2/__main__.py +0 -0
- {words2num2-0.3.0.dev1 → words2num2-0.3.1}/words2num2/converters/__init__.py +0 -0
|
@@ -1,17 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: words2num2
|
|
3
|
-
Version: 0.3.
|
|
4
|
-
Summary: Inverse of num2words2: convert spoken-form numbers back to numeric values across 100+ languages.
|
|
5
|
-
Home-page: https://github.com/jqueguiner/words2num2
|
|
6
|
-
Author: Jean-Louis Queguiner
|
|
7
|
-
Author-email: Jean-Louis Queguiner <jlqueguiner@gladia.io>
|
|
8
|
-
Maintainer: Jean-Louis Queguiner
|
|
9
|
-
Maintainer-email: Jean-Louis Queguiner <jlqueguiner@gladia.io>
|
|
10
|
-
License: LGPL-2.1
|
|
11
|
-
Project-URL: Homepage, https://github.com/jqueguiner/words2num2
|
|
12
|
-
Project-URL: Repository, https://github.com/jqueguiner/words2num2.git
|
|
13
|
-
Project-URL: Bug Tracker, https://github.com/jqueguiner/words2num2/issues
|
|
14
|
-
Keywords: number,word,numbers,words,parse,parser,convert,conversion,i18n,localisation,localization,internationalisation,internationalization,asr,speech,llm
|
|
3
|
+
Version: 0.3.1
|
|
15
4
|
Classifier: Development Status :: 4 - Beta
|
|
16
5
|
Classifier: Intended Audience :: Developers
|
|
17
6
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -20,21 +9,23 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
20
9
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
10
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
11
|
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
-
Classifier: Programming Language ::
|
|
12
|
+
Classifier: Programming Language :: Rust
|
|
24
13
|
Classifier: Topic :: Software Development :: Internationalization
|
|
25
14
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
26
15
|
Classifier: Topic :: Software Development :: Localization
|
|
27
16
|
Classifier: Topic :: Text Processing :: Linguistic
|
|
28
|
-
Requires-Python: >=3.10
|
|
29
|
-
Description-Content-Type: text/x-rst
|
|
30
17
|
License-File: COPYING
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
18
|
+
Summary: Rust-powered inverse of num2words2: parse spoken-form numbers back to numeric values across 100+ languages, optimized for ASR/LLM/speech.
|
|
19
|
+
Keywords: number,word,numbers,words,parse,parser,convert,conversion,i18n,localisation,localization,internationalisation,internationalization,asr,speech,llm,rust
|
|
20
|
+
Author-email: Jean-Louis Queguiner <jean-louis.queguiner@gmail.com>
|
|
21
|
+
Maintainer-email: Jean-Louis Queguiner <jean-louis.queguiner@gmail.com>
|
|
22
|
+
License-Expression: LGPL-2.1-only
|
|
23
|
+
Requires-Python: >=3.10
|
|
24
|
+
Description-Content-Type: text/x-rst; charset=UTF-8
|
|
25
|
+
Project-URL: Bug Tracker, https://github.com/jqueguiner/words2num2/issues
|
|
26
|
+
Project-URL: Documentation, https://github.com/jqueguiner/words2num2/wiki
|
|
27
|
+
Project-URL: Homepage, https://github.com/jqueguiner/words2num2
|
|
28
|
+
Project-URL: Repository, https://github.com/jqueguiner/words2num2.git
|
|
38
29
|
|
|
39
30
|
words2num2 — words to numbers
|
|
40
31
|
=============================
|
|
@@ -104,9 +95,21 @@ entries**) and adds a free-text *auto-parse* mode that handles
|
|
|
104
95
|
currencies, units, configurable thousands/decimal separators, and
|
|
105
96
|
ASR/LLM-style mixed text.
|
|
106
97
|
|
|
107
|
-
|
|
98
|
+
It is **Rust-powered with a thin Python binder**. The whole parsing engine —
|
|
99
|
+
the English grammar, the generic reverse-lookup backend, the sentence walker,
|
|
100
|
+
number-format parsing and auto-parse — runs in a compiled Rust core
|
|
101
|
+
(PyO3/``abi3``); Python only shapes arguments and results. The core embeds the
|
|
102
|
+
num2words2 conversion engine natively, so ``words2num2`` is **self-contained
|
|
103
|
+
and has no runtime dependencies**, while running several times faster than the
|
|
104
|
+
former pure-Python implementation. Output is unchanged — validated against a
|
|
105
|
+
frozen corpus of ~11,000 round-trip cases.
|
|
106
|
+
|
|
107
|
+
The project is hosted on GitHub_, and the full documentation is available
|
|
108
|
+
in the Wiki_. Contributions are welcome.
|
|
108
109
|
|
|
109
110
|
.. _GitHub: https://github.com/jqueguiner/words2num2
|
|
111
|
+
.. _Wiki: https://github.com/jqueguiner/words2num2/wiki
|
|
112
|
+
.. _GitHub Releases: https://github.com/jqueguiner/words2num2/releases
|
|
110
113
|
|
|
111
114
|
Why this library
|
|
112
115
|
----------------
|
|
@@ -130,13 +133,59 @@ the forward direction. ``words2num2``:
|
|
|
130
133
|
* Pluralizes long-form units in expand mode (``5 dollars`` /
|
|
131
134
|
``1 dollar``, ``5 feet`` / ``1 foot``, ``5 yen`` / ``1 yen``).
|
|
132
135
|
|
|
136
|
+
Performance
|
|
137
|
+
-----------
|
|
138
|
+
|
|
139
|
+
The parsing engine is compiled Rust (PyO3/``abi3``), so there is no
|
|
140
|
+
Python-level tokenising or table walking on the hot path. Typical native
|
|
141
|
+
throughput (Apple M-series, nanoseconds per call, after warmup):
|
|
142
|
+
|
|
143
|
+
.. list-table::
|
|
144
|
+
:header-rows: 1
|
|
145
|
+
:widths: 60 20
|
|
146
|
+
|
|
147
|
+
* - Operation
|
|
148
|
+
- ns/call
|
|
149
|
+
* - English cardinal (``"eight thousand seven hundred sixty-five"``)
|
|
150
|
+
- ~5,900
|
|
151
|
+
* - English ordinal (``"forty-second"``)
|
|
152
|
+
- ~4,100
|
|
153
|
+
* - French cardinal (``"trois cent quatre"``)
|
|
154
|
+
- ~1,900
|
|
155
|
+
* - Russian cardinal (``"сорок два"``)
|
|
156
|
+
- ~1,700
|
|
157
|
+
* - ``parse_number_string("1.234.567,89", lang="de")``
|
|
158
|
+
- ~240
|
|
159
|
+
* - ``auto_parse("$12,345.00")``
|
|
160
|
+
- ~990
|
|
161
|
+
|
|
162
|
+
For the 100+ generic locales, the first call in a given language builds the
|
|
163
|
+
``{words → number}`` reverse table once (~35 ms) and caches it in the core;
|
|
164
|
+
every call after that is a native lookup. Output is byte-for-byte identical to
|
|
165
|
+
the former pure-Python implementation, validated against a frozen corpus of
|
|
166
|
+
~11,000 round-trip cases and the full test suite.
|
|
167
|
+
|
|
133
168
|
Installation
|
|
134
169
|
------------
|
|
135
170
|
|
|
136
|
-
**pip
|
|
171
|
+
**pip** (Python 3.10+)::
|
|
137
172
|
|
|
138
173
|
pip install words2num2
|
|
139
174
|
|
|
175
|
+
That's it — the wheel bundles the Python binder and the compiled Rust
|
|
176
|
+
extension, and ``words2num2`` has **no runtime dependencies** (the num2words2
|
|
177
|
+
conversion engine is compiled in, so you do *not* need the num2words2 package).
|
|
178
|
+
|
|
179
|
+
Prebuilt wheels are published for:
|
|
180
|
+
|
|
181
|
+
* **Linux** — x86_64 and aarch64 (manylinux2014)
|
|
182
|
+
* **macOS** — Apple Silicon (arm64); Intel (x86_64) from a later release
|
|
183
|
+
* **Windows** — x86_64
|
|
184
|
+
|
|
185
|
+
On any other platform (or an older release without a matching wheel), pip
|
|
186
|
+
falls back to the source distribution and builds the extension locally — this
|
|
187
|
+
needs a **stable Rust toolchain** (`rustup <https://rustup.rs>`_); nothing else.
|
|
188
|
+
|
|
140
189
|
**Arch Linux / Manjaro (AUR):**
|
|
141
190
|
|
|
142
191
|
.. code-block:: bash
|
|
@@ -150,14 +199,15 @@ Installation
|
|
|
150
199
|
cd python-words2num2
|
|
151
200
|
makepkg -si
|
|
152
201
|
|
|
153
|
-
**From source
|
|
202
|
+
**From source** (needs a stable Rust toolchain and `maturin
|
|
203
|
+
<https://www.maturin.rs>`_)::
|
|
154
204
|
|
|
155
205
|
git clone https://github.com/jqueguiner/words2num2
|
|
156
206
|
cd words2num2
|
|
157
|
-
pip install -e .
|
|
207
|
+
pip install -e . # builds the Rust extension via maturin
|
|
208
|
+
# or, to produce a wheel: maturin build --release
|
|
158
209
|
|
|
159
|
-
|
|
160
|
-
backend and is installed automatically.
|
|
210
|
+
Wheels for every version are also attached to the `GitHub Releases`_ page.
|
|
161
211
|
|
|
162
212
|
Quickstart
|
|
163
213
|
----------
|
|
@@ -303,6 +353,13 @@ entries** including:
|
|
|
303
353
|
|
|
304
354
|
Aliases: ``jp`` → ``ja``, ``cn`` → ``zh_CN``.
|
|
305
355
|
|
|
356
|
+
Wiki
|
|
357
|
+
----
|
|
358
|
+
For the full documentation, including installation, API details, CLI
|
|
359
|
+
usage, supported locales, sentence conversion, auto-parse behavior, and
|
|
360
|
+
migration guidance, please check the Wiki_. Feel free to propose wiki
|
|
361
|
+
enhancements.
|
|
362
|
+
|
|
306
363
|
Conversion types
|
|
307
364
|
~~~~~~~~~~~~~~~~
|
|
308
365
|
|
|
@@ -387,3 +444,4 @@ License
|
|
|
387
444
|
-------
|
|
388
445
|
|
|
389
446
|
LGPL-2.1, mirroring ``num2words2``. See `COPYING`.
|
|
447
|
+
|
|
@@ -1,41 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: words2num2
|
|
3
|
-
Version: 0.3.0.dev1
|
|
4
|
-
Summary: Inverse of num2words2: convert spoken-form numbers back to numeric values across 100+ languages.
|
|
5
|
-
Home-page: https://github.com/jqueguiner/words2num2
|
|
6
|
-
Author: Jean-Louis Queguiner
|
|
7
|
-
Author-email: Jean-Louis Queguiner <jlqueguiner@gladia.io>
|
|
8
|
-
Maintainer: Jean-Louis Queguiner
|
|
9
|
-
Maintainer-email: Jean-Louis Queguiner <jlqueguiner@gladia.io>
|
|
10
|
-
License: LGPL-2.1
|
|
11
|
-
Project-URL: Homepage, https://github.com/jqueguiner/words2num2
|
|
12
|
-
Project-URL: Repository, https://github.com/jqueguiner/words2num2.git
|
|
13
|
-
Project-URL: Bug Tracker, https://github.com/jqueguiner/words2num2/issues
|
|
14
|
-
Keywords: number,word,numbers,words,parse,parser,convert,conversion,i18n,localisation,localization,internationalisation,internationalization,asr,speech,llm
|
|
15
|
-
Classifier: Development Status :: 4 - Beta
|
|
16
|
-
Classifier: Intended Audience :: Developers
|
|
17
|
-
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
-
Classifier: Programming Language :: Python :: 3.15
|
|
24
|
-
Classifier: Topic :: Software Development :: Internationalization
|
|
25
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
26
|
-
Classifier: Topic :: Software Development :: Localization
|
|
27
|
-
Classifier: Topic :: Text Processing :: Linguistic
|
|
28
|
-
Requires-Python: >=3.10
|
|
29
|
-
Description-Content-Type: text/x-rst
|
|
30
|
-
License-File: COPYING
|
|
31
|
-
Requires-Dist: docopt>=0.6.2
|
|
32
|
-
Requires-Dist: num2words2>=0.1.0.dev0
|
|
33
|
-
Dynamic: author
|
|
34
|
-
Dynamic: home-page
|
|
35
|
-
Dynamic: license
|
|
36
|
-
Dynamic: license-file
|
|
37
|
-
Dynamic: maintainer
|
|
38
|
-
|
|
39
1
|
words2num2 — words to numbers
|
|
40
2
|
=============================
|
|
41
3
|
|
|
@@ -104,9 +66,21 @@ entries**) and adds a free-text *auto-parse* mode that handles
|
|
|
104
66
|
currencies, units, configurable thousands/decimal separators, and
|
|
105
67
|
ASR/LLM-style mixed text.
|
|
106
68
|
|
|
107
|
-
|
|
69
|
+
It is **Rust-powered with a thin Python binder**. The whole parsing engine —
|
|
70
|
+
the English grammar, the generic reverse-lookup backend, the sentence walker,
|
|
71
|
+
number-format parsing and auto-parse — runs in a compiled Rust core
|
|
72
|
+
(PyO3/``abi3``); Python only shapes arguments and results. The core embeds the
|
|
73
|
+
num2words2 conversion engine natively, so ``words2num2`` is **self-contained
|
|
74
|
+
and has no runtime dependencies**, while running several times faster than the
|
|
75
|
+
former pure-Python implementation. Output is unchanged — validated against a
|
|
76
|
+
frozen corpus of ~11,000 round-trip cases.
|
|
77
|
+
|
|
78
|
+
The project is hosted on GitHub_, and the full documentation is available
|
|
79
|
+
in the Wiki_. Contributions are welcome.
|
|
108
80
|
|
|
109
81
|
.. _GitHub: https://github.com/jqueguiner/words2num2
|
|
82
|
+
.. _Wiki: https://github.com/jqueguiner/words2num2/wiki
|
|
83
|
+
.. _GitHub Releases: https://github.com/jqueguiner/words2num2/releases
|
|
110
84
|
|
|
111
85
|
Why this library
|
|
112
86
|
----------------
|
|
@@ -130,13 +104,59 @@ the forward direction. ``words2num2``:
|
|
|
130
104
|
* Pluralizes long-form units in expand mode (``5 dollars`` /
|
|
131
105
|
``1 dollar``, ``5 feet`` / ``1 foot``, ``5 yen`` / ``1 yen``).
|
|
132
106
|
|
|
107
|
+
Performance
|
|
108
|
+
-----------
|
|
109
|
+
|
|
110
|
+
The parsing engine is compiled Rust (PyO3/``abi3``), so there is no
|
|
111
|
+
Python-level tokenising or table walking on the hot path. Typical native
|
|
112
|
+
throughput (Apple M-series, nanoseconds per call, after warmup):
|
|
113
|
+
|
|
114
|
+
.. list-table::
|
|
115
|
+
:header-rows: 1
|
|
116
|
+
:widths: 60 20
|
|
117
|
+
|
|
118
|
+
* - Operation
|
|
119
|
+
- ns/call
|
|
120
|
+
* - English cardinal (``"eight thousand seven hundred sixty-five"``)
|
|
121
|
+
- ~5,900
|
|
122
|
+
* - English ordinal (``"forty-second"``)
|
|
123
|
+
- ~4,100
|
|
124
|
+
* - French cardinal (``"trois cent quatre"``)
|
|
125
|
+
- ~1,900
|
|
126
|
+
* - Russian cardinal (``"сорок два"``)
|
|
127
|
+
- ~1,700
|
|
128
|
+
* - ``parse_number_string("1.234.567,89", lang="de")``
|
|
129
|
+
- ~240
|
|
130
|
+
* - ``auto_parse("$12,345.00")``
|
|
131
|
+
- ~990
|
|
132
|
+
|
|
133
|
+
For the 100+ generic locales, the first call in a given language builds the
|
|
134
|
+
``{words → number}`` reverse table once (~35 ms) and caches it in the core;
|
|
135
|
+
every call after that is a native lookup. Output is byte-for-byte identical to
|
|
136
|
+
the former pure-Python implementation, validated against a frozen corpus of
|
|
137
|
+
~11,000 round-trip cases and the full test suite.
|
|
138
|
+
|
|
133
139
|
Installation
|
|
134
140
|
------------
|
|
135
141
|
|
|
136
|
-
**pip
|
|
142
|
+
**pip** (Python 3.10+)::
|
|
137
143
|
|
|
138
144
|
pip install words2num2
|
|
139
145
|
|
|
146
|
+
That's it — the wheel bundles the Python binder and the compiled Rust
|
|
147
|
+
extension, and ``words2num2`` has **no runtime dependencies** (the num2words2
|
|
148
|
+
conversion engine is compiled in, so you do *not* need the num2words2 package).
|
|
149
|
+
|
|
150
|
+
Prebuilt wheels are published for:
|
|
151
|
+
|
|
152
|
+
* **Linux** — x86_64 and aarch64 (manylinux2014)
|
|
153
|
+
* **macOS** — Apple Silicon (arm64); Intel (x86_64) from a later release
|
|
154
|
+
* **Windows** — x86_64
|
|
155
|
+
|
|
156
|
+
On any other platform (or an older release without a matching wheel), pip
|
|
157
|
+
falls back to the source distribution and builds the extension locally — this
|
|
158
|
+
needs a **stable Rust toolchain** (`rustup <https://rustup.rs>`_); nothing else.
|
|
159
|
+
|
|
140
160
|
**Arch Linux / Manjaro (AUR):**
|
|
141
161
|
|
|
142
162
|
.. code-block:: bash
|
|
@@ -150,14 +170,15 @@ Installation
|
|
|
150
170
|
cd python-words2num2
|
|
151
171
|
makepkg -si
|
|
152
172
|
|
|
153
|
-
**From source
|
|
173
|
+
**From source** (needs a stable Rust toolchain and `maturin
|
|
174
|
+
<https://www.maturin.rs>`_)::
|
|
154
175
|
|
|
155
176
|
git clone https://github.com/jqueguiner/words2num2
|
|
156
177
|
cd words2num2
|
|
157
|
-
pip install -e .
|
|
178
|
+
pip install -e . # builds the Rust extension via maturin
|
|
179
|
+
# or, to produce a wheel: maturin build --release
|
|
158
180
|
|
|
159
|
-
|
|
160
|
-
backend and is installed automatically.
|
|
181
|
+
Wheels for every version are also attached to the `GitHub Releases`_ page.
|
|
161
182
|
|
|
162
183
|
Quickstart
|
|
163
184
|
----------
|
|
@@ -303,6 +324,13 @@ entries** including:
|
|
|
303
324
|
|
|
304
325
|
Aliases: ``jp`` → ``ja``, ``cn`` → ``zh_CN``.
|
|
305
326
|
|
|
327
|
+
Wiki
|
|
328
|
+
----
|
|
329
|
+
For the full documentation, including installation, API details, CLI
|
|
330
|
+
usage, supported locales, sentence conversion, auto-parse behavior, and
|
|
331
|
+
migration guidance, please check the Wiki_. Feel free to propose wiki
|
|
332
|
+
enhancements.
|
|
333
|
+
|
|
306
334
|
Conversion types
|
|
307
335
|
~~~~~~~~~~~~~~~~
|
|
308
336
|
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["maturin>=1.5,<2.0"]
|
|
3
|
+
build-backend = "maturin"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "words2num2"
|
|
7
|
+
# Static base version. The release CI overrides it from the pushed git tag
|
|
8
|
+
# (see .github/workflows/release.yml); bump here for local source builds.
|
|
9
|
+
version = "0.3.1"
|
|
10
|
+
license = "LGPL-2.1-only"
|
|
11
|
+
license-files = ["COPYING"]
|
|
12
|
+
description = "Rust-powered inverse of num2words2: parse spoken-form numbers back to numeric values across 100+ languages, optimized for ASR/LLM/speech."
|
|
13
|
+
readme = "README.rst"
|
|
14
|
+
requires-python = ">=3.10"
|
|
15
|
+
# Self-contained: the num2words2 conversion engine is embedded in the compiled
|
|
16
|
+
# core (num2words2-core), so there is no runtime dependency on the num2words2
|
|
17
|
+
# package and no docopt (the CLI uses only the standard library).
|
|
18
|
+
dependencies = []
|
|
19
|
+
authors = [
|
|
20
|
+
{name = "Jean-Louis Queguiner", email = "jean-louis.queguiner@gmail.com"}
|
|
21
|
+
]
|
|
22
|
+
maintainers = [
|
|
23
|
+
{name = "Jean-Louis Queguiner", email = "jean-louis.queguiner@gmail.com"}
|
|
24
|
+
]
|
|
25
|
+
keywords = ["number", "word", "numbers", "words", "parse", "parser", "convert",
|
|
26
|
+
"conversion", "i18n", "localisation", "localization",
|
|
27
|
+
"internationalisation", "internationalization", "asr", "speech",
|
|
28
|
+
"llm", "rust"]
|
|
29
|
+
classifiers = [
|
|
30
|
+
"Development Status :: 4 - Beta",
|
|
31
|
+
"Intended Audience :: Developers",
|
|
32
|
+
"Programming Language :: Python :: 3",
|
|
33
|
+
"Programming Language :: Python :: 3.10",
|
|
34
|
+
"Programming Language :: Python :: 3.11",
|
|
35
|
+
"Programming Language :: Python :: 3.12",
|
|
36
|
+
"Programming Language :: Python :: 3.13",
|
|
37
|
+
"Programming Language :: Python :: 3.14",
|
|
38
|
+
"Programming Language :: Rust",
|
|
39
|
+
"Topic :: Software Development :: Internationalization",
|
|
40
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
41
|
+
"Topic :: Software Development :: Localization",
|
|
42
|
+
"Topic :: Text Processing :: Linguistic",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[project.urls]
|
|
46
|
+
Homepage = "https://github.com/jqueguiner/words2num2"
|
|
47
|
+
Documentation = "https://github.com/jqueguiner/words2num2/wiki"
|
|
48
|
+
Repository = "https://github.com/jqueguiner/words2num2.git"
|
|
49
|
+
"Bug Tracker" = "https://github.com/jqueguiner/words2num2/issues"
|
|
50
|
+
|
|
51
|
+
[project.scripts]
|
|
52
|
+
words2num2 = "words2num2.__main__:main"
|
|
53
|
+
|
|
54
|
+
# ---- maturin: mixed Rust/Python project -------------------------------------
|
|
55
|
+
# The compiled engine lives in ./rust (vendored crates `words2num2-py`, lib
|
|
56
|
+
# `_rust`, plus its `num2words2-core` dependency); the thin Python binder is
|
|
57
|
+
# ./words2num2. maturin bundles both into a single per-platform wheel. The
|
|
58
|
+
# wheel embeds num2words2-core natively — no lingua-rs models, so it stays
|
|
59
|
+
# small (~4MB), and there is only one variant.
|
|
60
|
+
[tool.maturin]
|
|
61
|
+
manifest-path = "rust/words2num2-py/Cargo.toml"
|
|
62
|
+
python-source = "."
|
|
63
|
+
module-name = "words2num2._rust"
|
|
64
|
+
features = ["pyo3/extension-module"]
|
|
65
|
+
strip = true
|
|
66
|
+
|
|
67
|
+
[tool.isort]
|
|
68
|
+
profile = "black"
|
|
69
|
+
line_length = 88
|
|
70
|
+
skip = ["words2num2/_version.py"]
|
|
71
|
+
multi_line_output = 3
|
|
72
|
+
include_trailing_comma = true
|
|
73
|
+
force_grid_wrap = 0
|
|
74
|
+
use_parentheses = true
|
|
75
|
+
ensure_newline_before_comments = true
|
|
76
|
+
|
|
77
|
+
[tool.black]
|
|
78
|
+
line-length = 88
|
|
79
|
+
target-version = ['py310']
|
|
80
|
+
include = '\.pyi?$'
|
|
81
|
+
exclude = '''
|
|
82
|
+
/(
|
|
83
|
+
\.git
|
|
84
|
+
| \.hg
|
|
85
|
+
| \.mypy_cache
|
|
86
|
+
| \.tox
|
|
87
|
+
| \.venv
|
|
88
|
+
| _build
|
|
89
|
+
| buck-out
|
|
90
|
+
| build
|
|
91
|
+
| dist
|
|
92
|
+
| words2num2/_version.py
|
|
93
|
+
)/
|
|
94
|
+
'''
|