1
1
from __future__ import (absolute_import , division , print_function ,
2
2
unicode_literals )
3
3
4
- import six
5
4
from six .moves import cPickle as pickle
6
5
from six .moves import range
7
6
15
14
import matplotlib .transforms as mtransforms
16
15
17
16
18
- def depth_getter (obj ,
19
- current_depth = 0 ,
20
- depth_stack = None ,
21
- nest_info = 'top level object' ):
22
- """
23
- Returns a dictionary mapping:
24
-
25
- id(obj): (shallowest_depth, obj, nest_info)
26
-
27
- for the given object (and its subordinates).
28
-
29
- This, in conjunction with recursive_pickle, can be used to debug
30
- pickling issues, although finding others is sometimes a case of
31
- trial and error.
32
-
33
- """
34
- if depth_stack is None :
35
- depth_stack = {}
36
-
37
- if id (obj ) in depth_stack :
38
- stack = depth_stack [id (obj )]
39
- if stack [0 ] > current_depth :
40
- del depth_stack [id (obj )]
41
- else :
42
- return depth_stack
43
-
44
- depth_stack [id (obj )] = (current_depth , obj , nest_info )
45
-
46
- if isinstance (obj , (list , tuple )):
47
- for i , item in enumerate (obj ):
48
- depth_getter (item , current_depth = current_depth + 1 ,
49
- depth_stack = depth_stack ,
50
- nest_info = ('list/tuple item #%s in '
51
- '(%s)' % (i , nest_info )))
52
- else :
53
- if isinstance (obj , dict ):
54
- state = obj
55
- elif hasattr (obj , '__getstate__' ):
56
- state = obj .__getstate__ ()
57
- if not isinstance (state , dict ):
58
- state = {}
59
- elif hasattr (obj , '__dict__' ):
60
- state = obj .__dict__
61
- else :
62
- state = {}
63
-
64
- for key , value in six .iteritems (state ):
65
- depth_getter (value , current_depth = current_depth + 1 ,
66
- depth_stack = depth_stack ,
67
- nest_info = ('attribute "%s" in '
68
- '(%s)' % (key , nest_info )))
69
-
70
- return depth_stack
71
-
72
-
73
- def recursive_pickle (top_obj ):
74
- """
75
- Recursively pickle all of the given objects subordinates, starting with
76
- the deepest first. **Very** handy for debugging pickling issues, but
77
- also very slow (as it literally pickles each object in turn).
78
-
79
- Handles circular object references gracefully.
80
-
81
- """
82
- objs = depth_getter (top_obj )
83
- # sort by depth then by nest_info
84
- objs = sorted (six .itervalues (objs ), key = lambda val : (- val [0 ], val [2 ]))
85
-
86
- for _ , obj , location in objs :
87
- try :
88
- pickle .dump (obj , BytesIO (), pickle .HIGHEST_PROTOCOL )
89
- except Exception as err :
90
- print (obj )
91
- print ('Failed to pickle %s. \n Type: %s. Traceback '
92
- 'follows:' % (location , type (obj )))
93
- raise
94
-
95
-
96
17
def test_simple ():
97
18
fig = plt .figure ()
98
- # un-comment to debug
99
- # recursive_pickle(fig)
100
19
pickle .dump (fig , BytesIO (), pickle .HIGHEST_PROTOCOL )
101
20
102
21
ax = plt .subplot (121 )
@@ -106,13 +25,9 @@ def test_simple():
106
25
plt .plot (np .arange (10 ), label = 'foobar' )
107
26
plt .legend ()
108
27
109
- # Uncomment to debug any unpicklable objects. This is slow so is not
110
- # uncommented by default.
111
- # recursive_pickle(fig)
112
28
pickle .dump (ax , BytesIO (), pickle .HIGHEST_PROTOCOL )
113
29
114
30
# ax = plt.subplot(121, projection='hammer')
115
- # recursive_pickle(ax, 'figure')
116
31
# pickle.dump(ax, BytesIO(), pickle.HIGHEST_PROTOCOL)
117
32
118
33
plt .figure ()
@@ -138,8 +53,9 @@ def test_complete():
138
53
data = u = v = np .linspace (0 , 10 , 80 ).reshape (10 , 8 )
139
54
v = np .sin (v * - 0.6 )
140
55
56
+ # Ensure lists also pickle correctly.
141
57
plt .subplot (3 , 3 , 1 )
142
- plt .plot (list (range (10 ))) # Ensure lists also pickle correctly.
58
+ plt .plot (list (range (10 )))
143
59
144
60
plt .subplot (3 , 3 , 2 )
145
61
plt .contourf (data , hatches = ['//' , 'ooo' ])
@@ -171,11 +87,9 @@ def test_complete():
171
87
plt .subplot (3 , 3 , 9 )
172
88
plt .errorbar (x , x * - 0.5 , xerr = 0.2 , yerr = 0.4 )
173
89
174
- ###### plotting is done, now test its pickle-ability #########
175
-
176
- # Uncomment to debug any unpicklable objects. This is slow (~200 seconds).
177
- # recursive_pickle(fig)
178
-
90
+ #
91
+ # plotting is done, now test its pickle-ability
92
+ #
179
93
result_fh = BytesIO ()
180
94
pickle .dump (fig , result_fh , pickle .HIGHEST_PROTOCOL )
181
95
@@ -227,7 +141,6 @@ def test_image():
227
141
def test_polar ():
228
142
ax = plt .subplot (111 , polar = True )
229
143
fig = plt .gcf ()
230
- result = BytesIO ()
231
144
pf = pickle .dumps (fig )
232
145
pickle .loads (pf )
233
146
plt .draw ()
0 commit comments