ionelmc / python-lazy-object-proxy

A fast and thorough lazy object proxy.
BSD 2-Clause "Simplified" License
247 stars 36 forks source link

Support for pickling #7

Closed alvinchow86 closed 9 years ago

alvinchow86 commented 9 years ago

I noticed that pickling a Proxy class does not always work, depending on what the underlying object is. This is in Python 2.7.

from datetime import datetime
from lazy_object_proxy import Proxy
import pickle

p = Proxy(lambda: datetime(2015, 1, 2))
pickled = pickle.dumps(p, -1)
print pickle.loads(pickled)
...venv/lib/python2.7/copy_reg.pyc in _reduce_ex(self, proto)
     68     else:
     69         if base is self.__class__:
---> 70             raise TypeError, "can't pickle %s objects" % base.__name__
     71         state = base(self)
     72     args = (self.__class__, base, state)

TypeError: can't pickle datetime objects

For me. the desired behavior would be to immediately evaluate the wrapped object and pickle that object. After reading a bit on the pickle documentation, I was able to get something to work for all the types I've encountered in my application - basically had to add a __reduce_ex()__ and __reduce()__ method on my Proxy subclass, with a couple of special cases for certain types. (The more important one was reduce_ex as that is called first). If you're interested I could share this code. That said I'm not an expert on Python's pickle functionality and why it seems to be so different for different data types.

Just wanted to bring this up, I'm not sure if this should be something built into the library or left as something for users to implement in their subclasses (maybe with some documentation on how to do this).

ionelmc commented 9 years ago

Alright, this is fixed in the master - the pickle will contain the proxied value, without any Proxy wrapping.