slightly modified version of Greg Ewing's extended call syntax patch

executive summary:
Instead of typing 'apply(f, args, kwargs)' you can type 'f(*arg, **kwargs)'.
Some file-by-file details follow.

Grammar/Grammar:
    simplify varargslist, replacing '*' '*' with '**'
    add * & ** options to arglist

Include/opcode.h & Lib/dis.py:
    define three new opcodes
        CALL_FUNCTION_VAR
        CALL_FUNCTION_KW
        CALL_FUNCTION_VAR_KW

Python/ceval.c:
    extend TypeError "keyword parameter redefined" message to include
        the name of the offending keyword
    reindent CALL_FUNCTION using four spaces
    add handling of sequences and dictionaries using extend calls
    fix function import_from to use PyErr_Format
diff --git a/Grammar/Grammar b/Grammar/Grammar
index dabf88e..57a39de 100644
--- a/Grammar/Grammar
+++ b/Grammar/Grammar
@@ -23,7 +23,7 @@
 
 funcdef: 'def' NAME parameters ':' suite
 parameters: '(' [varargslist] ')'
-varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME] | ('**'|'*' '*') NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [',']
+varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [',']
 fpdef: NAME | '(' fplist ')'
 fplist: fpdef (',' fpdef)* [',']
 
@@ -86,5 +86,5 @@
 
 classdef: 'class' NAME ['(' testlist ')'] ':' suite
 
-arglist:  argument (',' argument)* [',']
+arglist: (argument ',')* (argument [',']| '*' test [',' '**' test] | '**' test)
 argument: [test '='] test	# Really [keyword '='] test
diff --git a/Include/opcode.h b/Include/opcode.h
index 8b6890f..0e15497 100644
--- a/Include/opcode.h
+++ b/Include/opcode.h
@@ -138,10 +138,17 @@
    for new opcodes. */
 
 #define RAISE_VARARGS	130	/* Number of raise arguments (1, 2 or 3) */
+/* CALL_FUNCTION_XXX opcodes defined below depend on this definition */
 #define CALL_FUNCTION	131	/* #args + (#kwargs<<8) */
 #define MAKE_FUNCTION	132	/* #defaults */
 #define BUILD_SLICE 	133	/* Number of items */
 
+/* The next 3 opcodes must be contiguous and satisfy
+   (CALL_FUNCTION_STAR - CALL_FUNCTION) & 3 == 1  */
+#define CALL_FUNCTION_VAR          140	/* #args + (#kwargs<<8) */
+#define CALL_FUNCTION_KW           141	/* #args + (#kwargs<<8) */
+#define CALL_FUNCTION_VAR_KW       142	/* #args + (#kwargs<<8) */
+
 /* Comparison operator codes (argument to COMPARE_OP) */
 enum cmp_op {LT, LE, EQ, NE, GT, GE, IN, NOT_IN, IS, IS_NOT, EXC_MATCH, BAD};
 
diff --git a/Lib/dis.py b/Lib/dis.py
index 4c67642..899393d 100644
--- a/Lib/dis.py
+++ b/Lib/dis.py
@@ -247,10 +247,14 @@
 def_op('SET_LINENO', 127)	# Current line number
 SET_LINENO = 127
 
-def_op('RAISE_VARARGS', 130)
-def_op('CALL_FUNCTION', 131)
-def_op('MAKE_FUNCTION', 132)
-def_op('BUILD_SLICE', 133)
+def_op('RAISE_VARARGS', 130)    # Number of raise arguments (1, 2, or 3)
+def_op('CALL_FUNCTION', 131)    # #args + (#kwargs << 8)
+def_op('MAKE_FUNCTION', 132)    # Number of args with default values
+def_op('BUILD_SLICE', 133)      # Number of items
+
+def_op('CALL_FUNCTION_VAR', 140)     # #args + (#kwargs << 8)
+def_op('CALL_FUNCTION_KW', 141)      # #args + (#kwargs << 8)
+def_op('CALL_FUNCTION_VAR_KW', 142)  # #args + (#kwargs << 8)
 
 
 def _test():
diff --git a/Misc/ACKS b/Misc/ACKS
index 3fe3a90..82bd3e5 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -87,6 +87,7 @@
 Carey Evans
 Tim Everett
 Paul Everitt
+Greg Ewing
 Mark Favas
 Niels Ferguson
 Sebastian Fernandez
diff --git a/Python/ceval.c b/Python/ceval.c
index 46a60f1..7a97771 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -499,15 +499,16 @@
 				if (kwdict == NULL) {
 					PyErr_Format(PyExc_TypeError,
 					 "unexpected keyword argument: %.400s",
-					 PyString_AsString(keyword));
+					    PyString_AsString(keyword));
 					goto fail;
 				}
 				PyDict_SetItem(kwdict, keyword, value);
 			}
 			else {
 				if (GETLOCAL(j) != NULL) {
-					PyErr_SetString(PyExc_TypeError,
-						"keyword parameter redefined");
+					PyErr_Format(PyExc_TypeError, 
+				     "keyword parameter redefined: %.400s",
+					     PyString_AsString(keyword));
 					goto fail;
 				}
 				Py_INCREF(value);
@@ -1548,125 +1549,166 @@
 			break;
 
 		case CALL_FUNCTION:
+		case CALL_FUNCTION_VAR:
+		case CALL_FUNCTION_KW:
+		case CALL_FUNCTION_VAR_KW:
 		{
-			int na = oparg & 0xff;
-			int nk = (oparg>>8) & 0xff;
-			int n = na + 2*nk;
-			PyObject **pfunc = stack_pointer - n - 1;
-			PyObject *func = *pfunc;
-			PyObject *self = NULL;
-			PyObject *class = NULL;
-			f->f_lasti = INSTR_OFFSET() - 3; /* For tracing */
-			if (PyMethod_Check(func)) {
-				self = PyMethod_Self(func);
-				class = PyMethod_Class(func);
-				func = PyMethod_Function(func);
-				Py_INCREF(func);
-				if (self != NULL) {
-					Py_INCREF(self);
-					Py_DECREF(*pfunc);
-					*pfunc = self;
-					na++;
-					n++;
-				}
-				else {
-					/* Unbound methods must be
-					   called with an instance of
-					   the class (or a derived
-					   class) as first argument */
-					if (na > 0 &&
-					    (self = stack_pointer[-n])
-					 	!= NULL &&
-					    PyInstance_Check(self) &&
-					    PyClass_IsSubclass(
-						    (PyObject *)
-						    (((PyInstanceObject *)self)
-						     ->in_class),
-						    class))
-						/* Handy-dandy */ ;
-					else {
-						PyErr_SetString(
-							PyExc_TypeError,
-	   "unbound method must be called with class instance 1st argument");
-						x = NULL;
-						break;
-					}
-				}
-			}
-			else
-				Py_INCREF(func);
-			if (PyFunction_Check(func)) {
-				PyObject *co = PyFunction_GetCode(func);
-				PyObject *globals =
-					PyFunction_GetGlobals(func);
-				PyObject *argdefs =
-					PyFunction_GetDefaults(func);
-				PyObject **d;
-				int nd;
-				if (argdefs != NULL) {
-					d = &PyTuple_GET_ITEM(argdefs, 0);
-					nd = ((PyTupleObject *)argdefs) ->
-						ob_size;
-				}
-				else {
-					d = NULL;
-					nd = 0;
-				}
-				x = eval_code2(
-					(PyCodeObject *)co,
-					globals, (PyObject *)NULL,
-					stack_pointer-n, na,
-					stack_pointer-2*nk, nk,
-					d, nd,
-					class);
+		    int na = oparg & 0xff;
+		    int nk = (oparg>>8) & 0xff;
+		    int flags = (opcode - CALL_FUNCTION) & 3;
+		    int n = na + 2*nk + (flags & 1) + ((flags >> 1) & 1);
+		    PyObject **pfunc = stack_pointer - n - 1;
+		    PyObject *func = *pfunc;
+		    PyObject *self = NULL;
+		    PyObject *class = NULL;
+		    f->f_lasti = INSTR_OFFSET() - 3; /* For tracing */
+		    if (PyMethod_Check(func)) {
+			self = PyMethod_Self(func);
+			class = PyMethod_Class(func);
+			func = PyMethod_Function(func);
+			Py_INCREF(func);
+			if (self != NULL) {
+			    Py_INCREF(self);
+			    Py_DECREF(*pfunc);
+			    *pfunc = self;
+			    na++;
+			    n++;
 			}
 			else {
-				PyObject *args = PyTuple_New(na);
-				PyObject *kwdict = NULL;
-				if (args == NULL) {
-					x = NULL;
-					break;
+			    /* Unbound methods must be called with an
+			       instance of the class (or a derived
+			       class) as first argument */ 
+			    if (na > 0 && (self = stack_pointer[-n]) != NULL 
+				&& PyInstance_Check(self) 
+				&& PyClass_IsSubclass((PyObject *)
+				    (((PyInstanceObject *)self)->in_class),
+						      class))
+                                  /* Handy-dandy */ ;
+			    else {
+				PyErr_SetString(PyExc_TypeError,
+	    "unbound method must be called with class instance 1st argument");
+				x = NULL;
+				break;
+			    }
+			}
+		    }
+		    else
+			Py_INCREF(func);
+		    if (PyFunction_Check(func) && flags == 0) {
+			PyObject *co = PyFunction_GetCode(func);
+			PyObject *globals = PyFunction_GetGlobals(func);
+			PyObject *argdefs = PyFunction_GetDefaults(func);
+			PyObject **d;
+			int nd;
+			if (argdefs != NULL) {
+			    d = &PyTuple_GET_ITEM(argdefs, 0);
+			    nd = ((PyTupleObject *)argdefs)->ob_size;
+			}
+			else {
+			    d = NULL;
+			    nd = 0;
+			}
+			x = eval_code2((PyCodeObject *)co, globals, 
+				       (PyObject *)NULL, stack_pointer-n, na,
+				       stack_pointer-2*nk, nk, d, nd,
+				       class);
+		    }
+		    else {
+			int nstar = 0;
+			PyObject *args;
+			PyObject *stararg = 0;
+			PyObject *kwdict = NULL;
+			if (flags & 2) {
+			    kwdict = POP();
+			    if (!PyDict_Check(kwdict)) {
+				PyErr_SetString(PyExc_TypeError,
+					"** argument must be a dictionary");
+				x = NULL;
+				break;
+			    }
+			}
+			if (flags & 1) {
+			    stararg = POP();
+			    if (!PySequence_Check(stararg)) {
+				PyErr_SetString(PyExc_TypeError,
+					"* argument must be a sequence");
+				x = NULL;
+				break;
+			    }
+			    nstar = PySequence_Length(stararg);
+			}
+			if (nk > 0) {
+			    if (kwdict == NULL) {
+				kwdict = PyDict_New();
+				if (kwdict == NULL) {
+				    x = NULL;
+				    break;
 				}
-				if (nk > 0) {
-					kwdict = PyDict_New();
-					if (kwdict == NULL) {
-						x = NULL;
-						break;
-					}
-					err = 0;
-					while (--nk >= 0) {
-						PyObject *value = POP();
-						PyObject *key = POP();
-						err = PyDict_SetItem(
-							kwdict, key, value);
-						Py_DECREF(key);
-						Py_DECREF(value);
-						if (err)
-							break;
-					}
-					if (err) {
-						Py_DECREF(args);
-						Py_DECREF(kwdict);
-						break;
-					}
+			    }
+			    err = 0;
+			    while (--nk >= 0) {
+				PyObject *value = POP();
+				PyObject *key = POP();
+				if (PyDict_GetItem(kwdict, key) != NULL) {
+				    err = 1;
+				    PyErr_Format(PyExc_TypeError,
+					"keyword parameter redefined: %.400s",
+						 PyString_AsString(key));
+				    break;
 				}
-				while (--na >= 0) {
-					w = POP();
-					PyTuple_SET_ITEM(args, na, w);
-				}
-				x = PyEval_CallObjectWithKeywords(
-					func, args, kwdict);
+				err = PyDict_SetItem(kwdict, key, value);
+				Py_DECREF(key);
+				Py_DECREF(value);
+				if (err)
+				    break;
+			    }
+			    if (err) {
 				Py_DECREF(args);
-				Py_XDECREF(kwdict);
+				Py_DECREF(kwdict);
+				break;
+			    }
 			}
-			Py_DECREF(func);
-			while (stack_pointer > pfunc) {
-				w = POP();
-				Py_DECREF(w);
+			args = PyTuple_New(na + nstar);
+			if (args == NULL) {
+			    x = NULL;
+			    break;
 			}
-			PUSH(x);
-			if (x != NULL) continue;
-			break;
+			if (stararg) {
+			    PyObject *t = NULL;
+			    int i;
+			    if (!PyTuple_Check(stararg)) {
+				/* must be sequence to pass earlier test */
+				t = PySequence_Tuple(stararg);
+				if (t == NULL) {
+				    x = NULL;
+				    break;
+				}
+				Py_DECREF(stararg);
+				stararg = t;
+			    }
+			    for (i = 0; i < nstar; i++) {
+				PyObject *a = PyTuple_GET_ITEM(stararg, i);
+				Py_INCREF(a);
+				PyTuple_SET_ITEM(args, na + i, a);
+			    }
+			    Py_DECREF(stararg);
+			}
+			while (--na >= 0) {
+			    w = POP();
+			    PyTuple_SET_ITEM(args, na, w);
+			}
+			x = PyEval_CallObjectWithKeywords(func, args, kwdict);
+			Py_DECREF(args);
+			Py_XDECREF(kwdict);
+		    }
+		    Py_DECREF(func);
+		    while (stack_pointer > pfunc) {
+			w = POP();
+			Py_DECREF(w);
+		    }
+		    PUSH(x);
+		    if (x != NULL) continue;
+		    break;
 		}
 		
 		case MAKE_FUNCTION:
@@ -2687,10 +2729,9 @@
 	else {
 		x = PyDict_GetItem(w, name);
 		if (x == NULL) {
-			char buf[250];
-			sprintf(buf, "cannot import name %.230s",
-				PyString_AsString(name));
-			PyErr_SetString(PyExc_ImportError, buf);
+			PyErr_Format(PyExc_ImportError, 
+				     "cannot import name %.230s",
+				     PyString_AsString(name));
 			return -1;
 		}
 		else
diff --git a/Python/compile.c b/Python/compile.c
index 72848fa..1eed7c0 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -1185,11 +1185,17 @@
 		PyObject *keywords = NULL;
 		int i, na, nk;
 		int lineno = n->n_lineno;
+		int star_flag = 0;
+		int starstar_flag = 0;
+		int opcode;
 		REQ(n, arglist);
 		na = 0;
 		nk = 0;
 		for (i = 0; i < NCH(n); i += 2) {
 			node *ch = CHILD(n, i);
+			if (TYPE(ch) == STAR ||
+			    TYPE(ch) == DOUBLESTAR)
+			  break;
 			if (ch->n_lineno != lineno) {
 				lineno = ch->n_lineno;
 				com_addoparg(c, SET_LINENO, lineno);
@@ -1201,12 +1207,27 @@
 				nk++;
 		}
 		Py_XDECREF(keywords);
+		while (i < NCH(n)) {
+		    node *tok = CHILD(n, i);
+		    node *ch = CHILD(n, i+1);
+		    i += 3;
+		    switch (TYPE(tok)) {
+		    case STAR:       star_flag = 1;     break;
+		    case DOUBLESTAR: starstar_flag = 1;	break;
+		    }
+		    com_node(c, ch);
+		}
 		if (na > 255 || nk > 255) {
 			com_error(c, PyExc_SyntaxError,
 				  "more than 255 arguments");
 		}
-		com_addoparg(c, CALL_FUNCTION, na | (nk << 8));
-		com_pop(c, na + 2*nk);
+		if (star_flag || starstar_flag)
+		    opcode = CALL_FUNCTION_STAR - 1 + 
+			star_flag + (starstar_flag << 1);
+		else
+		    opcode = CALL_FUNCTION;
+		com_addoparg(c, opcode, na | (nk << 8));
+		com_pop(c, na + 2*nk + star_flag + starstar_flag);
 	}
 }
 
diff --git a/Python/graminit.c b/Python/graminit.c
index ba9359e..35d8de4 100644
--- a/Python/graminit.c
+++ b/Python/graminit.c
@@ -98,9 +98,8 @@
 	{22, 5},
 	{0, 1},
 };
-static arc arcs_5_2[2] = {
+static arc arcs_5_2[1] = {
 	{12, 6},
-	{23, 3},
 };
 static arc arcs_5_3[1] = {
 	{12, 7},
@@ -125,25 +124,20 @@
 	{22, 5},
 	{0, 8},
 };
-static arc arcs_5_9[2] = {
+static arc arcs_5_9[1] = {
 	{24, 3},
-	{23, 10},
 };
-static arc arcs_5_10[1] = {
-	{23, 3},
-};
-static state states_5[11] = {
+static state states_5[10] = {
 	{3, arcs_5_0},
 	{3, arcs_5_1},
-	{2, arcs_5_2},
+	{1, arcs_5_2},
 	{1, arcs_5_3},
 	{1, arcs_5_4},
 	{4, arcs_5_5},
 	{2, arcs_5_6},
 	{1, arcs_5_7},
 	{2, arcs_5_8},
-	{2, arcs_5_9},
-	{1, arcs_5_10},
+	{1, arcs_5_9},
 };
 static arc arcs_6_0[2] = {
 	{12, 1},
@@ -1169,21 +1163,46 @@
 	{1, arcs_54_6},
 	{1, arcs_54_7},
 };
-static arc arcs_55_0[1] = {
+static arc arcs_55_0[3] = {
 	{123, 1},
+	{23, 2},
+	{24, 3},
 };
 static arc arcs_55_1[2] = {
-	{22, 2},
+	{22, 4},
 	{0, 1},
 };
-static arc arcs_55_2[2] = {
-	{123, 1},
-	{0, 2},
+static arc arcs_55_2[1] = {
+	{21, 5},
 };
-static state states_55[3] = {
-	{1, arcs_55_0},
+static arc arcs_55_3[1] = {
+	{21, 6},
+};
+static arc arcs_55_4[4] = {
+	{123, 1},
+	{23, 2},
+	{24, 3},
+	{0, 4},
+};
+static arc arcs_55_5[2] = {
+	{22, 7},
+	{0, 5},
+};
+static arc arcs_55_6[1] = {
+	{0, 6},
+};
+static arc arcs_55_7[1] = {
+	{24, 3},
+};
+static state states_55[8] = {
+	{3, arcs_55_0},
 	{2, arcs_55_1},
-	{2, arcs_55_2},
+	{1, arcs_55_2},
+	{1, arcs_55_3},
+	{4, arcs_55_4},
+	{2, arcs_55_5},
+	{1, arcs_55_6},
+	{1, arcs_55_7},
 };
 static arc arcs_56_0[1] = {
 	{21, 1},
@@ -1215,7 +1234,7 @@
 	 "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
 	{260, "parameters", 0, 4, states_4,
 	 "\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000\000"},
-	{261, "varargslist", 0, 11, states_5,
+	{261, "varargslist", 0, 10, states_5,
 	 "\000\020\201\001\000\000\000\000\000\000\000\000\000\000\000\000"},
 	{262, "fpdef", 0, 4, states_6,
 	 "\000\020\001\000\000\000\000\000\000\000\000\000\000\000\000\000"},
@@ -1315,8 +1334,8 @@
 	 "\000\020\001\000\000\000\000\000\000\200\000\000\060\242\074\000"},
 	{310, "classdef", 0, 8, states_54,
 	 "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004"},
-	{311, "arglist", 0, 3, states_55,
-	 "\000\020\001\000\000\000\000\000\000\200\000\000\060\242\074\000"},
+	{311, "arglist", 0, 8, states_55,
+	 "\000\020\201\001\000\000\000\000\000\200\000\000\060\242\074\000"},
 	{312, "argument", 0, 4, states_56,
 	 "\000\020\001\000\000\000\000\000\000\200\000\000\060\242\074\000"},
 };