Skip to content

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

@nathanjmcdougall

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

Metadata

Metadata

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions