Changelog
变更日志¶
本文件记录该项目的所有重要变更。
格式基于 Keep a Changelog, 本项目遵循 语义化版本。
[Unreleased]¶
新增¶
- 命令行工具 — 新增
pyrs-yaml命令(通过pip install "pyrs-yaml[cli]"安装, 需 Python 3.10+),在终端中暴露库的核心能力:fmt(往返重新格式化,保留注释/ 锚点/顺序)、get(JSONPath 查询,支持--format yaml|json|text)、set/delete/rename(基于路径的编辑,支持--inplace、--string、--create-missing)、validate(对 CI 友好的退出码)以及to-json/from-json转换。所有命令通过-读取 stdin,默认输出到 stdout。实现为纯 Python(python/pyrs_yaml/cli/),基于 Cyclopts 作为可选 extra,基础安装保持零额外依赖并继续支持 Python 3.8。 基础安装保持零额外依赖并继续支持 Python 3.8。 - CLI 扩展 —— 新增
sort-keys(对路径处映射键排序)、move(将子树移动到已存在的目标)、frontmatter(提取 Markdown front matter 为 YAML,可选拆分正文)与compliance(YAML Test Suite 报告,支持--json)命令;为fmt/get/set/delete/rename/sort-keys/validate/to-json提供-A/--all-docs多文档模式;validate改为互斥的--schema <名称>与--schema-file <路径>。未成文的python -m pyrs_yaml.compliance入口已被子命令取代并移除。 - 可选第三方类型插件 —
!duration(pendulum.Duration)、!arrow(arrow.Arrow)、!ulid(ulid.ULID)在安装对应库时自动注册(python/pyrs_yaml/plugins/_builtin.py中的_register_third_party)。每个插件使用独立标签,不影响现有!timestamp/!date/!uuid处理器;标准库timedelta绝不会被!duration匹配。 - pydantic-settings YAML 配置来源 —
PyrsYamlConfigSettingsSource(python/pyrs_yaml/settings.py)是pydantic_settings.YamlConfigSettingsSource的即插即用替代,使用 pyrs-yaml(YAML 1.2 核心 schema)而非 PyYAML 解析。采用惰性 导出,import pyrs_yaml不依赖 pydantic-settings;通过pip install "pyrs-yaml[settings]"安装(Python 3.10+)。dump_pydantic与parse_as也已改为相同的模块级__getattr__惰性导出模式。
[v0.15.0] — 2026-08-19¶
新增¶
- Node 元数据 setter/getter — 新增
Node.comment/Node.anchor/Node.tag只读属性和set_comment/set_anchor/set_tag(及remove_*系列)。编辑别名或不存在路径会报错;内联标量值和序列项上的独立注释现在输出到独立的缩进行(修复child:\n # c\n val与- a\n# c\n- b既有的 round-trip 缺陷)。 - Verbatim 标签 —
set_tag("!<tag:yaml.org,2002:str>")现在生成 verbatim 标签(空 handle),且从源码解析的 verbatim 标签在 round-trip 中保留:Tag的Display对空 handle 标签以!<...>包裹输出,parse_tag识别!<...>形式,流事件通过Display序列化标签。 - Schema 文件 IO 与列表 —
load_schema(name, path)从文件读取 schema 定义并注册,list_schemas()返回所有已注册的 schema 名称(内置failsafe/json/core/yaml1.1+ 自定义)。 - Node style/format setter/getter — 新增
Node.scalar_style/Node.flow_style/Node.chomping只读属性和set_scalar_style/set_flow_style/set_chomping方法。ScalarStyle/Chomping 现在 deriveCopy。非标量节点返回None/ no-op,别名和缺失路径报错。 - Schema 结构化校验 — 在 schema 定义的
validate段添加结构检查(路径限定标量类型、sequence_of/mapping_of容器、required)。validate_against_schema(data, schema_yaml)列出所有失败项并抛YamlValidateError。 Node.copy()— 将子树深度复制为与文档分离的独立 Python 值(dict/list/scalar),可用于通过set_value()粘贴。- 深度编辑 API —
doc.set_many({path: value})在单次 splice 突发中设置多个路径(支持通配符[*]和深度扫描..);doc.sort_keys()原地排序映射键;Node.move(new_path)移动子树;Node.path/Node.find_first()/Node.value_eq()新增路径访问、首通配符查找、值比较。 - 0.14+ 新功能的属性测试 —
validate_node/ schema 解析 / style round-trip 的 Rust proptest,set_many通配符 / metadata 编辑 /sort_keys的 Python hypothesis 测试。hypothesis移至test组,确保 CI 运行属性测试。 - 序列化器修复 — 空 flow 容器(
key: {}/key: [])上的独立注释不再产生无效 YAML(降级为行内)。
变更¶
- NumPy 在自由线程 (cp314t) wheel 上重新启用 — 从 cp314t 构建参数移除
--no-default-features;rust-numpy 0.29 支持自由线程 Python,numpy.ndarray序列化现可在自由线程 wheel 上使用(运行时自动检测 NumPy 是否安装)。
文档¶
- 修正全部语言(en/zh/ja/ko)文档中的过时引用 —
saphyr-parser→granit-parser,YAML 合规率 98.1% → 99.75%(405/406 套件用例),ABI3 支持 3.9–3.13 → 3.8–3.15(py3.9+ → py3.8+),并更新基准测试表为当前 CodSpeed CI 数据(解析快 21–43 倍、序列化快 55–177 倍于 PyYAML)。Rust 侧基准测试章节从 Criterion 迁移到 divan(benches/yaml_bench.rs→crates/pyrs-yaml/benches/yaml_bench.rs)。
[v0.14.1] — 2026-08-15¶
修复¶
- 含反斜杠+控制字符/非字符的单引号标量 — 此类值改用双引号输出;单引号无法转义控制字符/非字符。
- 非字符与 BOM 引用 —
needs_quotes/needs_double_quoted现对 U+FFFE/U+FFFF/平面末尾非字符及 U+FEFF(BOM)要求引用。 - 双引号转义宽度 — U+FFFF 以上的码点现以 8 位
\Uxxxxxxxx形式转义(4 位\u仅限 BMP)。 - 折叠 plain 标量续行缩进 — 续行缩进改由值起始列推导,使嵌套序列/映射项续行缩进超过父块缩进。
- 多字节折叠边界 —
wrap_plain_scalar对折叠切片做 char boundary 向下取整,避免 4 字节 UTF-8 跨边界时 panic。 - publish 测试依赖含
hypothesis—.ci/requirements-test.txt固定hypothesis>=6.113.0,使发布工作流能运行属性测试。
Added¶
scripts/fuzz_panics.py— 本地大规模 Hypothesis fuzz 脚本,含恶意策略覆盖 dump/parse/edit/幂等。
[v0.14.0] — 2026-08-14¶
Added¶
- YAML Schema Language — 定义自定义 schema,将正则模式映射到 YAML 类型。
通过
register_schema()注册。 - 内联 dict schema —
schema参数可直接传入dict。 - Community Plugins — 通过
CustomType基类注册自定义节点类型。 使用register_type()注册。 - 内置插件 — 默认注册
!timestamp(datetime)和!set。
Changed¶
- Schema 解析可插拔 —
SchemaResolvertrait +Schema枚举 + 全局SchemaRegistry。内置 schema 保持零开销分发。 node_to_pyobject和direct_dump检查CustomType— 带标签的标量通过from_yaml()转换,Python 对象通过to_yaml()序列化。
修复¶
- 带引号标量恒为字符串 — 隐式类型解析仅作用于纯标量(YAML 1.2)。
safe_load('"true"')返回字符串"true"(而非True)。序列化器保持文档(to_yaml)路径下的负数正确往返。 - 单引号/双引号单字符键可往返 — 值为单个
'或"的映射键以引号标量输出,不再产生无法解析的 YAML。 - 空集合输出
{}/[]— 空映射/序列序列化后不再是解析为None的空文档。
变更¶
get()仅接受字面键 —YamlDocument.get()不再将含./[的键视为 JSONPath;所有键都按顶层映射键处理(与__getitem__/__setitem__一致)。路径访问请使用find()/node()。
[v0.13.0] — 2026-08-10¶
变更¶
- Rust MSRV 提升至 1.96,edition 升级为 2024 — 两个 crate 均声明
rust-version = "1.96"和edition = "2024";CI 将build/test-freethreaded任务固定在 Rust 1.96 以生成确定性 wheel;新增msrv-check任务在 MSRV 上运行cargo check/cargo test防止静默漂移(rust-lint仍使用stable)。 版本基线高于 PyO3 0.29 自身的基线(rustc 1.83),目的是获得 std API 的前瞻性 支持(如assert_matches!,1.96 稳定),无需代码迁移。TAG_REGISTRY(标签处理器存储)重构为std::sync::LazyLock, 移除了Mutex<Option<...>>间接层。
Performance¶
safe_dump/from_dict/dump_file/dump_iterable: direct writer — Python→YAML 序列化无需中间CustomNodeAST。 单次direct_dump替换旧的两次传递pyobject_to_node+to_yaml。safe_dump提速 7 倍(28ns→4ns),from_dict提速 6 倍(35ns→6ns)。(#60)safe_load/safe_loads/to_dict: fast-path skip anchor tracking — 当输入不含&字符时,跳过collect_anchors和锚点解析, 使用更简单的node_to_pyobject_simple路径。(#59)resolve_core_type: first-byte dispatch whitelist — 非数字/ 非布尔首字节立即返回Str,避免常见情况下的 schema 解析开销。(#59)- 迁移到 granit-parser — 用 granit-parser 1.0.1 替换 saphyr-parser,
借助原生
Event::Comment输出消除了全文scan_yaml()预扫描。 parse_small -18%、parse_large -21%、roundtrip_large -18%。
Fixed¶
float_to_yaml_stringround-trip 修复 — Rust Display 丢失小数部分时 补.0(42→42.0),使 float 按 float 而非 int 正确往返。- 回退
count_nodes预分配 — 全 AST 遍历的开销大于其避免的重新分配 (serialize_10mb 慢约 14%);缓冲扩容交给 Vec。
Added¶
max_depth支持流式与 frontmatter API —parse_stream(yaml, on_event, max_depth)、read_markdown(path, schema, max_depth)、read_markdown_str(content, schema, max_depth)接受max_depth(默认 1000)。流式解析现通过核心parse_stream_with_options强制嵌套深度限制(此前流式事件没有深度限制)。- Pydantic 集成 —
dump_pydantic()将 Pydantic 模型序列化为 YAML 字符串(model_dump(mode='json')+safe_dump);parse_as()将 YAML 字符串解析为 Pydantic 模型实例。两者均使用延迟导入,无硬性 pydantic 依赖。(#61)
Internal¶
- 拆分
py/mod.rs— 单体 1786 行模块拆分为document.rs(YamlDocument)、yaml_instance.rs(YAML 类)、functions.rs(模块级函数)、stream_iterator.rs、walk_helpers.rs。mod.rs缩减至 128 行。(#61) needs_quotes()守卫 +double_quoted_scalar()构造器 —'true'/'42'/'null'等字符串现以双引号标量输出,避免 core schema 重新解析时被误读(pyobject_to_node+json_value_to_node)。- CodSpeed 基准统一到
codspeed-divan-compat—exclude-allocations去除分配器噪声;跨库基准合并到tests/test_benchmark_crosslib.py, 引入共享tests/data/yaml_samples.py夹具和流式覆盖。
[v0.12.1] — 2026-08-06¶
Added¶
set(create_missing=True)- 编辑路径上缺失的中间映射键会创建为嵌套映射 (例如,对a: 1设置a.b.c会创建b和c);索引段缺失仍报错, 路径上的标量中间层仍会引发异常。doc.walk()/doc.scalars()- Rust 后端的深度优先 AST 遍历, 返回Node对象,避免逐节点to_dict()解析。walk()返回所有节点;scalars()仅返回标量/null 节点。- Rust 核心模块测试 - 39 个新测试,覆盖
editing::navigate(key_eq、navigate、navigate_mut、normalize_index、mapping_key_index)、editing::region(行辅助函数、node_is_flow、extend_delete_over_comments、 nav_err)、editing::dirty(DirtyKind/DirtyUnit 构造函数)以及editing::metadata(with_metadata_from、needs_quoting)。 - Python doc.walk() 边界测试 - 9 个新测试,覆盖空文档、空值、 深度嵌套、流集合、混合类型。
Changed¶
- Monorepo workspace - 源码拆分为
crates/pyrs-yaml-core/(纯 Rust,无 PyO3)和crates/pyrs-yaml/(PyO3 绑定)。根Cargo.toml现在是 workspace。旧的src/目录和build.rs已移除。 - pyproject.toml - 新增
tool.maturin.manifest-path指向crates/pyrs-yaml/Cargo.toml。 - 解析热路径 - 单次注释/锚点提取、延迟重复键检测、
shift_insert合并预处理,以及单文档解析跳过DocumentEnd深拷贝,大文档 解析成本降低约 19%(CodSpeed: parse[large] +13.9%,parse[medium] +16.6%, roundtrip[large] +12.2%)。 Arc<str>标量存储 -CustomNode::Scalar和注释/事件 文本通过Arc<str>共享分配;AST 节点缩减 8 字节, 克隆变为引用计数递增而非深拷贝。
Fixed¶
set(create_missing=True)嵌套链构建 - 创建的映射链 不再将第一段重复为嵌套键层级。set(create_missing=True)资格检查 - 新创建的键现在 可参与值写入(资格检查不再在合成对插入后运行)。- 简单映射键前的独立注释 - 往返之前会丢弃附加到 简单键节点的独立注释;现在保留(两个回归测试)。
[0.11.7] - 2026-08-04¶
Changed¶
- stub-build-check 替换为 release-guard — 故意失败以复现
v0.10.0
--generate-stubs失败模式的总是失败的容器构建 (validate.yml)被三个静态断言替换,当仓库正确时通过:grep保护publish.yml不含--generate-stubs,git ls-files断言提交的.pyi已追踪,test -f检查py.typed存在。任务现在在正确状态下给出绿色 CI, 仅在回归时红色。
Added¶
- Numpy free-threaded 跟踪 — ROADMAP.md 现在跟踪
rust-numpyfree-threaded 支持状态(PyO3/rust-numpy#476),作为 Rust 绑定成熟后在 cp314t wheel 上重新启用 ndarray 序列化的依赖。
[0.11.6] - 2026-08-04¶
Changed¶
- Free-threaded(cp314t)wheel 不再包含 numpy — 使用
--no-default-features构建,rust-numpy 完全排除(更小的 二进制,无运行时探测)。free-threaded 构建上对numpy.ndarray调用safe_dump会引发YamlTypeError;GIL 构建(Python 3.8-3.15) 保留完整的 ndarray 序列化。
Added¶
- Free-threaded CI 验证 —
test-freethreaded任务现在使用--no-default-features构建和测试,与分发的 free-threaded wheel 配置匹配。 - 安装文档 —
docs/{en,zh,ja,ko}注明 free-threaded wheel 不含 numpy(cp314t 上不可用 ndarray 序列化)。
[0.11.5] - 2026-08-04¶
Changed¶
- 解析器健壮性项目 3/4/5 通过 Phase 0 严格性审计关闭 —
70 探针语料库(缩进、块映射键、流上下文)与 PyYAML 预言机对比,
显示无可修复的接受但无效案例(64/70 匹配;6 处分歧是
有意为之的 YAML 1.2 / yaml-test-suite 要求,PyYAML 是异常项,
另有一个有意为之的重复键严格性)。合规率保持在
99.75%(405/406)。完整说明见
ROADMAP.md§v0.11.5 和tests/test_strictness_audit.py。
Added¶
tests/test_strictness_audit.py— 70 探针严格性回归语料库, 固定当前拒绝/接受行为(两个方向),使未来解析器变更无法 静默降低严格性或过度拒绝。
[0.11.4] - 2026-08-04¶
Fixed¶
- 重复的空/空映射键不再报错(
: a\n: b、~: a\n~: b)— 与 yaml-test-suite 2JQS 匹配;真实重复键仍会引发YamlDuplicateKeyError - 合规检测工具:正确拒绝的无效 YAML 现在计为通过(之前尽管行为合规 却降低了通过率)
- 合规检测工具:
convert_special_chars通过正则表达式解码制表符 — 任何—/‖+»序列均为一个制表符,修复制表符编码的套件用例
Changed¶
- YAML Test Suite 通过率阈值从 >75% 提升至 ≥95%;当前通过率 99.75%(405/406)
- 记录已知偏差:
ZYU8(%YAML 1.1 1.2)按设计拒绝(YAML 1.2 语法无效,与 PyYAML/libyaml 一致)
[0.11.3] - 2026-08-03¶
Added¶
- 流式写入:
YAML.dump_stream(file_obj, iterable)/YAML.dump_file(path, iterable),文档级恒定内存,自动---分隔符,以及explicit_start/explicit_end标志 YamlDocumentwith上下文管理器:快照/回滚事务作用域compliance_report():公开 YAML Test Suite 通过率报告(版本一致)
Changed¶
- 编辑爆发行偏移缓存:拼接层内部 O(N+edit) 传递(公开 API 不变)
compute_compliance从测试移至pyrs_yaml.compliance;版本不再硬编码
Fixed¶
- 变更日志镜像漂移防护:prek 钩子 + CI 任务断言根/镜像
[Unreleased]同步 - 发布存根预验证:CI 在 Release 前复现 v0.10.0 类
--generate-stubs容器失败
[0.11.2] - 2026-08-03¶
Added¶
YAML.load_stream(file_obj)/YAML.load_stream_file(path): O(锚点数 + 块) 内存的惰性事件迭代器
Performance¶
- 解析不再计算拼接资格 — O(文档) 布局检查现在在首次编辑时通过
YamlDocument.splice_checked惰性运行,恢复 v0.11.0 回归: parse_comments -59%、parse_anchors -42%、parse/roundtrip/edit -10~35% 全部回到 v0.10.0 水平 - 线性游标布局检查 — 取代基于预计算行偏移的逐节点二分查找 (单调源码顺序遍历)
Changed¶
parse_with_options返回CustomNode(原为(CustomNode, bool)); 拼接资格现在内置于YamlDocument并按需计算
[0.11.0] - 2026-08-02¶
Added¶
- 精准序列化 — 字节级源码范围追踪;基于段的拼接 — 编辑仅重新生成 触碰区域,未触碰文本按字节复制
- proptest 保真度属性测试(新开发依赖)
- 10MB 编辑-刷新基准测试(divan)
Changed¶
flush_source现在使用分段拼接;回退到全量序列化:流风格区域、 非默认布局文档、合并键、CRLF/BOM 文档,以及 materialize 之后 (单次爆发模型)- 拼接编辑保留
---/.../指令标记行为未触碰字节 (全量序列化之前会丢弃它们 — 设计上的行为差异)
[0.10.0] - 2026-08-01¶
Added¶
- 就地编辑 — 编辑已解析的文档而不丢失格式元数据:
- 路径 API:
doc.set(path, value)、doc.insert(path, index, value)、doc.append(path, value)、doc.delete(path)、doc.rename(path, new_key), 使用 JSONPath 风格路径($.a.b[0]);根节点语法糖doc["key"] = value和del doc["key"] - 节点 API:
doc.node()/doc.find(path)返回Node对象, 支持set_value/append/insert/delete/rename, 以及树遍历(parent、children、walk、filter) - 完整元数据保留 — 被替换的标量保留注释/锚点/标签/引号; 重命名的键保留位置和注释;删除时映射顺序保留
- 原子编辑 — 失败的操作不会改动文档(及其修订号)
- 惰性源文本重新同步 —
source()/to_yaml()/reparse()仅在编辑成功后重新序列化 - 过期节点检测 — 文档编辑后访问
Node引发YamlDocumentError(并发出RuntimeWarning) - 新异常:
YamlEditError、YamlPathError(支持 en/zh-CN/ja-JP/ko-KR 国际化) - 别名感知编辑 — 设置别名自身路径会就地替换它;
穿过别名编辑引发
YamlEditError
- 路径 API:
- 编辑基准测试 —
benches/yaml_bench.rs新增 6 个 divan 基准 (小到大文档的 set/insert/delete)
Changed¶
YamlDocument.source()现在返回str并在就地编辑后惰性重新序列化
[0.9.0] - 2026-08-01¶
Added¶
- Python 3.13、3.14 和 3.15 支持 — PyO3
abi3-py38wheel 覆盖 Python 3.8-3.15(GIL 构建);abi3t+abi3t-py315提供 free-threaded 稳定 ABI - Free-threaded CPython(无 GIL)支持 —
#[pymodule(gil_used = false)]声明模块对 free-threaded Python 线程安全;Py_GIL_DISABLEDcfg 标志门控 numpy(rust-numpy 尚不支持 free-threaded — 通过--no-default-features为 free-threaded 构建禁用 numpy feature) - CI free-threaded 任务 — 新增
test-freethreaded工作流任务, 针对 Python 3.14t 验证编译和测试 pyo3-build-config构建依赖 — 通过build.rs启用#[cfg(Py_GIL_DISABLED)]、#[cfg(Py_3_15)]等编译器标志numpy改为可选 — 由numpyfeature 门控(默认启用); 在Py_GIL_DISABLED下自动排除allow_duplicate_keys—YAML(allow_duplicate_keys=True)、parse(..., allow_duplicate_keys=True)、parse_file、safe_load、safe_loads、parse_all_docs均接受该标志;重复映射键默认 引发YamlDuplicateKeyError,允许时采用"最后值生效"SerializeOptions扩展 —doc.to_yaml_with_options()新增width(行包裹,0 = 关闭)、indent_mapping、indent_sequence、indent_offset,与现有的indent_size/explicit_start/explicit_end/sort_keys/max_depth并列 (src/py/mod.rs:432)- 标签处理器注册表 —
register_tag("!custom")装饰器和命令式形式clear_tag_handlers();携带已注册标签的标量节点通过处理器转换 (src/py/tag_registry.rs)
- 标签处理器优先级链 — 同一标签的多个处理器按升序
priority执行;YamlTagSkip让处理器传递给下一个,fallback 保留原值 - Pydantic 集成 —
parse_as(Model, yaml, **yaml_kwargs)解析 YAML 并针对 Pydantic v2 模型验证;缺少 pydantic 时引发ImportError并附指导信息(python/pyrs_yaml/pydantic.py) .pyi类型存根 — 由 maturin 自动生成并提交,使register_tag、parse_as、to_yaml_with_options和新异常 对类型检查器可见
Changed¶
- CI Python 矩阵扩展:ubuntu、windows、macos 上的 3.8-3.14
- 稳定 ABI:
abi3-py39→abi3-py38(更广的 Python 3.8+ 支持), 新增abi3t+abi3t-py315(free-threaded 稳定 ABI) pyproject.tomlclassifiers 更新 3.13、3.14、3.15 条目- CI 优化:消除冗余 Rust 编译 — 单个
rust-lint任务运行cargo clippy+cargo test一次;build任务为每个 OS 生成一个 abi3 wheel,测试任务安装而非运行maturin develop, 将 Rust 编译从 21 个矩阵任务中移除(减少约 86% 编译量); 所有任务添加Swatinem/rust-cache - pydantic 测试依赖 —
pydantic>=2.10.6加入[dependency-groups] test和.ci/requirements-test.txt(通过uv sync在 ci.yml 中统一管理)
Fixed¶
- Windows DLL 加载 — 移除
src/py/tag_registry.rs中的#[cfg(test)]块,该块在 Windows 上破坏了import pyrs_yaml(250b8d0) - Python 3.8 兼容性 —
pydantic.py中添加from __future__ import annotations(63d2495) - CI pydantic 跳过 — 使用
pytest.importorskip("pydantic")使测试在未安装 pydantic 时通过(7be011d) - CI Windows glob 展开 —
pip install dist/*.whl使用shell: bash(PowerShell 不展开*)(2f7778d) - 非字符串标签处理器返回值现在引发
YamlTagError— 返回 非str值的处理器(之前被静默忽略,保留原标量)现在报错Tag handler '!x' must return a string(src/py/mod.rs:resolve_tags) to_yaml_with_options缩进连线 —indent_mapping/indent_sequence/indent_offset现在被序列化器尊重 (之前为死字段);省略时分别默认indent_size/0 (src/serializer.rs)width不再对极小值死循环 —width < 续行缩进时回退为 直接输出未包裹的剩余内容而非无限循环(src/serializer.rs:write_plain_scalar)remove_tag(name)— 新增函数用于注销标签处理器; 补充register_tag/clear_tag_handlers(src/py/tag_registry.rs)duplicate-key错误国际化 —YamlDuplicateKeyError消息 现通过format_i18n_error在所有 4 个语言区域中传递 (src/i18n/locales/*.yml)
[0.8.0] - 2026-07-30¶
Added¶
YAML()实例 API —YAML(typ="rt"|"safe"|"full", schema="core"|"yaml1.1", max_depth=1000), 可复用配置;.parse()、.safe_load()、.safe_loads()、.parse_file()、.parse_all_docs()方法- Python
NodeAPI —Node类,具有find()、filter()、walk()、to_yaml()、parent、children、root_type、value,用于 AST 导航;JSONPath 风格查询语言 ($.key.sub、$.arr[0]、$..deep) doc.version元数据 —YamlDocument.version()返回 YAML 规范版本(默认 "1.2")MergedView—doc.merged()返回解析合并键后的只读 类字典视图- 生命周期警告 —
Node.release()显式使节点失效;过期 访问发出RuntimeWarning+YamlDocumentError
Changed¶
parse()/safe_load()现在作为语法糖委托至YAML().parse()/.safe_load()YamlDocument现在存储version字段用于文档元数据
[0.7.1] - 2026-07-30¶
Added¶
- ryaml 基准对比 —
tests/test_benchmark.py现在与ryaml(Rust YAML 库) alongside PyYAML 和 ruamel.yaml 进行 基准测试;benchmark_compare.py重写为特性对比报告 (tests/test_benchmark.py:25-28、.github/workflows/ci.yml:219) - CI 合规阈值提升 — YAML Test Suite 合规阈值从 70% 提升至
75%(
test_compliance_report());有效解析率阈值 95% (tests/test_yaml_suite.py:251) - CI 依赖整合 — 新增
.ci/requirements-test.txt和.ci/requirements-test-lite.txt,用于发布工作流和本地开发 的统一测试依赖管理 - 基准测试现代化 — 从
pytest-benchmark迁移至pytest-codspeed以实现更快的 C 扩展统计基准测试; 所有 CI 任务现在使用-r .ci/requirements-test.txt - Rust 基准测试迁移至 Divan — 用
codspeed-divan-compatv5.0.1 替换codspeed-criterion-compat;16 个基准测试从 Criterion 组重写为#[divan::bench]属性 (Cargo.toml、benches/yaml_bench.rs)
Changed¶
- CI 基准任务安装
ryaml用于跨库对比 benchmark_compare.py现在委托计时至pytest-benchmark, 作为特性对比/报告工具
[0.7.0] - 2026-07-29¶
Added¶
- 序列化器
max_depth守卫 —serialize_node_internal现在 跟踪递归深度,超出限制时引发YamlMaxDepthError(默认 1000), 与解析器保护一致(src/serializer.rs:135-145) - 序列化器热路径优化 — 5 项针对块风格序列化的优化,约
4.9% 往返加速:
- 内联
write_anchor_tag和write_inline_commentNone 检查 (消除约 99% 节点的函数调用) write_indent热/冷路径分离(缓存级别 ≤64 直接索引)write_plain_scalar短 ASCII 字母数字字符串快速路径 (≤8 字符)write_scalar_for_keyPlain 标量直接分派(避免分派链)
- 内联
- pytest-benchmark 迁移 — Python 基准测试从原始
time.perf_counter()迁移至pytest-benchmark以获得统计严谨性、 结构化 JSON 输出和 CI 集成(tests/test_benchmark.py+ 更新的tests/test_performance.py)
Changed¶
pytest-benchmark替换 Python 基准测试中的原始timeit- CI 基准任务现在运行
pytest --benchmark-json而非独立脚本
Removed¶
write_inline_comment方法 — 在所有调用点内联- 序列化器的
Comment导入 — 不再需要
[0.6.0] - 2026-07-27¶
Added¶
- 异步序列化 —
safe_dumps_async、safe_dump_async、safe_loads_async、safe_load_async,通过asyncio.run_in_executor(python/pyrs_yaml/async_dump.py) - JSON Schema 验证 —
YamlValidateError异常 +YamlDocument.validate(schema)方法(接受str或dict); 委托至 Pythonjsonschema模块 YamlDocument.to_json()— 将文档序列化为 JSON 字符串 (使用 Pythonjson.dumps)- 增量重新解析 —
YamlDocument现在存储源文本 (doc.source());doc.reparse(resolve_merges=True, schema="core")就地重新解析 - 29 个新测试 — 跨
test_async.py(8)、test_validate.py(14)、test_reparse.py(7)
Changed¶
YamlValidateError注册为新自定义异常(继承ValueError)rust_i18n::i18n!宏路径更新为"src/i18n/locales"validate_translations()测试路径更新以匹配新语言目录
Removed¶
- 删除冗余的
src/i18n/en.ftl、src/i18n/zh-CN.ftl(从未被 rust-i18n 引用) - 将
locales/*.yml移至src/i18n/locales/(与 i18n 模块共置)
依赖变更¶
- 运行时依赖:
jsonschema>=4.25.1 - 开发依赖:
pytest-asyncio>=0.23(从运行时移至开发依赖,不再固定)
[0.5.0] - 2026-07-27¶
Fixed¶
Serializer::write_node—block_mapping/block_sequence中.unwrap()onvalues.iter().next().unwrap()替换为安全 索引访问,消除边缘 AST 的潜在 panicYAML_SCHEMA常量 — 拼写错误yamorg2002修正为yamlorg2002(匹配 YAML 1.2 规范 URL)- 开发文档 —
AGENTS.md更新,为 Python 命令添加强制uv run前缀,Rust 命令直接使用cargo
[0.4.0] - 2026-07-27¶
Added¶
- 132 个新功能填补测试 — 全面覆盖之前未测试的 API
- i18n 函数测试 —
set_language、get_language、list_languages、detect_language、negotiate_language parse_all_docs专用测试套件 — 单文档、多文档、空、注释parse_file成功用例测试 — 基本解析、注释保留、文件未找到错误to_yaml_with_options测试 —explicit_start、explicit_end、indent_size、sort_keys顺序保留to_dict()方法测试 — 标量根、嵌套、列表、布尔、空、 锚点解析、空映射/序列- YamlDocument dunder 方法测试 —
__repr__、__str__、__contains__、__len__、__iter__、__getitem__、root_type() - 字节输入测试 —
parse(b"key: value")、UTF-8 字节、无效 UTF-8 错误 - Unicode 及特殊字符测试 — 中日韩、emoji、往返、CRLF 换行、重复键
safe_load/safe_loads特性覆盖 — 锚点、合并键、块标量、 流集合、特殊浮点数、类型解析from_dict边界用例 — 键中的特殊字符、嵌套列表、None 值、 空字典/列表from_json往返 — 嵌套结构、数组、无效 JSON 错误dump_file测试 — 成功路径、无效路径错误- YAML Test Suite 单个用例测试 — 八进制、十六进制、科学计数法、
NaN、无穷大、合并键、显式/隐式键、布尔/空变体、块标量截断
(
|-)、流集合 resolve_merges参数测试 — 禁用时保留<<,默认时解析- 流集合往返 — 根级和嵌套流映射/序列
- 非标量节点上的锚点 — 映射锚点(
&defaults)和序列锚点(&items) - 序列索引测试 — 正索引、越界错误
- 合并键集成 — 解析和未解析合并键的往返
- 标签保留 —
!!seq和!!map标签测试覆盖 - 注释保留 — 复杂结构上的内联和独立注释测试
Changed¶
- 修复版本同步:
python/pyrs_yaml/__init__.py的__version__从 0.2.0 更新至 0.4.0 以匹配 Cargo.toml/pyproject.toml - 移除
dist/中过时的 0.2.0 wheel 产物
[0.3.0] - 2026-07-27¶
Added¶
- NumPy ndarray 序列化 —
safe_dump()/safe_dumps()/from_dict()/dump_file()现在支持所有维度的numpy.ndarray(0-D 至 N-D)- 支持的数据类型:
int8/16/32/64、uint8/16/32/64、float32/64、complex64/128、bool - 多维数组序列化为嵌套 YAML 列表,缩进正确
- 复数序列化为
(re+imj)字符串格式 0-D标量数组重塑为 1-D 并序列化为单元素列表- 通过
numpyRust crate 的PyUntypedArray+PyArrayDyn实现零拷贝 dtype 分派 - 切片迭代期间释放 GIL 以获得最大性能
- 支持的数据类型:
quoted_scalar()— 新增CustomNode::quoted_scalar()构造函数,用于需要单引号 YAML 风格的值- 引号标量的类型解析 —
resolve_yaml_type现在应用于SingleQuoted/DoubleQuoted标量,以正确往返引号负数 - 全面 NumPy 测试套件 — 42 个测试覆盖所有数据类型、 维度(0-D 至 4-D)、负数、无穷大、NaN、空数组及边界用例
Fixed¶
- 负数往返 — YAML 1.2 块序列不能包含以
-开头的纯标量; 序列化时负数现在加引号,解析时正确还原为整数/浮点数 - N-D 数组支持 — 用
PyArrayDyn<T>替换PyArray1<T>, 支持任意维度数组而不仅限于 1-D - 正确嵌套深度 — 多维数组现在产生恰好 N 层嵌套
(shape[1..] 处理内部维度,根维度由
plain_sequence包裹)
Changed¶
- 新增
numpycrate(v0.29)作为 ndarray 类型分派的依赖
[0.1.0] - 2026-07-25¶
Added¶
- 初始发布,通过 saphyr-parser 实现 YAML 1.2 合规
- 自定义 AST,完整元数据(注释、锚点、标签、chomping、标量风格)
- 注释、锚点、标签和格式的往返保留
- PyYAML 兼容 API(
safe_load/safe_dump) from_dict/from_json转换函数read_markdown/read_markdown_str用于 YAML frontmatter 提取- 块标量(
|/>)带 chomping 指示符(|-/|+/>-/>+) - 转义序列(
\n、\t、\uXXXX、\xXX) - YAML 1.2 类型解析(null、bool、int、float、infinity、NaN)
- 合并键解析(
<<: *alias) - 复杂键(序列/映射作为键)