fix(778-2): 못옮김 기계 잇기 = 기계경비 기초 로직 줄 · 목록 밖 기계 셈 문맥 고침

- SkPatch LINK 기계 = 로직 · _Plan.link: EQ 키 → 기계경비 기초(그 기계를 고르기에 둔 기초 먼저) + 입력 기계 = 원문번호 · EQ 키 바로 더한줄 셈 오류 없앰
- master_pick resolve · machine · master_formula _inputs: 셈에 넘어온 마스터로 기계 찾음 — 까닭 = mp.EQ ContextVar 는 마스터를 지은 문맥에만 있어 서버 둘째 요청(스레드 풀 · 새 문맥)부터 목록 밖 기계(굴착기(타이어) 0.6㎥ 등)가 「고르기 밖」으로 막힘 · ContextVar 는 대신 길로 남김
- 새 시험 test_778_2_hopyo_machine_link(잇기 뒤 SK 셈 · 서버 두 요청 · 문맥 밖 스레드)
- 여덟 파일 기초 80 · SK 37 · 고름 대기 89 그대로 · SK 셈 오류 0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-04 11:54:09 +09:00
co-authored by Claude Opus 5.5
parent 560e2e0928
commit 026f6c667a
4 changed files with 103 additions and 15 deletions
@@ -512,7 +512,7 @@ def fill_empty(row: dict, given: dict) -> dict:
return {**given, **gap}
def _inputs(row: dict, given: dict) -> dict:
def _inputs(row: dict, given: dict, master=None) -> dict:
env = {}
for spec in row.get("입력", []):
name = spec["이름"]
@@ -529,8 +529,8 @@ def _inputs(row: dict, given: dict) -> dict:
pass
if isinstance(value, (int, float)):
value = Decimal(str(value))
value = mp.resolve(spec, value) # 기계 EQ 키 → 원문 분류번호
if "고르기" in spec and value not in spec["고르기"] and not mp.machine(spec, value):
value = mp.resolve(spec, value, master) # 기계 EQ 키 → 원문 분류번호
if "고르기" in spec and value not in spec["고르기"] and not mp.machine(spec, value, master):
raise FormulaError(f"입력 「{name}」={value} 고르기 밖")
if "범위" in spec:
low, high = spec["범위"]
@@ -567,7 +567,7 @@ def run(master: Master, ref: str, given: dict, depth: int = 0) -> dict:
if isinstance(row.get("흐름"), dict): # 흐름 로직 — 깔림에 기대지 않고 스스로 깖
_flow_hooks()
return FLOW_RUN(master, ref, row, given)
env = _inputs(row, given)
env = _inputs(row, given, master)
for step in row.get("중간", []):
try:
env[step["이름"]] = evaluate(parse(step["식"]), env, master, depth)
+13 -8
View File
@@ -33,22 +33,27 @@ def choosing(picks: dict | None):
CHOSEN.reset(token)
def _numbers() -> dict:
return EQ.get().numbers.get("EQ", {}) if EQ.get() else {}
def _eq(master=None):
"""기계를 찾을 마스터 — 셈에 넘어온 것(기계 줄 있음) › 지은 문맥의 것(`EQ` · 다른 스레드는 빔)."""
return master if (getattr(master, "numbers", None) or {}).get("EQ") else EQ.get()
def resolve(spec: dict, value):
def _numbers(master=None) -> dict:
return _eq(master).numbers.get("EQ", {}) if _eq(master) else {}
def resolve(spec: dict, value, master=None):
"""기계 입력이 EQ 키로 오면 원문 분류번호로 풂 — 고르기 목록(원문번호)과 같은 꼴."""
if not (isinstance(value, str) and value.strip()[:2] == "EQ" and EQ.get()):
if not (isinstance(value, str) and value.strip()[:2] == "EQ" and _eq(master)):
return value
row = EQ.get().index.get("EQ", {}).get(value.strip())
row = _eq(master).index.get("EQ", {}).get(value.strip())
number = str(row.get("원문번호") or "") if row else ""
return number if number and machine(spec, number) else value
return number if number and machine(spec, number, master) else value
def machine(spec: dict, value) -> bool:
def machine(spec: dict, value, master=None) -> bool:
"""기계 입력 — 고르기 목록 밖 원문 분류번호도 기계 마스터에 있으면 받음."""
known = _numbers()
known = _numbers(master)
picks = spec.get("고르기") or []
return bool(picks) and str(value).strip() in known and all(str(o) in known for o in picks)