[Python-checkins] CVS: python/dist/src/Python ceval.c,2.168,2.169 compile.c,2.100,2.101 graminit.c,2.22,2.23
Jeremy Hylton
python-dev@python.org
Tue, 28 Mar 2000 18:49:20 -0500
Update of /projects/cvsroot/python/dist/src/Python
In directory goon.cnri.reston.va.us:/home/jhylton/python/src/Python
Modified Files:
ceval.c compile.c graminit.c
Log Message:
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
Index: ceval.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Python/ceval.c,v
retrieving revision 2.168
retrieving revision 2.169
diff -C2 -r2.168 -r2.169
*** ceval.c 2000/02/23 22:18:48 2.168
--- ceval.c 2000/03/28 23:49:16 2.169
***************
*** 500,504 ****
PyErr_Format(PyExc_TypeError,
"unexpected keyword argument: %.400s",
! PyString_AsString(keyword));
goto fail;
}
--- 500,504 ----
PyErr_Format(PyExc_TypeError,
"unexpected keyword argument: %.400s",
! PyString_AsString(keyword));
goto fail;
}
***************
*** 507,512 ****
else {
if (GETLOCAL(j) != NULL) {
! PyErr_SetString(PyExc_TypeError,
! "keyword parameter redefined");
goto fail;
}
--- 507,513 ----
else {
if (GETLOCAL(j) != NULL) {
! PyErr_Format(PyExc_TypeError,
! "keyword parameter redefined: %.400s",
! PyString_AsString(keyword));
goto fail;
}
***************
*** 1549,1671 ****
case CALL_FUNCTION:
{
! 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);
}
else {
! PyObject *args = PyTuple_New(na);
! PyObject *kwdict = NULL;
! if (args == 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;
! }
! }
! 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;
}
--- 1550,1713 ----
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 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 {
! /* 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;
! }
! }
! 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;
! }
! err = PyDict_SetItem(kwdict, key, value);
! Py_DECREF(key);
! Py_DECREF(value);
! if (err)
! break;
! }
! if (err) {
! Py_DECREF(args);
! Py_DECREF(kwdict);
! break;
! }
! }
! args = PyTuple_New(na + nstar);
! if (args == NULL) {
! x = NULL;
! 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;
}
***************
*** 2688,2695 ****
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);
return -1;
}
--- 2730,2736 ----
x = PyDict_GetItem(w, name);
if (x == NULL) {
! PyErr_Format(PyExc_ImportError,
! "cannot import name %.230s",
! PyString_AsString(name));
return -1;
}
Index: compile.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Python/compile.c,v
retrieving revision 2.100
retrieving revision 2.101
diff -C2 -r2.100 -r2.101
*** compile.c 2000/03/10 23:01:36 2.100
--- compile.c 2000/03/28 23:49:16 2.101
***************
*** 1186,1189 ****
--- 1186,1192 ----
int i, na, nk;
int lineno = n->n_lineno;
+ int star_flag = 0;
+ int starstar_flag = 0;
+ int opcode;
REQ(n, arglist);
na = 0;
***************
*** 1191,1194 ****
--- 1194,1200 ----
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;
***************
*** 1202,1211 ****
}
Py_XDECREF(keywords);
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);
}
}
--- 1208,1232 ----
}
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");
}
! 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);
}
}
Index: graminit.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Python/graminit.c,v
retrieving revision 2.22
retrieving revision 2.23
diff -C2 -r2.22 -r2.23
*** graminit.c 1998/04/09 21:38:55 2.22
--- graminit.c 2000/03/28 23:49:17 2.23
***************
*** 99,105 ****
{0, 1},
};
! static arc arcs_5_2[2] = {
{12, 6},
- {23, 3},
};
static arc arcs_5_3[1] = {
--- 99,104 ----
{0, 1},
};
! static arc arcs_5_2[1] = {
{12, 6},
};
static arc arcs_5_3[1] = {
***************
*** 126,140 ****
{0, 8},
};
! static arc arcs_5_9[2] = {
{24, 3},
- {23, 10},
};
! static arc arcs_5_10[1] = {
! {23, 3},
! };
! static state states_5[11] = {
{3, arcs_5_0},
{3, arcs_5_1},
! {2, arcs_5_2},
{1, arcs_5_3},
{1, arcs_5_4},
--- 125,135 ----
{0, 8},
};
! static arc arcs_5_9[1] = {
{24, 3},
};
! static state states_5[10] = {
{3, arcs_5_0},
{3, arcs_5_1},
! {1, arcs_5_2},
{1, arcs_5_3},
{1, arcs_5_4},
***************
*** 143,148 ****
{1, arcs_5_7},
{2, arcs_5_8},
! {2, arcs_5_9},
! {1, arcs_5_10},
};
static arc arcs_6_0[2] = {
--- 138,142 ----
{1, arcs_5_7},
{2, arcs_5_8},
! {1, arcs_5_9},
};
static arc arcs_6_0[2] = {
***************
*** 1170,1188 ****
{1, arcs_54_7},
};
! static arc arcs_55_0[1] = {
{123, 1},
};
static arc arcs_55_1[2] = {
! {22, 2},
{0, 1},
};
! static arc arcs_55_2[2] = {
{123, 1},
! {0, 2},
};
! static state states_55[3] = {
! {1, arcs_55_0},
{2, arcs_55_1},
! {2, arcs_55_2},
};
static arc arcs_56_0[1] = {
--- 1164,1207 ----
{1, arcs_54_7},
};
! static arc arcs_55_0[3] = {
{123, 1},
+ {23, 2},
+ {24, 3},
};
static arc arcs_55_1[2] = {
! {22, 4},
{0, 1},
};
! static arc arcs_55_2[1] = {
! {21, 5},
! };
! 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},
! {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] = {
***************
*** 1216,1220 ****
{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,
"\000\020\201\001\000\000\000\000\000\000\000\000\000\000\000\000"},
{262, "fpdef", 0, 4, states_6,
--- 1235,1239 ----
{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, 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,
***************
*** 1316,1321 ****
{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"},
{312, "argument", 0, 4, states_56,
"\000\020\001\000\000\000\000\000\000\200\000\000\060\242\074\000"},
--- 1335,1340 ----
{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, 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"},