diff --git a/openspace/skill_engine/skill_utils.py b/openspace/skill_engine/skill_utils.py index 718f4de..485d986 100644 --- a/openspace/skill_engine/skill_utils.py +++ b/openspace/skill_engine/skill_utils.py @@ -77,7 +77,12 @@ def _yaml_unquote(value: str) -> str: (value[0] == "'" and value[-1] == "'"): inner = value[1:-1] if value[0] == '"': - inner = inner.replace('\\"', '"').replace("\\\\", "\\") + inner = ( + inner.replace("\\\\", "\0") + .replace('\\"', '"') + .replace("\\n", "\n") + .replace("\0", "\\") + ) return inner return value diff --git a/tests/skill_engine/test_set_frontmatter_multiline.py b/tests/skill_engine/test_set_frontmatter_multiline.py index 137df77..3af74b7 100644 --- a/tests/skill_engine/test_set_frontmatter_multiline.py +++ b/tests/skill_engine/test_set_frontmatter_multiline.py @@ -2,7 +2,13 @@ from __future__ import annotations -from openspace.skill_engine.skill_utils import parse_frontmatter, set_frontmatter_field +import builtins + +from openspace.skill_engine.skill_utils import ( + get_frontmatter_field, + parse_frontmatter, + set_frontmatter_field, +) def test_set_frontmatter_field_preserves_multiline_description(): @@ -16,3 +22,17 @@ def test_set_frontmatter_field_replaces_block_scalar_without_orphan_lines(): assert parse_frontmatter(out)["description"] == "new1\nnew2" assert "old1" not in out assert "old2" not in out + + +def test_multiline_round_trip_without_pyyaml(monkeypatch): + real_import = builtins.__import__ + + def no_yaml(name, *args, **kwargs): + if name == "yaml" or name.startswith("yaml."): + raise ImportError("forced missing yaml") + return real_import(name, *args, **kwargs) + + monkeypatch.setattr(builtins, "__import__", no_yaml) + out = set_frontmatter_field("---\nname: x\n---\n", "description", "line1\nline2") + assert get_frontmatter_field(out, "description") == "line1\nline2" + assert parse_frontmatter(out)["description"] == "line1\nline2"