"""Independent read of AME XML fields; no shared expected-parameter helper."""
from pathlib import Path
import ast, collections, hashlib, json, math, operator, re, sys, tarfile
import xml.etree.ElementTree as ET
ROOT=Path(__file__).resolve().parents[2]
sys.path.insert(0,str(ROOT))
from app.simulation.registry import get_component_model_spec
OUT=ROOT/'test/solver-newton-20260911/mql4/visual-recheck'
OUT.mkdir(parents=True,exist_ok=True)
with tarfile.open(ROOT/'tests/data/test_mql_4.ame') as archive:
cir=archive.extractfile('test_mql_4_.cir').read().decode('latin1')
# AME stores unescaped C-style && in visibility metadata, outside parameter values.
xml_text=re.sub(r'.*?', '', cir, flags=re.S)
xml_text=re.sub(r'&(?!amp;|lt;|gt;|quot;|apos;|#)', '&', xml_text)
root=ET.fromstring(xml_text)
BINARY={ast.Add:operator.add,ast.Sub:operator.sub,ast.Mult:operator.mul,ast.Div:operator.truediv,ast.Pow:operator.pow}
UNARY={ast.UAdd:operator.pos,ast.USub:operator.neg}
def evaluate(text,names):
def visit(node):
if isinstance(node,ast.Constant) and isinstance(node.value,(int,float)):return float(node.value)
if isinstance(node,ast.Name):return names[node.id]
if isinstance(node,ast.BinOp) and type(node.op) in BINARY:return BINARY[type(node.op)](visit(node.left),visit(node.right))
if isinstance(node,ast.UnaryOp) and type(node.op) in UNARY:return UNARY[type(node.op)](visit(node.operand))
raise ValueError(ast.dump(node))
return visit(ast.parse(text.strip().replace('^','**'),mode='eval').body)
variables={};pending={g.findtext('GLOB_PARAM_NAME').strip():g.findtext('VALUE').strip() for g in root.findall('.//GLOBALPARAM')}
while pending:
count=len(pending)
for key,value in list(pending.items()):
try:variables[key]=evaluate(value,variables)
except KeyError:continue
del pending[key]
assert len(pending)