h2non / jsonpath-ng

Finally, a JSONPath implementation for Python that aims to be standard compliant. That's all. Enjoy!
Apache License 2.0
582 stars 85 forks source link

JSONPath.update() supports create #71

Closed kaapstorm closed 3 years ago

kaapstorm commented 3 years ago

Currently, JSONPath.update() updates existing values.

This PR adds support for using JSONPath.update() to create new values, for the purpose of building out a JSON document. Here is an example based on tests in tests/test_create.py:

>>> data = {}
>>> jsonpath = parse('$.name[0].text')
>>> data = jsonpath.update(data, 'Sir Michael', create=True)
>>> data
{'name': [{'text': 'Sir Michael'}]}
>>> jsonpath = parse('$.birthDate')
>>> data = jsonpath.update(data, '1943-05-05', create=True)
>>> data
{'name': [{'text': 'Sir Michael'}],
 'birthDate': '1943-05-05'}

Creating new items is only implemented for JSONPath subclasses that make sense for this use case. For example, using Slice to create many values is not supported in this change, nor is using Filter to create items to satisfy filter criteria (although you can still use Filter to select existing items).

This branch is based off the "exceptions" branch (PR #70). The last four commits are new. I have tried to break commits up logically to make them easier to review.

kaapstorm commented 3 years ago

I've realised a problem with the approach I've taken here.

By calling find() on subclasses with its new create parameter, this change requires all subclasses to add the create parameter to their find() method. This is not a realistic expectation for subclasses outside of this codebase (i.e. subclasses implemented in codebases that use this library).

I am going to revert the find() method back to original signature, and I think I'll implement this by setting an instance attribute instead of passing a parameter. I should have a chance to do this over the next week. I will close this pull request for now, and open a new one when that's done.