[Python-checkins] python/dist/src/Objects methodobject.c,2.42,2.43

rhettinger@users.sourceforge.net rhettinger@users.sourceforge.net
Fri, 03 Jan 2003 16:37:55 -0800


Update of /cvsroot/python/python/dist/src/Objects
In directory sc8-pr-cvs1:/tmp/cvs-serv28624

Modified Files:
	methodobject.c 
Log Message:
SF Patch #661440: Refactor and streamline PyCFunction_Call

Refactor code in PyCFunction_Call giving a modest (tiny) speed boost,
a slight improvement in semantics (now detects invalid flag combinations),
and (arguably) improved clarity (making it blindingly clear which flag
combinations are allowed).  All this comes at a cost of a few lines of
code duplication.

* Folded test for METH_KEYWORDS into the switch/case.
* Deferred testing for an empty dictionary until when and where needed.
* Make a similar deferral for filling the "size" variable.
* Inverted the dictionary test so that the common case falls though
  instead of making a jump.
 


Index: methodobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/methodobject.c,v
retrieving revision 2.42
retrieving revision 2.43
diff -C2 -d -r2.42 -r2.43
*** methodobject.c	28 Mar 2002 05:33:33 -0000	2.42
--- methodobject.c	4 Jan 2003 00:37:53 -0000	2.43
***************
*** 63,103 ****
  	PyCFunction meth = PyCFunction_GET_FUNCTION(func);
  	PyObject *self = PyCFunction_GET_SELF(func);
! 	int flags = PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC);
! 	int size = PyTuple_GET_SIZE(arg);
! 
! 	if (flags & METH_KEYWORDS) {
! 		return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
! 	}
! 	if (kw != NULL && PyDict_Size(kw) != 0) {
! 		PyErr_Format(PyExc_TypeError,
! 			     "%.200s() takes no keyword arguments",
! 			     f->m_ml->ml_name);
! 		return NULL;
! 	}
  
! 	switch (flags) {
  	case METH_VARARGS:
! 		return (*meth)(self, arg);
  	case METH_NOARGS:
! 		if (size == 0)
! 			return (*meth)(self, NULL);
! 		PyErr_Format(PyExc_TypeError,
! 			     "%.200s() takes no arguments (%d given)",
! 			     f->m_ml->ml_name, size);
! 		return NULL;
  	case METH_O:
! 		if (size == 1)
! 			return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
! 		PyErr_Format(PyExc_TypeError,
! 			     "%.200s() takes exactly one argument (%d given)",
! 			     f->m_ml->ml_name, size);
! 		return NULL;
  	case METH_OLDARGS:
  		/* the really old style */
! 		if (size == 1)
! 			arg = PyTuple_GET_ITEM(arg, 0);
! 		else if (size == 0)
! 			arg = NULL;
! 		return (*meth)(self, arg);
  	default:
  		/* should never get here ??? */
--- 63,110 ----
  	PyCFunction meth = PyCFunction_GET_FUNCTION(func);
  	PyObject *self = PyCFunction_GET_SELF(func);
! 	int size;
  
! 	switch (PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC)) {
  	case METH_VARARGS:
! 		if (kw == NULL || PyDict_Size(kw) == 0)
! 			return (*meth)(self, arg);
! 		break;
! 	case METH_VARARGS | METH_KEYWORDS:
! 		return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
  	case METH_NOARGS:
! 		if (kw == NULL || PyDict_Size(kw) == 0) {
! 			size = PyTuple_GET_SIZE(arg);
! 			if (size == 0)
! 				return (*meth)(self, NULL);
! 			PyErr_Format(PyExc_TypeError,
! 			    "%.200s() takes no arguments (%d given)",
! 			    f->m_ml->ml_name, size);
! 			return NULL;
! 		}
! 		break;
  	case METH_O:
! 		if (kw == NULL || PyDict_Size(kw) == 0) {
! 			size = PyTuple_GET_SIZE(arg);
! 			if (size == 1)
! 				return (*meth)(self, PyTuple_GET_ITEM(arg, 0));
! 			PyErr_Format(PyExc_TypeError,
! 			    "%.200s() takes exactly one argument (%d given)",
! 			    f->m_ml->ml_name, size);
! 			return NULL;
! 		}
! 		break;
  	case METH_OLDARGS:
  		/* the really old style */
! 		if (kw == NULL || PyDict_Size(kw) == 0) {
! 			size = PyTuple_GET_SIZE(arg);
! 			if (size == 1)
! 				arg = PyTuple_GET_ITEM(arg, 0);
! 			else if (size == 0)
! 				arg = NULL;
! 			return (*meth)(self, arg);
! 		}
! 		break;
! 	case METH_OLDARGS | METH_KEYWORDS:
! 		return (*(PyCFunctionWithKeywords)meth)(self, arg, kw);
  	default:
  		/* should never get here ??? */
***************
*** 105,108 ****
--- 112,118 ----
  		return NULL;
  	}
+ 	PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
+ 		     f->m_ml->ml_name);
+ 	return NULL;
  }