chronaxis.configuration
源码基线:8904c2f744951857659abd40aaa3535d57faf53c
1"""共享配置语法入口;只读指定文件,返回原生值和加载期位置,不读取业务输入。"""2from pathlib import Path3from types import MappingProxyType45from .models import ConfigurationDocument, ConfigurationError, ConfigurationLocation, field_path_text6from .json_parser import parse_json78__all__=['ConfigurationDocument','ConfigurationError','ConfigurationLocation',9 'field_path_text','parse_configuration','load_configuration']101112def parse_configuration(text, *, format, source='<configuration>'):13 """解析显式格式文本。参数: str文本、json/yaml格式、显示来源。返回: 文档。异常: 语法或参数错误。1415 不替换环境变量或执行模板。UTF-8文件开头的BOM可选;字段原始字符串保留。16 """17 if type(text) is not str or type(source) is not str:18 raise TypeError('配置内容和来源名称需要文本')19 if type(format) is not str or format not in ('json','yaml'):20 raise ConfigurationError(source,(),None,'unsupported_format','配置格式只支持json或yaml')21 if text.startswith('\ufeff'):text=text[1:]22 if format=='json':23 data,locations=parse_json(text,source)24 else:25 from .yaml_parser import parse_yaml26 data,locations=parse_yaml(text,source)27 return ConfigurationDocument(data,source,format,MappingProxyType(locations))282930def load_configuration(path):31 """按.json/.yaml/.yml加载UTF-8文件。返回: 文档。异常: 定位读取/语法错误;取消原样传播。3233 后缀不识别时不打开文件;读取结束即关闭句柄,再解析文本,不持有调用者输入文件。34 """35 if not isinstance(path,(str,Path)):36 raise TypeError('配置路径需要Path或文本')37 target=Path(path).absolute()38 format={'.json':'json','.yaml':'yaml','.yml':'yaml'}.get(target.suffix.lower())39 if format is None:40 raise ConfigurationError(str(target),(),None,'unsupported_format','配置后缀需要.json、.yaml或.yml')41 try:42 with target.open('r',encoding='utf-8-sig') as stream:43 text=stream.read()44 except (OSError,UnicodeError) as error:45 raise ConfigurationError(str(target),(),None,'load_error',str(error)) from error46 return parse_configuration(text,format=format,source=str(target))47