radixor 4.1.0__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.
@@ -0,0 +1,254 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "adler2"
7
+ version = "2.0.1"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
10
+
11
+ [[package]]
12
+ name = "autocfg"
13
+ version = "1.5.1"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
16
+
17
+ [[package]]
18
+ name = "cfg-if"
19
+ version = "1.0.4"
20
+ source = "registry+https://github.com/rust-lang/crates.io-index"
21
+ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
22
+
23
+ [[package]]
24
+ name = "crc32fast"
25
+ version = "1.5.0"
26
+ source = "registry+https://github.com/rust-lang/crates.io-index"
27
+ checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
28
+ dependencies = [
29
+ "cfg-if",
30
+ ]
31
+
32
+ [[package]]
33
+ name = "flate2"
34
+ version = "1.1.9"
35
+ source = "registry+https://github.com/rust-lang/crates.io-index"
36
+ checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
37
+ dependencies = [
38
+ "crc32fast",
39
+ "miniz_oxide",
40
+ ]
41
+
42
+ [[package]]
43
+ name = "heck"
44
+ version = "0.5.0"
45
+ source = "registry+https://github.com/rust-lang/crates.io-index"
46
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
47
+
48
+ [[package]]
49
+ name = "indoc"
50
+ version = "2.0.7"
51
+ source = "registry+https://github.com/rust-lang/crates.io-index"
52
+ checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
53
+ dependencies = [
54
+ "rustversion",
55
+ ]
56
+
57
+ [[package]]
58
+ name = "libc"
59
+ version = "0.2.189"
60
+ source = "registry+https://github.com/rust-lang/crates.io-index"
61
+ checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
62
+
63
+ [[package]]
64
+ name = "memoffset"
65
+ version = "0.9.1"
66
+ source = "registry+https://github.com/rust-lang/crates.io-index"
67
+ checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
68
+ dependencies = [
69
+ "autocfg",
70
+ ]
71
+
72
+ [[package]]
73
+ name = "miniz_oxide"
74
+ version = "0.8.9"
75
+ source = "registry+https://github.com/rust-lang/crates.io-index"
76
+ checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
77
+ dependencies = [
78
+ "adler2",
79
+ "simd-adler32",
80
+ ]
81
+
82
+ [[package]]
83
+ name = "once_cell"
84
+ version = "1.21.4"
85
+ source = "registry+https://github.com/rust-lang/crates.io-index"
86
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
87
+
88
+ [[package]]
89
+ name = "portable-atomic"
90
+ version = "1.14.0"
91
+ source = "registry+https://github.com/rust-lang/crates.io-index"
92
+ checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3"
93
+
94
+ [[package]]
95
+ name = "proc-macro2"
96
+ version = "1.0.107"
97
+ source = "registry+https://github.com/rust-lang/crates.io-index"
98
+ checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
99
+ dependencies = [
100
+ "unicode-ident",
101
+ ]
102
+
103
+ [[package]]
104
+ name = "pyo3"
105
+ version = "0.22.6"
106
+ source = "registry+https://github.com/rust-lang/crates.io-index"
107
+ checksum = "f402062616ab18202ae8319da13fa4279883a2b8a9d9f83f20dbade813ce1884"
108
+ dependencies = [
109
+ "cfg-if",
110
+ "indoc",
111
+ "libc",
112
+ "memoffset",
113
+ "once_cell",
114
+ "portable-atomic",
115
+ "pyo3-build-config",
116
+ "pyo3-ffi",
117
+ "pyo3-macros",
118
+ "unindent",
119
+ ]
120
+
121
+ [[package]]
122
+ name = "pyo3-build-config"
123
+ version = "0.22.6"
124
+ source = "registry+https://github.com/rust-lang/crates.io-index"
125
+ checksum = "b14b5775b5ff446dd1056212d778012cbe8a0fbffd368029fd9e25b514479c38"
126
+ dependencies = [
127
+ "once_cell",
128
+ "target-lexicon",
129
+ ]
130
+
131
+ [[package]]
132
+ name = "pyo3-ffi"
133
+ version = "0.22.6"
134
+ source = "registry+https://github.com/rust-lang/crates.io-index"
135
+ checksum = "9ab5bcf04a2cdcbb50c7d6105de943f543f9ed92af55818fd17b660390fc8636"
136
+ dependencies = [
137
+ "libc",
138
+ "pyo3-build-config",
139
+ ]
140
+
141
+ [[package]]
142
+ name = "pyo3-macros"
143
+ version = "0.22.6"
144
+ source = "registry+https://github.com/rust-lang/crates.io-index"
145
+ checksum = "0fd24d897903a9e6d80b968368a34e1525aeb719d568dba8b3d4bfa5dc67d453"
146
+ dependencies = [
147
+ "proc-macro2",
148
+ "pyo3-macros-backend",
149
+ "quote",
150
+ "syn",
151
+ ]
152
+
153
+ [[package]]
154
+ name = "pyo3-macros-backend"
155
+ version = "0.22.6"
156
+ source = "registry+https://github.com/rust-lang/crates.io-index"
157
+ checksum = "36c011a03ba1e50152b4b394b479826cad97e7a21eb52df179cd91ac411cbfbe"
158
+ dependencies = [
159
+ "heck",
160
+ "proc-macro2",
161
+ "pyo3-build-config",
162
+ "quote",
163
+ "syn",
164
+ ]
165
+
166
+ [[package]]
167
+ name = "quote"
168
+ version = "1.0.47"
169
+ source = "registry+https://github.com/rust-lang/crates.io-index"
170
+ checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
171
+ dependencies = [
172
+ "proc-macro2",
173
+ ]
174
+
175
+ [[package]]
176
+ name = "radixor"
177
+ version = "4.1.0"
178
+ dependencies = [
179
+ "flate2",
180
+ "pyo3",
181
+ "unicode-general-category",
182
+ "unicode-normalization",
183
+ ]
184
+
185
+ [[package]]
186
+ name = "rustversion"
187
+ version = "1.0.23"
188
+ source = "registry+https://github.com/rust-lang/crates.io-index"
189
+ checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
190
+
191
+ [[package]]
192
+ name = "simd-adler32"
193
+ version = "0.3.10"
194
+ source = "registry+https://github.com/rust-lang/crates.io-index"
195
+ checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea"
196
+
197
+ [[package]]
198
+ name = "syn"
199
+ version = "2.0.119"
200
+ source = "registry+https://github.com/rust-lang/crates.io-index"
201
+ checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
202
+ dependencies = [
203
+ "proc-macro2",
204
+ "quote",
205
+ "unicode-ident",
206
+ ]
207
+
208
+ [[package]]
209
+ name = "target-lexicon"
210
+ version = "0.12.16"
211
+ source = "registry+https://github.com/rust-lang/crates.io-index"
212
+ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
213
+
214
+ [[package]]
215
+ name = "tinyvec"
216
+ version = "1.12.0"
217
+ source = "registry+https://github.com/rust-lang/crates.io-index"
218
+ checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f"
219
+ dependencies = [
220
+ "tinyvec_macros",
221
+ ]
222
+
223
+ [[package]]
224
+ name = "tinyvec_macros"
225
+ version = "0.1.1"
226
+ source = "registry+https://github.com/rust-lang/crates.io-index"
227
+ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
228
+
229
+ [[package]]
230
+ name = "unicode-general-category"
231
+ version = "0.6.0"
232
+ source = "registry+https://github.com/rust-lang/crates.io-index"
233
+ checksum = "2281c8c1d221438e373249e065ca4989c4c36952c211ff21a0ee91c44a3869e7"
234
+
235
+ [[package]]
236
+ name = "unicode-ident"
237
+ version = "1.0.24"
238
+ source = "registry+https://github.com/rust-lang/crates.io-index"
239
+ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
240
+
241
+ [[package]]
242
+ name = "unicode-normalization"
243
+ version = "0.1.25"
244
+ source = "registry+https://github.com/rust-lang/crates.io-index"
245
+ checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8"
246
+ dependencies = [
247
+ "tinyvec",
248
+ ]
249
+
250
+ [[package]]
251
+ name = "unindent"
252
+ version = "0.2.4"
253
+ source = "registry+https://github.com/rust-lang/crates.io-index"
254
+ checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
@@ -0,0 +1,21 @@
1
+ [package]
2
+ name = "radixor"
3
+ version = "4.1.0"
4
+ edition = "2021"
5
+ readme = "README.md"
6
+
7
+ [lib]
8
+ name = "_radixor"
9
+ crate-type = ["cdylib"]
10
+
11
+ [dependencies]
12
+ pyo3 = { version = "0.22", features = ["extension-module", "abi3-py39"] }
13
+ flate2 = "1.0"
14
+ unicode-normalization = "0.1"
15
+ unicode-general-category = "0.6"
16
+
17
+ [profile.release]
18
+ lto = true
19
+ codegen-units = 1
20
+ opt-level = 3
21
+ strip = true
radixor-4.1.0/LICENSE ADDED
@@ -0,0 +1,28 @@
1
+ Copyright (C) 2026, Leo Galambos
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ 3. Neither the name of the copyright holder nor the names of its contributors
15
+ may be used to endorse or promote products derived from this software
16
+ without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
+ POSSIBILITY OF SUCH DAMAGE.
radixor-4.1.0/PKG-INFO ADDED
@@ -0,0 +1,298 @@
1
+ Metadata-Version: 2.4
2
+ Name: radixor
3
+ Version: 4.1.0
4
+ Classifier: Development Status :: 5 - Production/Stable
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: Natural Language :: Czech
7
+ Classifier: Natural Language :: Danish
8
+ Classifier: Natural Language :: Dutch
9
+ Classifier: Natural Language :: English
10
+ Classifier: Natural Language :: Finnish
11
+ Classifier: Natural Language :: French
12
+ Classifier: Natural Language :: German
13
+ Classifier: Natural Language :: Hebrew
14
+ Classifier: Natural Language :: Hungarian
15
+ Classifier: Natural Language :: Italian
16
+ Classifier: Natural Language :: Norwegian
17
+ Classifier: Natural Language :: Persian
18
+ Classifier: Natural Language :: Polish
19
+ Classifier: Natural Language :: Portuguese
20
+ Classifier: Natural Language :: Russian
21
+ Classifier: Natural Language :: Spanish
22
+ Classifier: Natural Language :: Swedish
23
+ Classifier: Natural Language :: Ukrainian
24
+ Classifier: Natural Language :: Yiddish
25
+ Classifier: Programming Language :: Python
26
+ Classifier: Programming Language :: Python :: 3
27
+ Classifier: Programming Language :: Python :: 3.9
28
+ Classifier: Programming Language :: Python :: 3.10
29
+ Classifier: Programming Language :: Python :: 3.11
30
+ Classifier: Programming Language :: Python :: 3.12
31
+ Classifier: Programming Language :: Python :: 3.13
32
+ Classifier: Programming Language :: Python :: 3.14
33
+ Classifier: Programming Language :: Rust
34
+ Classifier: Topic :: Internet :: WWW/HTTP :: Indexing/Search
35
+ Classifier: Topic :: Text Processing :: Indexing
36
+ Classifier: Topic :: Text Processing :: Linguistic
37
+ Requires-Dist: radixor-models-standard>=1.0,<2.0
38
+ License-File: LICENSE
39
+ Summary: Radixor stemmer – fastest stemming for Python, backed by Rust
40
+ Keywords: python,information retrieval,language processing,morphology,stemming algorithms,stemmers,nlp,rust
41
+ License-Expression: BSD-3-Clause
42
+ Requires-Python: >=3.9
43
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
44
+
45
+ # radixor — Fastest Stemming for Python
46
+
47
+ **radixor** is a Python extension for the [Radixor](https://github.com/leogalambos/Radixor) stemmer library, built on a Rust core via [PyO3](https://pyo3.rs/). It provides sub-microsecond per-word stemming with a batch API that amortises the Python↔Rust bridge overhead across thousands of words at once.
48
+
49
+ ## Why radixor?
50
+
51
+ | Library | Approach | Batch API |
52
+ |---|---|---|
53
+ | **radixor** | Compiled patch-command trie in Rust | ✅ `stem_batch()` |
54
+ | PyStemmer (Snowball) | C extension (`libstemmer`) | ✅ `stemWords()` |
55
+ | snowballstemmer | Pure-Python Snowball | ✅ (Python loop) |
56
+ | NLTK Porter / CISTEM | Pure Python | ❌ |
57
+
58
+ **Performance.** On the shared UniMorph gold-standard corpus, measuring runtime
59
+ stemming only (construction excluded) and with a fair, cache-disabled,
60
+ same-input methodology, radixor won all **18 / 18** direct comparisons with
61
+ PyStemmer 3.1.0 (Snowball's C `libstemmer`) in the published 2026-08-08 run.
62
+ At batch size 100, the geometric-mean speedup was **1.67×**. The complete
63
+ machine metadata and current results are in the [Python performance
64
+ documentation](../docs/python/performance.md); benchmark implementation and
65
+ fairness notes are in [`benchmarks/`](benchmarks/README.md).
66
+
67
+ ## Installation
68
+
69
+ From PyPI, once publication is enabled:
70
+
71
+ ```bash
72
+ python -m pip install --only-binary=:all: radixor
73
+ ```
74
+
75
+ The GitHub Releases-backed index is the independent alternative:
76
+
77
+ ```bash
78
+ python -m pip install --only-binary=:all: \
79
+ --index-url https://leogalambos.github.io/Radixor/python/simple/ radixor
80
+ ```
81
+
82
+ The GitHub command becomes usable after the first model and native releases
83
+ populate that index. See the [installation guide](../docs/python/installation.md)
84
+ for current availability and source-checkout builds.
85
+
86
+ Wheels are provided for Linux, macOS, and Windows (Python 3.9+). The install
87
+ also resolves the mandatory pure `radixor-models-standard` dependency
88
+ with 20 precompiled standard models. Building the native source distribution
89
+ requires Rust ≥ 1.75 and [maturin](https://www.maturin.rs/).
90
+
91
+ ## Quick start
92
+
93
+ ```python
94
+ from radixor import Stemmer
95
+
96
+ s = Stemmer("en") # English (us-uk-default model)
97
+ s.stem("running") # → "run"
98
+ s.stem("cats") # → "cat"
99
+ s.stem("unknown_word") # → None
100
+ ```
101
+
102
+ ## Batch API — the fast path
103
+
104
+ ```python
105
+ words = ["running", "cats", "stemming", "quickly"]
106
+
107
+ # Amortises the Python→Rust bridge cost across all words at once
108
+ stems = s.stem_batch(words)
109
+ # → ["run", "cat", "stem", "quick"]
110
+ ```
111
+
112
+ For large corpora (tens of thousands of words) the batch call is the recommended interface. It avoids per-call Python frame overhead and keeps the hot loop entirely inside Rust.
113
+
114
+ ## Migrating from PyStemmer
115
+
116
+ Radixor provides PyStemmer's `stemWord` and `stemWords` method names. These
117
+ compatibility methods also follow PyStemmer's fallback behavior: when the trie
118
+ has no patch command, they return the original word instead of `None`.
119
+
120
+ ```python
121
+ # PyStemmer: import Stemmer
122
+ import radixor as Stemmer
123
+
124
+ stemmer = Stemmer.Stemmer("english")
125
+ stemmer.stemWord("running") # → "run"
126
+ stemmer.stemWord("unknown_word") # → "unknown_word"
127
+ stemmer.stemWords(["running", "unknown"]) # → ["run", "unknown"]
128
+ ```
129
+
130
+ The original Radixor methods remain unchanged: `stem` and `stem_batch` return
131
+ `None` for words without a matching patch command. Radixor accepts PyStemmer's
132
+ full language names for the languages represented by its bundled models, as
133
+ well as its existing two-letter codes and model IDs.
134
+
135
+ ## Supported languages
136
+
137
+ | Code | Language | Model ID |
138
+ |---|---|---|
139
+ | `cs` | Czech | `cs-cz-default` |
140
+ | `da` | Danish | `da-dk-default` |
141
+ | `de` | German | `de-de-default` |
142
+ | `en` | English | `us-uk-default` |
143
+ | `es` | Spanish | `es-es-default` |
144
+ | `fa` | Persian | `fa-ir-default` |
145
+ | `fi` | Finnish | `fi-fi-default` |
146
+ | `fr` | French | `fr-fr-default` |
147
+ | `he` | Hebrew | `he-il-default` |
148
+ | `hu` | Hungarian | `hu-hu-default` |
149
+ | `it` | Italian | `it-it-default` |
150
+ | `nb` | Norwegian Bokmål | `nb-no-default` |
151
+ | `nl` | Dutch | `nl-nl-default` |
152
+ | `nn` | Norwegian Nynorsk | `nn-no-default` |
153
+ | `pl` | Polish | `pl-pl-unimorph` |
154
+ | `pt` | Portuguese | `pt-pt-default` |
155
+ | `ru` | Russian | `ru-ru-default` |
156
+ | `sv` | Swedish | `sv-se-default` |
157
+ | `uk` | Ukrainian | `uk-ua-default` |
158
+ | `yi` | Yiddish | `yi-default` |
159
+
160
+ ## API reference
161
+
162
+ ### `Stemmer(language=None, *, path=None, compiled=None, backward=None, store_original=True, lowercase=True, cache_size=10_000)`
163
+
164
+ Create a stemmer for the given language code, model ID, custom textual
165
+ dictionary, or previously compiled version 7 trie. Textual dictionaries are
166
+ compiled in Rust; `compiled=` loads a prepared binary directly.
167
+
168
+ ```python
169
+ s = Stemmer("de") # by language code
170
+ s = Stemmer("de-de-default") # by model ID
171
+ s = Stemmer(path="/data/custom.gz") # custom gzipped dictionary
172
+ s = Stemmer(compiled="/data/custom.rxc") # prepared v7 binary
173
+ ```
174
+
175
+ `backward` selects the traversal direction; when left as `None` it is derived
176
+ from the language (BACKWARD, except right-to-left `fa`/`he`/`yi` which use
177
+ FORWARD). `store_original` (default `True`) maps each canonical stem to a no-op
178
+ patch so the stem itself is recognised. `lowercase=False` skips runtime
179
+ lowercasing for already-normalized input, and `cache_size` enables the bounded
180
+ result cache. The default holds up to 10,000 entries, matching PyStemmer;
181
+ `cache_size=0` disables it. One cache is shared by `stem()`, `stemWord()`,
182
+ `stem_batch()`, and `stemWords()`; the `stem_all*()` methods are not cached.
183
+
184
+ ### `stem(word: str) → str | None`
185
+
186
+ Return the stem, or `None` when the compiled trie finds no applicable patch
187
+ command. This does not mean that lookup is restricted to exact training words.
188
+
189
+ ### `stem_batch(words: list[str]) → list[str | None]`
190
+
191
+ Stem an entire list. Preferred for large inputs.
192
+
193
+ ### `stemWord(word: str) → str`
194
+
195
+ PyStemmer-compatible scalar method. Return the original word if it cannot be
196
+ stemmed.
197
+
198
+ ### `stemWords(words: list[str]) → list[str]`
199
+
200
+ PyStemmer-compatible batch method. Return each unrecognized word unchanged.
201
+
202
+ ### `stem_all(word: str) → list[str]`
203
+
204
+ Return all stems ordered by descending corpus frequency. Useful when multiple valid stems exist.
205
+
206
+ ### `stem_all_batch(words: list[str]) → list[list[str]]`
207
+
208
+ Return all stems for each word in a batch.
209
+
210
+ ## Compiling a model (compile once, load instantly)
211
+
212
+ Compiling the trie from a textual dictionary takes time for large languages
213
+ (seconds). You can compile it **once** to Radixor's binary format and then load
214
+ it near-instantly — the same workflow Java users have:
215
+
216
+ ```python
217
+ import radixor
218
+ radixor.compile("stemmer.gz", "en.rxc", language="en") # or backward=True/False
219
+ s = radixor.Stemmer(compiled="en.rxc") # instant load, no re-compile
220
+ ```
221
+
222
+ The compiled file uses Radixor's **v7 trie format and is byte-compatible with
223
+ the Java `StemmerPatchTrieBinaryIO`** (the inner stream is identical), so a file
224
+ compiled by Java can be loaded by Python and vice versa. `Stemmer(path=...)`
225
+ auto-detects whether it was given a compiled trie or a textual dictionary.
226
+
227
+ ## Using a custom model
228
+
229
+ Provide your own gzipped source dictionary (tab-separated
230
+ `stem<TAB>variant1<TAB>variant2…` per line, `#` / `//` line remarks allowed) and
231
+ load it directly:
232
+
233
+ ```python
234
+ s = Stemmer(path="my_dictionary.gz") # BACKWARD by default
235
+ s = Stemmer(path="my_rtl_dictionary.gz", backward=False) # right-to-left
236
+ ```
237
+
238
+ The dictionary is compiled to a patch-command trie in Rust at construction time.
239
+
240
+ ## Building from source
241
+
242
+ ```bash
243
+ cd Radixor/
244
+ pip install maturin build setuptools wheel pytest
245
+ ./gradlew pythonBuildStandardModels
246
+ pip install --no-deps build/python/dist/standard/radixor_models_standard-0.0.0-py3-none-any.whl
247
+ cd python/
248
+ maturin develop --release # editable install with release optimisations
249
+ ```
250
+
251
+ From the repository root, Gradle builds the native wheel/sdist and pure
252
+ standard-model wheel/sdist without installing them globally:
253
+
254
+ ```bash
255
+ ./gradlew pythonBuild
256
+ ```
257
+
258
+ The convenience tasks `pythonBuildLinux`, `pythonBuildWindows`, and
259
+ `pythonBuildMacos` use the host build when the requested platform matches the
260
+ current system. Other platforms are cross-compiled with the corresponding Rust
261
+ target and therefore require that target and its linker/SDK to be installed.
262
+ Override a default target with, for example,
263
+ `-PpythonWindowsTarget=x86_64-pc-windows-gnu`. Build artifacts are written below
264
+ `build/python/dist/`.
265
+
266
+ The complete batch benchmark runs Radixor for all bundled languages and every
267
+ available comparison engine for the languages it supports, using batch sizes
268
+ 10, 20, 50, and 100:
269
+
270
+ Comparison engines are auto-detected in the environment of `pythonExecutable`.
271
+ Install `python/benchmarks/requirements-bench.txt` there to enable the complete
272
+ comparison set.
273
+
274
+ ```bash
275
+ ./gradlew pythonBenchmarkAllLanguagesBatch
276
+ ```
277
+
278
+ Use `pythonBenchmarkWords`, `pythonBenchmarkRepeats`, and
279
+ `pythonBenchmarkWarmup` Gradle properties to tune the run. CSV and JSON reports
280
+ are written below `build/reports/python-benchmarks/`.
281
+
282
+ Neither runtime distribution contains textual dictionaries. The standard data
283
+ sdist contains build-ready gzip v7 `.rxc` files, a checksummed provenance
284
+ manifest, and per-model CC BY-SA 3.0 notices. They are generated below `build/`
285
+ from canonical `models/*/src/modelInput/stemmer.gz` inputs and are never stored
286
+ in Git. `./gradlew regeneratePythonStandardModels` performs this deterministic
287
+ generation; repository topology selects the 20 defaults and excludes optional
288
+ `pl-pl-polimorf`.
289
+
290
+ `radixor` requires `radixor-models-standard>=1.0,<2.0`. The Python distribution
291
+ version is independent of its `2026.1` Java model-catalog identity and of the
292
+ individual model versions recorded in the manifest.
293
+
294
+ ## License
295
+
296
+ The native/API package is BSD-3-Clause — see [LICENSE](LICENSE). Model data
297
+ is separately licensed under CC BY-SA 3.0 in its packaged notices.
298
+