mirror of https://github.com/python/cpython
3rd arg for raise; INCOMPLETE keyword parameter passing (currently f(kw=value) is seen as f('kw', value))
This commit is contained in:
parent
7faeab3103
commit
f10570b9eb
181
Python/ceval.c
181
Python/ceval.c
|
@ -775,43 +775,88 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
case BREAK_LOOP:
|
case BREAK_LOOP:
|
||||||
why = WHY_BREAK;
|
why = WHY_BREAK;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RAISE_EXCEPTION:
|
case RAISE_EXCEPTION:
|
||||||
v = POP();
|
oparg = 2;
|
||||||
w = POP();
|
/* Fallthrough */
|
||||||
|
case RAISE_VARARGS:
|
||||||
|
u = v = w = NULL;
|
||||||
|
switch (oparg) {
|
||||||
|
case 3:
|
||||||
|
u = POP(); /* traceback */
|
||||||
|
if (u == None) {
|
||||||
|
DECREF(u);
|
||||||
|
u = NULL;
|
||||||
|
}
|
||||||
|
else if (strcmp(u->ob_type->tp_name,
|
||||||
|
"traceback") != 0) {
|
||||||
|
/* XXX traceback.h needs to define
|
||||||
|
is_traceback() */
|
||||||
|
err_setstr(TypeError,
|
||||||
|
"raise 3rd arg must be traceback or None");
|
||||||
|
goto raise_error;
|
||||||
|
}
|
||||||
|
/* Fallthrough */
|
||||||
|
case 2:
|
||||||
|
v = POP(); /* value */
|
||||||
|
/* Fallthrough */
|
||||||
|
case 1:
|
||||||
|
w = POP(); /* exc */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
err_setstr(SystemError,
|
||||||
|
"bad RAISE_VARARGS oparg");
|
||||||
|
goto raise_error;
|
||||||
|
}
|
||||||
|
if (v == NULL) {
|
||||||
|
v = None;
|
||||||
|
INCREF(v);
|
||||||
|
}
|
||||||
/* A tuple is equivalent to its first element here */
|
/* A tuple is equivalent to its first element here */
|
||||||
while (is_tupleobject(w) && gettuplesize(w) > 0) {
|
while (is_tupleobject(w) && gettuplesize(w) > 0) {
|
||||||
u = w;
|
object *t = w;
|
||||||
w = GETTUPLEITEM(u, 0);
|
w = GETTUPLEITEM(t, 0);
|
||||||
INCREF(w);
|
INCREF(w);
|
||||||
DECREF(u);
|
DECREF(t);
|
||||||
}
|
}
|
||||||
if (is_stringobject(w)) {
|
if (is_stringobject(w)) {
|
||||||
err_setval(w, v);
|
;
|
||||||
} else if (is_classobject(w)) {
|
} else if (is_classobject(w)) {
|
||||||
if (!is_instanceobject(v)
|
if (!is_instanceobject(v)
|
||||||
|| !issubclass((object*)((instanceobject*)v)->in_class,
|
|| !issubclass((object*)((instanceobject*)v)->in_class,
|
||||||
w))
|
w)) {
|
||||||
err_setstr(TypeError,
|
err_setstr(TypeError,
|
||||||
"a class exception must have a value that is an instance of the class");
|
"a class exception must have a value that is an instance of the class");
|
||||||
else
|
goto raise_error;
|
||||||
err_setval(w,v);
|
}
|
||||||
} else if (is_instanceobject(w)) {
|
} else if (is_instanceobject(w)) {
|
||||||
if (v != None)
|
if (v != None) {
|
||||||
err_setstr(TypeError,
|
err_setstr(TypeError,
|
||||||
"an instance exception may not have a separate value");
|
"an instance exception may not have a separate value");
|
||||||
|
goto raise_error;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
DECREF(v);
|
DECREF(v);
|
||||||
v = w;
|
v = w;
|
||||||
w = (object*) ((instanceobject*)w)->in_class;
|
w = (object*) ((instanceobject*)w)->in_class;
|
||||||
INCREF(w);
|
INCREF(w);
|
||||||
err_setval(w, v);
|
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
|
else {
|
||||||
err_setstr(TypeError,
|
err_setstr(TypeError,
|
||||||
"exceptions must be strings, classes, or instances");
|
"exceptions must be strings, classes, or instances");
|
||||||
DECREF(v);
|
goto raise_error;
|
||||||
DECREF(w);
|
}
|
||||||
|
err_restore(w, v, u);
|
||||||
|
if (u == NULL)
|
||||||
|
why = WHY_EXCEPTION;
|
||||||
|
else
|
||||||
|
why = WHY_RERAISE;
|
||||||
|
break;
|
||||||
|
raise_error:
|
||||||
|
XDECREF(v);
|
||||||
|
XDECREF(w);
|
||||||
|
XDECREF(u);
|
||||||
why = WHY_EXCEPTION;
|
why = WHY_EXCEPTION;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -876,11 +921,8 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
}
|
}
|
||||||
else if (is_stringobject(v) || is_classobject(v)) {
|
else if (is_stringobject(v) || is_classobject(v)) {
|
||||||
w = POP();
|
w = POP();
|
||||||
err_setval(v, w);
|
u = POP();
|
||||||
DECREF(w);
|
err_restore(v, w, u);
|
||||||
w = POP();
|
|
||||||
tb_store(w);
|
|
||||||
DECREF(w);
|
|
||||||
why = WHY_RERAISE;
|
why = WHY_RERAISE;
|
||||||
}
|
}
|
||||||
else if (v != None) {
|
else if (v != None) {
|
||||||
|
@ -1000,6 +1042,7 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
err_setstr(TypeError,
|
err_setstr(TypeError,
|
||||||
"bad argument list");
|
"bad argument list");
|
||||||
why = WHY_EXCEPTION;
|
why = WHY_EXCEPTION;
|
||||||
|
DECREF(v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
n = gettuplesize(v);
|
n = gettuplesize(v);
|
||||||
|
@ -1308,8 +1351,7 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
}
|
}
|
||||||
x = call_object(x, w);
|
x = call_object(x, w);
|
||||||
DECREF(w);
|
DECREF(w);
|
||||||
if (x)
|
PUSH(x);
|
||||||
PUSH(x);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IMPORT_FROM:
|
case IMPORT_FROM:
|
||||||
|
@ -1402,6 +1444,85 @@ eval_code(co, globals, locals, owner, arg)
|
||||||
f, "line", None);
|
f, "line", None);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CALL_FUNCTION:
|
||||||
|
{
|
||||||
|
/* XXX To do:
|
||||||
|
- fill in default arguments here
|
||||||
|
- proper handling of keyword parameters
|
||||||
|
- change eval_code interface to take an
|
||||||
|
array of arguments instead of a tuple
|
||||||
|
*/
|
||||||
|
int na = oparg & 0xff;
|
||||||
|
int nk = (oparg>>8) & 0xff;
|
||||||
|
int n = na + 2*nk;
|
||||||
|
object **pfunc = stack_pointer - n - 1;
|
||||||
|
object *func = *pfunc;
|
||||||
|
object *self = NULL;
|
||||||
|
object *class = NULL;
|
||||||
|
object *args;
|
||||||
|
f->f_lasti = INSTR_OFFSET() - 3; /* For tracing */
|
||||||
|
INCREF(func);
|
||||||
|
if (is_instancemethodobject(func)) {
|
||||||
|
self = instancemethodgetself(func);
|
||||||
|
if (self != NULL) {
|
||||||
|
class = instancemethodgetclass(func);
|
||||||
|
DECREF(func);
|
||||||
|
func = instancemethodgetfunc(func);
|
||||||
|
INCREF(func);
|
||||||
|
INCREF(self);
|
||||||
|
DECREF(*pfunc);
|
||||||
|
*pfunc = self;
|
||||||
|
na++;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args = newtupleobject(n);
|
||||||
|
if (args == NULL)
|
||||||
|
x = NULL;
|
||||||
|
else {
|
||||||
|
while (--n >= 0) {
|
||||||
|
w = POP();
|
||||||
|
SETTUPLEITEM(args, n, w);
|
||||||
|
}
|
||||||
|
if (self == NULL)
|
||||||
|
POP();
|
||||||
|
if (is_funcobject(func)) {
|
||||||
|
int argcount;
|
||||||
|
object *argdefs =
|
||||||
|
getfuncargstuff(func, &argcount);
|
||||||
|
if (argdefs == NULL) { /* Fast path */
|
||||||
|
object *co, *loc, *glob;
|
||||||
|
co = getfunccode(func);
|
||||||
|
loc = newdictobject();
|
||||||
|
if (loc == NULL) {
|
||||||
|
x = NULL;
|
||||||
|
DECREF(func);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
glob = getfuncglobals(func);
|
||||||
|
INCREF(glob);
|
||||||
|
x = eval_code(
|
||||||
|
(codeobject *)co,
|
||||||
|
glob,
|
||||||
|
loc,
|
||||||
|
class,
|
||||||
|
args);
|
||||||
|
DECREF(glob);
|
||||||
|
DECREF(loc);
|
||||||
|
DECREF(args);
|
||||||
|
DECREF(func);
|
||||||
|
PUSH(x);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x = call_object(func, args);
|
||||||
|
DECREF(args);
|
||||||
|
PUSH(x);
|
||||||
|
}
|
||||||
|
DECREF(func);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
@ -1613,7 +1734,7 @@ call_trace(p_trace, p_newtrace, f, msg, arg)
|
||||||
char *msg;
|
char *msg;
|
||||||
object *arg;
|
object *arg;
|
||||||
{
|
{
|
||||||
object *arglist, *what;
|
object *args, *what;
|
||||||
object *res = NULL;
|
object *res = NULL;
|
||||||
static int tracing = 0;
|
static int tracing = 0;
|
||||||
|
|
||||||
|
@ -1626,26 +1747,26 @@ call_trace(p_trace, p_newtrace, f, msg, arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
arglist = newtupleobject(3);
|
args = newtupleobject(3);
|
||||||
if (arglist == NULL)
|
if (args == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
what = newstringobject(msg);
|
what = newstringobject(msg);
|
||||||
if (what == NULL)
|
if (what == NULL)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
INCREF(f);
|
INCREF(f);
|
||||||
SETTUPLEITEM(arglist, 0, (object *)f);
|
SETTUPLEITEM(args, 0, (object *)f);
|
||||||
SETTUPLEITEM(arglist, 1, what);
|
SETTUPLEITEM(args, 1, what);
|
||||||
if (arg == NULL)
|
if (arg == NULL)
|
||||||
arg = None;
|
arg = None;
|
||||||
INCREF(arg);
|
INCREF(arg);
|
||||||
SETTUPLEITEM(arglist, 2, arg);
|
SETTUPLEITEM(args, 2, arg);
|
||||||
tracing++;
|
tracing++;
|
||||||
fast_2_locals(f);
|
fast_2_locals(f);
|
||||||
res = call_object(*p_trace, arglist); /* May clear *p_trace! */
|
res = call_object(*p_trace, args); /* May clear *p_trace! */
|
||||||
locals_2_fast(f, 1);
|
locals_2_fast(f, 1);
|
||||||
tracing--;
|
tracing--;
|
||||||
cleanup:
|
cleanup:
|
||||||
XDECREF(arglist);
|
XDECREF(args);
|
||||||
if (res == NULL) {
|
if (res == NULL) {
|
||||||
/* The trace proc raised an exception */
|
/* The trace proc raised an exception */
|
||||||
tb_here(f);
|
tb_here(f);
|
||||||
|
|
100
Python/compile.c
100
Python/compile.c
|
@ -782,19 +782,72 @@ com_apply_subscript(c, n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
com_argument(c, n, inkeywords)
|
||||||
|
struct compiling *c;
|
||||||
|
node *n; /* argument */
|
||||||
|
int inkeywords;
|
||||||
|
{
|
||||||
|
node *m;
|
||||||
|
REQ(n, argument); /* [test '='] test; really [ keyword '='] keyword */
|
||||||
|
if (NCH(n) == 1) {
|
||||||
|
if (inkeywords) {
|
||||||
|
err_setstr(SyntaxError,
|
||||||
|
"non-keyword arg after keyword arg");
|
||||||
|
c->c_errors++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
com_node(c, CHILD(n, 0));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
m = n;
|
||||||
|
do {
|
||||||
|
m = CHILD(m, 0);
|
||||||
|
} while (NCH(m) == 1);
|
||||||
|
if (TYPE(m) != NAME) {
|
||||||
|
err_setstr(SyntaxError, "keyword can't be an expression");
|
||||||
|
c->c_errors++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
object *v = newstringobject(STR(m));
|
||||||
|
if (v == NULL)
|
||||||
|
c->c_errors++;
|
||||||
|
else {
|
||||||
|
com_addoparg(c, LOAD_CONST, com_addconst(c, v));
|
||||||
|
DECREF(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
com_node(c, CHILD(n, 2));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
com_call_function(c, n)
|
com_call_function(c, n)
|
||||||
struct compiling *c;
|
struct compiling *c;
|
||||||
node *n; /* EITHER testlist OR ')' */
|
node *n; /* EITHER arglist OR ')' */
|
||||||
{
|
{
|
||||||
if (TYPE(n) == RPAR) {
|
if (TYPE(n) == RPAR) {
|
||||||
com_addoparg(c, BUILD_TUPLE, 0);
|
com_addoparg(c, CALL_FUNCTION, 0);
|
||||||
com_addbyte(c, BINARY_CALL);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
REQ(n, testlist);
|
int inkeywords, i, na, nk;
|
||||||
com_list(c, n, 1);
|
REQ(n, arglist);
|
||||||
com_addbyte(c, BINARY_CALL);
|
inkeywords = 0;
|
||||||
|
na = 0;
|
||||||
|
nk = 0;
|
||||||
|
for (i = 0; i < NCH(n); i += 2) {
|
||||||
|
inkeywords = com_argument(c, CHILD(n, i), inkeywords);
|
||||||
|
if (!inkeywords)
|
||||||
|
na++;
|
||||||
|
else
|
||||||
|
nk++;
|
||||||
|
}
|
||||||
|
if (na > 255 || nk > 255) {
|
||||||
|
err_setstr(SyntaxError, "more than 255 arguments");
|
||||||
|
c->c_errors++;
|
||||||
|
}
|
||||||
|
com_addoparg(c, CALL_FUNCTION, na | (nk << 8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1482,13 +1535,18 @@ com_raise_stmt(c, n)
|
||||||
struct compiling *c;
|
struct compiling *c;
|
||||||
node *n;
|
node *n;
|
||||||
{
|
{
|
||||||
REQ(n, raise_stmt); /* 'raise' test [',' test] */
|
REQ(n, raise_stmt); /* 'raise' test [',' test [',' test]] */
|
||||||
com_node(c, CHILD(n, 1));
|
com_node(c, CHILD(n, 1));
|
||||||
if (NCH(n) > 3)
|
if (NCH(n) > 3)
|
||||||
com_node(c, CHILD(n, 3));
|
com_node(c, CHILD(n, 3));
|
||||||
else
|
else
|
||||||
com_addoparg(c, LOAD_CONST, com_addconst(c, None));
|
com_addoparg(c, LOAD_CONST, com_addconst(c, None));
|
||||||
com_addbyte(c, RAISE_EXCEPTION);
|
if (NCH(n) > 5) {
|
||||||
|
com_node(c, CHILD(n, 5));
|
||||||
|
com_addoparg(c, RAISE_VARARGS, 3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
com_addbyte(c, RAISE_EXCEPTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1980,19 +2038,16 @@ com_argdefs(c, n, argcount_return)
|
||||||
if (TYPE(n) != varargslist)
|
if (TYPE(n) != varargslist)
|
||||||
return -1;
|
return -1;
|
||||||
/* varargslist:
|
/* varargslist:
|
||||||
(fpdef ['=' test] ',')* '*' NAME |
|
(fpdef ['=' test] ',')* '*' NAME ....... |
|
||||||
fpdef ['=' test] (',' fpdef ['=' test])* [','] */
|
fpdef ['=' test] (',' fpdef ['=' test])* [','] */
|
||||||
nch = NCH(n);
|
nch = NCH(n);
|
||||||
if (nch >= 2 && TYPE(CHILD(n, nch-2)) == STAR) {
|
|
||||||
star = 1;
|
|
||||||
nch -= 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
star = 0;
|
|
||||||
nargs = 0;
|
nargs = 0;
|
||||||
ndefs = 0;
|
ndefs = 0;
|
||||||
|
star = 0;
|
||||||
for (i = 0; i < nch; i++) {
|
for (i = 0; i < nch; i++) {
|
||||||
int t;
|
int t;
|
||||||
|
if (TYPE(CHILD(n, i)) == STAR)
|
||||||
|
break;
|
||||||
nargs++;
|
nargs++;
|
||||||
i++;
|
i++;
|
||||||
if (i >= nch)
|
if (i >= nch)
|
||||||
|
@ -2285,17 +2340,18 @@ com_arglist(c, n)
|
||||||
int nch, op, nargs, i, t;
|
int nch, op, nargs, i, t;
|
||||||
REQ(n, varargslist);
|
REQ(n, varargslist);
|
||||||
/* varargslist:
|
/* varargslist:
|
||||||
(fpdef ['=' test] ',')* '*' NAME |
|
(fpdef ['=' test] ',')* '*' NAME ..... |
|
||||||
fpdef ['=' test] (',' fpdef ['=' test])* [','] */
|
fpdef ['=' test] (',' fpdef ['=' test])* [','] */
|
||||||
nch = NCH(n);
|
nch = NCH(n);
|
||||||
if (nch >= 2 && TYPE(CHILD(n, nch-2)) == STAR) {
|
op = UNPACK_ARG;
|
||||||
op = UNPACK_VARARG;
|
|
||||||
nch -= 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
op = UNPACK_ARG;
|
|
||||||
nargs = 0;
|
nargs = 0;
|
||||||
for (i = 0; i < nch; i++) {
|
for (i = 0; i < nch; i++) {
|
||||||
|
if (TYPE(CHILD(n, i)) == STAR) {
|
||||||
|
nch = i;
|
||||||
|
if (TYPE(CHILD(n, i+1)) != STAR)
|
||||||
|
op = UNPACK_VARARG;
|
||||||
|
break;
|
||||||
|
}
|
||||||
nargs++;
|
nargs++;
|
||||||
i++;
|
i++;
|
||||||
if (i >= nch)
|
if (i >= nch)
|
||||||
|
|
Loading…
Reference in New Issue