-
-
Notifications
You must be signed in to change notification settings - Fork 29.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
python doc does not say that the state kwarg in Pickler.save_reduce can be a tuple (and not only a dict) #80114
Comments
Hello all, (*) ac5b5d2 |
Does it still work? With both the C and Python pickler? |
It turns out that both pickle and _pickle implement this feature, but the behavior is inconsistent.
(- Finally, The second dict in state contains the slotted attribute. ) Here are the lines in the two files causing the inconsistent behavior: I included an example that illustrates it. |
You can have both a dict and slots by subclassing: >>> class A:
...: __slots__ = ('x',)
...:
>>> class B(A): pass
>>>
>>> b = B()
>>> b.x = 5
>>> b.y = 6
>>> b.__dict__
{'y': 6}
>>> A.x
<member 'x' of 'A' objects>
>>> A.x.__get__(b)
5 |
Interestingly, you can also put an instance dict in slots: >>> class A:
__slots__ = ['x', '__dict__']
>>> a = A()
>>> a.x = 5
>>> a.y = 6
>>> a.__dict__
{'y': 6}
>>> a.x
5 |
Thanks Antoine and Raymond for the feedback. Indeed, a subclass of a slotted class can have a dict: I enriched the script, pickling_depickling instances of such subclasses, with the length-2 tuple __getstate__ method, and made sure their attributes were properly retrieved. Apart from the different checks on state carried out in the c load_build and the python load_build, AFAICT, it seems like this feature works :) |
A slotted class will have a dict also when it inherits it from a non-slotted class. This is why the base class of slotted class should have slots if you do not want an instance dict. __getstate__ and __setstate__ for slotted classes are described in PEP-307. Unfortunately this was not copied to the module documentation. |
I added a PR with a small patch to document this behavior and reconcile _pickle.c and pickle.py Some explanations on why I am pushing this forward: Pickling instances of classes/subclasses with slots is done natively for pickle protocol >= 2. Mentioning this behavior in the docs should *not* make the user worry about implementing custom __getstate__ methods just to preserve slots. Here is the reason why I think this functionality (allowing state and slotstate) is worth documenting: pickle gives us a lot of flexibility for reducing thanks to the dispatch_table. But unpickling is rather rigid: if no __setstate__ exists, we have to deal with the default state updating procedure present in load_build. Might as well document all of it ;) |
See also bpo-26579 which propose to add a function or method for standard implementation of __getstate__ and use it consistently in custom __getstate__ implementations. I am not sure about API yet. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: