cdgriffith / Box

Python dictionaries with advanced dot notation access
https://github.com/cdgriffith/Box/wiki
MIT License
2.61k stars 106 forks source link

`__add__` and `__or__` operators for frozen boxes #238

Closed ptrba closed 1 year ago

ptrba commented 1 year ago

Frozen boxes are great for enforcing a functional style of programming at runtime. But the implementation of Box.__add__ assumes that the left-hand side is non-frozen.

The following piece of code fails in box/box.py:274: box.box.Box.__add__ with box.exceptions.BoxError: Box is frozen

foo = box.Box(frozen_box=True)
foobar = foo + {"bar": 1}

As far as I can judge, there is no reason to restrict __add__ (and __or__) operations to non-frozen boxes. The implementation of Box.__add__ creates a copy of the input box before merging/updating, thus the operations leave the input boxes unmodified.

This implementation of Box.__or__ would solve the issue:

...
new_box = other.copy()
new_box._box_config["frozen_box"] = False
new_box.update(other)
new_box._box_config["frozen_box"] = other._box_config["frozen_box"]
...

I've made a quick check that this works for flat and nested structures. But there might be some unintended side effects for nested structures. But this would be an issue even for non-frozen boxes. I guess most programmers will assume that writing foobar = foo + {"bar": 1} won't mutate foo.

What are the objections against frozen boxes in Box.__add__ (Box.__or__)? And, how should this be implemented?

cdgriffith commented 1 year ago

noobjection

Simply never thought of that case.

I think the way you have it is nearly same as I would (would just use self._box_config["frozen_box"] instead of other.)

cdgriffith commented 1 year ago

Adding this feature in Box 7! Please test and give feedback if possible pip install python-box[all]~=7.0.0rc0

cdgriffith commented 1 year ago

Added in 7.0.0