subclass of `Box` does not unpickle correctly

Open Beginner friendly
#308 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
70/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
python
Domain
tooling

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.

Description

Steps to reproduce

Execute this program:

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:  <class '__main__.MyBox'>
in .a:    <class '__main__.MyBox'>
out root: <class '__main__.MyBox'>
out .a:   <class '__main__.MyBox'>

Actual behavior

Output:

in root:  <class '__main__.MyBox'>
in .a:    <class '__main__.MyBox'>
out root: <class '__main__.MyBox'>
out .a:   <class 'box.box.Box'>

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:

    class MyBox(box.Box):
       def __new__(cls, *args, **kwargs):
          kwargs["box_class"] = MyBox
          return super().__new__(cls, *args, **kwargs)
    
Dominant language
Python
Stars
2.8k
Forks
135
PR merge metrics
No merged PRs in 30d

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from cdgriffith/Box

All issues in cdgriffith/Box

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.