[Python-checkins] CVS: python/dist/src/Python ceval.c,2.240,2.241

Guido van Rossum gvanrossum@users.sourceforge.net
Mon, 23 Apr 2001 07:08:51 -0700


Update of /cvsroot/python/python/dist/src/Python
In directory usw-pr-cvs1:/tmp/cvs-serv26282/Python

Modified Files:
	ceval.c 
Log Message:
Mondo changes to the iterator stuff, without changing how Python code
sees it (test_iter.py is unchanged).

- Added a tp_iternext slot, which calls the iterator's next() method;
  this is much faster for built-in iterators over built-in types
  such as lists and dicts, speeding up pybench's ForLoop with about
  25% compared to Python 2.1.  (Now there's a good argument for
  iterators. ;-)

- Renamed the built-in sequence iterator SeqIter, affecting the C API
  functions for it.  (This frees up the PyIter prefix for generic
  iterator operations.)

- Added PyIter_Check(obj), which checks that obj's type has a
  tp_iternext slot and that the proper feature flag is set.

- Added PyIter_Next(obj) which calls the tp_iternext slot.  It has a
  somewhat complex return condition due to the need for speed: when it
  returns NULL, it may not have set an exception condition, meaning
  the iterator is exhausted; when the exception StopIteration is set
  (or a derived exception class), it means the same thing; any other
  exception means some other error occurred.



Index: ceval.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v
retrieving revision 2.240
retrieving revision 2.241
diff -C2 -r2.240 -r2.241
*** ceval.c	2001/04/21 02:46:11	2.240
--- ceval.c	2001/04/23 14:08:49	2.241
***************
*** 382,386 ****
  	char *filename = PyString_AsString(co->co_filename);
  #endif
- 	static PyObject *nextstr;
  
  /* Code access macros */
--- 382,385 ----
***************
*** 418,426 ****
  
  /* Start of code */
- 	if (nextstr == NULL) {
- 		nextstr = PyString_InternFromString("next");
- 		if (nextstr == NULL)
- 			return NULL;
- 	}
  
  #ifdef USE_STACKCHECK
--- 417,420 ----
***************
*** 1888,1898 ****
  			Py_DECREF(v);
  			if (x != NULL) {
! 				w = x;
! 				x = PyObject_GetAttr(w, nextstr);
! 				Py_DECREF(w);
! 				if (x != NULL) {
! 					PUSH(x);
! 					continue;
! 				}
  			}
  			break;
--- 1882,1887 ----
  			Py_DECREF(v);
  			if (x != NULL) {
! 				PUSH(x);
! 				continue;
  			}
  			break;
***************
*** 1901,1919 ****
  			/* before: [iter]; after: [iter, iter()] *or* [] */
  			v = TOP();
! 			x = PyObject_CallObject(v, NULL);
! 			if (x == NULL) {
! 				if (PyErr_ExceptionMatches(
! 					PyExc_StopIteration))
! 				{
! 					PyErr_Clear();
! 					x = v = POP();
! 					Py_DECREF(v);
! 					JUMPBY(oparg);
! 					continue;
! 				}
! 				break;
  			}
! 			PUSH(x);
! 			continue;
  
  		case FOR_LOOP:
--- 1890,1908 ----
  			/* before: [iter]; after: [iter, iter()] *or* [] */
  			v = TOP();
! 			x = PyIter_Next(v);
! 			if (x != NULL) {
! 				PUSH(x);
! 				continue;
  			}
! 			if (!PyErr_Occurred() ||
! 			    PyErr_ExceptionMatches(
! 				    PyExc_StopIteration))
! 			{
! 				x = v = POP();
! 				Py_DECREF(v);
! 				JUMPBY(oparg);
! 				continue;
! 			}
! 			break;
  
  		case FOR_LOOP: