[Python-ideas] New 3.x restriction on number of keyword arguments

M.-A. Lemburg mal at egenix.com
Tue Oct 26 16:37:29 CEST 2010


Cesare Di Mauro wrote:
> 2010/10/26 M.-A. Lemburg <mal at egenix.com>
> 
>> Cesare Di Mauro wrote:
>>  > I can provide another patch that will not use EXTENDED_ARG (no VM
>> changes),
>>> and uses *args and/or **kwargs function calls when there are more than
>> 255
>>> arguments or keyword arguments.
>>>
>>> But I need some days.
>>>
>>> If needed, I'll post it at most on this week-end.
>>
>> You mean a version that pushes the *args tuple and **kws dict
>> on the stack and then uses those for calling the function/method ?
>>
>> I think that would be a lot more efficient than pushing/popping
>> hundreds of parameters on/off the stack.
>>
>> --
>>  Marc-Andre Lemburg
>>
> 
> I was referring to the solution (which I prefer) that I proposed answering
> to Greg, two days ago.
> 
> Unfortunately, the stack must be used whatever the solution we will use.
> 
> Pushing the "final" tuple and/or dictionary is a possible optimization, but
> we can use it only when we have a tuple or dict of constants; otherwise we
> need to use the stack.
> 
> Good case:  f(1, 2, 3, a = 1, b = 2)
> We can push (1, 2, 3) tuple and {'a' : 1, 'b' : 2}, then calling f with
> CALL_FUNCTION_VAR_KW opcode passing narg = nkarg = 0.
> 
> Worst case: f(1, x, 3, a = x, b = 2)
> We can't push the tuple and dict as a whole, because they need first to be
> built using the stack.
> 
> The good case is possible, and I have already done some work in wpython
> collecting constants on parameters push (even partial constant sequences),
> but some additional work must be done recognizing costants-only tuple /
> dict.
> 
> However, the worst case rest unresolved.

I don't understand. What is the difference between pushing values
on the stack and building a tuple/dict and then pushing those on
the stack ?

In your worst case example, the compiler would first build
a tuple/dict using the args already on the stack (BUILD_TUPLE,
BUILD_MAP) and then call the function with this tuple/dict
combination - you'd basically move the tuple/dict building to
the compiler rather than having the CALL* opcodes do this
internally.

It would essentially run:

f(*(1,x,3), **{'a':x, 'b':2})

and bypass the "max. number of opcode args" limit without
degrading performance, since BUILD_TUPLE et al. essentially
run the same code for building the call arguments as the
helpers for calling a function.

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Source  (#1, Oct 26 2010)
>>> Python/Zope Consulting and Support ...        http://www.egenix.com/
>>> mxODBC.Zope.Database.Adapter ...             http://zope.egenix.com/
>>> mxODBC, mxDateTime, mxTextTools ...        http://python.egenix.com/
________________________________________________________________________

::: Try our new mxODBC.Connect Python Database Interface for free ! ::::


   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
    D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
           Registered at Amtsgericht Duesseldorf: HRB 46611
               http://www.egenix.com/company/contact/



More information about the Python-ideas mailing list