chronaxis.results.input_diagnostics
源码基线:8904c2f744951857659abd40aaa3535d57faf53c
1"""保存明确请求的输入检查范围;摘要只覆盖实际交给分析层的记录。23一份来源说明关联必要路径、所需别名、检查范围及可选摘要,不复制输入文件。4本模型不读取数据;EOF和摘要由同次运行提供,不能当成全文件内容证明。5"""6from dataclasses import dataclass7from ..core.validation import require_identifier,require_text8910@dataclass(frozen=True)11class InputDiagnostic:12 """一个实际来源的有限诊断;记录数与摘要均指同一所需记录流。"""13 source: str14 source_type: str15 paths: tuple[str,...]16 aliases: tuple[str,...]17 bindings: tuple[tuple[str,str],...]18 input_check: str19 time_scope: str20 record_count: int21 source_eof: bool22 sha256: str | None = None23 digest_scope: str = 'required-decoded-records-v1'2425 def __post_init__(self):26 """核有限范围声明。参数: 无。返回: None。异常: 类型/值错误。"""27 require_identifier(self.source,'diagnostic.source')28 if self.source_type not in ('can_blf','can_asc','asc_or_blf','raw_can_csv','memory','signal_csv'):29 raise ValueError('诊断来源类型无效')30 for values in (self.paths,self.aliases):31 if type(values) is not tuple:raise TypeError('诊断路径/别名需要tuple')32 for value in values:require_text(value,'diagnostic.locator')33 if type(self.bindings) is not tuple or any(type(pair) is not tuple or len(pair)!=234 or pair[0] not in self.aliases or type(pair[1]) is not str or not pair[1] for pair in self.bindings):35 raise ValueError('诊断绑定需要别名及实际原字段')36 if self.input_check not in ('auto','full') or self.time_scope not in ('none','selected','source'):37 raise ValueError('诊断检查范围无效')38 if type(self.record_count) is not int or self.record_count<0 or self.source_eof is not True:39 raise ValueError('诊断需要真实EOF与非负记录数')40 if self.sha256 is not None and (type(self.sha256) is not str or len(self.sha256)!=6441 or any(c not in '0123456789abcdef' for c in self.sha256)):42 raise ValueError('诊断摘要必须是SHA256或None')43 if self.digest_scope!='required-decoded-records-v1':44 raise ValueError('不能把所需记录流摘要声明为全文件证明')4546 def to_dict(self):47 """输出一份来源/绑定范围,未请求摘要时不写空摘要栏。参数: 无。返回: dict。异常: 无。"""48 result={name:getattr(self,name) for name in ('source','source_type','paths','bindings','input_check','time_scope','record_count','source_eof')}49 result['record_scope']=self.digest_scope50 if self.sha256 is not None:result['sha256']=self.sha25651 return result52