views:

667

answers:

2

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?

+3  A: 

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.

Alex Martelli
+5  A: 

Here is a 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)
Anurag Uniyal
cons: it relies on internal logic of CookieJar
Anurag Uniyal
pros: it's simple and elegant!
Alex
for some definitions of 'elegant' =P. I do like this approach too, though.
Claudiu