From: <ar...@co...> - 2010-02-22 13:16:47
|
Author: arigo Date: Mon Feb 22 14:16:33 2010 New Revision: 71405 Modified: psyco/branch/py27/c/Python/pycompiler.c psyco/branch/py27/test/btrun.py psyco/branch/py27/test/test5.py Log: Detect duplicate keyword arguments. Fix a bug about it ("break" instead of "goto fail"). Test. Modified: psyco/branch/py27/c/Python/pycompiler.c ============================================================================== --- psyco/branch/py27/c/Python/pycompiler.c (original) +++ psyco/branch/py27/c/Python/pycompiler.c Mon Feb 22 14:16:33 2010 @@ -1288,6 +1288,23 @@ } } +static int +cimpl_pydict_setitem_new(PyObject *mp, PyObject *key, PyObject *item) +{ + if (PyDict_GetItem(mp, key) != NULL) { + char *argname; + if (PyString_Check(key)) + argname = PyString_AS_STRING(key); + else + argname = "?"; + PyErr_Format(PyExc_TypeError, + "got multiple values for keyword argument '%s'", + argname); + return -1; + } + return PyDict_SetItem(mp, key, item); +} + #define CALL_FLAG_VAR 1 #define CALL_FLAG_KW 2 static vinfo_t* psyco_ext_do_calls(PsycoObject* po, int opcode, int oparg, @@ -1332,6 +1349,8 @@ wdict = psyco_vi_Zero(); /* no keyword arguments */ else { int i; + int(*setter)(PyObject*, PyObject*, PyObject*); + setter = PyDict_SetItem; if (flags & CALL_FLAG_KW) { /* '**kw' call syntax */ vinfo_t* w = args[--n]; /* pop keyword dictionary */ /* check that it is a dictionary */ @@ -1351,6 +1370,7 @@ /* make a copy of the dictionary; the original one must not be modified */ wdict = PsycoDict_Copy(po, w); + setter = cimpl_pydict_setitem_new; } else { wdict = w; @@ -1369,10 +1389,10 @@ check for duplicate keywords */ for (i = na + 2*nk; i > na; ) { i -= 2; - if (!psyco_generic_call(po, PyDict_SetItem, + if (!psyco_generic_call(po, setter, CfNoReturnValue|CfPyErrIfNonNull, "vvv", wdict, args[i], args[i+1])) - break; + goto fail; } } Modified: psyco/branch/py27/test/btrun.py ============================================================================== --- psyco/branch/py27/test/btrun.py (original) +++ psyco/branch/py27/test/btrun.py Mon Feb 22 14:16:33 2010 @@ -715,6 +715,9 @@ >>> test5.negintpow(8) 0.015625 +>>> test5.duplicatekwarg() +correctly detected + ########################### #### COMPACTOBJECT #### ########################### Modified: psyco/branch/py27/test/test5.py ============================================================================== --- psyco/branch/py27/test/test5.py (original) +++ psyco/branch/py27/test/test5.py Mon Feb 22 14:16:33 2010 @@ -430,12 +430,24 @@ return key x = X(["Ok"]) print x["foobar"] + count = 0 for item in x: print item + count += 1 + if count > 10: + break def negintpow(x): print x ** -2 +def duplicatekwarg(): + try: + double2(x=5, **{'x': 6}) + except TypeError: + print 'correctly detected' + else: + print 'missing TypeError!' + if __name__ == '__main__': from test1 import go, print_results import time |