Skip to content

Support complex values (dicts/lists) in upsert and replace #18

Description

@nathanjmcdougall

Problem

Currently, Document.upsert() and Document.replace() only accept scalar values (strings, ints, floats, bools, null). Passing a dict or list raises:

yamltrip.errors.PatchError: input is not valid YAML

This forces consumers to implement workarounds like:

  1. Manually serializing the complex value to YAML text
  2. Removing the key with prune_remove
  3. Concatenating the serialized text onto the remaining document
  4. Re-parsing with yamltrip.loads()

This document-rebuild approach loses the round-tripping benefits of yamltrip (e.g. comments on the replaced value are lost, and formatting may change).

Desired Behavior

`python
import yamltrip

doc = yamltrip.loads('repos: []\n')

Should work — currently raises PatchError

doc = doc.upsert('repos', value=[{'repo': 'local', 'hooks': [{'id': 'my-hook'}]}])

Similarly for replace

doc = yamltrip.loads('config:\n key: value\n')
doc = doc.replace('config', value={'key': 'new', 'extra': 'field'})
`

Complex values should be serialized in block style and inserted/replaced at the correct indentation level, preserving comments and formatting on other keys in the document.

Use Case

In usethis-python, we manage .pre-commit-config.yaml files where the
epos\ key contains a list of dicts. Operations like adding/removing hooks require setting
epos\ to a new list of complex repo configurations. Without complex value support, we're forced to rebuild documents from scratch, losing inline comments.

See: usethis-python/usethis-python#1937

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions