How to pickle a CookieJar?
Asked Answered
A

2

9

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?

Antrorse answered 21/6, 2009 at 4:46 Comment(4)
Wow!! The question sounds like question for working in the kitchen. I am amazed the names used for the tools :)Quito
Did you get a good solution? If so, please post.Musicale
@Paul both Alex's and Anurag's solutions work. While Anurag's solution is hackish and faster, Alex's solution is more general and slower, so I will leave it up to the community to decide which is better.Antrorse
at first glance I thought this was a joke questionPooi
C
9

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)
Cindycine answered 21/6, 2009 at 5:1 Comment(3)
cons: it relies on internal logic of CookieJarCindycine
pros: it's simple and elegant!Trachyte
for some definitions of 'elegant' =P. I do like this approach too, though.Pooi
M
7

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.

March answered 21/6, 2009 at 4:56 Comment(1)
I feel this is a much better answer than the one that was accepted. It's possible that pickling is really what he needs, but it seems rather unlikely. The FileCookieJar subclasses are simpler, reliable, portable, and ready out of the box.Hamlani

© 2022 - 2024 — McMap. All rights reserved.