diff options
author | Guido van Rossum <guido@python.org> | 2006-10-27 23:31:49 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2006-10-27 23:31:49 (GMT) |
commit | 4f72a78684bbfcdc43ceeabb240ceee54706c4b0 (patch) | |
tree | 743c27c5125dcef580cffe77395fe97bedf40d5f /Objects | |
parent | fc2a0a8e3cb1d40fd965576060c28c8bd2ea1ad5 (diff) | |
download | cpython-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 'Objects')
-rw-r--r-- | Objects/codeobject.c | 25 | ||||
-rw-r--r-- | Objects/funcobject.c | 73 |
2 files changed, 93 insertions, 5 deletions
diff --git a/Objects/codeobject.c b/Objects/codeobject.c index ca156e8..6d5daa8 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -41,7 +41,8 @@ intern_strings(PyObject *tuple) PyCodeObject * -PyCode_New(int argcount, int nlocals, int stacksize, int flags, +PyCode_New(int argcount, int kwonlyargcount, + int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, @@ -80,6 +81,7 @@ PyCode_New(int argcount, int nlocals, int stacksize, int flags, co = PyObject_NEW(PyCodeObject, &PyCode_Type); if (co != NULL) { co->co_argcount = argcount; + co->co_kwonlyargcount = kwonlyargcount; co->co_nlocals = nlocals; co->co_stacksize = stacksize; co->co_flags = flags; @@ -112,6 +114,7 @@ PyCode_New(int argcount, int nlocals, int stacksize, int flags, static PyMemberDef code_memberlist[] = { {"co_argcount", T_INT, OFF(co_argcount), READONLY}, + {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), READONLY}, {"co_nlocals", T_INT, OFF(co_nlocals), READONLY}, {"co_stacksize",T_INT, OFF(co_stacksize), READONLY}, {"co_flags", T_INT, OFF(co_flags), READONLY}, @@ -182,6 +185,7 @@ static PyObject * code_new(PyTypeObject *type, PyObject *args, PyObject *kw) { int argcount; + int kwonlyargcount; int nlocals; int stacksize; int flags; @@ -197,8 +201,9 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw) int firstlineno; PyObject *lnotab; - if (!PyArg_ParseTuple(args, "iiiiSO!O!O!SSiS|O!O!:code", - &argcount, &nlocals, &stacksize, &flags, + if (!PyArg_ParseTuple(args, "iiiiiSO!O!O!SSiS|O!O!:code", + &argcount, &kwonlyargcount, + &nlocals, &stacksize, &flags, &code, &PyTuple_Type, &consts, &PyTuple_Type, &names, @@ -216,6 +221,12 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw) goto cleanup; } + if (kwonlyargcount < 0) { + PyErr_SetString( + PyExc_ValueError, + "code: kwonlyargcount must not be negative"); + goto cleanup; + } if (nlocals < 0) { PyErr_SetString( PyExc_ValueError, @@ -242,7 +253,8 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw) if (ourcellvars == NULL) goto cleanup; - co = (PyObject *)PyCode_New(argcount, nlocals, stacksize, flags, + co = (PyObject *)PyCode_New(argcount, kwonlyargcount, + nlocals, stacksize, flags, code, consts, ournames, ourvarnames, ourfreevars, ourcellvars, filename, name, firstlineno, lnotab); @@ -312,6 +324,8 @@ code_richcompare(PyObject *self, PyObject *other, int op) if (eq <= 0) goto unequal; eq = co->co_argcount == cp->co_argcount; if (!eq) goto unequal; + eq = co->co_kwonlyargcount == cp->co_kwonlyargcount; + if (!eq) goto unequal; eq = co->co_nlocals == cp->co_nlocals; if (!eq) goto unequal; eq = co->co_flags == cp->co_flags; @@ -369,7 +383,8 @@ code_hash(PyCodeObject *co) h6 = PyObject_Hash(co->co_cellvars); if (h6 == -1) return -1; h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^ - co->co_argcount ^ co->co_nlocals ^ co->co_flags; + co->co_argcount ^ co->co_kwonlyargcount ^ + co->co_nlocals ^ co->co_flags; if (h == -1) h = -2; return h; } diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 1ba74c5..06a4fe9 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -24,6 +24,7 @@ PyFunction_New(PyObject *code, PyObject *globals) op->func_name = ((PyCodeObject *)code)->co_name; Py_INCREF(op->func_name); op->func_defaults = NULL; /* No default arguments */ + op->func_kwdefaults = NULL; /* No keyword only defaults */ op->func_closure = NULL; consts = ((PyCodeObject *)code)->co_consts; if (PyTuple_Size(consts) >= 1) { @@ -122,6 +123,38 @@ PyFunction_SetDefaults(PyObject *op, PyObject *defaults) } PyObject * +PyFunction_GetKwDefaults(PyObject *op) +{ + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + return ((PyFunctionObject *) op) -> func_kwdefaults; +} + +int +PyFunction_SetKwDefaults(PyObject *op, PyObject *defaults) +{ + if (!PyFunction_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + if (defaults == Py_None) + defaults = NULL; + else if (defaults && PyDict_Check(defaults)) { + Py_INCREF(defaults); + } + else { + PyErr_SetString(PyExc_SystemError, + "non-dict keyword only default args"); + return -1; + } + Py_XDECREF(((PyFunctionObject *)op) -> func_kwdefaults); + ((PyFunctionObject *) op) -> func_kwdefaults = defaults; + return 0; +} + +PyObject * PyFunction_GetClosure(PyObject *op) { if (!PyFunction_Check(op)) { @@ -325,10 +358,49 @@ func_set_defaults(PyFunctionObject *op, PyObject *value) return 0; } +static PyObject * +func_get_kwdefaults(PyFunctionObject *op) +{ + if (restricted()) + return NULL; + if (op->func_kwdefaults == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + Py_INCREF(op->func_kwdefaults); + return op->func_kwdefaults; +} + +static int +func_set_kwdefaults(PyFunctionObject *op, PyObject *value) +{ + PyObject *tmp; + + if (restricted()) + return -1; + + if (value == Py_None) + value = NULL; + /* Legal to del f.func_defaults. + * Can only set func_kwdefaults to NULL or a dict. */ + if (value != NULL && !PyDict_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "func_kwdefaults must be set to a dict object"); + return -1; + } + tmp = op->func_kwdefaults; + Py_XINCREF(value); + op->func_kwdefaults = value; + Py_XDECREF(tmp); + return 0; +} + static PyGetSetDef func_getsetlist[] = { {"func_code", (getter)func_get_code, (setter)func_set_code}, {"func_defaults", (getter)func_get_defaults, (setter)func_set_defaults}, + {"func_kwdefaults", (getter)func_get_kwdefaults, + (setter)func_set_kwdefaults}, {"func_dict", (getter)func_get_dict, (setter)func_set_dict}, {"__dict__", (getter)func_get_dict, (setter)func_set_dict}, {"func_name", (getter)func_get_name, (setter)func_set_name}, @@ -519,6 +591,7 @@ function_call(PyObject *func, PyObject *arg, PyObject *kw) PyFunction_GET_GLOBALS(func), (PyObject *)NULL, &PyTuple_GET_ITEM(arg, 0), PyTuple_Size(arg), k, nk, d, nd, + PyFunction_GET_KW_DEFAULTS(func), PyFunction_GET_CLOSURE(func)); if (k != NULL) |