StrictYAML
StrictYAML 是一个 类型安全 的 YAML 解析器,它解析并验证 YAML 规范的受限子集。
优先事项
- 漂亮的 API
- 拒绝解析 YAML 中丑陋、难读且不安全的特性,例如 挪威问题。
- 严格验证标记和直接类型转换。
- 清晰、可读的异常,带有代码片段和行号。
- 充当 pyyaml、ruamel.yaml 或 poyo 的近乎直接的替代品。
- 能够读取 YAML,进行更改,并将其写回,同时保留注释。
- 目前不是速度。
简单示例
# All about the character
name: Ford Prefect
age: 42
possessions:
- Towel
from strictyaml import load, Map, Str, Int, Seq, YAMLError
默认解析结果
>>> load(yaml_snippet)
YAML({'name': 'Ford Prefect', 'age': '42', 'possessions': ['Towel']})
所有数据都是字符串、列表或 OrderedDict
>>> load(yaml_snippet).data
{'name': 'Ford Prefect', 'age': '42', 'possessions': ['Towel']}
使用模式的快速入门
from strictyaml import load, Map, Str, Int, Seq, YAMLError
schema = Map({"name": Str(), "age": Int(), "possessions": Seq(Str())})
42 现在被解析为整数
>>> person = load(yaml_snippet, schema)
>>> person.data
{'name': 'Ford Prefect', 'age': 42, 'possessions': ['Towel']}
如果存在语法问题、违反模式或使用不允许的 YAML 功能,将引发 YAMLError
# All about the character
name: Ford Prefect
age: 42
例如,模式违规
try:
person = load(yaml_snippet, schema)
except YAMLError as error:
print(error)
while parsing a mapping
in "<unicode string>", line 1, column 1:
# All about the character
^ (line: 1)
required key(s) 'possessions' not found
in "<unicode string>", line 3, column 1:
age: '42'
^ (line: 3)
如果解析正确
from strictyaml import load, Map, Str, Int, Seq, YAMLError, as_document
schema = Map({"name": Str(), "age": Int(), "possessions": Seq(Str())})
你可以修改值并写出 YAML,同时保留注释
person = load(yaml_snippet, schema)
person['age'] = 43
print(person.as_yaml())
# All about the character
name: Ford Prefect
age: 43
possessions:
- Towel
以及查找行号
>>> person = load(yaml_snippet, schema)
>>> person['possessions'][0].start_line
5
并从字典或列表构建 YAML 文档
print(as_document({"x": 1}).as_yaml())
x: 1
安装
$ pip install strictyaml
为什么使用 StrictYAML?
有许多格式和方法可以实现与 StrictYAML 类似的目的。我尝试使其成为最佳方法。下面是一系列经过记录的理由
- 为什么避免使用环境变量作为配置?
- 为什么不使用 HJSON?
- 为什么不使用 HOCON?
- 为什么不使用 INI 文件?
- 为什么不使用 JSON Schema 进行验证?
- 为什么不使用 JSON 作为简单的配置文件?
- 为什么不使用 JSON5?
- 为什么不使用 YAML 1.2 标准? - 我们不需要新的标准!
- 为什么不使用 kwalify 和标准 YAML 来验证我的 YAML?
- 为什么不使用 Python 的模式库(或类似库)进行验证?
- 为什么不使用 SDLang?
- TOML 有什么问题?
- 为什么我不应该直接使用 Python 代码进行配置?
- 为什么不使用 XML 进行配置或 DSL?
使用 StrictYAML
如何
- 从头开始在代码中构建 YAML 文档
- 对不同但同样有效的不同类型的 YAML 进行“或”模式验证
- 标记异常
- 合并 YAML 文档
- 重新验证已验证的文档
- 读取 YAML,编辑它,然后将其写回,同时保留注释
- 获取 YAML 元素的行号
- 解析没有模式的 YAML
复合验证器
- 固定长度序列 (FixedSeq)
- 组合定义和未定义键的映射 (MapCombined)
- 具有任意键名的映射 (MapPattern)
- 具有定义键和自定义键验证器的映射 (Map)
- 使用解析映射的 YAML 对象
- 具有定义键的映射 (Map)
- 具有默认值的可选键 (Map/Optional)
- 验证映射中的可选键 (Map)
- 唯一项序列 (UniqueSeq)
- 序列/列表验证器 (Seq)
- 使用模式更新文档
标量验证器
- 布尔值 (Bool)
- 解析逗号分隔的项目 (CommaSeparated)
- 日期时间 (Datetime)
- 十进制数 (Decimal)
- 电子邮件和 URL 验证器
- 空键验证
- 枚举标量 (Enum)
- 浮点数 (Float)
- 十六进制整数 (HexInt)
- 整数 (Int)
- 使用正则表达式验证字符串 (Regex)
- 解析字符串 (Str)
限制
设计理由
StrictYAML 中有一些设计决策存在争议或不明显。这些都在这里有记录
- 重复键有什么问题?
- 显式标签有什么问题?
- 流式 YAML 有什么问题?
- 挪威问题 - 为什么 StrictYAML 拒绝进行隐式类型化,你也应该这样做
- 节点锚点和引用有什么问题?
- 为什么 StrictYAML 不解析 Python 对象的直接表示?
- 为什么 StrictYAML 只能从字符串而不是文件解析?
- 为什么解析速度不是 StrictYAML 的优先事项?
- 什么是语法类型?
- 为什么 StrictYAML 让你在 Python(一种图灵完备的语言)中定义模式?
明星贡献者
- @wwoods
- @chrisburr
- @jnichols0
其他贡献者
- @eulores
- @WaltWoods
- @ChristopherGS
- @gvx
- @AlexandreDecan
- @lots0logs
- @tobbez
- @jaredsampson
- @BoboTIG
StrictYAML 还包含来自 ruamel.yaml 的代码,版权所有 Anthon van der Neut。
贡献
- 在编写任何代码之前,请阅读有关 向 hitchdev 库贡献代码 的教程。
- 在编写任何代码之前,如果你正在提议一个新功能,请在 github 上提出。如果这是一个现有的功能/错误,请评论并简要描述你将如何实现它。
- 所有代码都需要附带一个故事,来测试它或修改现有故事。这既用于测试代码,也用于构建文档。