<br><br><div class="gmail_quote">On Mon, Feb 18, 2013 at 2:47 AM, John Reid <span dir="ltr">&lt;<a href="mailto:j.reid@mail.cryst.bbk.ac.uk" target="_blank">j.reid@mail.cryst.bbk.ac.uk</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


Hi,<br>
<br>
I think the parallel functionality in ipython used to work with<br>
collections.namedtuples but does not with version 0.12.1.<br>
<br>
For example if I have module parallel_helper.py:<br>
<br>
from collections import namedtuple<br>
Result = namedtuple(&#39;Result&#39;, &#39;pid duration&#39;)<br>
<br>
and a script:<br>
<br>
def sleep(secs):<br>
    import os, time, parallel_helper<br>
    start = time.time()<br>
    time.sleep(secs)<br>
    return parallel_helper.Result(os.getpid(), time.time() - start)<br>
<br>
rc = parallel.Client()<br>
v = rc.load_balanced_view()<br>
async_result = v.map_async(sleep, range(3, 0, -1), ordered=False)<br>
for ar in async_result:<br>
    print ar<br>
<br>
then an error is raised when the results are passed back:<br>
<br>
RemoteError: TypeError(__new__() takes exactly 3 arguments (2 given))<br>
Traceback (most recent call last):<br>
  File<br>
&quot;/usr/lib/python2.7/dist-packages/IPython/parallel/engine/streamkernel.py&quot;,<br>
line 345, in apply_request<br>
    packed_result,buf = serialize_object(result)<br>
  File &quot;/usr/lib/python2.7/dist-packages/IPython/parallel/util.py&quot;, line<br>
230, in serialize_object<br>
    clist = canSequence(obj)<br>
  File &quot;/usr/lib/python2.7/dist-packages/IPython/utils/pickleutil.py&quot;,<br>
line 121, in canSequence<br>
    return t([can(i) for i in obj])<br>
  File &quot;/usr/lib/python2.7/dist-packages/IPython/utils/pickleutil.py&quot;,<br>
line 105, in can<br>
    return canSequence(obj)<br>
  File &quot;/usr/lib/python2.7/dist-packages/IPython/utils/pickleutil.py&quot;,<br>
line 121, in canSequence<br>
    return t([can(i) for i in obj])<br>
TypeError: __new__() takes exactly 3 arguments (2 given)<br>
<br>
I think the problem is somewhere in the code that treats lists and<br>
tuples as special cases in pickleutil.py:<br>
<br>
def canSequence(obj):<br>
    if isinstance(obj, (list, tuple)):<br>
        t = type(obj)<br>
        return t([can(i) for i in obj])<br>
    else:<br>
        return obj<br>
<br>
As far as I can remember namedtuples that were well defined in their own<br>
modules were perfectly usable across the parallel interface.<br>
<br>
Is there any way that I can still use them? I find them extremely useful.<br></blockquote><div><br></div><div>Sorry about this.  I&#39;ve made a <a href="https://github.com/ipython/ipython/pull/2951">pull request</a> against master that should fix it.</div>

<div><br></div><div>A patch for stable IPython is a bit messy.  You would have to monkeypatch IPython.zmq.serialize.serialize_object/unserialize_object to handle namedtuples specially.</div><div><br></div><div>The other (probably better) options in the meantime are:</div>

<div><br></div><div>use a trivial class instead of namedtuple:</div><div><br></div><div>class Result(object):</div><div>    def __init__(self, **kwargs):</div>
<div>        for key, value in kwargs.items():</div><div>            setattr(self, key, value)</div><div><br></div><div>r = Result(pid=os.getpid(), duration=<span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:10px">time.time() - start)</span></div>

<div><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:10px"><br></span></div><div><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:10px">or do the namedtuple wrapping on the Client side:</span></div>

<div><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:10px"><br></span></div><div><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:10px">def task():</span></div>

<div><font color="#222222" face="arial, sans-serif">    ...</font></div><div><font color="#222222" face="arial, sans-serif">    return </font>os.getpid(), <span style="font-size:10px;background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif">time.time() - start</span></div>

<div><span style="font-size:10px;background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif"><br></span></div><div><span style="font-size:10px;background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif">amr = view.map_async(task)</span></div>

<div><span style="font-size:10px;background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif">for tup in amr:</span></div><div><span style="font-size:10px;background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif">    r = helper.Result(tup)</span></div>

<div><br></div><div><br></div><div>Neither of which is awesome, but thanks for the report, the fix should be in master shortly.</div><div><br></div><div>-MinRK</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



<br>
Thanks,<br>
John.<br>
<br>
<br>
<br>
_______________________________________________<br>
IPython-User mailing list<br>
<a href="mailto:IPython-User@scipy.org" target="_blank">IPython-User@scipy.org</a><br>
<a href="http://mail.scipy.org/mailman/listinfo/ipython-user" target="_blank">http://mail.scipy.org/mailman/listinfo/ipython-user</a><br>
</blockquote></div><br>