[Python-checkins] CVS: python/dist/src/Python ceval.c,2.252,2.253

Tim Peters tim_one@users.sourceforge.net
Wed, 20 Jun 2001 19:49:57 -0700


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

Modified Files:
	ceval.c 
Log Message:
Teach the UNPACK_SEQUENCE opcode how to tease an iterable object into
giving up the goods.
NEEDS DOC CHANGES


Index: ceval.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v
retrieving revision 2.252
retrieving revision 2.253
diff -C2 -r2.252 -r2.253
*** ceval.c	2001/06/21 02:41:10	2.252
--- ceval.c	2001/06/21 02:49:55	2.253
***************
*** 477,481 ****
  
  static enum why_code do_raise(PyObject *, PyObject *, PyObject *);
! static int unpack_sequence(PyObject *, int, PyObject **);
  
  
--- 477,481 ----
  
  static enum why_code do_raise(PyObject *, PyObject *, PyObject *);
! static int unpack_iterable(PyObject *, int, PyObject **);
  
  
***************
*** 1489,1504 ****
  				}
  			}
! 			else if (PySequence_Check(v)) {
! 				if (unpack_sequence(v, oparg,
! 						    stack_pointer + oparg))
! 					stack_pointer += oparg;
! 				else
! 					why = WHY_EXCEPTION;
! 			}
! 			else {
! 				PyErr_SetString(PyExc_TypeError,
! 						"unpack non-sequence");
  				why = WHY_EXCEPTION;
- 			}
  			Py_DECREF(v);
  			break;
--- 1489,1497 ----
  				}
  			}
! 			else if (unpack_iterable(v, oparg,
! 						 stack_pointer + oparg))
! 				stack_pointer += oparg;
! 			else
  				why = WHY_EXCEPTION;
  			Py_DECREF(v);
  			break;
***************
*** 2695,2729 ****
  }
  
  static int
! unpack_sequence(PyObject *v, int argcnt, PyObject **sp)
  {
! 	int i;
  	PyObject *w;
  
! 	for (i = 0; i < argcnt; i++) {
! 		if (! (w = PySequence_GetItem(v, i))) {
! 			if (PyErr_ExceptionMatches(PyExc_IndexError))
! 				PyErr_SetString(PyExc_ValueError,
! 					      "unpack sequence of wrong size");
! 			goto finally;
  		}
  		*--sp = w;
  	}
! 	/* we better get an IndexError now */
! 	if (PySequence_GetItem(v, i) == NULL) {
! 		if (PyErr_ExceptionMatches(PyExc_IndexError)) {
! 			PyErr_Clear();
! 			return 1;
! 		}
! 		/* some other exception occurred. fall through to finally */
  	}
! 	else
! 		PyErr_SetString(PyExc_ValueError,
! 				"unpack sequence of wrong size");
  	/* fall through */
! finally:
  	for (; i > 0; i--, sp++)
  		Py_DECREF(*sp);
! 
  	return 0;
  }
--- 2688,2735 ----
  }
  
+ /* Iterate v argcnt times and store the results on the stack (via decreasing
+    sp).  Return 1 for success, 0 if error. */
+ 
  static int
! unpack_iterable(PyObject *v, int argcnt, PyObject **sp)
  {
! 	int i = 0;
! 	PyObject *it;  /* iter(v) */
  	PyObject *w;
  
! 	assert(v != NULL);
! 
! 	it = PyObject_GetIter(v);
! 	if (it == NULL)
! 		goto Error;
! 
! 	for (; i < argcnt; i++) {
! 		w = PyIter_Next(it);
! 		if (w == NULL) {
! 			/* Iterator done, via error or exhaustion. */
! 			if (!PyErr_Occurred()) {
! 				PyErr_Format(PyExc_ValueError,
! 					"need more than %d value%s to unpack",
! 					i, i == 1 ? "" : "s");
! 			}
! 			goto Error;
  		}
  		*--sp = w;
  	}
! 
! 	/* We better have exhausted the iterator now. */
! 	w = PyIter_Next(it);
! 	if (w == NULL) {
! 		if (PyErr_Occurred())
! 			goto Error;
! 		Py_DECREF(it);
! 		return 1;
  	}
! 	PyErr_SetString(PyExc_ValueError, "too many values to unpack");
  	/* fall through */
! Error:
  	for (; i > 0; i--, sp++)
  		Py_DECREF(*sp);
! 	Py_XDECREF(it);
  	return 0;
  }