How to pickle a CookieJar?
-
06-07-2019 - |
Question
I have an object with a CookieJar that I want to pickle.
However as you all probably know, pickle chokes on objects that contain lock objects. And for some horrible reason, a CookieJar has a lock object.
from cPickle import dumps
from cookielib import CookieJar
class Person(object):
def __init__(self, name):
self.name = name
self.cookies = CookieJar()
bob = Person("bob")
dumps(bob)
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# cPickle.UnpickleableError: Cannot pickle <type 'thread.lock'> objects
How do I persist this?
The only solution I can think of is to use FileCookieJar.save and FileCookieJar.load to a stringIO object. But is there a better way?
Solution
Here is an attempt, by deriving a class from CookieJar, which override getstate/setstate used by pickle. I haven't used cookieJar, so don't know if it is usable but you can dump derived class
from cPickle import dumps
from cookielib import CookieJar
import threading
class MyCookieJar(CookieJar):
def __getstate__(self):
state = self.__dict__.copy()
del state['_cookies_lock']
return state
def __setstate__(self, state):
self.__dict__ = state
self._cookies_lock = threading.RLock()
class Person(object):
def __init__(self, name):
self.name = name
self.cookies = MyCookieJar()
bob = Person("bob")
print dumps(bob)
OTHER TIPS
CookieJar
is not particularly well-designed for persisting (that's what the FileCookieJar
subclasses are mostly about!-), but you can iterate over a CookieJar
instance to get all cookies (and persist a list of those, for example), and, to rebuild the jar given the cookies, use set_cookie
on each. That's how I would set about persisting and unpersisting cookie jars, using the copy_reg
method to register the appropriate functions if I needed to use them often.