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.
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 8a6df76..f656747 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -1748,10 +1748,32 @@
 		f = t->tp_iter;
 	if (f == NULL) {
 		if (PySequence_Check(o))
-			return PyIter_New(o);
+			return PySeqIter_New(o);
 		PyErr_SetString(PyExc_TypeError, "iter() of non-sequence");
 		return NULL;
 	}
-	else
-		return (*f)(o);
+	else {
+		PyObject *res = (*f)(o);
+		if (res != NULL && !PyIter_Check(res)) {
+			PyErr_Format(PyExc_TypeError,
+				     "iter() returned non-iterator "
+				     "of type '%.100s'",
+				     res->ob_type->tp_name);
+			Py_DECREF(res);
+			res = NULL;
+		}
+		return res;
+	}
+}
+
+PyObject *
+PyIter_Next(PyObject *iter)
+{
+	if (!PyIter_Check(iter)) {
+		PyErr_Format(PyExc_TypeError,
+			     "'%.100s' object is not an iterator",
+			     iter->ob_type->tp_name);
+		return NULL;
+	}
+	return (*iter->ob_type->tp_iternext)(iter);
 }