Index: Include/object.h =================================================================== --- Include/object.h (revision 66078) +++ Include/object.h (working copy) @@ -473,6 +473,7 @@ PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *); PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_NextNotImplemented(PyObject *); PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *, PyObject *, PyObject *); Index: Objects/object.c =================================================================== --- Objects/object.c (revision 66078) +++ Objects/object.c (working copy) @@ -1286,6 +1286,15 @@ return obj; } +PyObject * +PyObject_NextNotImplemented(PyObject *self) +{ + PyErr_Format(PyExc_TypeError, + "'%.200s' object is not iterable", + Py_TYPE(self)->tp_name); + return NULL; +} + /* Generic GetAttr functions - put these in your tp_[gs]etattro slot */ PyObject * Index: Objects/typeobject.c =================================================================== --- Objects/typeobject.c (revision 66078) +++ Objects/typeobject.c (working copy) @@ -6057,8 +6057,12 @@ } do { descr = _PyType_Lookup(type, p->name_strobj); - if (descr == NULL) + if (descr == NULL) { + if (ptr == (void**)&type->tp_iternext) { + specific = PyObject_NextNotImplemented; + } continue; + } if (Py_TYPE(descr) == &PyWrapperDescr_Type) { void **tptr = resolve_slotdups(type, p->name_strobj); if (tptr == NULL || tptr == ptr) Index: Objects/abstract.c =================================================================== --- Objects/abstract.c (revision 66078) +++ Objects/abstract.c (working copy) @@ -3067,7 +3067,6 @@ PyIter_Next(PyObject *iter) { PyObject *result; - assert(PyIter_Check(iter)); result = (*iter->ob_type->tp_iternext)(iter); if (result == NULL && PyErr_Occurred() &&