This enhancement extends the procedure calling syntax of Python 1.5.2 to allow passing a tuple and/or dictionary of extra arguments without the need to use apply. This is mainly intended for passing arguments on to an inherited method, for example,
class MyClass(AnotherClass):def __init__(self, fee, fie, fo, *args, **kw):AnotherClass.__init__(self, *args, **kw)
extcall.tar.gz
(4732 bytes, last updated 29 August 1999)
arguments :== (argument ',')* (argument | '*' test | '**' test | '*' test , '**' test)The '*' argument, if present, must be a tuple, and its contents are appended to the ordinary arguments before making the call. The '**' argument, if present, must be a dictionary, and any explicit keyword arguments are added to it before making the call. If there are any collisions between the explicit keyword arguments and the contents of the '**' dictionary, the explicit keyword arguments take precedence.
The '**' must be two consecutive stars with no space between, unlike the corresponding syntax for a formal parameter list, which allows whitespace between them. If this causes anyone great hardship it could be fixed, but I don't consider it worth the bother right now.
CALL_FUNCTION_STARone for each of the possible combinations of * and ** arguments. The * and ** arguments are simply pushed onto the stack after the regular arguments, and the appropriate opcode emitted.
CALL_FUNCTION_STARSTAR
CALL_FUNCTION_STAR_STARSTAR
All the new opcodes lead to the existing code for CALL_FUNCTION in ceval.c, which has been modified to test the opcode and do the appropriate things with the extra arguments. The special case which calls eval_code2 directly when the called object is a PyFunctionObject is only used when there is no * or ** argument. When there is, the code for the general case is entered.
If there is a * argument, an argument tuple is created which is big
enough for the explicit arguments plus the contents of the * tuple, and
all of these are copied into it. If there is a ** argument, instead of
creating a new keyword dictionary, the ** dictionary is used as a starting
point; any explicit keyword arguments are then added to it. The resulting
tuple and dictionary are then passed to PyObject_CallObjectWithKeywords
as usual.