[pywin32-checkins] pywin32/com/win32com/src MiscTypes.cpp,1.6,1.7 PyIBase.cpp,1.6,1.7
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
From: <mha...@us...> - 2003-11-02 09:55:30
|
Update of /cvsroot/pywin32/pywin32/com/win32com/src In directory sc8-pr-cvs1:/tmp/cvs-serv3446 Modified Files: MiscTypes.cpp PyIBase.cpp Log Message: Fix iterators yet again. Drop the PyIEnum classes, and keep all the functionality in the new types. This means we can still be an enumerator even if we dont derive directly from PyIUnknown (eg, IMoniker) Index: MiscTypes.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32com/src/MiscTypes.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** MiscTypes.cpp 2 Nov 2003 05:26:13 -0000 1.6 --- MiscTypes.cpp 2 Nov 2003 09:55:27 -0000 1.7 *************** *** 113,122 **** PyComTypeObject( name, pBase, typeSize, methodList, thector) { ! tp_iter = PyIEnum::iter; ! tp_iternext = PyIEnum::iternext; tp_flags |= Py_TPFLAGS_HAVE_ITER; } ! // Our type for IEnum provider interfaces PyComEnumProviderTypeObject::PyComEnumProviderTypeObject( const char *name, --- 113,158 ---- PyComTypeObject( name, pBase, typeSize, methodList, thector) { ! tp_iter = iter; ! tp_iternext = iternext; tp_flags |= Py_TPFLAGS_HAVE_ITER; } ! // PyIEnum iter methods - generic for any "standard" COM IEnum interface, but ! // if the object provides a real one, we use it. ! PyObject *PyComEnumTypeObject::iter(PyObject *self) ! { ! assert(!PyErr_Occurred()); ! PyObject *rc = ((PyIBase *)self)->iter(); ! if (rc || PyErr_Occurred()) ! return rc; ! Py_INCREF(self); ! return self; ! } ! ! PyObject *PyComEnumTypeObject::iternext(PyObject *self) ! { ! PyObject *ret = ((PyIBase *)self)->iter(); ! if (ret || PyErr_Occurred()) ! return ret; ! PyObject *method = PyObject_GetAttrString(self, "Next"); ! if (!method) ! return NULL; ! PyObject *args=Py_BuildValue("(i)", 1); ! PyObject *result = PyObject_Call(method, args, NULL); ! Py_DECREF(method); ! Py_DECREF(args); ! if (!result) ! return NULL; ! if (PySequence_Length(result)==0){ ! PyErr_SetNone(PyExc_StopIteration); ! ret = NULL; ! } else ! ret = PySequence_GetItem(result, 0); ! Py_DECREF(result); ! return ret; ! } ! ! ! // Our type for IEnum provider interfaces PyComEnumProviderTypeObject::PyComEnumProviderTypeObject( const char *name, *************** *** 129,136 **** enum_method_name(penum_method_name) { ! tp_iter = PyIEnumProvider::iter; // tp_iternext remains NULL tp_flags |= Py_TPFLAGS_HAVE_ITER; } ///////////////////////////////////////////////////////////////////////////// --- 165,203 ---- enum_method_name(penum_method_name) { ! tp_iter = iter; // tp_iternext remains NULL tp_flags |= Py_TPFLAGS_HAVE_ITER; } + + // PyIEnumProvider iter methods - generic for COM object that can provide an IEnum* + // interface via a method call taking no args. + PyObject *PyComEnumProviderTypeObject::iter(PyObject *self) + { + PyObject *result = ((PyIBase *)self)->iter(); + if (result || PyErr_Occurred()) + return result; + PyComEnumProviderTypeObject *t = (PyComEnumProviderTypeObject *)self->ob_type; + PyObject *method = PyObject_GetAttrString(self, (char *)t->enum_method_name); + if (!method) + return NULL; + PyObject *args=PyTuple_New(0); + result = PyObject_Call(method, args, NULL); + Py_DECREF(method); + Py_DECREF(args); + if (result==Py_None) { + // If we returned None for the iterator (but there is + // no error) then we simulate an empty iterator + // Otherwise we get: + // TypeError: iter() returned non-iterator of type 'NoneType' + Py_DECREF(result); + PyObject *dummy = PyTuple_New(0); + if (!dummy) + return NULL; + result = PySeqIter_New(dummy); + Py_DECREF(dummy); + } + return result; + } + ///////////////////////////////////////////////////////////////////////////// Index: PyIBase.cpp =================================================================== RCS file: /cvsroot/pywin32/pywin32/com/win32com/src/PyIBase.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** PyIBase.cpp 2 Nov 2003 05:26:13 -0000 1.6 --- PyIBase.cpp 2 Nov 2003 09:55:27 -0000 1.7 *************** *** 90,134 **** } - // PyIEnum iter methods - generic for any "standard" COM IEnum interface. - PyObject *PyIEnum::iter() - { - Py_INCREF(this); - return this; - } - - PyObject *PyIEnum::iternext() - { - PyObject *method = PyObject_GetAttrString(this, "Next"); - if (!method) - return NULL; - PyObject *args=Py_BuildValue("(i)", 1); - PyObject *result = PyObject_Call(method, args, NULL); - Py_DECREF(method); - Py_DECREF(args); - if (!result) - return NULL; - PyObject *ret; - if (PySequence_Length(result)==0){ - PyErr_SetNone(PyExc_StopIteration); - ret = NULL; - } else - ret = PySequence_GetItem(result, 0); - Py_DECREF(result); - return ret; - } - - // PyIEnumProvider iter methods - generic for COM object that can provide an IEnum* - // interface via a method call taking no args. - PyObject *PyIEnumProvider::iter() - { - PyComEnumProviderTypeObject *t = (PyComEnumProviderTypeObject *)ob_type; - PyObject *method = PyObject_GetAttrString(this, (char *)t->enum_method_name); - if (!method) - return NULL; - PyObject *args=PyTuple_New(0); - PyObject *result = PyObject_Call(method, args, NULL); - Py_DECREF(method); - Py_DECREF(args); - return result; - } - --- 90,91 ---- |