summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2006-10-27 23:31:49 (GMT)
committerGuido van Rossum <guido@python.org>2006-10-27 23:31:49 (GMT)
commit4f72a78684bbfcdc43ceeabb240ceee54706c4b0 (patch)
tree743c27c5125dcef580cffe77395fe97bedf40d5f /Python/ceval.c
parentfc2a0a8e3cb1d40fd965576060c28c8bd2ea1ad5 (diff)
downloadcpython-4f72a78684bbfcdc43ceeabb240ceee54706c4b0.zip
cpython-4f72a78684bbfcdc43ceeabb240ceee54706c4b0.tar.gz
cpython-4f72a78684bbfcdc43ceeabb240ceee54706c4b0.tar.bz2
Jiwon Seo's PEP 3102 implementation.
See SF#1549670. The compiler package has not yet been updated.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c78
1 files changed, 64 insertions, 14 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index dcbe53d..5d5acd0 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -494,7 +494,7 @@ PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
(PyObject **)NULL, 0,
(PyObject **)NULL, 0,
(PyObject **)NULL, 0,
- NULL);
+ NULL, NULL);
}
@@ -2290,26 +2290,46 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
}
case MAKE_FUNCTION:
+ {
+ int posdefaults = oparg & 0xff;
+ int kwdefaults = (oparg>>8) & 0xff;
+
v = POP(); /* code object */
x = PyFunction_New(v, f->f_globals);
Py_DECREF(v);
/* XXX Maybe this should be a separate opcode? */
- if (x != NULL && oparg > 0) {
- v = PyTuple_New(oparg);
+ if (x != NULL && posdefaults > 0) {
+ v = PyTuple_New(posdefaults);
if (v == NULL) {
Py_DECREF(x);
x = NULL;
break;
}
- while (--oparg >= 0) {
+ while (--posdefaults >= 0) {
w = POP();
- PyTuple_SET_ITEM(v, oparg, w);
+ PyTuple_SET_ITEM(v, posdefaults, w);
}
err = PyFunction_SetDefaults(x, v);
Py_DECREF(v);
}
+ if (x != NULL && kwdefaults > 0) {
+ v = PyDict_New();
+ if (v == NULL) {
+ Py_DECREF(x);
+ x = NULL;
+ break;
+ }
+ while (--kwdefaults >= 0) {
+ w = POP(); /* default value */
+ u = POP(); /* kw only arg name */
+ PyDict_SetItem(v, u, w);
+ }
+ err = PyFunction_SetKwDefaults(x, v);
+ Py_DECREF(v);
+ }
PUSH(x);
break;
+ }
case MAKE_CLOSURE:
{
@@ -2577,7 +2597,7 @@ fast_yield:
PyObject *
PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
PyObject **args, int argcount, PyObject **kws, int kwcount,
- PyObject **defs, int defcount, PyObject *closure)
+ PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure)
{
register PyFrameObject *f;
register PyObject *retval = NULL;
@@ -2601,6 +2621,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
freevars = f->f_localsplus + co->co_nlocals;
if (co->co_argcount > 0 ||
+ co->co_kwonlyargcount > 0 ||
co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) {
int i;
int n = argcount;
@@ -2609,7 +2630,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
kwdict = PyDict_New();
if (kwdict == NULL)
goto fail;
- i = co->co_argcount;
+ i = co->co_argcount + co->co_kwonlyargcount;
if (co->co_flags & CO_VARARGS)
i++;
SETLOCAL(i, kwdict);
@@ -2618,7 +2639,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
if (!(co->co_flags & CO_VARARGS)) {
PyErr_Format(PyExc_TypeError,
"%.200s() takes %s %d "
- "%sargument%s (%d given)",
+ "%spositional argument%s (%d given)",
PyString_AsString(co->co_name),
defcount ? "at most" : "exactly",
co->co_argcount,
@@ -2638,7 +2659,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
u = PyTuple_New(argcount - n);
if (u == NULL)
goto fail;
- SETLOCAL(co->co_argcount, u);
+ SETLOCAL(co->co_argcount + co->co_kwonlyargcount, u);
for (i = n; i < argcount; i++) {
x = args[i];
Py_INCREF(x);
@@ -2656,7 +2677,9 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
goto fail;
}
/* XXX slow -- speed up using dictionary? */
- for (j = 0; j < co->co_argcount; j++) {
+ for (j = 0;
+ j < co->co_argcount + co->co_kwonlyargcount;
+ j++) {
PyObject *nm = PyTuple_GET_ITEM(
co->co_varnames, j);
int cmp = PyObject_RichCompareBool(
@@ -2669,7 +2692,7 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
/* Check errors from Compare */
if (PyErr_Occurred())
goto fail;
- if (j >= co->co_argcount) {
+ if (j >= co->co_argcount + co->co_kwonlyargcount) {
if (kwdict == NULL) {
PyErr_Format(PyExc_TypeError,
"%.200s() got an unexpected "
@@ -2694,13 +2717,38 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
SETLOCAL(j, value);
}
}
+ if (co->co_kwonlyargcount > 0) {
+ for (i = co->co_argcount;
+ i < co->co_argcount + co->co_kwonlyargcount;
+ i++) {
+ if (GETLOCAL(i) != NULL)
+ continue;
+ PyObject *name =
+ PyTuple_GET_ITEM(co->co_varnames, i);
+ PyObject *def = NULL;
+ if (kwdefs != NULL)
+ def = PyDict_GetItem(kwdefs, name);
+ if (def != NULL) {
+ Py_INCREF(def);
+ SETLOCAL(i, def);
+ continue;
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() needs "
+ "keyword only argument %s",
+ PyString_AsString(co->co_name),
+ PyString_AsString(name));
+ goto fail;
+ }
+ }
if (argcount < co->co_argcount) {
int m = co->co_argcount - defcount;
for (i = argcount; i < m; i++) {
if (GETLOCAL(i) == NULL) {
PyErr_Format(PyExc_TypeError,
"%.200s() takes %s %d "
- "%sargument%s (%d given)",
+ "%spositional argument%s "
+ "(%d given)",
PyString_AsString(co->co_name),
((co->co_flags & CO_VARARGS) ||
defcount) ? "at least"
@@ -3565,12 +3613,14 @@ fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk)
PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
PyObject *globals = PyFunction_GET_GLOBALS(func);
PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
+ PyObject *kwdefs = PyFunction_GET_KW_DEFAULTS(func);
PyObject **d = NULL;
int nd = 0;
PCALL(PCALL_FUNCTION);
PCALL(PCALL_FAST_FUNCTION);
- if (argdefs == NULL && co->co_argcount == n && nk==0 &&
+ if (argdefs == NULL && co->co_argcount == n &&
+ co->co_kwonlyargcount == 0 && nk==0 &&
co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) {
PyFrameObject *f;
PyObject *retval = NULL;
@@ -3608,7 +3658,7 @@ fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk)
}
return PyEval_EvalCodeEx(co, globals,
(PyObject *)NULL, (*pp_stack)-n, na,
- (*pp_stack)-2*nk, nk, d, nd,
+ (*pp_stack)-2*nk, nk, d, nd, kwdefs,
PyFunction_GET_CLOSURE(func));
}