Joe Jevnik added the comment:

in _PyEval_EvalCodeWithName we will have already pulled the underlying array 
out of the tuple subclass and the then we will reconstruct the vararg value in 
the locals from this array. This means that with this patch we can get:

>>> class C(tuple): pass
... 
>>> def f(*args): print(type(args))
... 
>>> f(*C([1, 2, 3]))
<class 'tuple'>

The only case where we get potentially strange behavior is if we have a type 
whose tp_call did not forward to PyArg_Parse* or the PyTupleObject api and went 
though the abstract object interface. I ran the tests and the benchmark suite 
and did not run into any issues here but I can see how this would be 
potentially problematic behavior.

I have updated the code to also do a PyTuple_CheckExact against `stararg`. The 
tests I ran are:

timeit("h(*(a, b, c, d, e, f, g))", 'def h(a, b, c, d, e, f, g): pass\na, b, c, 
d, e, f, g = range(7)', number=int(10e7))

default: 17.191688070015516
patch: 14.060781285981648

There is also a really great case where you star unpack a tuple of literals 
which gets pushed into the co_consts:

timeit("f(*('a', 'b', 'c', 'd', 'e', 'f', 'g'))", 'def f(a, b, c, d, e, f, g): 
pass', number=int(10e7))

default: 13.842308042978402
patch: 9.696972723002546

This case seems far less common, but maybe someone has something like:

a = 1, 2, 3
...
f(*a)

----------
type: performance -> 
Added file: http://bugs.python.org/file42515/call-function-var.patch

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue26802>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to