如何从Python数据类生成适配yaml-ls的YAML Schema?
问题
我有一个包含MyStocksConf数据类的配置类,定义如下:
@dataclass class MyStocksConf: File: str = r'buydicnk.cache' SrcFile: str = "example_mystock.csv" PortofolioName: str = "My Portfolio" Use: Union[UseCache, int] = UseCache.USEIFAVALIABLE
UseCache枚举类定义:
@to_yaml class UseCache(int,Enum): DONT=0 USEIFAVALIABLE=1 FORCEUSE=2
我通过ruamel.yaml注册自定义类,但采用不安全加载方式。为了让yaml-ls实现YAML的IntelliSense功能,需要生成匹配以下YAML格式的Schema:
MyStocks: !MyStocksConf File: buydicnk.cache PortofolioName: My Portfolio SrcFile: C:\Users\...\.compare_my_stocks Use: !UseCache DONT
要求Schema包含字段类型,枚举类型需列出成员;现有生成的Schema如下,但需要优化以支持枚举名称(比如DONT而非仅数字):
{'$defs': {'UseCache': {'enum': [0, 1, 2], 'title': 'UseCache', 'type': 'integer'}}, 'properties': {'File': {'default': 'buydicnk.cache', 'title': 'File', 'type': 'string'}, 'SrcFile': {'default': 'example_mystock.csv', 'title': 'Srcfile', 'type': 'string'}, 'PortofolioName': {'default': 'My Portfolio', 'title': 'Portofolioname', 'type': 'string'}, 'Use': {'anyOf': [{'$ref': '#/$defs/UseCache'}, {'type': 'integer'}], 'default': 1, 'title': 'Use'}}, 'title': 'MyStocksConf', 'type': 'object'}
请问如何从类定义生成符合要求的Schema?
解决方案
要生成支持枚举名称(如DONT)的JSON Schema,需要调整枚举类的Schema生成逻辑,同时适配YAML标签的使用场景,具体操作如下:
1. 重构枚举类的Schema定义
原Schema仅支持枚举数值,需要改成同时兼容枚举名称(字符串)和对应数值的结构。推荐用oneOf分别定义字符串和整数枚举分支,并通过description标注对应关系,这样yaml-ls能同时提示枚举名称和数值。
2. 适配YAML自定义标签
在Schema中添加自定义扩展字段(如x-tag)标识YAML标签(!MyStocksConf、!UseCache),yaml-ls可识别这类字段提供标签提示。
3. 修正字段细节
修正原Schema中字段标题的小写问题(如Srcfile改为SrcFile),保持和Python类字段名一致;调整Use字段的默认值为枚举名称,贴合YAML写法。
优化后的Schema示例
{ "$defs": { "UseCache": { "title": "UseCache", "oneOf": [ { "type": "string", "enum": ["DONT", "USEIFAVALIABLE", "FORCEUSE"], "description": "枚举名称:DONT=0, USEIFAVALIABLE=1, FORCEUSE=2" }, { "type": "integer", "enum": [0, 1, 2], "description": "枚举数值:0=DONT, 1=USEIFAVALIABLE, 2=FORCEUSE" } ] } }, "title": "MyStocksConf", "type": "object", "properties": { "File": { "title": "File", "type": "string", "default": "buydicnk.cache" }, "SrcFile": { "title": "SrcFile", "type": "string", "default": "example_mystock.csv" }, "PortofolioName": { "title": "PortofolioName", "type": "string", "default": "My Portfolio" }, "Use": { "title": "Use", "anyOf": [ {"$ref": "#/$defs/UseCache"}, {"type": "integer"} ], "default": "USEIFAVALIABLE", "description": "支持枚举名称(如DONT)或对应数值(如0)" } }, "x-tag": "!MyStocksConf", "required": [] }
自动生成的实现思路
如果要从Python类自动生成该Schema,可通过以下方式实现:
- 遍历
UseCache枚举成员,收集名称和数值,构建oneOf结构。 - 保留Python类的原字段名作为Schema的字段标题,避免自动小写转换。
- 添加
x-tag等自定义字段标识YAML标签。 - 处理
Union类型,保留对枚举和整数的双重支持。
内容的提问来源于stack exchange,提问作者Eyal M
相关产品推荐
相关产品推荐

