subclass of `Box` does not unpickle correctly
- Dominant language
- Python
- Stars
- 2.8k
- Forks
- 135
- PR merge metrics
- No merged PRs in 30d
Description
## Steps to reproduce
Execute this program:
```python
import box
import pickle
class MyBox(box.Box):
...
b_in = MyBox()
b_in.a = dict()
print("in root: %s" % type(b_in))
print("in .a: %s" % type(b_in.a))
p = pickle.dumps(b_in, protocol=pickle.HIGHEST_PROTOCOL)
b_out = pickle.loads(p)
print("out root: %s" % type(b_out))
print("out .a: %s" % type(b_out.a))
```
## Expected behavior
Output:
```
in root:
in .a:
out root:
out .a:
```
## Actual behavior
Output:
```
in root:
in .a:
out root:
out .a:
```
i.e., the type of key `a` is `box.box.Box` when it should be `__main__.MyBox`.
## Comments
1. I believe the problem lies in this line:
https://github.com/cdgriffith/Box/blob/a4c10e977b574114613431394b30412b50aaacce/box/box.py#L236
where `Box` should insted be `cls`.
2. Instantiating `b_in` with `box_class=MyBox` does not help, I assume because there is something about class instantiation I don’t understand. However it did seem like it should work.
3. This does, however, work around the bug:
```python
class MyBox(box.Box):
def __new__(cls, *args, **kwargs):
kwargs["box_class"] = MyBox
return super().__new__(cls, *args, **kwargs)
```
Contributor guide
Research direction
Run the reproduction program from the issue, then inspect box/box.py around line 236 where nested boxes are constructed during unpickling. Confirm that a Box subclass remains the type of nested values after pickle.dumps and pickle.loads; done means the reported output shows MyBox for both the root and key a.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 70/100