[Python-checkins] python/dist/src/Objects funcobject.c,2.55,2.56

jhylton@users.sourceforge.net jhylton@users.sourceforge.net
2002年7月11日 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;
 	}
 

AltStyle によって変換されたページ (->オリジナル) /