[pywin32-checkins] /hgrepo/p/py/pywin32/pywin32: 4 new changesets
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
From: <pyw...@li...> - 2011-04-23 12:41:35
|
changeset a64d8ac23e61 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=a64d8ac23e61 summary: avoid installation errors if sys.stdout is None or invalid changeset b7d001d8059a in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=b7d001d8059a summary: add signed/unsigned integer methods to test COM object changeset e20a65e27c65 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=e20a65e27c65 summary: treat VT_UINT as VT_UI4 rather than VT_I4 changeset 62ea09011278 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=62ea09011278 summary: detect overflow error and correctly handling unsigned ints in variants diffstat: CHANGES.txt | 6 +++ com/TestSources/PyCOMTest/PyCOMImpl.cpp | 28 ++++++++++++++ com/TestSources/PyCOMTest/PyCOMImpl.h | 4 ++ com/TestSources/PyCOMTest/PyCOMTest.idl | 4 ++ com/win32com/client/build.py | 2 +- com/win32com/src/oleargs.cpp | 12 ++++-- com/win32com/test/testPyComTest.py | 56 +++++++++++++++++++++++----- pywin32_postinstall.py | 12 +++++- 8 files changed, 107 insertions(+), 17 deletions(-) diffs (256 lines): diff -r cdbcf976e498 -r 62ea09011278 CHANGES.txt --- a/CHANGES.txt Thu Apr 14 14:54:45 2011 +1000 +++ b/CHANGES.txt Sat Apr 23 22:40:29 2011 +1000 @@ -7,6 +7,12 @@ Since build 216: ---------------- +* When passing integers/unsigned integers to COM objects which did not fit + into 32bits, OverflowErrors were silently discarded and -1 was silently + passed. This has been fixed for signed integers (an OverflowError is now + raised) and unsigned integers now allow for values with the high-bit set to + be passed correctly. + * Fixed that in some cases win32file.GetOpenFileName and GetSaveFileName could have returned trailing garbage after an embedded NULL character. (bug 3277647) diff -r cdbcf976e498 -r 62ea09011278 com/TestSources/PyCOMTest/PyCOMImpl.cpp --- a/com/TestSources/PyCOMTest/PyCOMImpl.cpp Thu Apr 14 14:54:45 2011 +1000 +++ b/com/TestSources/PyCOMTest/PyCOMImpl.cpp Sat Apr 23 22:40:29 2011 +1000 @@ -206,6 +206,34 @@ return VariantCopy(out, &var); } +STDMETHODIMP CPyCOMTest::GetSetInt(int invar, int *outvar) +{ + if (!outvar) + return E_POINTER; + *outvar = invar; +} + +STDMETHODIMP CPyCOMTest::GetSetUnsignedInt(unsigned int invar, unsigned int *outvar) +{ + if (!outvar) + return E_POINTER; + *outvar = invar; +} + +STDMETHODIMP CPyCOMTest::GetSetLong(long invar, long *outvar) +{ + if (!outvar) + return E_POINTER; + *outvar = invar; +} + +STDMETHODIMP CPyCOMTest::GetSetUnsignedLong(unsigned long invar, unsigned long *outvar) +{ + if (!outvar) + return E_POINTER; + *outvar = invar; +} + STDMETHODIMP CPyCOMTest::TestByRefVariant(VARIANT *v) { if (V_VT(v)==VT_I4) { diff -r cdbcf976e498 -r 62ea09011278 com/TestSources/PyCOMTest/PyCOMImpl.h --- a/com/TestSources/PyCOMTest/PyCOMImpl.h Thu Apr 14 14:54:45 2011 +1000 +++ b/com/TestSources/PyCOMTest/PyCOMImpl.h Sat Apr 23 22:40:29 2011 +1000 @@ -66,6 +66,10 @@ STDMETHOD(GetSetDispatch)(IDispatch *indisp, IDispatch **outdisp); STDMETHOD(GetSetUnknown)(IUnknown *inunk, IUnknown **outunk); STDMETHOD(GetSetVariant)(VARIANT vin, VARIANT *vout); + STDMETHOD(GetSetInt)(int invar, int *outvar); + STDMETHOD(GetSetUnsignedInt)(unsigned int invar, unsigned int *outvar); + STDMETHOD(GetSetLong)(long invar, long *outvar); + STDMETHOD(GetSetUnsignedLong)(unsigned long invar, unsigned long *outvar); STDMETHOD(TestByRefVariant)(VARIANT *v); STDMETHOD(TestByRefString)(BSTR *v); STDMETHOD(TakeByRefTypedDispatch)(IPyCOMTest **inout); diff -r cdbcf976e498 -r 62ea09011278 com/TestSources/PyCOMTest/PyCOMTest.idl --- a/com/TestSources/PyCOMTest/PyCOMTest.idl Thu Apr 14 14:54:45 2011 +1000 +++ b/com/TestSources/PyCOMTest/PyCOMTest.idl Sat Apr 23 22:40:29 2011 +1000 @@ -198,6 +198,10 @@ HRESULT GetSetDispatch([in] IDispatch *indisp, [out, retval] IDispatch **outdisp); HRESULT GetSetUnknown([in] IUnknown *inunk, [out, retval] IUnknown **outunk); HRESULT GetSetVariant([in] VARIANT vin, [out, retval] VARIANT *vout); + HRESULT GetSetInt([in] int invar, [out, retval] int *outunk); + HRESULT GetSetUnsignedInt([in] unsigned int invar, [out, retval] unsigned int *outunk); + HRESULT GetSetLong([in] long invar, [out, retval] long *outunk); + HRESULT GetSetUnsignedLong([in] unsigned long invar, [out, retval] unsigned long *outunk); HRESULT TestByRefVariant([in, out] VARIANT *v); HRESULT TestByRefString([in, out] BSTR *v); HRESULT TakeByRefTypedDispatch([in, out] IPyCOMTest **inout); diff -r cdbcf976e498 -r 62ea09011278 com/win32com/client/build.py --- a/com/win32com/client/build.py Thu Apr 14 14:54:45 2011 +1000 +++ b/com/win32com/client/build.py Sat Apr 23 22:40:29 2011 +1000 @@ -416,7 +416,7 @@ typeSubstMap = { pythoncom.VT_INT: pythoncom.VT_I4, - pythoncom.VT_UINT: pythoncom.VT_I4, + pythoncom.VT_UINT: pythoncom.VT_UI4, pythoncom.VT_HRESULT: pythoncom.VT_I4, } diff -r cdbcf976e498 -r 62ea09011278 com/win32com/src/oleargs.cpp --- a/com/win32com/src/oleargs.cpp Thu Apr 14 14:54:45 2011 +1000 +++ b/com/win32com/src/oleargs.cpp Sat Apr 23 22:40:29 2011 +1000 @@ -1159,6 +1159,7 @@ case VT_I4: if ((obUse=PyNumber_Int(obj))==NULL) BREAK_FALSE V_I4(var) = PyInt_AsLong(obUse); + if (V_I4(var)==-1 && PyErr_Occurred()) BREAK_FALSE; break; case VT_I4 | VT_BYREF: if (bCreateBuffers) @@ -1167,12 +1168,14 @@ if (!VALID_BYREF_MISSING(obj)) { if ((obUse=PyNumber_Int(obj))==NULL) BREAK_FALSE *V_I4REF(var) = PyInt_AsLong(obUse); + if (*V_I4REF(var)==-1 && PyErr_Occurred()) BREAK_FALSE; } else *V_I4REF(var) = 0; break; case VT_UI4: if ((obUse=PyNumber_Int(obj))==NULL) BREAK_FALSE - V_UI4(var) = PyInt_AsLong(obUse); + V_UI4(var) = PyLong_AsUnsignedLongMask(obUse); + if (V_UI4(var)==(unsigned long)-1 && PyErr_Occurred()) BREAK_FALSE; break; case VT_UI4 | VT_BYREF: if (bCreateBuffers) @@ -1180,7 +1183,8 @@ if (!VALID_BYREF_MISSING(obj)) { if ((obUse=PyNumber_Int(obj))==NULL) BREAK_FALSE - *V_UI4REF(var) = PyInt_AsLong(obUse); + *V_UI4REF(var) = PyLong_AsUnsignedLongMask(obUse); + if (*V_UI4REF(var)==(unsigned long)-1 && PyErr_Occurred()) BREAK_FALSE; } else *V_UI4REF(var) = 0; break; @@ -1200,7 +1204,7 @@ break; case VT_UI2: if ((obUse=PyNumber_Int(obj))==NULL) BREAK_FALSE - V_UI2(var) = (short)PyInt_AsLong(obUse); + V_UI2(var) = (short)PyLong_AsUnsignedLongMask(obUse); break; case VT_UI2 | VT_BYREF: if (bCreateBuffers) @@ -1208,7 +1212,7 @@ if (!VALID_BYREF_MISSING(obj)) { if ((obUse=PyNumber_Int(obj))==NULL) BREAK_FALSE - *V_UI2REF(var) = (short)PyInt_AsLong(obUse); + *V_UI2REF(var) = (unsigned short)PyLong_AsUnsignedLongMask(obUse); } else *V_UI2REF(var) = 0; break; diff -r cdbcf976e498 -r 62ea09011278 com/win32com/test/testPyComTest.py --- a/com/win32com/test/testPyComTest.py Thu Apr 14 14:54:45 2011 +1000 +++ b/com/win32com/test/testPyComTest.py Sat Apr 23 22:40:29 2011 +1000 @@ -46,6 +46,19 @@ # on py2x, we just use an expression that results in a long return 0x100000000-0x100000000+int_val +def check_get_set(func, arg): + got = func(arg) + if got != arg: + raise error("%s failed - expected %r, got %r" % (func, arg, got)) + +def check_get_set_raises(exc, func, arg): + try: + got = func(arg) + except exc, e: + pass # what we expect! + else: + raise error("%s with arg %r didn't raise %s - returned %r" % (func, arg, exc, got)) + def progress(*args): if verbose: for arg in args: @@ -232,26 +245,49 @@ if o.GetLastVarArgs() != ("Hi", "There", "From", "Python", 1): raise error("VarArgs failed -" + str(o.GetLastVarArgs())) progress("Checking getting/passing IUnknown") - if o.GetSetUnknown(o) != o: - raise error("GetSetUnknown failed") + check_get_set(o.GetSetUnknown, o) progress("Checking getting/passing IDispatch") if not isinstance(o.GetSetDispatch(o), DispatchBaseClass): raise error("GetSetDispatch failed") progress("Checking getting/passing IDispatch of known type") if o.GetSetInterface(o).__class__ != o.__class__: raise error("GetSetDispatch failed") - if o.GetSetVariant(4) != 4: - raise error("GetSetVariant (int) failed") - if o.GetSetVariant("foo") != "foo": - raise error("GetSetVariant (str) failed") - if o.GetSetVariant(o) != o: - raise error("GetSetVariant (dispatch) failed") + check_get_set(o.GetSetVariant, 4) + check_get_set(o.GetSetVariant, "foo") + check_get_set(o.GetSetVariant, o) + # signed/unsigned. + check_get_set(o.GetSetInt, 0) + check_get_set(o.GetSetInt, -1) + check_get_set(o.GetSetInt, 1) + check_get_set_raises(OverflowError, o.GetSetInt, 0x80000000) + check_get_set_raises(ValueError, o.GetSetInt, "foo") + + check_get_set(o.GetSetUnsignedInt, 0) + check_get_set(o.GetSetUnsignedInt, 1) + check_get_set(o.GetSetUnsignedInt, 0x80000000) + if o.GetSetUnsignedInt(-1) != 0xFFFFFFFF: + # -1 is a special case - we accept a negative int (silently converting to + # unsigned) but when getting it back we convert it to a long. + raise error("unsigned -1 failed") + + check_get_set(o.GetSetLong, 0) + check_get_set(o.GetSetLong, -1) + check_get_set(o.GetSetLong, 1) + check_get_set_raises(OverflowError, o.GetSetLong, 0x80000000) + check_get_set_raises(ValueError, o.GetSetLong, "foo") + + check_get_set(o.GetSetUnsignedLong, 0) + check_get_set(o.GetSetUnsignedLong, 1) + check_get_set(o.GetSetUnsignedLong, 0x80000000) + # -1 is a special case - see above. + if o.GetSetUnsignedLong(-1) != 0xFFFFFFFF: + raise error("unsigned -1 failed") + # We want to explicitly test > 32 bits. py3k has no 'maxint' and # 'maxsize+1' is no good on 64bit platforms as its 65 bits! big = 2147483647 # sys.maxint on py2k for l in big, big+1, 1 << 65: - if o.GetSetVariant(l) != l: - raise error("GetSetVariant (long) failed") + check_get_set(o.GetSetVariant, l) if o.TestByRefVariant(2) != 4: raise error("TestByRefVariant failed") if o.TestByRefString("Foo") != "FooFoo": diff -r cdbcf976e498 -r 62ea09011278 pywin32_postinstall.py --- a/pywin32_postinstall.py Thu Apr 14 14:54:45 2011 +1000 +++ b/pywin32_postinstall.py Sat Apr 23 22:40:29 2011 +1000 @@ -12,10 +12,18 @@ def __init__(self, file): self.f = file def write(self, what): - self.f.write(what) + if self.f is not None: + try: + self.f.write(what) + except IOError: + pass tee_f.write(what) def flush(self): - self.f.flush() + if self.f is not None: + try: + self.f.flush() + except IOError: + pass tee_f.flush() sys.stderr = Tee(sys.stderr) |