-
-
Notifications
You must be signed in to change notification settings - Fork 625
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
Allow Schema.from_dict() to be pickled #1469
Allow Schema.from_dict() to be pickled #1469
Conversation
Thanks. I'd be happy to merge the fix if it doesn't add too much complexity to the code. Are you working on the fix? |
Great! I'll work on it today |
@sloria Just so I have a better idea of what's going on, what's reason for creating a class with a dynamic name? https://github.com/marshmallow-code/marshmallow/blob/dev/src/marshmallow/schema.py#L444 |
Or I guess I can just come out and ask the question rather than asking a leading question: I thought I don't have a solution if this is a problem, but maybe you do? |
btw thanks for creating your blog! I just found this post via a google search and it helped me at work |
https://docs.python.org/3/reference/datamodel.html#object.__repr__ AFAIK no classes or class instances produce valid expressions in the default implementation of
https://docs.python.org/3/library/pickle.html#comparison-with-marshal This makes it sound like it is unpicklable since the type is generated. It might be possible to override https://docs.python.org/3/library/pickle.html#object.__reduce__ |
Thanks for posting that documentation. I tried using the Example class Foo(object):
def __reduce__(self):
print("here")
return "A"
pickle.dumps(Foo) # pickles the class and outputs: b'\x80\x03c__main__\nFoo\nq\x00.'
pickle.dumps(Foo()) # outputs: here and throws an error about not being able to find `A` In the case of |
Here's a more relevant example showing that class Foo(object):
def __reduce__(self):
return 'Foo'
pickle.dumps(type('A', (Foo,), {}))
Can't pickle <class '__main__.A'>: attribute lookup A on __main__ failed |
FWIW, you can pickle a In [1]: from marshmallow import Schema, fields
In [2]: import pickle
In [3]: import cloudpickle
In [4]: pickled = cloudpickle.dumps(Schema.from_dict({"foo": fields.Str()}))
In [5]: pickle.loads(pickled)().load({"foo": "hello"})
Out[5]: {'foo': 'hello'} The result from |
Hm, that cloudpickle is purpose-built to handle dynamically-created classes suggests that we shouldn't need to handle pickle-ability here. @smith-kyle wdyt? Would using cloudpickle meet your use case? |
Possibly although cloudpickle introduces the constraint that the dumped object needs to be loaded in the exact same python version. TBH I'd sooner just tweak my object so that when it's pickled it saves the dictionary passed to Thanks for linking cloudpickle @hdoupe |
Unless a maintainer sees a path forward I'll close this out |
No problem! You can set the protocol to |
Fixes #1468
Right now it's just a failing test. I'm opening this now to have a place to get early feedback