From db5b4d3ef8f8b0911e71af9cbb3944639f8ee41b Mon Sep 17 00:00:00 2001 From: Umut CAN Date: Thu, 24 Sep 2026 16:10:24 +0300 Subject: [PATCH] fix(understand): the bare Russian "to" before a panel is a wiring callout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A Russian P&ID often closes a load's text with the panel it is wired to: '... кВт' on one line, then 'к CP1' ('to CP1') or 'к щиту CP-2' ('to switchboard CP-2') on the next. wiring_target knew 'подключение к ...' but not the bare preposition. On the field P&ID most loads therefore had no panel and no measurable cable. The preposition к / ко now counts when it is a whole word and the panel is the next word, optionally after щиту / шкафу / панели. The к of кВт is never read as the preposition. The new test failed before the change. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd --- README.md | 2 +- engineering/understand/labels.py | 17 ++++++++++++++++- tests/test_understand_labels.py | 10 ++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e6f0480..2489600 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Live through COM on Windows, or headless through ezdxf anywhere — one typed co -> **v1.5 release snapshot:** 247 tools · 8 resources · 5 prompt templates · 4981 collected tests. +> **v1.5 release snapshot:** 247 tools · 8 resources · 5 prompt templates · 4982 collected tests. > 247 is the **registered** count; a default install advertises 242 over `tools/list`, > because `ENABLE_3D` is unset. `system_about` is the runtime authority. diff --git a/engineering/understand/labels.py b/engineering/understand/labels.py index 3704a87..06f4289 100644 --- a/engineering/understand/labels.py +++ b/engineering/understand/labels.py @@ -135,6 +135,15 @@ _WIRING_PHRASES = ( ) #: Turkish puts the panel first: ``CP1 panosuna`` ("to the CP1 panel"). _WIRING_PHRASES_AFTER = ("panosuna", "panosundan") +#: The bare Russian preposition к / ко ("to") with the panel as the next word, +#: optionally after "щиту" / "шкафу" / "панели" (switchboard / cabinet / panel): +#: a Russian P&ID closes a load's text with ``к CP1``. Only a whole word counts, +#: so the к of кВт is no preposition. +_RU_TO_PANEL = re.compile( + r"(?:^|\s)ко?\s+" + r"(?:(?:щиту|шкафу|панели)\s+)?", + re.IGNORECASE, +) def plain(text: str | None) -> str: @@ -295,7 +304,9 @@ def wiring_target(text: str | None) -> str | None: ``"Wiring to CP1"`` -> ``"CP-1"``; ``"подключение к шкафу CP-1"`` -> ``"CP-1"``; ``"CP 2 panosuna"`` -> ``"CP-2"`` (Turkish names the panel - first). None when the text has no wiring phrase or no panel beside it. + first); ``"... кВт\\nк CP1"`` -> ``"CP-1"`` (the bare Russian "to", the + panel as the next word). None when the text has no wiring phrase or no + panel beside it. """ body = plain(text) lowered = body.lower() @@ -311,4 +322,8 @@ def wiring_target(text: str | None) -> str | None: matches = list(_PANEL_RE.finditer(fold_lookalikes(body[:at]))) if matches: return f"{matches[-1].group(1)}-{matches[-1].group(2)}" + for to in _RU_TO_PANEL.finditer(body): + panel = _PANEL_RE.match(fold_lookalikes(body[to.end() :])) + if panel is not None: + return f"{panel.group(1)}-{panel.group(2)}" return None diff --git a/tests/test_understand_labels.py b/tests/test_understand_labels.py index 1faeed8..dc1eeca 100644 --- a/tests/test_understand_labels.py +++ b/tests/test_understand_labels.py @@ -212,6 +212,16 @@ def test_wiring_callouts_in_four_languages(): assert wiring_target("CP 2 panosuna") == "CP-2" +def test_the_russian_to_before_a_panel_is_a_wiring_callout(): + # A Russian P&ID closes a load's text with the panel it is wired to: 'к CP1' + # ('to CP1'), or 'к щиту CP-2' ('to switchboard CP-2'). The unit кВт holds + # the same letter and is no preposition. + assert wiring_target("к CP1") == "CP-1" + assert wiring_target("P = 2,2 кВт\nк CP1") == "CP-1" + assert wiring_target("к щиту CP-2") == "CP-2" + assert wiring_target("P = 2,2 кВт") is None + + def test_a_callout_without_a_wiring_phrase_names_no_panel(): assert wiring_target("CP1") is None assert wiring_target("Wiring to") is None