views:

855

answers:

4

It's somewhat common knowledge that Python functions can have a maximum of 256 arguments. What I'm curious to know is if this limit applies to *args and **kwargs when they're unrolled in the following manner:

items = [1,2,3,4,5,6]

def do_something(*items):
    pass

I ask because, hypothetically, there might be cases where a list larger than 256 items gets unrolled as a set of *args or **kwargs.

+3  A: 

I tried for a list of 4000 items, and it worked. So I'm guessing it will work for larger values as well.

Geo
+5  A: 

WFM

>>> fstr = 'def f(%s): pass'%(', '.join(['arg%d'%i for i in range(5000)]))
>>> exec(fstr)
>>> f
<function f at 0x829bae4>

Update: as Brian noticed, the limit is on the calling side:

>>> exec 'f(' + ','.join(str(i) for i in range(5000)) + ')'

Traceback (most recent call last):
  File "<pyshell#63>", line 1, in <module>
    exec 'f(' + ','.join(str(i) for i in range(5000)) + ')'
  File "<string>", line 1
SyntaxError: more than 255 arguments (<string>, line 1)

on the other hand this works:

>>> f(*range(5000))
>>>

Conclusion: no, it does not apply to unrolled arguments.

vartec
It looks like the limit is on the calling side. Try exec 'f(' + ','.join(str(i) for i in range(5000)) + ')'
Brian
+2  A: 

for **kwargs, If I remember well, this is a dictionary. It therefore has about no limits.

for *args, I am not so sure, but I think it is a tuple or a list, so it also has about no limits.

By no limits, I mean except maybe the memory limit.

Martin
Yes *args is a tuple.
S.Lott
+1  A: 

This appears to be a restriction in compiling the source, so will probably exist only for arguments being passed directly, not in *args or **kwargs.

The relevant code can be found in ast.c:

if (nargs + nkeywords + ngens > 255) {
  ast_error(n, "more than 255 arguments");
  return NULL;
}

But note that this is in ast_for_call, and so only applys to the calling side. ie f(a,b,c,d,e...), rather than the definition, though it will count both positional (a,b,c,d) and keyword (a=1, b=2, c=3) style parameters . Actual *args and **kwargs parameters look like they should only count as one argument for these purposes on the calling side.

Brian