scriptconv 0.0.4a6__tar.gz → 0.0.4a7__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.
- {scriptconv-0.0.4a6/scriptconv.egg-info → scriptconv-0.0.4a7}/PKG-INFO +8 -4
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/README.md +7 -3
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/diacritics.py +58 -10
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/version.py +1 -1
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7/scriptconv.egg-info}/PKG-INFO +8 -4
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_diacritics.py +106 -11
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/LICENSE +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/pyproject.toml +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/requirements.txt +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/__init__.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/__main__.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/cangjie.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/conventions.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/data/__init__.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/data/cangjie5_tc.tsv.gz +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/graph.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/notation.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/__init__.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/__init__.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/bw2ipa.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/hangul2ipa.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/ko_tables/aspiration.csv +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/ko_tables/assimilation.csv +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/ko_tables/double_coda.csv +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/ko_tables/hanja.tsv +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/ko_tables/ipa.csv +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/ko_tables/neutralization.csv +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/ko_tables/tensification.csv +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/ko_tables/yale.csv +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/__init__.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/codeswitch.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/diacritize.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/dialectal.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/english_g2p.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/espeak.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/frontend.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/levantine_g2p.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/normalize.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/phoneme_inventory.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/zh_num.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/__init__.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/kog2p/LICENSE.md +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/kog2p/__init__.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/kog2p/rulebook.txt +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/mantoq/LICENSE.md +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/mantoq/__init__.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/mantoq/buck/__init__.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/mantoq/buck/phonetise_buckwalter.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/mantoq/buck/symbols.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/mantoq/buck/tokenization.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/mantoq/num2words.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/mantoq/unicode_symbol2label.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/ar.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/base.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/en.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/enums.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/eu.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/fa.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/gl.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/he.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/ja.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/ko.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/mul.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/mwl.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/o2ipa.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/pt.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/registry.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/shami.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/vi.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/zh.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/py.typed +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/readings.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/scripts.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/translit.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv.egg-info/SOURCES.txt +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv.egg-info/dependency_links.txt +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv.egg-info/requires.txt +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv.egg-info/top_level.txt +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/setup.cfg +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_arpa_stress.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_cangjie.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_cli.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_conventions.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_diacritics_graph.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_errors_policy.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_examples.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_graph.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_notation.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_phonemizers_base.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_phonemizers_cjk_ar.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_readings.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_readings_zh.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_scripts.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_scripts_stressonnx_compat.py +0 -0
- {scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/tests/test_translit.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: scriptconv
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4a7
|
|
4
4
|
Summary: Zero-dependency script & phoneme-notation core — ISO-15924 detection & metadata, IPA↔ARPABET/X-SAMPA/Lexique/Kirshenbaum/Cotovía/RFE, Buckwalter↔Arabic, Hangul→jamo, kana
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Project-URL: Homepage, https://github.com/TigreGotico/scriptconv
|
|
@@ -373,9 +373,13 @@ Two design points worth knowing:
|
|
|
373
373
|
phonemizing; that needs language resources scriptconv doesn't ship. Pass
|
|
374
374
|
`normalizer=` (a `(text, lang) -> str` callable) to run yours inside the
|
|
375
375
|
pipeline; without it, text is phonemized as-is.
|
|
376
|
-
- **
|
|
377
|
-
local `model=` path; resolving and caching model
|
|
378
|
-
concern.
|
|
376
|
+
- **Large/licensed model-backed engines never download.** ByT5/Charsiu
|
|
377
|
+
require an explicit local `model=` path; resolving and caching those model
|
|
378
|
+
files is the caller's concern. Small, known-good, unencumbered models are
|
|
379
|
+
the exception: the Hebrew phonikud diacritizer auto-provisions its ONNX
|
|
380
|
+
model to a cache dir on first use (`phonikud_model=` still overrides it
|
|
381
|
+
with a path or callable; cache location via `SCRIPTCONV_CACHE`/
|
|
382
|
+
`XDG_CACHE_HOME`).
|
|
379
383
|
|
|
380
384
|
**Pre-G2P disambiguation.** `add_diacritics(text, lang, model=None)` restores
|
|
381
385
|
information ordinary orthography omits but a G2P needs, before phonemization:
|
|
@@ -246,9 +246,13 @@ Two design points worth knowing:
|
|
|
246
246
|
phonemizing; that needs language resources scriptconv doesn't ship. Pass
|
|
247
247
|
`normalizer=` (a `(text, lang) -> str` callable) to run yours inside the
|
|
248
248
|
pipeline; without it, text is phonemized as-is.
|
|
249
|
-
- **
|
|
250
|
-
local `model=` path; resolving and caching model
|
|
251
|
-
concern.
|
|
249
|
+
- **Large/licensed model-backed engines never download.** ByT5/Charsiu
|
|
250
|
+
require an explicit local `model=` path; resolving and caching those model
|
|
251
|
+
files is the caller's concern. Small, known-good, unencumbered models are
|
|
252
|
+
the exception: the Hebrew phonikud diacritizer auto-provisions its ONNX
|
|
253
|
+
model to a cache dir on first use (`phonikud_model=` still overrides it
|
|
254
|
+
with a path or callable; cache location via `SCRIPTCONV_CACHE`/
|
|
255
|
+
`XDG_CACHE_HOME`).
|
|
252
256
|
|
|
253
257
|
**Pre-G2P disambiguation.** `add_diacritics(text, lang, model=None)` restores
|
|
254
258
|
information ordinary orthography omits but a G2P needs, before phonemization:
|
|
@@ -51,6 +51,10 @@ tracks which backend/model produced the marks: overlay backends (phonikud,
|
|
|
51
51
|
tashkeel, stressonnx) are strippable; spelling-integral backends (bifonia) are
|
|
52
52
|
not.
|
|
53
53
|
"""
|
|
54
|
+
import os
|
|
55
|
+
import tempfile
|
|
56
|
+
import urllib.request
|
|
57
|
+
from pathlib import Path
|
|
54
58
|
from typing import Optional
|
|
55
59
|
|
|
56
60
|
from scriptconv.graph import Edge
|
|
@@ -119,20 +123,61 @@ _DEFAULT_DIACRITIZER_MODEL = "rawi-ensemble"
|
|
|
119
123
|
_PHONIKUD_CACHE: dict = {} # resolved model path/string -> Phonikud instance
|
|
120
124
|
_TASHKEEL_CACHE: dict = {} # model name -> text2tashkeel Diacritizer
|
|
121
125
|
|
|
126
|
+
# phonikud is a small (~100MB), public, unlicensed-restriction ONNX model, so
|
|
127
|
+
# — unlike the large/licensed models behind mul.py's ByT5/Charsiu backends —
|
|
128
|
+
# scriptconv auto-provisions it: no local path is required unless the caller
|
|
129
|
+
# wants to override the cache (e.g. an air-gapped host).
|
|
130
|
+
_PHONIKUD_URL = "https://huggingface.co/thewh1teagle/phonikud-onnx/resolve/main/phonikud-1.0.int8.onnx"
|
|
122
131
|
|
|
123
|
-
|
|
132
|
+
|
|
133
|
+
def _default_phonikud_model() -> str:
|
|
134
|
+
"""Resolve (downloading and caching on first use if needed) the path to
|
|
135
|
+
the default phonikud ONNX model.
|
|
136
|
+
|
|
137
|
+
Cache directory: ``<base>/scriptconv/phonikud`` where ``<base>`` is
|
|
138
|
+
``$SCRIPTCONV_CACHE`` if set, else ``$XDG_CACHE_HOME`` (default
|
|
139
|
+
``~/.cache``) — i.e. ``~/.cache/scriptconv/phonikud`` by default. The
|
|
140
|
+
download is written to a temp file
|
|
141
|
+
in the same directory and atomically moved into place via
|
|
142
|
+
:func:`os.replace`, so a failed or interrupted download never leaves a
|
|
143
|
+
partial file at the destination path.
|
|
144
|
+
"""
|
|
145
|
+
base = os.environ.get("SCRIPTCONV_CACHE") or os.environ.get(
|
|
146
|
+
"XDG_CACHE_HOME", os.path.expanduser("~/.cache"))
|
|
147
|
+
cache_dir = Path(base) / "scriptconv" / "phonikud"
|
|
148
|
+
dest = cache_dir / "phonikud-1.0.int8.onnx"
|
|
149
|
+
if not dest.is_file():
|
|
150
|
+
cache_dir.mkdir(parents=True, exist_ok=True)
|
|
151
|
+
fd, tmp_path = tempfile.mkstemp(dir=str(cache_dir), prefix=".phonikud-", suffix=".tmp")
|
|
152
|
+
try:
|
|
153
|
+
with os.fdopen(fd, "wb") as tmp_f, urllib.request.urlopen(_PHONIKUD_URL) as resp:
|
|
154
|
+
while True:
|
|
155
|
+
chunk = resp.read(1024 * 1024)
|
|
156
|
+
if not chunk:
|
|
157
|
+
break
|
|
158
|
+
tmp_f.write(chunk)
|
|
159
|
+
os.replace(tmp_path, dest)
|
|
160
|
+
except BaseException:
|
|
161
|
+
if os.path.exists(tmp_path):
|
|
162
|
+
os.remove(tmp_path)
|
|
163
|
+
raise
|
|
164
|
+
return str(dest)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _phonikud(phonikud_model=None):
|
|
124
168
|
"""Lazily build (and cache) the phonikud Phonikud instance used for Hebrew.
|
|
125
169
|
|
|
126
|
-
``phonikud_model`` is a local path to a phonikud ONNX model, or
|
|
127
|
-
zero-arg callable resolving one lazily
|
|
128
|
-
the
|
|
129
|
-
|
|
170
|
+
``phonikud_model`` is optional: a local path to a phonikud ONNX model, or
|
|
171
|
+
a zero-arg callable resolving one lazily. When omitted, scriptconv
|
|
172
|
+
auto-provisions the small public phonikud model, downloading it once into
|
|
173
|
+
a cache dir (see :func:`_default_phonikud_model`) and reusing it on
|
|
174
|
+
subsequent calls. Pass an explicit path/callable to override — e.g. to
|
|
175
|
+
point at a model already on disk, or on an air-gapped host. Install
|
|
176
|
+
phonikud-onnx with ``pip install scriptconv[he]`` (or ``pip install
|
|
177
|
+
phonikud-onnx``)."""
|
|
130
178
|
model = phonikud_model() if callable(phonikud_model) else phonikud_model
|
|
131
179
|
if not model:
|
|
132
|
-
|
|
133
|
-
"Hebrew diacritization needs a local phonikud ONNX model: "
|
|
134
|
-
"pass phonikud_model=<path> (scriptconv never downloads "
|
|
135
|
-
"models; obtain one from the phonikud-onnx release)")
|
|
180
|
+
model = _default_phonikud_model()
|
|
136
181
|
if model not in _PHONIKUD_CACHE:
|
|
137
182
|
try:
|
|
138
183
|
from phonikud_onnx import Phonikud
|
|
@@ -207,7 +252,10 @@ def diacritize(text: str, lang: str = "und", model=None,
|
|
|
207
252
|
Four backends, each restoring information ordinary orthography omits but
|
|
208
253
|
downstream G2P needs:
|
|
209
254
|
|
|
210
|
-
- Hebrew (``he``) — niqqud via phonikud
|
|
255
|
+
- Hebrew (``he``) — niqqud via phonikud. ``phonikud_model=`` is optional:
|
|
256
|
+
omitted, the small public phonikud ONNX model is auto-downloaded and
|
|
257
|
+
cached (``$SCRIPTCONV_CACHE``/``$XDG_CACHE_HOME``); pass a path or
|
|
258
|
+
zero-arg callable to override.
|
|
211
259
|
- Arabic (``ar``) — tashkeel via text2tashkeel (``[tashkeel]``,
|
|
212
260
|
``model=``/``diacritizer_model=``).
|
|
213
261
|
- East Slavic, Bulgarian/Macedonian/Slovene, Latvian, Armenian, Georgian,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: scriptconv
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4a7
|
|
4
4
|
Summary: Zero-dependency script & phoneme-notation core — ISO-15924 detection & metadata, IPA↔ARPABET/X-SAMPA/Lexique/Kirshenbaum/Cotovía/RFE, Buckwalter↔Arabic, Hangul→jamo, kana
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Project-URL: Homepage, https://github.com/TigreGotico/scriptconv
|
|
@@ -373,9 +373,13 @@ Two design points worth knowing:
|
|
|
373
373
|
phonemizing; that needs language resources scriptconv doesn't ship. Pass
|
|
374
374
|
`normalizer=` (a `(text, lang) -> str` callable) to run yours inside the
|
|
375
375
|
pipeline; without it, text is phonemized as-is.
|
|
376
|
-
- **
|
|
377
|
-
local `model=` path; resolving and caching model
|
|
378
|
-
concern.
|
|
376
|
+
- **Large/licensed model-backed engines never download.** ByT5/Charsiu
|
|
377
|
+
require an explicit local `model=` path; resolving and caching those model
|
|
378
|
+
files is the caller's concern. Small, known-good, unencumbered models are
|
|
379
|
+
the exception: the Hebrew phonikud diacritizer auto-provisions its ONNX
|
|
380
|
+
model to a cache dir on first use (`phonikud_model=` still overrides it
|
|
381
|
+
with a path or callable; cache location via `SCRIPTCONV_CACHE`/
|
|
382
|
+
`XDG_CACHE_HOME`).
|
|
379
383
|
|
|
380
384
|
**Pre-G2P disambiguation.** `add_diacritics(text, lang, model=None)` restores
|
|
381
385
|
information ordinary orthography omits but a G2P needs, before phonemization:
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
No optional backend is required — strip_diacritics/_overlay_marks/_supports_strip
|
|
4
4
|
never load a phonemizer model.
|
|
5
5
|
"""
|
|
6
|
+
import os
|
|
7
|
+
|
|
6
8
|
import pytest
|
|
7
9
|
|
|
8
10
|
from scriptconv.diacritics import (
|
|
@@ -90,27 +92,120 @@ def test_overlay_marks_none_for_native_orthography():
|
|
|
90
92
|
assert _overlay_marks("en") is None
|
|
91
93
|
|
|
92
94
|
|
|
93
|
-
class
|
|
94
|
-
def
|
|
95
|
-
from scriptconv
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
class TestHebrewDiacritizerAutoProvisions:
|
|
96
|
+
def test_no_model_given_auto_provisions(self, monkeypatch):
|
|
97
|
+
from scriptconv import diacritics
|
|
98
|
+
|
|
99
|
+
monkeypatch.setitem(diacritics._PHONIKUD_CACHE, "/sentinel/path.onnx", object())
|
|
100
|
+
monkeypatch.setattr(diacritics, "_default_phonikud_model",
|
|
101
|
+
lambda: "/sentinel/path.onnx")
|
|
102
|
+
result = diacritics._phonikud(None)
|
|
103
|
+
assert result is diacritics._PHONIKUD_CACHE["/sentinel/path.onnx"]
|
|
104
|
+
|
|
105
|
+
def test_explicit_path_bypasses_provisioner(self, monkeypatch):
|
|
106
|
+
from scriptconv import diacritics
|
|
107
|
+
|
|
108
|
+
calls = []
|
|
109
|
+
monkeypatch.setattr(diacritics, "_default_phonikud_model",
|
|
110
|
+
lambda: calls.append(1) or "/should/not/be/used.onnx")
|
|
111
|
+
|
|
112
|
+
class FakePhonikud:
|
|
113
|
+
def __init__(self, model):
|
|
114
|
+
self.model = model
|
|
115
|
+
|
|
116
|
+
monkeypatch.setattr(diacritics, "_PHONIKUD_CACHE", {})
|
|
117
|
+
import sys
|
|
118
|
+
import types
|
|
119
|
+
fake_mod = types.ModuleType("phonikud_onnx")
|
|
120
|
+
fake_mod.Phonikud = FakePhonikud
|
|
121
|
+
monkeypatch.setitem(sys.modules, "phonikud_onnx", fake_mod)
|
|
122
|
+
|
|
123
|
+
result = diacritics._phonikud("/explicit/path.onnx")
|
|
124
|
+
assert result.model == "/explicit/path.onnx"
|
|
125
|
+
assert calls == [] # provisioner never invoked
|
|
99
126
|
|
|
100
127
|
|
|
101
128
|
class TestPhonikudModelResolver:
|
|
102
|
-
def test_callable_resolver_invoked_lazily(self):
|
|
103
|
-
from scriptconv
|
|
129
|
+
def test_callable_resolver_invoked_lazily(self, monkeypatch):
|
|
130
|
+
from scriptconv import diacritics
|
|
131
|
+
|
|
104
132
|
calls = []
|
|
105
133
|
|
|
106
134
|
def resolver():
|
|
107
135
|
calls.append(1)
|
|
108
|
-
return ""
|
|
136
|
+
return "/from/callable.onnx"
|
|
137
|
+
|
|
138
|
+
class FakePhonikud:
|
|
139
|
+
def __init__(self, model):
|
|
140
|
+
self.model = model
|
|
141
|
+
|
|
142
|
+
monkeypatch.setattr(diacritics, "_PHONIKUD_CACHE", {})
|
|
143
|
+
import sys
|
|
144
|
+
import types
|
|
145
|
+
fake_mod = types.ModuleType("phonikud_onnx")
|
|
146
|
+
fake_mod.Phonikud = FakePhonikud
|
|
147
|
+
monkeypatch.setitem(sys.modules, "phonikud_onnx", fake_mod)
|
|
109
148
|
|
|
110
149
|
assert calls == [] # not resolved at construction
|
|
111
|
-
|
|
112
|
-
diacritize("שלום", "he", phonikud_model=resolver)
|
|
150
|
+
result = diacritics._phonikud(resolver)
|
|
113
151
|
assert calls == [1]
|
|
152
|
+
assert result.model == "/from/callable.onnx"
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class TestDefaultPhonikudModelProvisioning:
|
|
156
|
+
def test_downloads_to_cache_dir_and_returns_path(self, monkeypatch, tmp_path):
|
|
157
|
+
from scriptconv import diacritics
|
|
158
|
+
|
|
159
|
+
monkeypatch.setenv("SCRIPTCONV_CACHE", str(tmp_path))
|
|
160
|
+
calls = []
|
|
161
|
+
|
|
162
|
+
class FakeResponse:
|
|
163
|
+
def __enter__(self):
|
|
164
|
+
return self
|
|
165
|
+
|
|
166
|
+
def __exit__(self, *a):
|
|
167
|
+
return False
|
|
168
|
+
|
|
169
|
+
def read(self, n):
|
|
170
|
+
if calls and calls[-1] == "read-done":
|
|
171
|
+
return b""
|
|
172
|
+
calls.append("read-done")
|
|
173
|
+
return b"dummy-onnx-bytes"
|
|
174
|
+
|
|
175
|
+
def fake_urlopen(url):
|
|
176
|
+
calls.append(("urlopen", url))
|
|
177
|
+
return FakeResponse()
|
|
178
|
+
|
|
179
|
+
monkeypatch.setattr(diacritics.urllib.request, "urlopen", fake_urlopen)
|
|
180
|
+
|
|
181
|
+
path = diacritics._default_phonikud_model()
|
|
182
|
+
assert path == str(tmp_path / "scriptconv" / "phonikud" / "phonikud-1.0.int8.onnx")
|
|
183
|
+
assert os.path.isfile(path)
|
|
184
|
+
|
|
185
|
+
# idempotent: second call must not re-download
|
|
186
|
+
urlopen_calls_before = sum(1 for c in calls if isinstance(c, tuple))
|
|
187
|
+
diacritics._default_phonikud_model()
|
|
188
|
+
urlopen_calls_after = sum(1 for c in calls if isinstance(c, tuple))
|
|
189
|
+
assert urlopen_calls_before == urlopen_calls_after == 1
|
|
190
|
+
|
|
191
|
+
def test_failed_download_leaves_no_partial_file(self, monkeypatch, tmp_path):
|
|
192
|
+
from scriptconv import diacritics
|
|
193
|
+
|
|
194
|
+
monkeypatch.setenv("SCRIPTCONV_CACHE", str(tmp_path))
|
|
195
|
+
|
|
196
|
+
def failing_urlopen(url):
|
|
197
|
+
raise OSError("network unavailable")
|
|
198
|
+
|
|
199
|
+
monkeypatch.setattr(diacritics.urllib.request, "urlopen", failing_urlopen)
|
|
200
|
+
|
|
201
|
+
with pytest.raises(OSError):
|
|
202
|
+
diacritics._default_phonikud_model()
|
|
203
|
+
|
|
204
|
+
dest = tmp_path / "scriptconv" / "phonikud" / "phonikud-1.0.int8.onnx"
|
|
205
|
+
assert not dest.exists()
|
|
206
|
+
cache_dir = tmp_path / "scriptconv" / "phonikud"
|
|
207
|
+
if cache_dir.exists():
|
|
208
|
+
assert list(cache_dir.iterdir()) == []
|
|
114
209
|
|
|
115
210
|
|
|
116
211
|
class TestEuropeanPortugueseSenseDiacritics:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/ko_tables/hanja.tsv
RENAMED
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/ko_tables/ipa.csv
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/ko_tables/yale.csv
RENAMED
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/__init__.py
RENAMED
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/codeswitch.py
RENAMED
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/diacritize.py
RENAMED
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/dialectal.py
RENAMED
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/english_g2p.py
RENAMED
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/espeak.py
RENAMED
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/frontend.py
RENAMED
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/levantine_g2p.py
RENAMED
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_thirdparty/shami/normalize.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/kog2p/__init__.py
RENAMED
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/kog2p/rulebook.txt
RENAMED
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/mantoq/LICENSE.md
RENAMED
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/mantoq/__init__.py
RENAMED
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/mantoq/buck/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/mantoq/buck/symbols.py
RENAMED
|
File without changes
|
|
File without changes
|
{scriptconv-0.0.4a6 → scriptconv-0.0.4a7}/scriptconv/phonemizers/_vendored/mantoq/num2words.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|