[pywin32-checkins] /hgroot/pywin32/pywin32: 2 new changesets
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
From: <pyw...@li...> - 2013-06-13 09:16:49
|
changeset 758c693673d2 in /hgroot/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgroot/pywin32/pywin32?cmd=changeset;node=758c693673d2 summary: Add support for VT_I8 and VT_UI8 when converting a variant into a Pythonobject (Stefan Schukat via patch #128) changeset cbcbd126551c in /hgroot/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgroot/pywin32/pywin32?cmd=changeset;node=cbcbd126551c summary: Conversions from a Python object to a variant now does a better job at deciding what variant type to use (Stefan Schukat) diffstat: CHANGES.txt | 7 +++ com/win32com/src/oleargs.cpp | 81 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 70 insertions(+), 18 deletions(-) diffs (120 lines): diff -r 1594b8c27383 -r cbcbd126551c CHANGES.txt --- a/CHANGES.txt Thu Jun 13 18:29:09 2013 +1000 +++ b/CHANGES.txt Thu Jun 13 19:16:16 2013 +1000 @@ -6,6 +6,13 @@ Since build 218: ---------------- + * Conversions from a Python object to a variant now does a better job at + deciding what variant type to use, taking into account the size and sign of + the value (Stefan Schukat via patch #127) + + * Add support for VT_I8 and VT_UI8 when converting a variant into a Python + object (Stefan Schukat via patch #128) + * win32com.mapi.exchange Added 64-bit support by excluding the 32-bit Ex2kSdk.lib functions from 64-bit builds. Unfortunately, this means that only IExchangeManageStore::CreateStoreEntryID diff -r 1594b8c27383 -r cbcbd126551c com/win32com/src/oleargs.cpp --- a/com/win32com/src/oleargs.cpp Thu Jun 13 18:29:09 2013 +1000 +++ b/com/win32com/src/oleargs.cpp Thu Jun 13 19:16:16 2013 +1000 @@ -145,29 +145,58 @@ } else if (PyLong_Check(obj)) { - __int64 lval = PyLong_AsLongLong(obj); - if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_OverflowError)) + int sign = _PyLong_Sign(obj); + size_t nbits = _PyLong_NumBits(obj); + if (nbits == (size_t)-1 && PyErr_Occurred()) return FALSE; - if (PyErr_Occurred()) { - PyErr_Clear(); + if (64 < nbits) { // too big for 64 bits! Use a double. - double dval = PyLong_AsDouble(obj); V_VT(var) = VT_R8; - V_R8(var) = dval; + V_R8(var) = PyLong_AsDouble(obj); + } + else if (32 < nbits) { + // between 32 and 64 use longlong + // signed and using all bits use unsigned + if (sign > 0 && 64 == nbits) { + V_VT(var) = VT_UI8; + V_UI8(var) = PyLong_AsUnsignedLongLong(obj); + } else { + // Negative so use signed + V_VT(var) = VT_I8; + V_I8(var) = PyLong_AsLongLong(obj); + // Problem if value is between LLONG_MIN and -ULLONG_MAX + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + // Take now double + PyErr_Clear(); + V_VT(var) = VT_R8; + V_R8(var) = PyLong_AsDouble(obj); + } else { + return FALSE; + } + } + } } else { - // 64 bits is OK - but if it fits in 32 we will - // use that. Prefer VT_I4 if possible as VBScript - // etc like it better. - if (lval >= LONG_MIN && lval <= LONG_MAX) { + // less then 32 bit use standard long + // positive and using all bits so unsigned + if (sign > 0 && 32 == nbits) { + V_VT(var) = VT_UI4; + V_UI4(var) = PyLong_AsUnsignedLong(obj); + } else { + // Negative so use signed V_VT(var) = VT_I4; - V_I4(var) = (long)lval; - // OK, we know it must be > LONG_MAX, but zero is clearer - } else if (lval >= 0 && lval <= ULONG_MAX) { - V_VT(var) = VT_UI4; - V_UI4(var) = (unsigned long)lval; - } else { - V_VT(var) = VT_I8; - V_I8(var) = lval; + V_I4(var) = PyLong_AsLong(obj); + // Problem if value is between LONG_MIN and -ULONG_MAX + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + // Take now double + PyErr_Clear(); + V_VT(var) = VT_I8; + V_I8(var) = PyLong_AsLongLong(obj); + } else { + return FALSE; + } + } } } } @@ -371,6 +400,22 @@ result = PyInt_FromLong(V_I4(&varValue)); break; + case VT_UI8: + // The result may be too large for a simple "long". If so, + // we must return a long. + if (V_UI8(&varValue) <= LONG_MAX) + result = PyInt_FromLong((long)V_UI8(&varValue)); + else + result = PyLong_FromUnsignedLongLong(V_UI8(&varValue)); + break; + + case VT_I8: + if ((LONG_MIN <= V_I8(&varValue)) && (V_I8(&varValue) <= LONG_MAX)) + result = PyInt_FromLong((long)V_I8(&varValue)); + else + result = PyLong_FromLongLong(V_I8(&varValue)); + break; + case VT_HRESULT: case VT_ERROR: result = PyInt_FromLong(V_ERROR(&varValue)); |