Skip to content

v0.5.1

Latest

Choose a tag to compare

@jlevy jlevy released this 26 Oct 06:25
a9e062a

What's Changed

Fixes

  • Metadata lines split only at real line endings: fmf_write and
    fmf_insert_frontmatter split the YAML text with str.splitlines(), which also breaks
    at LS, PS, NEL, VT, FF and the FS, GS and RS separators. A value holding one of them got
    a real line break in the file and read back changed, with no error. The writers now
    split only at LF, CRLF and CR, the line endings the readers recognize.
  • Strings with line-break and control characters read back exactly: ruamel wrote NEL,
    LS, PS and CR raw outside double quotes, where a reader takes them as line breaks: a NEL
    read back as a space, and a CRLF in a multi-line string came back as LF. A multi-line
    string holding a NEL or a character outside YAML 1.2’s c-printable set (the C0 and C1
    controls but tab, LF, CR and NEL; DEL; U+FFFE and U+FFFF) was written as YAML that did
    not parse. Such strings are now written double-quoted with escapes (see below).
  • A # preamble is kept: fmf_insert_frontmatter and fmf_strip_frontmatter
    dropped a shebang or PEP 723 block that came before hash-style frontmatter. Both now
    keep those lines.
  • Atomic writes keep the file mode: fmf_write, fmf_insert_frontmatter,
    fmf_strip_frontmatter and write_yaml_file used one fixed temp name per target, so
    concurrent writes to one file could collide and fail, and they reset a replaced file’s
    mode, so a 0755 script came back as 0644. Every write now goes through its own
    exclusively created temp file beside the target, removed on any error, and keeps the
    replaced file’s mode. On a filesystem that refuses chmod, such as some FUSE mounts, the
    write still happens with the default mode, as does a new file (0o666 less the umask).
  • The C-first gate admits only ruamel.yaml.clib: The gate checked the libyaml
    version string, which ruamel.yaml.clibz also reports, though it is a different build
    (compiled with Zig, with a free-threading flag) that the search behind the guards never
    covered. No ruamel release hands clibz’s parser to YAML() yet, but one that did would
    have put the readers on it. They now use libyaml only through clib’s own parser and
    read pure otherwise. Results are unchanged; only speed is affected.
  • ruamel.yaml 0.19.0 is excluded: It was the one release that depended on clibz by
    default, which builds from source with Zig at install time. The dependency is now
    ruamel-yaml>=0.18.10,!=0.19.0.

Behavior Changes

  • Escaped output for those strings: A string holding NEL, LS, PS, CR or any
    character outside c-printable is now always written double-quoted, as \N, \L,
    \P, \r, \0, \x1F and so on, whatever style was asked for. This applies to keys
    and values in every writer and every new_yaml instance. For the control characters
    it changes only output that could not be read back. Every other string’s output bytes
    are unchanged.
  • Blank, comment-only and null frontmatter read as None: ---\n\n---,
    ---\n# note\n--- and ---\n~\n--- (or null) raised FmFormatError, while empty
    frontmatter (---\n---) returned None metadata. All of them now return None. Any
    other value that is not a mapping still raises.
  • fmf_has_frontmatter returns False for an unclosed delimiter: A file that starts
    with a Markdown --- thematic break and has no closing delimiter made it raise. It now
    returns False. fmf_read still raises on such a file.
  • Inserting a non-hash style after # lines raises: On a file that begins with a
    shebang or PEP 723 block, fmf_insert_frontmatter with any style but hash now raises
    FmFormatError and leaves the file unchanged, since only hash-style frontmatter can
    follow those lines. Before, it dropped them.

Performance

  • Cheaper routing checks: The check that decides whether a text may go to libyaml
    settles typical frontmatter from character counts, in about 1 µs instead of 27 µs. It
    routes every text as before.
  • fmf_read_raw opens the file once: It reads the body from the same stream as the
    frontmatter instead of opening the file again.

Full commit history: v0.5.0...v0.5.1