Jiwon Seo's PEP 3102 implementation.

See SF#1549670.
The compiler package has not yet been updated.
This commit is contained in:
Guido van Rossum 2006-10-27 23:31:49 +00:00
parent fc2a0a8e3c
commit 4f72a78684
31 changed files with 739 additions and 227 deletions

View file

@ -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;
}

View file

@ -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) {
@ -121,6 +122,38 @@ PyFunction_SetDefaults(PyObject *op, PyObject *defaults)
return 0;
}
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)
{
@ -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)