Update of /cvsroot/pywin32/pywin32/com/win32com/src
In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv16356/win32com/src
Modified Files:
Tag: py3k
MiscTypes.cpp PyIBase.cpp PyIUnknown.cpp PyRecord.cpp
PythonCOM.cpp
Log Message:
merge rich-compare, PyRecord and other misc changes from trunk
Index: PythonCOM.cpp
===================================================================
RCS file: /cvsroot/pywin32/pywin32/com/win32com/src/PythonCOM.cpp,v
retrieving revision 1.52.2.3
retrieving revision 1.52.2.4
diff -C2 -d -r1.52.2.3 -r1.52.2.4
*** PythonCOM.cpp 13 Sep 2008 04:26:18 -0000 1.52.2.3
--- PythonCOM.cpp 19 Dec 2008 02:33:56 -0000 1.52.2.4
***************
*** 15,18 ****
--- 15,19 ----
#include "PythonCOMServer.h"
#include "PyFactory.h"
+ #include "PyRecord.h"
#include "PyComTypeObjects.h"
#include "OleAcc.h" // for ObjectFromLresult proto...
***************
*** 1973,1982 ****
/* Module initialisation */
! extern "C" __declspec(dllexport)
! #if (PY_VERSION_HEX < 0x03000000)
! void initpythoncom()
! #else
! PyObject *PyInit_pythoncom(void)
! #endif
{
// The DLL Load inited the module.
--- 1974,1978 ----
/* Module initialisation */
! PYWIN_MODULE_INIT_FUNC(pythoncom)
{
// The DLL Load inited the module.
***************
*** 2001,2032 ****
// manually CoInit() to see!
! PyObject *dict, *module;
! #if (PY_VERSION_HEX < 0x03000000)
! #define RETURN_ERROR return;
! module = Py_InitModule("pythoncom", pythoncom_methods);
! if (!module)
! return;
! dict = PyModule_GetDict(module);
! if (!dict)
! return;
! #else
! #define RETURN_ERROR return NULL;
! static PyModuleDef pythoncom_def = {
! PyModuleDef_HEAD_INIT,
! "pythoncom",
! "A module, encapsulating the OLE automation API",
! -1,
! pythoncom_methods
! };
! module = PyModule_Create(&pythoncom_def);
! if (!module)
! return NULL;
! dict = PyModule_GetDict(module);
! if (!dict)
! return NULL;
! #endif
// ensure the framework has valid state to work with.
! PyWinGlobals_Ensure();
PyCom_RegisterCoreSupport();
--- 1997,2005 ----
// manually CoInit() to see!
! PYWIN_MODULE_INIT_PREPARE(pythoncom, pythoncom_methods,
! "A module, encapsulating the OLE automation API");
// ensure the framework has valid state to work with.
! // XXX - more error checking?
PyCom_RegisterCoreSupport();
***************
*** 2038,2042 ****
||PyType_Ready(&PyOleMissingType) == -1
||PyType_Ready(&PyOleArgNotFoundType) == -1)
! RETURN_ERROR;
g_obEmpty = new PyOleEmpty;
PyDict_SetItemString(dict, "Empty", g_obEmpty);
--- 2011,2015 ----
||PyType_Ready(&PyOleMissingType) == -1
||PyType_Ready(&PyOleArgNotFoundType) == -1)
! PYWIN_MODULE_INIT_RETURN_ERROR;
g_obEmpty = new PyOleEmpty;
PyDict_SetItemString(dict, "Empty", g_obEmpty);
***************
*** 2054,2076 ****
// This is created by PyWin_Globals_Ensure
PyErr_SetString(PyExc_MemoryError, "can't define ole_error");
! RETURN_ERROR;
}
PyObject *pycom_Error = PyWinExc_COMError;
if (PyDict_SetItemString(dict, "ole_error", PyWinExc_COMError) != 0)
! RETURN_ERROR;
if (PyDict_SetItemString(dict, "error", pycom_Error) != 0)
! RETURN_ERROR;
// Add the same constant, but with a "new name"
if (PyDict_SetItemString(dict, "com_error", PyWinExc_COMError) != 0)
! RETURN_ERROR;
PyCom_InternalError = PyErr_NewException("pythoncom.internal_error", NULL, NULL);
if (PyDict_SetItemString(dict, "internal_error", PyCom_InternalError) != 0)
! RETURN_ERROR;
// Add the IIDs
if (PyCom_RegisterCoreIIDs(dict) != 0)
! RETURN_ERROR;
// Initialize various non-interface types
--- 2027,2049 ----
// This is created by PyWin_Globals_Ensure
PyErr_SetString(PyExc_MemoryError, "can't define ole_error");
! PYWIN_MODULE_INIT_RETURN_ERROR;
}
PyObject *pycom_Error = PyWinExc_COMError;
if (PyDict_SetItemString(dict, "ole_error", PyWinExc_COMError) != 0)
! PYWIN_MODULE_INIT_RETURN_ERROR;
if (PyDict_SetItemString(dict, "error", pycom_Error) != 0)
! PYWIN_MODULE_INIT_RETURN_ERROR;
// Add the same constant, but with a "new name"
if (PyDict_SetItemString(dict, "com_error", PyWinExc_COMError) != 0)
! PYWIN_MODULE_INIT_RETURN_ERROR;
PyCom_InternalError = PyErr_NewException("pythoncom.internal_error", NULL, NULL);
if (PyDict_SetItemString(dict, "internal_error", PyCom_InternalError) != 0)
! PYWIN_MODULE_INIT_RETURN_ERROR;
// Add the IIDs
if (PyCom_RegisterCoreIIDs(dict) != 0)
! PYWIN_MODULE_INIT_RETURN_ERROR;
// Initialize various non-interface types
***************
*** 2078,2087 ****
PyType_Ready(&PySTGMEDIUM::Type) == -1 ||
PyType_Ready(&PyTYPEATTR::Type) == -1 ||
! PyType_Ready(&PyVARDESC::Type) == -1)
! RETURN_ERROR;
// Setup our sub-modules
if (!initunivgw(dict))
! RETURN_ERROR;
// Load function pointers.
--- 2051,2061 ----
PyType_Ready(&PySTGMEDIUM::Type) == -1 ||
PyType_Ready(&PyTYPEATTR::Type) == -1 ||
! PyType_Ready(&PyVARDESC::Type) == -1 ||
! PyType_Ready(&PyRecord::Type) == -1)
! PYWIN_MODULE_INIT_RETURN_ERROR;
// Setup our sub-modules
if (!initunivgw(dict))
! PYWIN_MODULE_INIT_RETURN_ERROR;
// Load function pointers.
***************
*** 2435,2441 ****
// @property int|pythoncom|dcom|1 if the system is DCOM aware, else 0. Only Win95 without DCOM extensions should return 0
! #if (PY_VERSION_HEX >= 0x03000000)
! return module;
! #endif;
}
-
--- 2409,2412 ----
// @property int|pythoncom|dcom|1 if the system is DCOM aware, else 0. Only Win95 without DCOM extensions should return 0
! PYWIN_MODULE_INIT_RETURN_SUCCESS;
}
Index: PyRecord.cpp
===================================================================
RCS file: /cvsroot/pywin32/pywin32/com/win32com/src/PyRecord.cpp,v
retrieving revision 1.11.4.3
retrieving revision 1.11.4.4
diff -C2 -d -r1.11.4.3 -r1.11.4.4
*** PyRecord.cpp 1 Oct 2008 12:53:00 -0000 1.11.4.3
--- PyRecord.cpp 19 Dec 2008 02:33:56 -0000 1.11.4.4
***************
*** 1,4 ****
--- 1,5 ----
#include "stdafx.h"
#include "PythonCOM.h"
+ #include "PyRecord.h"
// @doc
***************
*** 100,125 ****
};
- // @object PyRecord|An object that represents a COM User Defined Type.
- // @comm Once created or obtained from other methods, you can simply
- // get and set attributes.
- class PyRecord : public PyObject
- {
- public:
- PyRecord(IRecordInfo *ri, PVOID data, PyRecordBuffer *owner);
- ~PyRecord();
-
- static void tp_dealloc(PyObject *ob);
- static PyObject *getattro(PyObject *self, PyObject *obname);
- static int setattro(PyObject *self, PyObject *obname, PyObject *v);
- static PyObject *tp_repr(PyObject *self);
- static int tp_compare(PyObject *self, PyObject *other);
- static struct PyMethodDef methods[];
-
- static PyTypeObject Type;
- IRecordInfo *pri;
- void *pdata;
- PyRecordBuffer *owner;
- };
-
BOOL PyRecord_Check(PyObject *ob) {return ((ob)->ob_type == &PyRecord::Type);}
--- 101,104 ----
***************
*** 307,311 ****
0, /* tp_getattr */
0, /* tp_setattr */
! PyRecord::tp_compare, /* tp_compare */
&PyRecord::tp_repr, /* tp_repr */
0, /* tp_as_number */
--- 286,290 ----
0, /* tp_getattr */
0, /* tp_setattr */
! 0, /* tp_compare */
&PyRecord::tp_repr, /* tp_repr */
0, /* tp_as_number */
***************
*** 322,326 ****
0, /* tp_traverse */
0, /* tp_clear */
! 0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
--- 301,305 ----
0, /* tp_traverse */
0, /* tp_clear */
! PyRecord::tp_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
***************
*** 438,441 ****
--- 417,446 ----
}
+ #if (PY_VERSION_HEX < 0x03000000)
+ #define PyWinCoreString_ConcatAndDel PyString_ConcatAndDel
+ #define PyWinCoreString_Concat PyString_Concat
+ #else
+ // Unicode versions of '_Concat' etc have different sigs. Make them the
+ // same here...
+ void PyWinCoreString_Concat(register PyObject **pv, register PyObject *w)
+ {
+ if (!w) { // hrm - string version doesn't do this, but I saw PyObject_Repr() return NULL...
+ Py_XDECREF(*pv);
+ *pv = NULL;
+ return;
+ }
+ PyObject *tmp = PyUnicode_Concat(*pv, w);
+ Py_DECREF(*pv);
+ *pv = tmp;
+ }
+
+ void PyWinCoreString_ConcatAndDel(register PyObject **pv, register PyObject *w)
+ {
+ PyWinCoreString_Concat(pv, w);
+ Py_XDECREF(w);
+ }
+
+ #endif
+
PyObject *PyRecord::tp_repr(PyObject *self)
{
***************
*** 448,527 ****
PyObject *obrepr=NULL, *obattrname;
BOOL bsuccess=FALSE;
! #if (PY_VERSION_HEX < 0x03000000)
! static PyObject *comma = PyString_FromString(", ");
! static PyObject *equals = PyString_FromString(" = ");
! obrepr = PyString_FromString("com_struct{");
! if (obrepr==NULL || comma==NULL || equals==NULL)
goto done;
for (i = 0; i < num_names && obrepr != NULL; i++) {
! obattrname=PyString_FromUnicode(strings[i]);
if (obattrname==NULL)
! goto done; // missing some cleanup here
if (i > 0){
! PyString_Concat(&obrepr, comma);
if (!obrepr)
! goto done;
}
! PyString_ConcatAndDel(&obrepr, obattrname);
if (!obrepr)
! goto done;
! PyString_Concat(&obrepr, equals);
if (!obrepr)
! goto done;
PyObject *sub_object = PyRecord::getattro(self, obattrname);
if (!sub_object)
! goto done;
! PyString_ConcatAndDel(&obrepr, PyObject_Repr(sub_object));
! }
! PyString_ConcatAndDel(&obrepr, PyString_FromString("}"));
! #else
! // Create unicode repr in py3k
! static PyObject *comma = PyWinObject_FromWCHAR(L", ");
! static PyObject *equals = PyWinObject_FromWCHAR(L" = ");
! static PyObject *closing_paren=PyWinObject_FromWCHAR(L")");
! obrepr = PyWinObject_FromWCHAR(L"com_struct{");
! PyObject *tmp=NULL;
! for (i = 0; i < num_names && obrepr != NULL; i++) {
! obattrname=PyWinObject_FromWCHAR(strings[i]);
! if (obattrname==NULL)
! goto done;
! if (i > 0){
! tmp=PyUnicode_Concat(obrepr, comma);
! if (!tmp)
! goto done;
! Py_DECREF(obrepr);
! obrepr=tmp;
! }
! tmp=PyUnicode_Concat(obrepr, obattrname);
! if (!tmp)
! goto done;
! Py_DECREF(obrepr);
! obrepr=tmp;
Py_DECREF(obattrname);
- tmp=PyUnicode_Concat(obrepr, equals);
- if (!tmp)
- goto done;
- Py_DECREF(obrepr);
- obrepr=tmp;
- PyObject *sub_object = PyRecord::getattro(self, obattrname);
- if (!sub_object)
- goto done;
- tmp=PyUnicode_Concat(obrepr, PyObject_Repr(sub_object));
- if (!tmp)
- goto done;
- Py_DECREF(obrepr);
- obrepr=tmp;
- Py_DECREF(sub_object); // ??? still missing a DECREF for subobject's repr ???
- }
- tmp=PyUnicode_Concat(obrepr, closing_paren);
- if (!tmp)
goto done;
! Py_DECREF(obrepr);
! obrepr=tmp;
! #endif
bsuccess=TRUE;
done:
if (strings)
_FreeFieldNames(strings, num_names);
--- 453,498 ----
PyObject *obrepr=NULL, *obattrname;
BOOL bsuccess=FALSE;
+ PyObject *comma = PyWinCoreString_FromString(_T(", "));
+ PyObject *equals = PyWinCoreString_FromString(_T("="));
+ PyObject *closing_paren=PyWinCoreString_FromString(_T(")"));
+ obrepr = PyWinCoreString_FromString(_T("com_struct("));
! if (obrepr==NULL || comma==NULL || equals==NULL || closing_paren==NULL)
goto done;
for (i = 0; i < num_names && obrepr != NULL; i++) {
! obattrname=PyWinCoreString_FromString(strings[i]);
if (obattrname==NULL)
! goto done;
! // must exit on error via loop_error from here...
if (i > 0){
! PyWinCoreString_Concat(&obrepr, comma);
if (!obrepr)
! goto loop_error;
}
! PyWinCoreString_Concat(&obrepr, obattrname);
if (!obrepr)
! goto loop_error;
! PyWinCoreString_Concat(&obrepr, equals);
if (!obrepr)
! goto loop_error;
PyObject *sub_object = PyRecord::getattro(self, obattrname);
if (!sub_object)
! goto loop_error;
! PyWinCoreString_ConcatAndDel(&obrepr, PyObject_Repr(sub_object));
! Py_DECREF(sub_object);
! Py_DECREF(obattrname);
! continue;
! // loop error handler.
! loop_error:
Py_DECREF(obattrname);
goto done;
! }
! PyWinCoreString_Concat(&obrepr, closing_paren);
bsuccess=TRUE;
done:
+ Py_XDECREF(comma);
+ Py_XDECREF(equals);
+ Py_XDECREF(closing_paren);
if (strings)
_FreeFieldNames(strings, num_names);
***************
*** 555,559 ****
res = PyList_New(cnames);
for (ULONG i=0;i<cnames && res != NULL;i++) {
! PyObject *item = PyString_FromUnicode(strs[i]);
SysFreeString(strs[i]);
if (item==NULL) {
--- 526,530 ----
res = PyList_New(cnames);
for (ULONG i=0;i<cnames && res != NULL;i++) {
! PyObject *item = PyWinCoreString_FromString(strs[i]);
SysFreeString(strs[i]);
if (item==NULL) {
***************
*** 582,599 ****
PY_INTERFACE_PRECALL;
HRESULT hr = pyrec->pri->GetFieldNoCopy(pyrec->pdata, wname, &vret, &sub_data);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
if (hr == TYPE_E_FIELDNOTFOUND){
! PyErr_Format(PyExc_AttributeError,
! "This record has no field named '%s'", wname);
! PyWinObject_FreeWCHAR(wname);
return NULL;
}
- PyWinObject_FreeWCHAR(wname);
return PyCom_BuildPyException(hr, pyrec->pri, g_IID_IRecordInfo);
}
- PyWinObject_FreeWCHAR(wname);
// Short-circuit sub-structs and arrays here, so we dont allocate a new chunk
// of memory and copy it - we need sub-structs to persist.
--- 553,571 ----
PY_INTERFACE_PRECALL;
HRESULT hr = pyrec->pri->GetFieldNoCopy(pyrec->pdata, wname, &vret, &sub_data);
+ PyWinObject_FreeWCHAR(wname);
PY_INTERFACE_POSTCALL;
if (FAILED(hr)) {
if (hr == TYPE_E_FIELDNOTFOUND){
! // This is slightly suspect - throwing a unicode
! // object for an AttributeError in py2k - but this
! // is the value we asked COM for, so it makes sense...
! // (and PyErr_Format doesn't handle unicode in py2x)
! PyErr_SetObject(PyExc_AttributeError, obname);
return NULL;
}
return PyCom_BuildPyException(hr, pyrec->pri, g_IID_IRecordInfo);
}
// Short-circuit sub-structs and arrays here, so we dont allocate a new chunk
// of memory and copy it - we need sub-structs to persist.
***************
*** 668,679 ****
}
! int PyRecord::tp_compare(PyObject *self, PyObject *other)
{
PyRecord *pyself = (PyRecord *)self;
PyRecord *pyother = (PyRecord *)other;
if (!pyself->pri->IsMatchingType(pyother->pri)) {
! // Not matching types - just compare the object addresses!
! // (doesnt matter what we use here, as long as it is consistent)
! return pyself->pdata < pyother->pdata ? -1 : 1;
}
// Need to do a recursive compare, as some elements may be pointers
--- 640,659 ----
}
! PyObject *PyRecord::tp_richcompare(PyObject *self, PyObject *other, int op)
{
+ PyObject *ret = NULL;
+ if (op != Py_EQ && op != Py_NE) {
+ PyErr_SetString(PyExc_TypeError, "IIDs only compare equal or not equal");
+ return NULL;
+ }
+ int success = op == Py_EQ ? TRUE : FALSE;
+
+ if (self->ob_type != other->ob_type)
+ return PyBool_FromLong(!success);
PyRecord *pyself = (PyRecord *)self;
PyRecord *pyother = (PyRecord *)other;
if (!pyself->pri->IsMatchingType(pyother->pri)) {
! // Not matching types, so must compare False.
! return PyBool_FromLong(!success);
}
// Need to do a recursive compare, as some elements may be pointers
***************
*** 682,686 ****
BSTR *strings = _GetFieldNames(pyself->pri, &num_names);
if (strings==NULL) return NULL;
- int ret;
for (ULONG i=0;i<num_names;i++) {
ret = 0;
--- 662,665 ----
***************
*** 688,714 ****
obattrname=PyWinCoreString_FromString(strings[i]);
if (obattrname==NULL)
! return -2;
// There appear to be several problems here. This will leave an exception hanging
// if an attribute is not found, and should probably return False if other does not
// have an attr that self does ???
PyObject *self_sub = PyRecord::getattro(self, obattrname);
! if (self_sub) {
! PyObject *other_sub = PyRecord::getattro(other, obattrname);
! if (other_sub){
! ret = PyObject_Compare(self_sub, other_sub);
! Py_DECREF(other_sub);
! }
! else{
! PyErr_Clear();
! ret=1;
! }
Py_DECREF(self_sub);
! }
! else
! PyErr_Clear();
Py_DECREF(obattrname);
! if (ret != 0)
! break;
}
_FreeFieldNames(strings, num_names);
return ret;
--- 667,702 ----
obattrname=PyWinCoreString_FromString(strings[i]);
if (obattrname==NULL)
! goto done;
// There appear to be several problems here. This will leave an exception hanging
// if an attribute is not found, and should probably return False if other does not
// have an attr that self does ???
+ // MarkH: but is that possible in practice? For structures,
+ // an attribute must be found, and the set must be identical
+ // (we have already checked the 'type' is the same above)
+ // (defense against COM errors etc would be nice though :)
PyObject *self_sub = PyRecord::getattro(self, obattrname);
! if (!self_sub) {
! Py_DECREF(obattrname);
! goto done;
! }
! PyObject *other_sub = PyRecord::getattro(other, obattrname);
! if (!other_sub){
! Py_DECREF(obattrname);
Py_DECREF(self_sub);
! goto done;
! }
! int c = PyObject_RichCompareBool(self_sub, other_sub, op);
! Py_DECREF(self_sub);
! Py_DECREF(other_sub);
Py_DECREF(obattrname);
! if (c == -1)
! goto done;
! if (c != success) {
! ret = PyBool_FromLong(c);
! goto done;
! }
}
+ ret = PyBool_FromLong(success);
+ done:
_FreeFieldNames(strings, num_names);
return ret;
Index: MiscTypes.cpp
===================================================================
RCS file: /cvsroot/pywin32/pywin32/com/win32com/src/MiscTypes.cpp,v
retrieving revision 1.8.4.2
retrieving revision 1.8.4.3
diff -C2 -d -r1.8.4.2 -r1.8.4.3
*** MiscTypes.cpp 2 Nov 2008 12:43:47 -0000 1.8.4.2
--- MiscTypes.cpp 19 Dec 2008 02:33:56 -0000 1.8.4.3
***************
*** 49,53 ****
--- 49,58 ----
0, /*tp_getattr*/
0, /*tp_setattr*/
+ // For b/w compat, we still allow 'cmp()' to work with Py2k, but for Py3k only rich compare is supported.
+ #if (PY_VERSION_HEX < 0x03000000)
PyIBase::cmp, /*tp_compare*/
+ #else
+ 0,
+ #endif
(reprfunc)PyIBase::repr, /*tp_repr*/
0, /*tp_as_number*/
***************
*** 64,68 ****
0, /* tp_traverse */
0, /* tp_clear */
! 0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
--- 69,73 ----
0, /* tp_traverse */
0, /* tp_clear */
! PyIBase::richcmp, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
***************
*** 71,75 ****
0, /* tp_members */
0, /* tp_getset */
! 0, // &PyInterfaceType_Type, /* tp_base */
};
--- 76,80 ----
0, /* tp_members */
0, /* tp_getset */
! 0, // setup to a real value below. /* tp_base */
};
***************
*** 84,88 ****
// All interfaces are based on PyInterfaceType, so this type will inherit from it thru pBase
- // tp_bases=Py_BuildValue("OO", &PyInterfaceType_Type, pBase);
if (pBase)
tp_base=pBase;
--- 89,92 ----
Index: PyIUnknown.cpp
===================================================================
RCS file: /cvsroot/pywin32/pywin32/com/win32com/src/PyIUnknown.cpp,v
retrieving revision 1.12.2.4
retrieving revision 1.12.2.5
diff -C2 -d -r1.12.2.4 -r1.12.2.5
*** PyIUnknown.cpp 26 Nov 2008 07:17:39 -0000 1.12.2.4
--- PyIUnknown.cpp 19 Dec 2008 02:33:56 -0000 1.12.2.5
***************
*** 168,172 ****
if (!PyCom_InterfaceFromPyObject(this, IID_IUnknown, (void **)&pUnkThis, FALSE))
return -1;
! if (!PyCom_InterfaceFromPyObject(other, IID_IUnknown, (void **)&pUnkOther, FALSE)) {
pUnkThis->Release();
return -1;
--- 168,174 ----
if (!PyCom_InterfaceFromPyObject(this, IID_IUnknown, (void **)&pUnkThis, FALSE))
return -1;
! // in a nod to rich comparisons, which end up calling this, we allow
! // 'other' to be an instance.
! if (!PyCom_InterfaceFromPyInstanceOrObject(other, IID_IUnknown, (void **)&pUnkOther, FALSE)) {
pUnkThis->Release();
return -1;
Index: PyIBase.cpp
===================================================================
RCS file: /cvsroot/pywin32/pywin32/com/win32com/src/PyIBase.cpp,v
retrieving revision 1.7.4.2
retrieving revision 1.7.4.3
diff -C2 -d -r1.7.4.2 -r1.7.4.3
*** PyIBase.cpp 4 Dec 2008 00:07:22 -0000 1.7.4.2
--- PyIBase.cpp 19 Dec 2008 02:33:56 -0000 1.7.4.3
***************
*** 23,34 ****
PyIBase::getattro(PyObject *self, PyObject *name)
{
- /*
- if (PyString_Check(name)) {
- PyObject *rc = ((PyIBase *)self)->getattr(PyString_AsString(name));
- if (rc)
- return rc;
- PyErr_Clear();
- }
- */
// Using PyObject_GenericGetAttr allows some special type magic
// (ie,
--- 23,26 ----
***************
*** 81,82 ****
--- 73,94 ----
}
+ /*static*/ PyObject *PyIBase::richcmp(PyObject *ob1, PyObject *ob2, int op)
+ {
+ // our 'compare' implementations don't assume ob2 is our type, so
+ // no additional checks are needed.
+ int c = cmp(ob1, ob2);
+ // BUT - it doesn't propogate exceptions correctly.
+ if (c==-1 && PyErr_Occurred())
+ return NULL;
+ assert(!PyErr_Occurred()); // should always have returned -1 on error.
+ BOOL ret;
+ if (op==Py_EQ)
+ ret = c == 0;
+ else if (op==Py_NE)
+ ret = c != 0;
+ else {
+ PyErr_SetString(PyExc_TypeError, "Interface pointers only compare equal or not equal");
+ return NULL;
+ }
+ return PyBool_FromLong(ret);
+ }
|