<
8000
/td> 7
7
# Copyright (c) 2009 Gael Varoquaux
8
8
# License: BSD Style, 3 clauses.
9
9
10
+ import warnings
10
11
import pickle
11
12
import hashlib
12
13
import sys
@@ -29,6 +30,13 @@ def __init__(self, set_sequence):
29
30
self ._sequence = sorted (set_sequence )
30
31
31
32
33
+ class _MyHash (object ):
34
+ """ Class used to hash objects that won't normaly pickle """
35
+
36
+ def __init__ (self , * args ):
37
+ self .args = args
38
+
39
+
32
40
class Hasher (Pickler ):
33
41
""" A subclass of pickler, to do cryptographic hashing, rather than
34
42
pickling.
@@ -43,9 +51,8 @@ def __init__(self, hash_name='md5'):
43
51
def hash (self , obj , return_digest = True ):
44
52
try :
45
53
self .dump (obj )
46
- except pickle .PicklingError :
47
- pass
48
- #self.dump(
54
+ except pickle .PicklingError as e :
55
+ warnings .warn ('PicklingError while hashing %r: %r' % (obj , e ))
49
56
dumps = self .stream .getvalue ()
50
57
self ._hash .update (dumps )
51
58
if return_digest :
@@ -60,8 +67,14 @@ def save(self, obj):
60
67
else :
61
68
func_name = obj .__name__
62
69
inst = obj .__self__
63
- cls = obj .__self__ .__class__
64
- obj = (func_name , inst , cls )
70
+ if type (inst ) == type (pickle ):
71
+ obj = _MyHash (func_name , inst .__name__ )
72
+ elif inst is None :
73
+ # type(None) or type(module) do not pickle
74
+ obj = _MyHash (func_name , inst )
75
+ else :
76
+ cls = obj .__self__ .__class__
77
+ obj = _MyHash (func_name , inst , cls )
65
78
Pickler .save (self , obj )
66
79
67
80
# The dispatch table of the pickler is not accessible in Python
@@ -70,17 +83,20 @@ def save_global(self, obj, name=None, pack=struct.pack):
70
83
# We have to override this method in order to deal with objects
71
84
# defined interactively in IPython that are not injected in
72
85
# __main__
73
- module = getattr (obj , "__module__" , None )
74
- if module == '__main__' :
75
- my_name = name
76
- if my_name is None :
77
- my_name = obj .__name__
78
- mod = sys .modules [module ]
79
- if not hasattr (mod , my_name ):
80
- # IPython doesn't inject the variables define
81
- # interactively in __main__
82
- setattr (mod , my_name , obj )
83
- Pickler .save_global (self , obj , name = name , pack = struct .pack )
86
+ try :
87
+ Pickler .save_global (self , obj , name = name , pack = pack )
88
+ except pickle .PicklingError :
89
+ Pickler .save_global (self , obj , name = name , pack = pack )
90
+ module = getattr (obj , "__module__" , None )
91
+ if module == '__main__' :
92
+ my_name = name
93
+ if my_name is None :
94
+ my_name = obj .__name__
95
+ mod = sys .modules [module ]
96
+ if not hasattr (mod , my_name ):
97
+ # IPython doesn't inject the variables define
98
+ # interactively in __main__
99
+ setattr (mod , my_name , obj )
84
100
85
101
dispatch = Pickler .dispatch .copy ()
86
102
# builtin
0 commit comments