plesty.server.model.yaml_edit ============================= .. py:module:: plesty.server.model.yaml_edit .. autoapi-nested-parse:: Change values in a YAML configuration's text, and nothing else. A form that edits two values of a configuration must not re-serialise the whole file: that drops every comment and rewrites what nobody touched (``[a, b]`` into a block list, ``1.0e+9`` into ``1000000000.0``). So a value is replaced where it stands, on its own line, with the rest of the line — its comment — kept; a key the file does not have is added at the end of its group. Only what this can do safely is done this way: a key one or two levels deep. A value written as a block below its key is replaced by one flow line, so only that key is laid out anew. Anything else — a block scalar, an anchor, a result that does not parse back to what was asked — returns ``None``, and the caller falls back to re-serialising. Attributes ---------- .. autoapisummary:: plesty.server.model.yaml_edit.Change plesty.server.model.yaml_edit._LINE Functions --------- .. autoapisummary:: plesty.server.model.yaml_edit.flow plesty.server.model.yaml_edit.set_values plesty.server.model.yaml_edit._set_one plesty.server.model.yaml_edit._find plesty.server.model.yaml_edit._block_end plesty.server.model.yaml_edit._child_indent plesty.server.model.yaml_edit._append Module Contents --------------- .. py:data:: Change .. py:data:: _LINE .. py:function:: flow(value: Any) -> str *value* as one line of YAML: ``0.5``, ``[1, 2]``, ``{a: 1}``, ``'yes'``. .. py:function:: set_values(text: str, changes: collections.abc.Sequence[Change]) -> str | None *text* with each change made in place, or ``None`` when one cannot be. :param text: The configuration as written. :param changes: What to set, each ``(group, key, value)``. :returns: The edited text, which parses to the document with the changes made; ``None`` when a change cannot be placed on a line of its own. .. py:function:: _set_one(lines: list[str], group: str | None, key: str, value: Any) -> bool Make one change in *lines*; ``False`` when it cannot be made in place. .. py:function:: _find(lines: list[str], start: int, end: int, indent: str, key: str) -> tuple[int, re.Match[str]] | None The line in ``lines[start:end]`` holding *key* at exactly *indent*. .. py:function:: _block_end(lines: list[str], index: int) -> int Where the block opened by the key on line *index* ends. .. py:function:: _child_indent(lines: list[str], start: int, end: int) -> str The indentation of the first key in ``lines[start:end]``. .. py:function:: _append(lines: list[str], at: int, indent: str, line: str) -> None Insert ``indent + line`` before *at*, ending the line before it if it is open.