Skip to content

Deprecate and remove klass.SlotsPicklingMixin #117

@ferringb

Description

@ferringb

Py3k supports pickling directly from the slot structure of a class, without requiring a __getstate__ override. Thus

class SlotsPicklingMixin:
"""Default pickling support for classes that use __slots__."""
__slots__ = ()
def __getstate__(self):
return dict(get_attrs_of(self))
def __setstate__(self, state):
for k, v in state.items():
object.__setattr__(self, k, v)
is unneeded. That code exists- I think- as part of the bridge over py2k old/new style. Either way, it's dead.

Removing that removes at least 2 levels of python function calls in all serialize usage of those consumers- likely more. The underlying get_slots_of doesn't cache (some day, it may) so that's MRO walk of the class every instance serialization. It adds up, even if those functions themselves are fast.

Presumably this is sensitive to the slot ordering, but pickles are ephemeral- it's the consumers problem if they're changing swapping order and assuming the results to be stable. If that turns out to be an actual problem in real world code, a version of SlotsPicklingMixin can be implemented that forces the state to be by sorted slot order, assuming python doesn't already do this.

Removal of this is simple, exempting the usage of Immutable style class protections. There's two implementations possible here:

  • is the class fully slotted, and no custom __setstate__ is in? Install a __setstate__ that is allow_mutations(object.__setsetate__), roughly. It'll defer the core work steps to python while allowing mutation. This however will still lead to python invoking the Immutable.__setattr__ for every object, which isn't efficient. This is still faster than what's in place now for SlotsPicklingMixin however.
  • A solution there is to special case __setstate__ so it installs a function that is the loop of object.__setattribute__. Single function frame for a state restore, and arguably more 'correct' in my view since deserializing an object shouldn't be going through it's custom __setattr__- marshalling is a lower level then runtime manipulation of objects.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions