|
@@
-0,0
+1,463
b''
|
|
|
1
|
{
|
|
|
2
|
"metadata": {
|
|
|
3
|
"gist_id": "5241793",
|
|
|
4
|
"name": ""
|
|
|
5
|
},
|
|
|
6
|
"nbformat": 3,
|
|
|
7
|
"nbformat_minor": 0,
|
|
|
8
|
"worksheets": [
|
|
|
9
|
{
|
|
|
10
|
"cells": [
|
|
|
11
|
{
|
|
|
12
|
"cell_type": "heading",
|
|
|
13
|
"level": 1,
|
|
|
14
|
"metadata": {},
|
|
|
15
|
"source": [
|
|
|
16
|
"Using dill to pickle anything"
|
|
|
17
|
]
|
|
|
18
|
},
|
|
|
19
|
{
|
|
|
20
|
"cell_type": "markdown",
|
|
|
21
|
"metadata": {},
|
|
|
22
|
"source": [
|
|
|
23
|
"IPython.parallel doesn't do much in the way of serialization.\n",
|
|
|
24
|
"It has custom zero-copy handling of numpy arrays,\n",
|
|
|
25
|
"but other than that, it doesn't do anything other than the bare minimum to make basic interactively defined functions and classes sendable.\n",
|
|
|
26
|
"\n",
|
|
|
27
|
"There are a few projects that extend pickle to make just about anything sendable, and one of these is [dill](http://www.cacr.caltech.edu/~mmckerns/dill).\n",
|
|
|
28
|
"\n",
|
|
|
29
|
"To install dill:\n",
|
|
|
30
|
" \n",
|
|
|
31
|
" pip install dill"
|
|
|
32
|
]
|
|
|
33
|
},
|
|
|
34
|
{
|
|
|
35
|
"cell_type": "markdown",
|
|
|
36
|
"metadata": {},
|
|
|
37
|
"source": [
|
|
|
38
|
"First, as always, we create a task function, this time with a closure"
|
|
|
39
|
]
|
|
|
40
|
},
|
|
|
41
|
{
|
|
|
42
|
"cell_type": "code",
|
|
|
43
|
"collapsed": false,
|
|
|
44
|
"input": [
|
|
|
45
|
"def make_closure(a):\n",
|
|
|
46
|
" \"\"\"make a function with a closure, and return it\"\"\"\n",
|
|
|
47
|
" def has_closure(b):\n",
|
|
|
48
|
" return a * b\n",
|
|
|
49
|
" return has_closure"
|
|
|
50
|
],
|
|
|
51
|
"language": "python",
|
|
|
52
|
"metadata": {},
|
|
|
53
|
"outputs": [],
|
|
|
54
|
"prompt_number": 1
|
|
|
55
|
},
|
|
|
56
|
{
|
|
|
57
|
"cell_type": "code",
|
|
|
58
|
"collapsed": false,
|
|
|
59
|
"input": [
|
|
|
60
|
"closed = make_closure(5)"
|
|
|
61
|
],
|
|
|
62
|
"language": "python",
|
|
|
63
|
"metadata": {},
|
|
|
64
|
"outputs": [],
|
|
|
65
|
"prompt_number": 2
|
|
|
66
|
},
|
|
|
67
|
{
|
|
|
68
|
"cell_type": "code",
|
|
|
69
|
"collapsed": false,
|
|
|
70
|
"input": [
|
|
|
71
|
"closed(2)"
|
|
|
72
|
],
|
|
|
73
|
"language": "python",
|
|
|
74
|
"metadata": {},
|
|
|
75
|
"outputs": [
|
|
|
76
|
{
|
|
|
77
|
"metadata": {},
|
|
|
78
|
"output_type": "pyout",
|
|
|
79
|
"prompt_number": 3,
|
|
|
80
|
"text": [
|
|
|
81
|
"10"
|
|
|
82
|
]
|
|
|
83
|
}
|
|
|
84
|
],
|
|
|
85
|
"prompt_number": 3
|
|
|
86
|
},
|
|
|
87
|
{
|
|
|
88
|
"cell_type": "code",
|
|
|
89
|
"collapsed": false,
|
|
|
90
|
"input": [
|
|
|
91
|
"import pickle"
|
|
|
92
|
],
|
|
|
93
|
"language": "python",
|
|
|
94
|
"metadata": {},
|
|
|
95
|
"outputs": [],
|
|
|
96
|
"prompt_number": 4
|
|
|
97
|
},
|
|
|
98
|
{
|
|
|
99
|
"cell_type": "markdown",
|
|
|
100
|
"metadata": {},
|
|
|
101
|
"source": [
|
|
|
102
|
"Without help, pickle can't deal with closures"
|
|
|
103
|
]
|
|
|
104
|
},
|
|
|
105
|
{
|
|
|
106
|
"cell_type": "code",
|
|
|
107
|
"collapsed": false,
|
|
|
108
|
"input": [
|
|
|
109
|
"pickle.dumps(closed)"
|
|
|
110
|
],
|
|
|
111
|
"language": "python",
|
|
|
112
|
"metadata": {},
|
|
|
113
|
"outputs": [
|
|
|
114
|
{
|
|
|
115
|
"ename": "PicklingError",
|
|
|
116
|
"evalue": "Can't pickle <function has_closure at 0x10d2552a8>: it's not found as __main__.has_closure",
|
|
|
117
|
"output_type": "pyerr",
|
|
|
118
|
"traceback": [
|
|
|
119
|
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mPicklingError\u001b[0m Traceback (most recent call last)",
|
|
|
120
|
"\u001b[1;32m<ipython-input-5-0f1f376cfea0>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mpickle\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdumps\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mclosed\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
|
|
|
121
|
"\u001b[1;32m/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.pyc\u001b[0m in \u001b[0;36mdumps\u001b[1;34m(obj, protocol)\u001b[0m\n\u001b[0;32m 1372\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mdumps\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mprotocol\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1373\u001b[0m \u001b[0mfile\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mStringIO\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1374\u001b[1;33m \u001b[0mPickler\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfile\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mprotocol\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdump\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1375\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mfile\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgetvalue\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1376\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
|
122
|
"\u001b[1;32m/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.pyc\u001b[0m in \u001b[0;36mdump\u001b[1;34m(self, obj)\u001b[0m\n\u001b[0;32m 222\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mproto\u001b[0m \u001b[1;33m>=\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 223\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mPROTO\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mchr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mproto\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 224\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msave\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 225\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mSTOP\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 226\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
|
123
|
"\u001b[1;32m/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.pyc\u001b[0m in \u001b[0;36msave\u001b[1;34m(self, obj)\u001b[0m\n\u001b[0;32m 284\u001b[0m \u001b[0mf\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdispatch\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mt\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 285\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 286\u001b[1;33m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mobj\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m# Call unbound method with explicit self\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 287\u001b[0m \u001b[1;32mreturn\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 288\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
|
124
|
"\u001b[1;32m/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.pyc\u001b[0m in \u001b[0;36msave_global\u001b[1;34m(self, obj, name, pack)\u001b[0m\n\u001b[0;32m 746\u001b[0m raise PicklingError(\n\u001b[0;32m 747\u001b[0m \u001b[1;34m\"Can't pickle %r: it's not found as %s.%s\"\u001b[0m \u001b[1;33m%\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 748\u001b[1;33m (obj, module, name))\n\u001b[0m\u001b[0;32m 749\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 750\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mklass\u001b[0m \u001b[1;32mis\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mobj\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
|
125
|
"\u001b[1;31mPicklingError\u001b[0m: Can't pickle <function has_closure at 0x10d2552a8>: it's not found as __main__.has_closure"
|
|
|
126
|
]
|
|
|
127
|
}
|
|
|
128
|
],
|
|
|
129
|
"prompt_number": 5
|
|
|
130
|
},
|
|
|
131
|
{
|
|
|
132
|
"cell_type": "markdown",
|
|
|
133
|
"metadata": {},
|
|
|
134
|
"source": [
|
|
|
135
|
"But after we import dill, magic happens"
|
|
|
136
|
]
|
|
|
137
|
},
|
|
|
138
|
{
|
|
|
139
|
"cell_type": "code",
|
|
|
140
|
"collapsed": false,
|
|
|
141
|
"input": [
|
|
|
142
|
"import dill"
|
|
|
143
|
],
|
|
|
144
|
"language": "python",
|
|
|
145
|
"metadata": {},
|
|
|
146
|
"outputs": [],
|
|
|
147
|
"prompt_number": 6
|
|
|
148
|
},
|
|
|
149
|
{
|
|
|
150
|
"cell_type": "code",
|
|
|
151
|
"collapsed": false,
|
|
|
152
|
"input": [
|
|
|
153
|
"pickle.dumps(closed)[:64] + '...'"
|
|
|
154
|
],
|
|
|
155
|
"language": "python",
|
|
|
156
|
"metadata": {},
|
|
|
157
|
"outputs": [
|
|
|
158
|
{
|
|
|
159
|
"metadata": {},
|
|
|
160
|
"output_type": "pyout",
|
|
|
161
|
"prompt_number": 7,
|
|
|
162
|
"text": [
|
|
|
163
|
"\"cdill.dill\\n_load_type\\np0\\n(S'FunctionType'\\np1\\ntp2\\nRp3\\n(cdill.dill...\""
|
|
|
164
|
]
|
|
|
165
|
}
|
|
|
166
|
],
|
|
|
167
|
"prompt_number": 7
|
|
|
168
|
},
|
|
|
169
|
{
|
|
|
170
|
"cell_type": "markdown",
|
|
|
171
|
"metadata": {},
|
|
|
172
|
"source": [
|
|
|
173
|
"So from now on, pretty much everything is pickleable."
|
|
|
174
|
]
|
|
|
175
|
},
|
|
|
176
|
{
|
|
|
177
|
"cell_type": "heading",
|
|
|
178
|
"level": 2,
|
|
|
179
|
"metadata": {},
|
|
|
180
|
"source": [
|
|
|
181
|
"Now use this in IPython.parallel"
|
|
|
182
|
]
|
|
|
183
|
},
|
|
|
184
|
{
|
|
|
185
|
"cell_type": "markdown",
|
|
|
186
|
"metadata": {},
|
|
|
187
|
"source": [
|
|
|
188
|
"As usual, we start by creating our Client and View"
|
|
|
189
|
]
|
|
|
190
|
},
|
|
|
191
|
{
|
|
|
192
|
"cell_type": "code",
|
|
|
193
|
"collapsed": false,
|
|
|
194
|
"input": [
|
|
|
195
|
"from IPython import parallel\n",
|
|
|
196
|
"rc = parallel.Client()\n",
|
|
|
197
|
"view = rc.load_balanced_view()"
|
|
|
198
|
],
|
|
|
199
|
"language": "python",
|
|
|
200
|
"metadata": {},
|
|
|
201
|
"outputs": [],
|
|
|
202
|
"prompt_number": 8
|
|
|
203
|
},
|
|
|
204
|
{
|
|
|
205
|
"cell_type": "markdown",
|
|
|
206
|
"metadata": {},
|
|
|
207
|
"source": [
|
|
|
208
|
"Now let's try sending our function with a closure:"
|
|
|
209
|
]
|
|
|
210
|
},
|
|
|
211
|
{
|
|
|
212
|
"cell_type": "code",
|
|
|
213
|
"collapsed": false,
|
|
|
214
|
"input": [
|
|
|
215
|
"view.apply_sync(closed, 3)"
|
|
|
216
|
],
|
|
|
217
|
"language": "python",
|
|
|
218
|
"metadata": {},
|
|
|
219
|
"outputs": [
|
|
|
220
|
{
|
|
|
221
|
"ename": "ValueError",
|
|
|
222
|
"evalue": "Sorry, cannot pickle code objects with closures",
|
|
|
223
|
"output_type": "pyerr",
|
|
|
224
|
"traceback": [
|
|
|
225
|
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)",
|
|
|
226
|
"\u001b[1;32m<ipython-input-9-23a646829fdc>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mview\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mapply_sync\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mclosed\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m3\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
|
|
|
227
|
"\u001b[1;32m/Users/minrk/dev/ip/mine/IPython/parallel/client/view.pyc\u001b[0m in \u001b[0;36mapply_sync\u001b[1;34m(self, f, *args, **kwargs)\u001b[0m\n",
|
|
|
228
|
"\u001b[1;32m/Users/minrk/dev/ip/mine/IPython/parallel/client/view.pyc\u001b[0m in \u001b[0;36mspin_after\u001b[1;34m(f, self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 73\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mspin_after\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mf\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 74\u001b[0m \u001b[1;34m\"\"\"call spin after the method.\"\"\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 75\u001b[1;33m \u001b[0mret\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 76\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mspin\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 77\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mret\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
|
229
|
"\u001b[1;32m/Users/minrk/dev/ip/mine/IPython/parallel/client/view.pyc\u001b[0m in \u001b[0;36mapply_sync\u001b[1;34m(self, f, *args, **kwargs)\u001b[0m\n\u001b[0;32m 248\u001b[0m \u001b[0mreturns\u001b[0m\u001b[1;33m:\u001b[0m \u001b[0mactual\u001b[0m \u001b[0mresult\u001b[0m \u001b[0mof\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 249\u001b[0m \"\"\"\n\u001b[1;32m--> 250\u001b[1;33m \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_really_apply\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mf\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mblock\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 251\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 252\u001b[0m \u001b[1;31m#----------------------------------------------------------------\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
|
230
|
"\u001b[1;32m/Users/minrk/dev/ip/mine/IPython/parallel/client/view.pyc\u001b[0m in \u001b[0;36m_really_apply\u001b[1;34m(self, f, args, kwargs, block, track, after, follow, timeout, targets, retries)\u001b[0m\n",
|
|
|
231
|
"\u001b[1;32m/Users/minrk/dev/ip/mine/IPython/parallel/client/view.pyc\u001b[0m in \u001b[0;36msync_results\u001b[1;34m(f, self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 64\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_in_sync_results\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mTrue\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 65\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 66\u001b[1;33m \u001b[0mret\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 67\u001b[0m \u001b[1;32mfinally\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 68\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_in_sync_results\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mFalse\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
|
232
|
"\u001b[1;32m/Users/minrk/dev/ip/mine/IPython/parallel/client/view.pyc\u001b[0m in \u001b[0;36m_really_apply\u001b[1;34m(self, f, args, kwargs, block, track, after, follow, timeout, targets, retries)\u001b[0m\n",
|
|
|
233
|
"\u001b[1;32m/Users/minrk/dev/ip/mine/IPython/parallel/client/view.pyc\u001b[0m in \u001b[0;36msave_ids\u001b[1;34m(f, self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 49\u001b[0m \u001b[0mn_previous\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mclient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mhistory\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 50\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 51\u001b[1;33m \u001b[0mret\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m*\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 52\u001b[0m \u001b[1;32mfinally\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 53\u001b[0m \u001b[0mnmsgs\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mclient\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mhistory\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m-\u001b[0m \u001b[0mn_previous\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
|
234
|
"\u001b[1;32m/Users/minrk/dev/ip/mine/IPython/parallel/client/view.pyc\u001b[0m in \u001b[0;36m_really_apply\u001b[1;34m(self, f, args, kwargs, block, track, after, follow, timeout, targets, retries)\u001b[0m\n\u001b[0;32m 1053\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1054\u001b[0m msg = self.client.send_apply_request(self._socket, f, args, kwargs, track=track,\n\u001b[1;32m-> 1055\u001b[1;33m metadata=metadata)\n\u001b[0m\u001b[0;32m 1056\u001b[0m \u001b[0mtracker\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mNone\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mtrack\u001b[0m \u001b[1;32mis\u001b[0m \u001b[0mFalse\u001b[0m \u001b[1;32melse\u001b[0m \u001b[0mmsg\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'tracker'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 1057\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
|
235
|
"\u001b[1;32m/Users/minrk/dev/ip/mine/IPython/parallel/client/client.pyc\u001b[0m in \u001b[0;36msend_apply_request\u001b[1;34m(self, socket, f, args, kwargs, metadata, track, ident)\u001b[0m\n\u001b[0;32m 1252\u001b[0m bufs = serialize.pack_apply_message(f, args, kwargs,\n\u001b[0;32m 1253\u001b[0m \u001b[0mbuffer_threshold\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msession\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mbuffer_threshold\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m-> 1254\u001b[1;33m \u001b[0mitem_threshold\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msession\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mitem_threshold\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 1255\u001b[0m )\n\u001b[0;32m 1256\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
|
236
|
"\u001b[1;32m/Users/minrk/dev/ip/mine/IPython/kernel/zmq/serialize.pyc\u001b[0m in \u001b[0;36mpack_apply_message\u001b[1;34m(f, args, kwargs, buffer_threshold, item_threshold)\u001b[0m\n\u001b[0;32m 163\u001b[0m \u001b[0minfo\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mdict\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnargs\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0margs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mnarg_bufs\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0marg_bufs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkw_keys\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mkw_keys\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 164\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 165\u001b[1;33m \u001b[0mmsg\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[0mpickle\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdumps\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcan\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mf\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 166\u001b[0m \u001b[0mmsg\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpickle\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdumps\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minfo\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 167\u001b[0m \u001b[0mmsg\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mextend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0marg_bufs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
|
237
|
"\u001b[1;32m/Users/minrk/dev/ip/mine/IPython/utils/codeutil.pyc\u001b[0m in \u001b[0;36mreduce_code\u001b[1;34m(co)\u001b[0m\n\u001b[0;32m 36\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mreduce_code\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mco\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 37\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mco\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mco_freevars\u001b[0m \u001b[1;32mor\u001b[0m \u001b[0mco\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mco_cellvars\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 38\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Sorry, cannot pickle code objects with closures\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 39\u001b[0m args = [co.co_argcount, co.co_nlocals, co.co_stacksize,\n\u001b[0;32m 40\u001b[0m \u001b[0mco\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mco_flags\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mco\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mco_code\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mco\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mco_consts\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mco\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mco_names\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
|
|
|
238
|
"\u001b[1;31mValueError\u001b[0m: Sorry, cannot pickle code objects with closures"
|
|
|
239
|
]
|
|
|
240
|
}
|
|
|
241
|
],
|
|
|
242
|
"prompt_number": 9
|
|
|
243
|
},
|
|
|
244
|
{
|
|
|
245
|
"cell_type": "markdown",
|
|
|
246
|
"metadata": {},
|
|
|
247
|
"source": [
|
|
|
248
|
"Oops, no dice. For IPython to work with dill,\n",
|
|
|
249
|
"there are one or two more steps. IPython will do these for you if you call `pickleutil.use_dill`:"
|
|
|
250
|
]
|
|
|
251
|
},
|
|
|
252
|
{
|
|
|
253
|
"cell_type": "code",
|
|
|
254
|
"collapsed": false,
|
|
|
255
|
"input": [
|
|
|
256
|
"from IPython.utils import pickleutil\n",
|
|
|
257
|
"pickleutil.use_dill()"
|
|
|
258
|
],
|
|
|
259
|
"language": "python",
|
|
|
260
|
"metadata": {},
|
|
|
261
|
"outputs": [],
|
|
|
262
|
"prompt_number": 10
|
|
|
263
|
},
|
|
|
264
|
{
|
|
|
265
|
"cell_type": "markdown",
|
|
|
266
|
"metadata": {},
|
|
|
267
|
"source": [
|
|
|
268
|
"Now let's try again"
|
|
|
269
|
]
|
|
|
270
|
},
|
|
|
271
|
{
|
|
|
272
|
"cell_type": "code",
|
|
|
273
|
"collapsed": false,
|
|
|
274
|
"input": [
|
|
|
275
|
"view.apply_sync(closed, 3)"
|
|
|
276
|
],
|
|
|
277
|
"language": "python",
|
|
|
278
|
"metadata": {},
|
|
|
279
|
"outputs": [
|
|
|
280
|
{
|
|
|
281
|
"metadata": {},
|
|
|
282
|
"output_type": "pyout",
|
|
|
283
|
"prompt_number": 11,
|
|
|
284
|
"text": [
|
|
|
285
|
"15"
|
|
|
286
|
]
|
|
|
287
|
}
|
|
|
288
|
],
|
|
|
289
|
"prompt_number": 11
|
|
|
290
|
},
|
|
|
291
|
{
|
|
|
292
|
"cell_type": "markdown",
|
|
|
293
|
"metadata": {},
|
|
|
294
|
"source": [
|
|
|
295
|
"Yay! Now we can use dill to allow IPython.parallel to send anything.\n",
|
|
|
296
|
"\n",
|
|
|
297
|
"And that's it! We can send closures and other previously non-pickleables to our engines.\n",
|
|
|
298
|
"\n",
|
|
|
299
|
"But wait, there's more!"
|
|
|
300
|
]
|
|
|
301
|
},
|
|
|
302
|
{
|
|
|
303
|
"cell_type": "code",
|
|
|
304
|
"collapsed": false,
|
|
|
305
|
"input": [
|
|
|
306
|
"view.apply_sync(make_closure, 2)"
|
|
|
307
|
],
|
|
|
308
|
"language": "python",
|
|
|
309
|
"metadata": {},
|
|
|
310
|
"outputs": [
|
|
|
311
|
{
|
|
|
312
|
"ename": "RemoteError",
|
|
|
313
|
"evalue": "ValueError(Sorry, cannot pickle code objects with closures)",
|
|
|
314
|
"output_type": "pyerr",
|
|
|
315
|
"traceback": [
|
|
|
316
|
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
|
|
317
|
"\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)\u001b[1;32m/Users/minrk/dev/ip/mine/IPython/kernel/zmq/serialize.pyc\u001b[0m in \u001b[0;36mserialize_object\u001b[1;34m(obj, buffer_threshold, item_threshold)\u001b[0m",
|
|
|
318
|
"\u001b[0;32m 100\u001b[0m \u001b[0mbuffers\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mextend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0m_extract_buffers\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcobj\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mbuffer_threshold\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m",
|
|
|
319
|
"\u001b[0;32m 101\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m",
|
|
|
320
|
"\u001b[1;32m--> 102\u001b[1;33m \u001b[0mbuffers\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0minsert\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mpickle\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdumps\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcobj\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m",
|
|
|
321
|
"\u001b[0m\u001b[0;32m 103\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mbuffers\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m",
|
|
|
322
|
"\u001b[0;32m 104\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m",
|
|
|
323
|
"\u001b[1;32m/Users/minrk/dev/ip/mine/IPython/utils/codeutil.pyc\u001b[0m in \u001b[0;36mreduce_code\u001b[1;34m(co)\u001b[0m",
|
|
|
324
|
"\u001b[0;32m 36\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mreduce_code\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mco\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m",
|
|
|
325
|
"\u001b[0;32m 37\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mco\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mco_freevars\u001b[0m \u001b[1;32mor\u001b[0m \u001b[0mco\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mco_cellvars\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m",
|
|
|
326
|
"\u001b[1;32m---> 38\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Sorry, cannot pickle code objects with closures\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m",
|
|
|
327
|
"\u001b[0m\u001b[0;32m 39\u001b[0m args = [co.co_argcount, co.co_nlocals, co.co_stacksize,",
|
|
|
328
|
"\u001b[0;32m 40\u001b[0m \u001b[0mco\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mco_flags\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mco\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mco_code\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mco\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mco_consts\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mco\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mco_names\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m",
|
|
|
329
|
"\u001b[1;31mValueError\u001b[0m: Sorry, cannot pickle code objects with closures"
|
|
|
330
|
]
|
|
|
331
|
}
|
|
|
332
|
],
|
|
|
333
|
"prompt_number": 12
|
|
|
334
|
},
|
|
|
335
|
{
|
|
|
336
|
"cell_type": "markdown",
|
|
|
337
|
"metadata": {},
|
|
|
338
|
"source": [
|
|
|
339
|
"If we want dill support for objects coming *from* the engines,\n",
|
|
|
340
|
"then we need to call `use_dill()` there as well.\n",
|
|
|
341
|
"\n",
|
|
|
342
|
"`DirectView` objects have a method to call `use_dill` locally and on every engine:"
|
|
|
343
|
]
|
|
|
344
|
},
|
|
|
345
|
{
|
|
|
346
|
"cell_type": "code",
|
|
|
347
|
"collapsed": false,
|
|
|
348
|
"input": [
|
|
|
349
|
"rc[:].use_dill()"
|
|
|
350
|
],
|
|
|
351
|
"language": "python",
|
|
|
352
|
"metadata": {},
|
|
|
353
|
"outputs": [
|
|
|
354
|
{
|
|
|
355
|
"metadata": {},
|
|
|
356
|
"output_type": "pyout",
|
|
|
357
|
"prompt_number": 13,
|
|
|
358
|
"text": [
|
|
|
359
|
"<AsyncResult: use_dill>"
|
|
|
360
|
]
|
|
|
361
|
}
|
|
|
362
|
],
|
|
|
363
|
"prompt_number": 13
|
|
|
364
|
},
|
|
|
365
|
{
|
|
|
366
|
"cell_type": "markdown",
|
|
|
367
|
"metadata": {},
|
|
|
368
|
"source": [
|
|
|
369
|
"This is equivalent to\n",
|
|
|
370
|
"\n",
|
|
|
371
|
"```python\n",
|
|
|
372
|
"from IPython.utils.pickleutil import use_dill\n",
|
|
|
373
|
"use_dill()\n",
|
|
|
374
|
"rc[:].apply(use_dill)\n",
|
|
|
375
|
"```"
|
|
|
376
|
]
|
|
|
377
|
},
|
|
|
378
|
{
|
|
|
379
|
"cell_type": "markdown",
|
|
|
380
|
"metadata": {},
|
|
|
381
|
"source": [
|
|
|
382
|
"Let's give it a try now:"
|
|
|
383
|
]
|
|
|
384
|
},
|
|
|
385
|
{
|
|
|
386
|
"cell_type": "code",
|
|
|
387
|
"collapsed": false,
|
|
|
388
|
"input": [
|
|
|
389
|
"remote_closure = view.apply_sync(make_closure, 4)\n",
|
|
|
390
|
"remote_closure(5)"
|
|
|
391
|
],
|
|
|
392
|
"language": "python",
|
|
|
393
|
"metadata": {},
|
|
|
394
|
"outputs": [
|
|
|
395
|
{
|
|
|
396
|
"metadata": {},
|
|
|
397
|
"output_type": "pyout",
|
|
|
398
|
"prompt_number": 14,
|
|
|
399
|
"text": [
|
|
|
400
|
"20"
|
|
|
401
|
]
|
|
|
402
|
}
|
|
|
403
|
],
|
|
|
404
|
"prompt_number": 14
|
|
|
405
|
},
|
|
|
406
|
{
|
|
|
407
|
"cell_type": "markdown",
|
|
|
408
|
"metadata": {},
|
|
|
409
|
"source": [
|
|
|
410
|
"At this point, we can send/recv all kinds of stuff"
|
|
|
411
|
]
|
|
|
412
|
},
|
|
|
413
|
{
|
|
|
414
|
"cell_type": "code",
|
|
|
415
|
"collapsed": false,
|
|
|
416
|
"input": [
|
|
|
417
|
"def outer(a):\n",
|
|
|
418
|
" def inner(b):\n",
|
|
|
419
|
" def inner_again(c):\n",
|
|
|
420
|
" return c * b * a\n",
|
|
|
421
|
" return inner_again\n",
|
|
|
422
|
" return inner"
|
|
|
423
|
],
|
|
|
424
|
"language": "python",
|
|
|
425
|
"metadata": {},
|
|
|
426
|
"outputs": [],
|
|
|
427
|
"prompt_number": 15
|
|
|
428
|
},
|
|
|
429
|
{
|
|
|
430
|
"cell_type": "markdown",
|
|
|
431
|
"metadata": {},
|
|
|
432
|
"source": [
|
|
|
433
|
"So outer returns a function with a closure, which returns a function with a closure.\n",
|
|
|
434
|
"\n",
|
|
|
435
|
"Now, we can resolve the first closure on the engine, the second here, and the third on a different engine,\n",
|
|
|
436
|
"after passing through a lambda we define here and call there, just for good measure."
|
|
|
437
|
]
|
|
|
438
|
},
|
|
|
439
|
{
|
|
|
440
|
"cell_type": "code",
|
|
|
441
|
"collapsed": false,
|
|
|
442
|
"input": [
|
|
|
443
|
"view.apply_sync(lambda f: f(3),view.apply_sync(outer, 1)(2))"
|
|
|
444
|
],
|
|
|
445
|
"language": "python",
|
|
|
446
|
"metadata": {},
|
|
|
447
|
"outputs": [
|
|
|
448
|
{
|
|
|
449
|
"metadata": {},
|
|
|
450
|
"output_type": "pyout",
|
|
|
451
|
"prompt_number": 16,
|
|
|
452
|
"text": [
|
|
|
453
|
"6"
|
|
|
454
|
]
|
|
|
455
|
}
|
|
|
456
|
],
|
|
|
457
|
"prompt_number": 16
|
|
|
458
|
}
|
|
|
459
|
],
|
|
|
460
|
"metadata": {}
|
|
|
461
|
}
|
|
|
462
|
]
|
|
|
463
|
}
No newline at end of file
|