[pywin32-checkins] /hgroot/pywin32/pywin32: Allow variant currency conversions (VT_...
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
From: <pyw...@li...> - 2012-08-28 05:14:05
|
changeset bec283d926a5 in /hgroot/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgroot/pywin32/pywin32?cmd=changeset;node=bec283d926a5 summary: Allow variant currency conversions (VT_CY) to work with _decimal module in Python 3.3 diffstat: com/win32com/src/PyComHelpers.cpp | 63 +++++++++++++++++++++++++++----------- 1 files changed, 44 insertions(+), 19 deletions(-) diffs (90 lines): diff -r e2e6637fbaa1 -r bec283d926a5 com/win32com/src/PyComHelpers.cpp --- a/com/win32com/src/PyComHelpers.cpp Sat Aug 25 14:59:12 2012 -0400 +++ b/com/win32com/src/PyComHelpers.cpp Tue Aug 28 01:12:51 2012 -0400 @@ -41,6 +41,31 @@ } // Currency conversions. +// Should probably place this in module dict so it can be DECREF'ed on finalization +// Also may get borked by a reload of the decimal module +static PyObject *Decimal_class = NULL; + +PyObject *get_Decimal_class(void) +{ + // Try to import compiled _decimal module introduced in Python 3.3 + TmpPyObject decimal_module = PyImport_ImportModule("_decimal"); + + // Look for python implemented module introduced in Python 2.4 + if (decimal_module==NULL){ + PyErr_Clear(); + decimal_module = PyImport_ImportModule("decimal"); + } + + // Look for our own copy included in Pywin32 for Python 2.3 + if (decimal_module==NULL){ + PyErr_Clear(); + decimal_module=PyImport_ImportModule("win32com.decimal_23"); + } + if (decimal_module==NULL) + return NULL; + return PyObject_GetAttrString(decimal_module, "Decimal"); +} + PyObject *PyObject_FromCurrency(CURRENCY &cy) { #if (PY_VERSION_HEX < 0x03000000) @@ -48,35 +73,35 @@ #else static char *divname = "__truediv__"; #endif - static PyObject *decimal_module=NULL; - PyObject *result = NULL; - - if (decimal_module==NULL){ - decimal_module=PyImport_ImportModule("decimal"); - if (!decimal_module) { - PyErr_Clear(); - decimal_module=PyImport_ImportModule("win32com.decimal_23"); - } + if (Decimal_class == NULL){ + Decimal_class = get_Decimal_class(); + if (Decimal_class == NULL) + return NULL; } - if (decimal_module==NULL) + + TmpPyObject unscaled_result = PyObject_CallFunction(Decimal_class, "L", cy.int64); + if (unscaled_result == NULL) return NULL; - - PyObject *unscaled_result; - unscaled_result=PyObject_CallMethod(decimal_module, "Decimal", "L", cy.int64); - if (unscaled_result!=NULL){ - result=PyObject_CallMethod(unscaled_result, divname, "l", 10000); - Py_DECREF(unscaled_result); - } - return result; + return PyObject_CallMethod(unscaled_result, divname, "l", 10000); } PYCOM_EXPORT BOOL PyObject_AsCurrency(PyObject *ob, CURRENCY *pcy) { - if (strcmp(ob->ob_type->tp_name, "Decimal")!=0){ + if (Decimal_class == NULL){ + Decimal_class = get_Decimal_class(); + if (Decimal_class == NULL) + return FALSE; + } + + int right_type = PyObject_IsInstance(ob, Decimal_class); + if (right_type == -1) + return FALSE; + else if (right_type == 0){ PyErr_Format(PyExc_TypeError, "Currency object must be a Decimal instance (got %s).",ob->ob_type->tp_name); return FALSE; } + TmpPyObject scaled = PyObject_CallMethod(ob, "__mul__", "l", 10000); if (scaled == NULL) return FALSE; |