ruamel 压缩注释并注入 0x07

ruamel condensing comments and injecting 0x07

给定以下代码:

from ruamel.yaml import YAML

yaml = YAML()
with open(filename) as f:
    z = yaml.load(f)
yaml.dump(z, sys.stdout)

以及以下文件:

a: >
  Hello.<b>
  World.

<b> 是 space 字符 (0x20) 时,生成以下 YAML:

a: >
  Hello. <0x07> World.

<0x07>为字节0x07时。 尝试使用 PyYAML 重新加载此 YAML 会导致错误,因为 0x07 是无效字符。

当我删除输入 YAML 中 Hello. 后的尾随空白时,不会发生这种情况。

知道是什么原因造成的吗?

BEL 字符 (0x07\a) 在块样式折叠字符串的解析过程中被插入,因此 Python 中该标量的表示形式 (ruamel.yaml.scalarstring.FoldedScalarString ) 可以记录原始折叠确实发生的位置。在转储时,反向操作:位置被转换为 BEL 字符(如果它们对应于 spaces),因此将这些折叠位置从表示器传输到发射器,然后输出带有 [= 的标量32=] 在原始点发生。这当然 can/should 只有在职位仍然代表 "foldable" 职位的情况下才会发生。

这里的问题是解析器应该在加载期间抱怨您的 YAML 不正确。它没有这样做,加载了错误的数据,然后未能正确转储它首先允许加载的混乱,导致 BEL 字符最终出现在输出中。

YAML specification 状态:

Folding allows long lines to be broken anywhere a single space character separates two non-space characters.

并且由于您的行没有在两个非 space 字符之间折叠,如果不是立即出现解析器错误,这应该会导致警告。¹

此外,如果要替换的 space 与白色 space 相邻,则代表当然应该足够聪明,不会用 BEL 字符替换 space。在使用折叠字符串更改从正确 YAML 加载的字符串后,也会发生这种情况。我基本上认为这是一个错误。

ruamel.yaml>0.15.80 修复了不正确的表示。加载 error/warning 的实现可能很快就会跟进。


¹ 当只发出警告时,我最初的反应是我应该去掉错误的尾随 space,或者 spaces 以防有更多,因为它是不可见,并保持折叠。