from __future__ import annotations from dataclasses import dataclass, field from typing import Optional @dataclass class Field: name: str level: int pic: str usage: str = "DISPLAY" offset: int = 0 length: int = 0 decimal: int = 0 signed: bool = False sign_separate: bool = False occurs: Optional[int] = None occurs_max: Optional[int] = None redefines: Optional[str] = None redefines_variant: Optional[str] = None conditions: list[dict] = field(default_factory=list) children: list["Field"] = field(default_factory=list) @dataclass class FieldTree: fields: list[Field] = field(default_factory=list) copybook_name: str = "" sha256: str = "" def flatten(self) -> dict[str, Field]: result = {} def _walk(ff): for f in ff: result[f.name] = f _walk(f.children) _walk(self.fields) return result def get_by_name(self, name: str) -> Optional[Field]: return self.flatten().get(name) @classmethod def from_list(cls, fields: list[Field], name: str = "") -> "FieldTree": return cls(fields=fields, copybook_name=name) _f = Field(name="BR-AMT", level=5, pic="S9(7)V99", usage="COMP-3", offset=0, length=5, decimal=2, signed=True) assert _f.name == "BR-AMT" assert _f.decimal == 2 assert _f.signed _ft = FieldTree(fields=[_f], copybook_name="BILLCPY") assert "BR-AMT" in _ft.flatten() assert _ft.get_by_name("BR-AMT") is _f