[Python-checkins] python/dist/src/Objects funcobject.c,2.55,2.56
jhylton@users.sourceforge.net
jhylton@users.sourceforge.net
Thu, 11 Jul 2002 11:30:30 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv2891/Objects
Modified Files:
funcobject.c
Log Message:
Extend function() to support an optional closure argument.
Also, simplify some ref counting for other optional arguments.
Index: funcobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v
retrieving revision 2.55
retrieving revision 2.56
diff -C2 -d -r2.55 -r2.56
*** funcobject.c 14 Jun 2002 20:41:15 -0000 2.55
--- funcobject.c 11 Jul 2002 18:30:27 -0000 2.56
***************
*** 268,291 ****
PyDoc_STRVAR(func_doc,
! "function(code, globals[, name[, argdefs]])\n\
\n\
Create a function object from a code object and a dictionary.\n\
The optional name string overrides the name from the code object.\n\
! The optional argdefs tuple specifies the default argument values.");
static PyObject *
func_new(PyTypeObject* type, PyObject* args, PyObject* kw)
{
! PyObject *code;
PyObject *globals;
PyObject *name = Py_None;
PyObject *defaults = Py_None;
PyFunctionObject *newfunc;
! if (!PyArg_ParseTuple(args, "O!O!|OO!:function",
&PyCode_Type, &code,
&PyDict_Type, &globals,
! &name,
! &PyTuple_Type, &defaults))
return NULL;
if (name != Py_None && !PyString_Check(name)) {
--- 268,303 ----
PyDoc_STRVAR(func_doc,
! "function(code, globals[, name[, argdefs[, closure]]])\n\
\n\
Create a function object from a code object and a dictionary.\n\
The optional name string overrides the name from the code object.\n\
! The optional argdefs tuple specifies the default argument values.\n\
! The optional closure tuple supplies the bindings for free variables.");
!
! /* func_new() maintains the following invariants for closures. The
! closure must correspond to the free variables of the code object.
!
! if len(code.co_freevars) == 0:
! closure = NULL
! else:
! len(closure) == len(code.co_freevars)
! for every elt in closure, type(elt) == cell
! */
static PyObject *
func_new(PyTypeObject* type, PyObject* args, PyObject* kw)
{
! PyCodeObject *code;
PyObject *globals;
PyObject *name = Py_None;
PyObject *defaults = Py_None;
+ PyObject *closure = Py_None;
PyFunctionObject *newfunc;
+ int nfree, nclosure;
! if (!PyArg_ParseTuple(args, "O!O!|OOO:function",
&PyCode_Type, &code,
&PyDict_Type, &globals,
! &name, &defaults, &closure))
return NULL;
if (name != Py_None && !PyString_Check(name)) {
***************
*** 294,311 ****
return NULL;
}
! newfunc = (PyFunctionObject *)PyFunction_New(code, globals);
if (newfunc == NULL)
return NULL;
!
if (name != Py_None) {
! Py_XINCREF(name);
! Py_XDECREF(newfunc->func_name);
newfunc->func_name = name;
}
if (defaults != Py_None) {
! Py_XINCREF(defaults);
! Py_XDECREF(newfunc->func_defaults);
newfunc->func_defaults = defaults;
}
--- 306,364 ----
return NULL;
}
+ if (defaults != Py_None && !PyTuple_Check(defaults)) {
+ PyErr_SetString(PyExc_TypeError,
+ "arg 4 (defaults) must be None or tuple");
+ return NULL;
+ }
+ nfree = PyTuple_GET_SIZE(code->co_freevars);
+ if (!PyTuple_Check(closure)) {
+ if (nfree && closure == Py_None) {
+ PyErr_SetString(PyExc_TypeError,
+ "arg 5 (closure) must be tuple");
+ return NULL;
+ }
+ else if (closure != Py_None) {
+ PyErr_SetString(PyExc_TypeError,
+ "arg 5 (closure) must be None or tuple");
+ return NULL;
+ }
+ }
! /* check that the closure is well-formed */
! nclosure = closure == Py_None ? 0 : PyTuple_GET_SIZE(closure);
! if (nfree != nclosure)
! return PyErr_Format(PyExc_ValueError,
! "%s requires closure of length %d, not %d",
! PyString_AS_STRING(code->co_name),
! nfree, nclosure);
! if (nclosure) {
! int i;
! for (i = 0; i < nclosure; i++) {
! PyObject *o = PyTuple_GET_ITEM(closure, i);
! if (!PyCell_Check(o)) {
! return PyErr_Format(PyExc_TypeError,
! "arg 5 (closure) expected cell, found %s",
! o->ob_type->tp_name);
! }
! }
! }
!
! newfunc = (PyFunctionObject *)PyFunction_New((PyObject *)code,
! globals);
if (newfunc == NULL)
return NULL;
!
if (name != Py_None) {
! Py_INCREF(name);
! Py_DECREF(newfunc->func_name);
newfunc->func_name = name;
}
if (defaults != Py_None) {
! Py_INCREF(defaults);
newfunc->func_defaults = defaults;
+ }
+ if (closure != Py_None) {
+ Py_INCREF(closure);
+ newfunc->func_closure = closure;
}