From f60c64d528c84395ec1ce4bdd7be878006d864af Mon Sep 17 00:00:00 2001 From: Mark Hammond Date: Tue, 14 Mar 2006 12:12:44 +0000 Subject: [PATCH] pythoncom.Empty now does what it implies - a Variant with VT_EMPTY. The new pythoncom.ArgNotFound supports the old behaviour (of VT_ERROR with DISP_E_PARAMNOTFOUND) --- com/win32com/client/genpy.py | 2 +- com/win32com/src/MiscTypes.cpp | 31 ++++++++++++++++++++++++++++ com/win32com/src/PythonCOM.cpp | 4 ++++ com/win32com/src/include/PythonCOM.h | 7 +++++++ com/win32com/src/oleargs.cpp | 8 +++++-- 5 files changed, 49 insertions(+), 3 deletions(-) diff --git a/com/win32com/client/genpy.py b/com/win32com/client/genpy.py index 347f61432..d2b64a07e 100644 --- a/com/win32com/client/genpy.py +++ b/com/win32com/client/genpy.py @@ -805,7 +805,7 @@ def do_gen_file_header(self): print >> self.file, 'from win32com.client import Dispatch' print >> self.file print >> self.file, '# The following 3 lines may need tweaking for the particular server' - print >> self.file, '# Candidates are pythoncom.Missing and pythoncom.Empty' + print >> self.file, '# Candidates are pythoncom.Missing, .Empty and .ArgNotFound' print >> self.file, 'defaultNamedOptArg=pythoncom.Empty' print >> self.file, 'defaultNamedNotOptArg=pythoncom.Empty' print >> self.file, 'defaultUnnamedArg=pythoncom.Empty' diff --git a/com/win32com/src/MiscTypes.cpp b/com/win32com/src/MiscTypes.cpp index 68088cfb0..f5b3fb469 100644 --- a/com/win32com/src/MiscTypes.cpp +++ b/com/win32com/src/MiscTypes.cpp @@ -261,4 +261,35 @@ PYCOM_EXPORT PyTypeObject PyOleMissingType = 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ }; +///////////////////////////////////////////////////////////////////////////// +// class PyOleArgNotFound +PyOleArgNotFound::PyOleArgNotFound() +{ + ob_type = &PyOleArgNotFoundType; + _Py_NewReference(this); +} + +static void notfound_dealloc(PyOleArgNotFound *o) +{ + delete o; +} + +PyTypeObject PyOleArgNotFoundType = +{ + PyObject_HEAD_INIT(&PyType_Type) + 0, + "ArgNotFound", + sizeof(PyOleArgNotFound), + 0, + (destructor)notfound_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ +}; + //////////////////////////////// diff --git a/com/win32com/src/PythonCOM.cpp b/com/win32com/src/PythonCOM.cpp index 03508da86..be2ad2929 100644 --- a/com/win32com/src/PythonCOM.cpp +++ b/com/win32com/src/PythonCOM.cpp @@ -30,6 +30,7 @@ extern PyObject *g_obPyCom_MapInterfaceNameToIID; static PyObject *g_obEmpty = NULL; static PyObject *g_obMissing = NULL; +static PyObject *g_obArgNotFound = NULL; PyObject *PyCom_InternalError = NULL; @@ -1818,6 +1819,9 @@ extern "C" __declspec(dllexport) void initpythoncom() g_obMissing = new PyOleMissing; PyDict_SetItemString(dict, "Missing", g_obMissing); + g_obArgNotFound = new PyOleArgNotFound; + PyDict_SetItemString(dict, "ArgNotFound", g_obArgNotFound); + // Add some symbolic constants to the module // pycom_Error = PyString_FromString("pythoncom.error"); PyObject *pycom_Error = PyWinExc_COMError; diff --git a/com/win32com/src/include/PythonCOM.h b/com/win32com/src/include/PythonCOM.h index 29ab4c91e..c5fd3a1a9 100644 --- a/com/win32com/src/include/PythonCOM.h +++ b/com/win32com/src/include/PythonCOM.h @@ -221,6 +221,7 @@ class PYCOM_EXPORT PyIBase : /* Special Type objects */ extern PYCOM_EXPORT PyTypeObject PyOleEmptyType; // equivalent to VT_EMPTY extern PYCOM_EXPORT PyTypeObject PyOleMissingType; // special Python handling. +extern PYCOM_EXPORT PyTypeObject PyOleArgNotFoundType; // special VT_ERROR value // ALL of these set an appropriate Python error on bad return. @@ -395,6 +396,12 @@ class PYCOM_EXPORT PyOleMissing : public PyObject PyOleMissing(); }; +class PYCOM_EXPORT PyOleArgNotFound : public PyObject +{ +public: + PyOleArgNotFound(); +}; + // We need to dynamically create C++ Python objects // These helpers allow each type object to create it. #define MAKE_PYCOM_CTOR(classname) static PyIUnknown * classname::PyObConstruct(IUnknown *pInitObj) {return new classname(pInitObj);} diff --git a/com/win32com/src/oleargs.cpp b/com/win32com/src/oleargs.cpp index dac6bfa9c..a8c3679da 100644 --- a/com/win32com/src/oleargs.cpp +++ b/com/win32com/src/oleargs.cpp @@ -53,6 +53,7 @@ static PyObject* OleSetTypeErrorW(TCHAR *msg) // you need to use the complicated ArgHelpers class for that! BOOL PyCom_VariantFromPyObject(PyObject *obj, VARIANT *var) { + BOOL bGoodEmpty = FALSE; // Set if VT_EMPTY should really be used. V_VT(var) = VT_EMPTY; if ( PyString_Check(obj) || PyUnicode_Check(obj) ) { @@ -131,7 +132,10 @@ BOOL PyCom_VariantFromPyObject(PyObject *obj, VARIANT *var) V_UNKNOWN(var) = PyIUnknown::GetI(obj); V_UNKNOWN(var)->AddRef(); } - else if (obj->ob_type == &PyOleEmptyType) + else if (obj->ob_type == &PyOleEmptyType) { + bGoodEmpty = TRUE; + } + else if (obj->ob_type == &PyOleArgNotFoundType) { // use default parameter // Note the SDK documentation for FUNCDESC describes this behaviour @@ -185,7 +189,7 @@ BOOL PyCom_VariantFromPyObject(PyObject *obj, VARIANT *var) { } */ - if (V_VT(var) == VT_EMPTY) { + if (V_VT(var) == VT_EMPTY && !bGoodEmpty) { // Must ensure we have a Python error set if we fail! if (!PyErr_Occurred()) { char *extraMessage = "";