pyrsistent
pyrsistent copied to clipboard
Transformation that not strict with missing fields
I would suggest a version of the transform
method, where there is no change if a field is missing.
My motivation is, that I like the idea of pyrsistent's tranformation, but I use document databases with optional fields and subfields and I would like to keep the original state where a field or parent field is missing. (Also pydantic
can use Optional fields.) Coming up with some weird lambda function instead of ny
would mess up the code.
I give you some examples:
data = v(
m(timeout="13", description="send email"),
m(description="start database"),
)
loose_transform(data, (ny, "timeout"), int)
# or
data.transform((ny, "timeout"), int, mode="loose")
would give back
data = v(
m(timeout=13, description="send email"), # The only place that changes is timeout here.
m(description="start database"),
)
doesn't do anything with the second element.
A second example:
data = m(
composer=m(birth=m(place="Salzburg", year=1777), name="Felix"),
lyrics=m(name="John"),
arranged_by=m(name="Jack", birth=m(year=1977))
)
result = loose_transform(data, [ny, "birth", "place"], str.upper)
gives back
m(
composer=m(birth=m(place="SALZBURG", year=1777), name="Felix"), # The only place that changes is place here.
lyrics=m(name="John"),
arranged_by=m(name="Jack", birth=m(year=1977))
)
doesn't create birth/place in lyrics and arranged_by. And I don't need to use a more difficult function instead of str.upper
to handle the missing fields.
I have a loose_transform
implementation and unit tests as gist.
Maybe pyrsistent
could use the same transform
method with an additional mode
keyword argument, that is "strict"
by default with the current behavior, and maybe "loose"
is the behavior I presented here. (I'm not a native English speaker, so I couldn't find better word than loose.)
I think that discard
could work with the same way, so using discard
instead of str.upper
in the second example would just remove place="Salzburg"
from the composer field.
Hi!
Thanks for opening this issue. The use case seems reasonable to me. Could you please create a PR with a suggested implementation for me to review (the gist looks fine in principle but I need to have a look at it in a pyrsistent-context) and eventually merge if you want it included in pyrsistent?
Using a new keyword arg to transform seems like the most discoverable way of doing I think.
My main concern is: the transform
function's current version works for every pyrsistant data structure. As I would like to use JSON-like structures, I don't need any other than PVector and PMap. Is is ok if for the other data structures it just raises an exception if I don't use the current strict
mode?
I'm not sure I can create any PR soon.