Skip to content

Private dispatch table not checked #437

@wuisawesome

Description

@wuisawesome

I'm attempting to register a custom reducer with cloudpickle. In my use case, I need multiple CloudPickler's to serialize an object with different behavior, so I can't override the class-level global dispatch table.

To demonstrate, assume I have the following class:

class CustomClass:
    def __init__(self, *args):
        self.x = len(args)

c = CustomClass()

I can define a custom reducer and register it with a private dispatch table:

def custom_reducer(obj):
    return CustomClass, (0,)

io_buffer = io.BytesIO()
custom_pickler = pickle.Pickler(io_buffer)
custom_pickler.dispatch_table = {CustomClass: custom_reducer}
custom_pickler.dump(c)

io_buffer.seek(0)
c1 = pickle.load(io_buffer)
assert c1.x == 1

I can also prove that this doesn't affect the global dispatch table:

c2 = pickle.loads(pickle.dumps(c))
assert c2.x == 0

Unfortunately, when I try the same behavior with cloudpickle, it doesn't respect the private dispatch table:

io_buffer = io.BytesIO()
custom_pickler = cloudpickle.CloudPickler(io_buffer)
custom_pickler.dispatch_table = {CustomClass: custom_reducer}
custom_pickler.dump(c)

io_buffer.seek(0)
c3 = cloudpickle.load(io_buffer)
assert c3.x == 1 # assertion fails becase c3.x == 0

(reference to how this was implemented in pickle)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions