-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Currently, applying a patch with an operation like {insert} fails when the target key does not exist in the input document. It would be useful if cels could optionally perform an upsert-like behavior — that is, automatically create missing keys when applying certain operations.
Reproduction
from cels import patch_document
patch = """\
list {insert}: c
"""
case1 = """\
foo:
bar: 1
baz: 2
list:
- a
- b
"""
case2 = """\
foo:
bar: 1
baz: 2
"""
def run_case(name, input_yaml):
print(f"=== {name} ===")
output = patch_document(
input_format="yaml",
input_text=input_yaml,
patch_format="yaml",
patch_text=patch,
output_format="yaml",
)
print(output)
run_case("case1 (list exists)", case1)
run_case("case2 (list missing)", case2)Result:
=== case1 (list exists) ===
foo:
bar: 1
baz: 2
list:
- a
- b
- c
=== case2 (list missing) ===
Traceback (most recent call last):
File "/Users/ookinozomu/project6/tmp/python/main.py", line 34, in <module>
run_case("case2 (list missing)", case2)
File "/Users/ookinozomu/project6/tmp/python/main.py", line 24, in run_case
output = patch_document(
^^^^^^^^^^^^^^^
File "/Users/ookinozomu/project6/tmp/python/.venv/lib/python3.12/site-packages/cels/services/patch_document.py", line 105, in patch_document
output_dict = patch_dictionary(
^^^^^^^^^^^^^^^^^
File "/Users/ookinozomu/project6/tmp/python/.venv/lib/python3.12/site-packages/cels/services/patch_dictionary.py", line 27, in patch_dictionary
return patch_dictionary_rec(
^^^^^^^^^^^^^^^^^^^^^
File "/Users/ookinozomu/project6/tmp/python/.venv/lib/python3.12/site-packages/cels/services/patch_dictionary.py", line 69, in patch_dictionary_rec
change.apply(output_dict, key, patch, path, root_input_dict)
File "/Users/ookinozomu/project6/tmp/python/.venv/lib/python3.12/site-packages/cels/models/change.py", line 122, in apply
action(
File "/Users/ookinozomu/project6/tmp/python/.venv/lib/python3.12/site-packages/cels/models/actions/__init__.py", line 17, in wrapped_func
return action_func(
^^^^^^^^^^^^
File "/Users/ookinozomu/project6/tmp/python/.venv/lib/python3.12/site-packages/cels/models/actions/action_insert.py", line 14, in action_insert
safe_extend(container[index], None, [change_value])
~~~~~~~~~^^^^^^^
KeyError: 'list'
Expected behavior
It would be helpful if cels could create the missing key when applying a patch, for example:
# patch
list {insert}: cIf list does not exist, it would automatically be created as a list and then have the element appended.
Result:
foo:
bar: 1
baz: 2
list:
- cPossible approaches
-
Make upsert the default behavior
When an {insert} (or similar) operation targets a missing key, cels would automatically create it with a suitable type (list, mapping, etc.). -
Introduce a new {upsert} operator
A new operator could combine the semantics of {add} and {insert} — creating the key if missing, or inserting into it if it already exists.