John,<br><br><div class="gmail_quote">On Tue, Nov 9, 2010 at 2:18 AM, John Reid <span dir="ltr"><<a href="mailto:j.reid@mail.cryst.bbk.ac.uk">j.reid@mail.cryst.bbk.ac.uk</a>></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'm having some problems returning named tuples from a multi-engine<br>
client. I do something like:<br>
<br>
from IPython.kernel import client<br>
mec = client.MultiEngineClient()<br>
<br>
@mec.parallel()<br>
def parallel_get_starts(arg):<br>
<do some work><br>
return <some named tuples><br>
<br>
results = parallel_get_starts(<some list>)<br>
<br>
<br>
but I always get errors like:<br>
TypeError: __new__() takes exactly 8 arguments (2 given)<br></blockquote><div><br></div><div>Hmm, that is an odd error that I have never seen. Even the fact that it is a TypeError is odd to me. A couple of things to look at:</div>
<div><br></div><div>* Make sure that named tuples can be pickled and unpickled.</div><div>* See if you can come up with a super simple example that displays this error (isolate it).</div><div>* See if you can figure out where the TypeError is coming from.</div>
<div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
whenever the results of the parallel_get_starts() function contain named<br>
tuples. I'm using a namedtuple as given by Raymond Hettinger in the<br>
Python Cookbook:<br>
<a href="http://code.activestate.com/recipes/500261-named-tuples/" target="_blank">http://code.activestate.com/recipes/500261-named-tuples/</a><br>
See below.<br>
<br>
Does anyone know how I might get it to work? presumably I could move to<br>python 2.6 and use the collections.namedtuple type.<br>
<br></blockquote><div><br></div><div>It would be interesting to see if that shows the error as well. I am wondering if the namedtuple implementation you are using has problems.</div><div><br></div><div>Cheers,</div><div>
<br></div><div>Brian</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Thanks,<br>
John.<br>
<br>
<br>
<br>
def namedtuple(typename, field_names, verbose=False):<br>
"""Returns a new subclass of tuple with named fields.<br>
<br>
>>> Point = namedtuple('Point', 'x y')<br>
>>> Point.__doc__ # docstring for the new class<br>
'Point(x, y)'<br>
>>> p = Point(11, y=22) # instantiate with positional<br>
args or keywords<br>
>>> p[0] + p[1] # indexable like a plain tuple<br>
33<br>
>>> x, y = p # unpack like a regular tuple<br>
>>> x, y<br>
(11, 22)<br>
>>> p.x + p.y # fields also accessable by name<br>
33<br>
>>> d = p._asdict() # convert to a dictionary<br>
>>> d['x']<br>
11<br>
>>> Point(**d) # convert from a dictionary<br>
Point(x=11, y=22)<br>
>>> p._replace(x=100) # _replace() is like<br>
str.replace() but targets named fields<br>
Point(x=100, y=22)<br>
<br>
"""<br>
<br>
# Parse and validate the field names. Validation serves two purposes,<br>
# generating informative error messages and preventing template<br>
injection attacks.<br>
if isinstance(field_names, basestring):<br>
field_names = field_names.replace(',', ' ').split() # names<br>
separated by whitespace and/or commas<br>
field_names = tuple(field_names)<br>
for name in (typename,) + field_names:<br>
if not min(c.isalnum() or c=='_' for c in name):<br>
raise ValueError('Type names and field names can only<br>
contain alphanumeric characters and underscores: %r' % name)<br>
if _iskeyword(name):<br>
raise ValueError('Type names and field names cannot be a<br>
keyword: %r' % name)<br>
if name[0].isdigit():<br>
raise ValueError('Type names and field names cannot start<br>
with a number: %r' % name)<br>
seen_names = set()<br>
for name in field_names<br>
if name.startswith('_'):<br>
raise ValueError('Field names cannot start with an<br>
underscore: %r' % name)<br>
if name in seen_names:<br>
raise ValueError('Encountered duplicate field name: %r' % name)<br>
seen_names.add(name)<br>
<br>
# Create and fill-in the class template<br>
numfields = len(field_names)<br>
argtxt = repr(field_names).replace("'", "")[1:-1] # tuple repr<br>
without parens or quotes<br>
reprtxt = ', '.join('%s=%%r' % name for name in field_names)<br>
dicttxt = ', '.join('%r: t[%d]' % (name, pos) for pos, name in<br>
enumerate(field_names))<br>
template = '''class %(typename)s(tuple):<br>
'%(typename)s(%(argtxt)s)' \n<br>
__slots__ = () \n<br>
_fields = %(field_names)r \n<br>
def __new__(cls, %(argtxt)s):<br>
return tuple.__new__(cls, (%(argtxt)s)) \n<br>
@classmethod<br>
def _make(cls, iterable, new=tuple.__new__, len=len):<br>
'Make a new %(typename)s object from a sequence or iterable'<br>
result = new(cls, iterable)<br>
if len(result) != %(numfields)d:<br>
raise TypeError('Expected %(numfields)d arguments, got<br>
%%d' %% len(result))<br>
return result \n<br>
def __repr__(self):<br>
return '%(typename)s(%(reprtxt)s)' %% self \n<br>
def _asdict(t):<br>
'Return a new dict which maps field names to their values'<br>
return {%(dicttxt)s} \n<br>
def _replace(self, **kwds):<br>
'Return a new %(typename)s object replacing specified<br>
fields with new values'<br>
result = self._make(map(kwds.pop, %(field_names)r, self))<br>
if kwds:<br>
raise ValueError('Got unexpected field names: %%r' %%<br>
kwds.keys())<br>
return result \n\n''' % locals()<br>
for i, name in enumerate(field_names):<br>
template += ' %s = property(itemgetter(%d))\n' % (name, i)<br>
if verbose:<br>
print template<br>
<br>
# Execute the template string in a temporary namespace<br>
namespace = dict(itemgetter=_itemgetter)<br>
try:<br>
exec template in namespace<br>
except SyntaxError, e:<br>
raise SyntaxError(e.message + ':\n' + template)<br>
result = namespace[typename]<br>
<br>
# For pickling to work, the __module__ variable needs to be set to<br>
the frame<br>
# where the named tuple is created. Bypass this step in<br>
enviroments where<br>
# sys._getframe is not defined (Jython for example).<br>
if hasattr(_sys, '_getframe'):<br>
result.__module__ = _sys._getframe(1).f_globals['__name__']<br>
<br>
return result<br>
<br>
_______________________________________________<br>
IPython-User mailing list<br>
<a href="mailto:IPython-User@scipy.org">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><br clear="all"><br>-- <br>Brian E. Granger, Ph.D.<br>Assistant Professor of Physics<br>Cal Poly State University, San Luis Obispo<br><a href="mailto:bgranger@calpoly.edu">bgranger@calpoly.edu</a><br>
<a href="mailto:ellisonbg@gmail.com">ellisonbg@gmail.com</a><br>