Skip to content

Commit

Permalink
pythoncom.Empty now does what it implies - a Variant with VT_EMPTY. The
Browse files Browse the repository at this point in the history
new pythoncom.ArgNotFound supports the old behaviour (of VT_ERROR with
DISP_E_PARAMNOTFOUND)
  • Loading branch information
mhammond committed Mar 14, 2006
1 parent ddcdb36 commit f60c64d
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 3 deletions.
2 changes: 1 addition & 1 deletion com/win32com/client/genpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
31 changes: 31 additions & 0 deletions com/win32com/src/MiscTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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*/
};

////////////////////////////////
4 changes: 4 additions & 0 deletions com/win32com/src/PythonCOM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down
7 changes: 7 additions & 0 deletions com/win32com/src/include/PythonCOM.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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);}
Expand Down
8 changes: 6 additions & 2 deletions com/win32com/src/oleargs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) )
{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 = "";
Expand Down

0 comments on commit f60c64d

Please sign in to comment.