My favorites | Sign in
Project Logo
                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/usr/bin/env python
''' This module implements a serializable Thread subclass.
http://jessenoller.com/2008/10/08/threads-cant-be-serialized/
'''

import threading

def loads_function(spec):
''' Wraps a common usage of __import__.
>>> loads_function('time.sleep') is __import__('time').sleep
True
'''
spec = spec.split('.')
return getattr(__import__('.'.join(spec[:-1])), spec[-1])

def dumps_function(fun):
''' Inverse of loads_function.
>>> print dumps_function(__import__('time').sleep)
time.sleep
'''
if fun is None:
return None
return '%s.%s' % (fun.__module__, fun.__name__)

def override():
import copy_reg
import types
for t in [types.BuiltinFunctionType, types.FunctionType, types.ClassType]:
copy_reg.pickle(t, dumps_function, loads_function)

class Thread(threading.Thread):
FORMAT = ('%(self)s(target=%(target)r, '
'name=%(name)r, '
'args=%(args)r, '
'kwargs=%(kwargs)r, '
'verbose=%(verbose)r, '
'daemon=%(daemon)r)')

def __setstate__(self, state):
self.__init__(target=state.pop('target'),
name=state.pop('name', None),
args=state.pop('args', ()),
kwargs=state.pop('kwargs', None),
verbose=state.pop('verbose', None))
for k, v in state.iteritems():
setattr(self, k, v)

def __getstate__(self):
#assert not self.started.is_set(), "Cannot pickle running threads."
return dict(
daemon=self.isDaemon(),
name=self.getName(),
args=self.__args,
kwargs=self.__kwargs,
verbose=self._Verbose__verbose,
target=self.__target,
)

def __repr__(self):
d = self.__getstate__()
d['self'] = dumps_function(self.__class__)
d['target'] = dumps_function(d['target'])
return self.FORMAT % d

if __name__ == '__main__':
import time
from cPickle import loads, dumps
for f in [time.sleep, loads, dumps, Thread, threading.Thread]:
assert f is loads(dumps(f))
for i in xrange(2):
for t in [Thread(target=time.sleep, args=(1,)), Thread(),
Thread(target=loads_function, args=(dumps_function(loads_function),)),
Thread(target=dumps_function, args=(dumps_function,)),
Thread(target=Thread)]:
s = dumps(t)
# compare the strings because Thread doesn't implement __cmp__
assert s == dumps(loads(s))
override()
print 'TESTS PASS.'
Show details Hide details

Change log

r289 by benjhayden on Oct 09, 2008   Diff
...
Go to: 
Project members, sign in to write a code review

Older revisions

r287 by benjhayden on Oct 08, 2008   Diff
...
r286 by benjhayden on Oct 08, 2008   Diff
...
r284 by benjhayden on Oct 08, 2008   Diff
...
All revisions of this file

File info

Size: 2672 bytes, 79 lines
Hosted by Google Code