|
5 | 5 | from collections.abc import Mapping, Sequence |
6 | 6 | from dataclasses import dataclass, field |
7 | 7 | from functools import cached_property |
8 | | -from itertools import chain |
9 | 8 | from pathlib import Path |
10 | | -from subprocess import run |
11 | | -from time import time |
12 | 9 | from unicodedata import normalize |
13 | 10 |
|
14 | 11 | from .. import PYCONLANG_PATH |
15 | 12 | from ..assets import LEXURGY_VERSION |
16 | 13 | from ..checksum import checksum |
17 | 14 | from ..domain import Component, Morpheme, ResolvedForm |
18 | | -from ..lexurgy.domain import TraceLine |
| 15 | +from ..lexurgy import client |
| 16 | +from ..lexurgy.client import LexurgyClient |
| 17 | +from ..lexurgy.domain import ( |
| 18 | + LexurgyErrorResponse, |
| 19 | + LexurgyRequest, |
| 20 | + LexurgyResponse, |
| 21 | + TraceLine, |
| 22 | +) |
19 | 23 | from ..lexurgy.tracer import parse_trace_lines |
20 | 24 | from .arrange import AffixArranger |
21 | 25 | from .batch import Batcher, Cache, ComponentQuery, CompoundQuery, Query |
@@ -59,6 +63,10 @@ class Evolver: |
59 | 63 | def arranger(self) -> AffixArranger: |
60 | 64 | return AffixArranger.from_path(CHANGES_PATH) |
61 | 65 |
|
| 66 | + @cached_property |
| 67 | + def lexurgy(self) -> LexurgyClient: |
| 68 | + return client() # .value |
| 69 | + |
62 | 70 | @classmethod |
63 | 71 | def load(cls) -> "Evolver": |
64 | 72 | if not all( |
@@ -188,67 +196,41 @@ def evolve_words( |
188 | 196 | if not words: |
189 | 197 | return [], {} |
190 | 198 |
|
191 | | - base_name = f"words-{time():.0f}" |
192 | | - |
193 | | - self.evolve_directory.mkdir(parents=True, exist_ok=True) |
194 | | - |
195 | | - input_words = self.evolve_directory / f"{base_name}.wli" |
196 | | - input_words.write_text("\n".join(words)) |
197 | | - |
198 | | - output_words = self.evolve_directory / f"{base_name}_ev.wli" |
199 | | - output_words.unlink(missing_ok=True) |
200 | | - |
201 | | - phonetic_words = self.evolve_directory / f"{base_name}_phonetic.wli" |
202 | | - phonetic_words.unlink(missing_ok=True) |
203 | | - |
204 | | - trace_file = self.evolve_directory / f"{base_name}_trace.wli" |
205 | | - trace_file.unlink(missing_ok=True) |
206 | | - |
207 | | - args = [ |
208 | | - "sh", |
209 | | - str(LEXURGY_PATH), |
210 | | - "sc", |
211 | | - str(CHANGES_PATH), |
212 | | - str(input_words), |
213 | | - "-m", |
214 | | - ] |
215 | | - |
216 | | - if start is not None: |
217 | | - args.append("-a") |
218 | | - args.append(start) |
| 199 | + debug_words = [] |
| 200 | + if trace: |
| 201 | + debug_words = words |
219 | 202 |
|
220 | | - if end is not None: |
221 | | - args.append("-b") |
222 | | - args.append(end) |
| 203 | + request = LexurgyRequest(words, start, end, debug_words) |
223 | 204 |
|
224 | | - if trace: |
225 | | - args.extend(chain(*zip(["-t"] * len(words), words))) |
| 205 | + response = self.lexurgy.roundtrip(request) |
226 | 206 |
|
227 | | - result = run(args, capture_output=True, text=True) |
| 207 | + match response: |
| 208 | + case LexurgyErrorResponse(): |
| 209 | + raise LexurgyError(response.message) |
228 | 210 |
|
229 | | - if result.returncode != 0: |
230 | | - # todo too heuristic? |
231 | | - stdout = result.stdout.strip().splitlines() |
232 | | - if len(stdout) > 0: |
233 | | - raise LexurgyError(result.stdout.strip().splitlines()[-1]) |
234 | | - else: |
235 | | - raise LexurgyError(result.stderr) |
| 211 | + case LexurgyResponse(): |
| 212 | + moderns = [normalize("NFD", word) for word in response.words] |
236 | 213 |
|
237 | | - moderns = normalize("NFD", output_words.read_text().strip()).split("\n") |
| 214 | + if "phonetic" in response.intermediates: |
| 215 | + phonetics = [ |
| 216 | + normalize("NFD", word) |
| 217 | + for word in response.intermediates["phonetic"] |
| 218 | + ] |
| 219 | + else: |
| 220 | + phonetics = moderns |
238 | 221 |
|
239 | | - if phonetic_words.exists(): |
240 | | - phonetics = normalize("NFD", phonetic_words.read_text()).strip().split("\n") |
241 | | - else: |
242 | | - phonetics = moderns |
| 222 | + assert len(phonetics) == len(moderns) |
243 | 223 |
|
244 | | - trace_lines: Mapping[str, list[TraceLine]] = {} |
245 | | - if trace: |
246 | | - trace_lines = parse_trace_lines(trace_file.read_text(), words[0]) |
| 224 | + trace_lines: Mapping[str, list[TraceLine]] = {} |
| 225 | + if trace: |
| 226 | + trace_lines = parse_trace_lines( |
| 227 | + "\n".join(response.trace_lines), words[0] |
| 228 | + ) |
247 | 229 |
|
248 | | - return [ |
249 | | - Evolved(proto, modern, phonetic) |
250 | | - for proto, modern, phonetic in zip(words, moderns, phonetics) |
251 | | - ], trace_lines |
| 230 | + return [ |
| 231 | + Evolved(proto, modern, phonetic) |
| 232 | + for proto, modern, phonetic in zip(words, moderns, phonetics) |
| 233 | + ], trace_lines |
252 | 234 |
|
253 | 235 | def cleanup(self) -> None: |
254 | 236 | if self.evolve_directory.exists(): |
|
0 commit comments