[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;
}