pywin32-checkins Mailing List for Python for Windows Extensions (Page 8)
OLD project page for the Python extensions for Windows
Brought to you by:
mhammond
You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
(1) |
Jun
(6) |
Jul
(50) |
Aug
(11) |
Sep
(24) |
Oct
(184) |
Nov
(118) |
Dec
(22) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(31) |
Feb
(25) |
Mar
(34) |
Apr
(105) |
May
(49) |
Jun
(38) |
Jul
(39) |
Aug
(7) |
Sep
(98) |
Oct
(79) |
Nov
(20) |
Dec
(17) |
2005 |
Jan
(66) |
Feb
(32) |
Mar
(43) |
Apr
(30) |
May
(58) |
Jun
(30) |
Jul
(16) |
Aug
(4) |
Sep
(21) |
Oct
(42) |
Nov
(11) |
Dec
(14) |
2006 |
Jan
(42) |
Feb
(30) |
Mar
(22) |
Apr
(1) |
May
(9) |
Jun
(15) |
Jul
(20) |
Aug
(9) |
Sep
(8) |
Oct
(1) |
Nov
(9) |
Dec
(43) |
2007 |
Jan
(52) |
Feb
(45) |
Mar
(20) |
Apr
(12) |
May
(59) |
Jun
(39) |
Jul
(35) |
Aug
(31) |
Sep
(17) |
Oct
(20) |
Nov
(4) |
Dec
(4) |
2008 |
Jan
(28) |
Feb
(111) |
Mar
(4) |
Apr
(27) |
May
(40) |
Jun
(27) |
Jul
(32) |
Aug
(94) |
Sep
(87) |
Oct
(153) |
Nov
(336) |
Dec
(331) |
2009 |
Jan
(298) |
Feb
(127) |
Mar
(20) |
Apr
(8) |
May
|
Jun
(10) |
Jul
(6) |
Aug
|
Sep
(2) |
Oct
(2) |
Nov
|
Dec
(1) |
2010 |
Jan
(7) |
Feb
(1) |
Mar
|
Apr
|
May
(15) |
Jun
(4) |
Jul
(3) |
Aug
(28) |
Sep
(1) |
Oct
(19) |
Nov
(16) |
Dec
(6) |
2011 |
Jan
(2) |
Feb
(18) |
Mar
(17) |
Apr
(12) |
May
(5) |
Jun
(11) |
Jul
(7) |
Aug
(2) |
Sep
(2) |
Oct
(4) |
Nov
(4) |
Dec
|
2012 |
Jan
(6) |
Feb
(2) |
Mar
|
Apr
(8) |
May
(4) |
Jun
(3) |
Jul
(13) |
Aug
(27) |
Sep
(8) |
Oct
(9) |
Nov
(3) |
Dec
(2) |
2013 |
Jan
|
Feb
(1) |
Mar
(5) |
Apr
(10) |
May
|
Jun
(2) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
(9) |
2014 |
Jan
(2) |
Feb
(4) |
Mar
(4) |
Apr
(1) |
May
(4) |
Jun
(2) |
Jul
|
Aug
|
Sep
|
Oct
(2) |
Nov
|
Dec
(1) |
2015 |
Jan
(1) |
Feb
|
Mar
|
Apr
(6) |
May
(2) |
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
2016 |
Jan
(3) |
Feb
(2) |
Mar
|
Apr
(3) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2017 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
From: <pyw...@li...> - 2011-06-21 22:07:56
|
changeset c59fea6e83fb in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=c59fea6e83fb summary: Add some more VT_VECTOR conversions diffstat: com/win32com/src/extensions/PyIPropertyStorage.cpp | 76 +++++++++++++++++++----- 1 files changed, 59 insertions(+), 17 deletions(-) diffs (127 lines): diff -r 7dce71d174a9 -r c59fea6e83fb com/win32com/src/extensions/PyIPropertyStorage.cpp --- a/com/win32com/src/extensions/PyIPropertyStorage.cpp Sat Jun 18 10:16:06 2011 -0400 +++ b/com/win32com/src/extensions/PyIPropertyStorage.cpp Tue Jun 21 18:05:52 2011 -0400 @@ -124,6 +124,45 @@ return ret; } +// Some helper functions for the Vector conversion template +PyObject *PyWinObject_FromCHAR(CHAR c){ + return PyInt_FromLong(c); +} + +PyObject *PyWinObject_FromUCHAR(UCHAR uc){ + return PyInt_FromLong(uc); +} + +PyObject *PyWinObject_FromSHORT(SHORT s){ + return PyInt_FromLong(s); +} + +PyObject *PyWinObject_FromUSHORT(USHORT us){ + return PyInt_FromLong(us); +} + +PyObject *PyWinObject_FromFLOAT(FLOAT f){ + return PyFloat_FromDouble(f); +} + +PyObject *PyWinObject_FromVT_BSTR(BSTR b){ + return PyWinObject_FromBstr(b, FALSE); +} + +PyObject *PyWinObject_FromVARIANT_BOOL(VARIANT_BOOL b){ + PyObject *ret; + if (b == VARIANT_TRUE) + ret = Py_True; + else if (b == VARIANT_FALSE) + ret = Py_False; + else{ + ret = NULL; + PyErr_Format(PyExc_ValueError, "Invalid value for VARIANT_BOOL"); + } + Py_XINCREF(ret); + return ret; +} + PyObject *PyObject_FromPROPVARIANT( PROPVARIANT *pVar ) { switch (pVar->vt) { @@ -134,12 +173,20 @@ return Py_None; case VT_I1: return PyInt_FromLong(pVar->cVal); + case VT_I1|VT_VECTOR: + return VectorToSeq(pVar->cac.pElems, pVar->cac.cElems, PyWinObject_FromCHAR); case VT_UI1: return PyInt_FromLong(pVar->bVal); + case VT_UI1|VT_VECTOR: + return VectorToSeq(pVar->caub.pElems, pVar->caub.cElems, PyWinObject_FromUCHAR); case VT_I2: return PyInt_FromLong(pVar->iVal); + case VT_I2|VT_VECTOR: + return VectorToSeq(pVar->cai.pElems, pVar->cai.cElems, PyWinObject_FromSHORT); case VT_UI2: return PyInt_FromLong(pVar->uiVal); + case VT_UI2|VT_VECTOR: + return VectorToSeq(pVar->caui.pElems, pVar->caui.cElems, PyWinObject_FromUSHORT); case VT_I4: return PyInt_FromLong(pVar->lVal); case VT_I4|VT_VECTOR: @@ -162,9 +209,8 @@ return VectorToSeq<ULARGE_INTEGER>(pVar->cauh.pElems, pVar->cauh.cElems, PyWinObject_FromULARGE_INTEGER); case VT_R4: return PyFloat_FromDouble(pVar->fltVal); - // Template parameter must match exactly, need to create an intermediate function. - // case VT_R4|VT_VECTOR: - // return VectorToSeq(pVar->caflt.pElems, pVar->caflt.cElems, PyFloat_FromDouble); + case VT_R4|VT_VECTOR: + return VectorToSeq(pVar->caflt.pElems, pVar->caflt.cElems, PyWinObject_FromFLOAT); case VT_R8: return PyFloat_FromDouble(pVar->dblVal); case VT_R8|VT_VECTOR: @@ -179,12 +225,12 @@ return VectorToSeq(pVar->cadate.pElems, pVar->cadate.cElems, PyWinObject_FromDATE); case VT_BSTR: return PyWinObject_FromBstr(pVar->bstrVal); - case VT_BOOL:{ - PyObject *ob; - ob = pVar->boolVal ? Py_True : Py_False; - Py_INCREF(ob); - return ob; - } + case VT_BSTR|VT_VECTOR: + return VectorToSeq(pVar->cabstr.pElems, pVar->cabstr.cElems, PyWinObject_FromVT_BSTR); + case VT_BOOL: + return PyWinObject_FromVARIANT_BOOL(pVar->boolVal); + case VT_BOOL|VT_VECTOR: + return VectorToSeq(pVar->cabool.pElems, pVar->cabool.cElems, PyWinObject_FromVARIANT_BOOL); case VT_ERROR: return PyInt_FromLong(pVar->scode); case VT_ERROR|VT_VECTOR: @@ -241,7 +287,10 @@ return PyCom_PyObjectFromIUnknown(pVar->pStorage, IID_IStorage, TRUE); case VT_VECTOR | VT_VARIANT: return PyObject_FromPROPVARIANTs(pVar->capropvar.pElems, pVar->capropvar.cElems); - + case VT_BLOB: + case VT_BLOB_OBJECT: + return PyString_FromStringAndSize((const char *)pVar->blob.pBlobData, + pVar->blob.cbSize); // case VT_UNKNOWN: // return PyCom_PyObjectFromIUnknown(pVar->punkVal, IID_IUnknown, TRUE); // case VT_DISPATCH: @@ -260,13 +309,6 @@ pVar->pclipdata->pClipData, (int)cb); } - case VT_BLOB: - // DWORD count of bytes, followed by that many bytes of data. - // The byte count does not include the four bytes for the - // length of the count itself; an empty blob member would - // have a count of zero, followed by zero bytes. - return PyString_FromStringAndSize((const char *)pVar->blob.pBlobData, - pVar->blob.cbSize); */ default: PyErr_Format(PyExc_TypeError, "Unsupported property type 0x%x", pVar->vt); |
From: <pyw...@li...> - 2011-06-18 19:27:34
|
changeset 7dce71d174a9 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=7dce71d174a9 summary: Add VT_VECTOR conversions for types with a simple conversion function diffstat: com/win32com/src/extensions/PyIPropertyStorage.cpp | 91 ++++++++++++++++++++-- 1 files changed, 83 insertions(+), 8 deletions(-) diffs (146 lines): diff -r 3cc6365d7461 -r 7dce71d174a9 com/win32com/src/extensions/PyIPropertyStorage.cpp --- a/com/win32com/src/extensions/PyIPropertyStorage.cpp Sat Jun 18 07:08:30 2011 -0400 +++ b/com/win32com/src/extensions/PyIPropertyStorage.cpp Sat Jun 18 10:16:06 2011 -0400 @@ -73,9 +73,59 @@ free(pFree); } +// Generic conversion from VT_VECTOR arrays to list. +template <typename arraytype> +PyObject* VectorToSeq(arraytype *A, ULONG count, PyObject * (*converter)(arraytype)){ + PyObject *ret = PyList_New(count); + if (ret==NULL) + return NULL; + for (ULONG i=0; i<count; i++){ + PyObject *subitem=(*converter)(A[i]); + if (subitem == NULL){ + Py_DECREF(ret); + return NULL; + } + PyList_SET_ITEM(ret, i, subitem); + } + return ret; +} + +// Some converters take a reference, eg PyWinObject_FromLARGE_INTEGER +template <typename arraytype> +PyObject* VectorToSeq(arraytype *A, ULONG count, PyObject * (*converter)(arraytype&)){ + PyObject *ret = PyList_New(count); + if (ret==NULL) + return NULL; + for (ULONG i=0; i<count; i++){ + PyObject *subitem=(*converter)(A[i]); + if (subitem == NULL){ + Py_DECREF(ret); + return NULL; + } + PyList_SET_ITEM(ret, i, subitem); + } + return ret; +} + +// ... and some take a const reference, eg PyWinObject_FromIID +template <typename arraytype> +PyObject* VectorToSeq(arraytype *A, ULONG count, PyObject * (*converter)(const arraytype&)){ + PyObject *ret = PyList_New(count); + if (ret==NULL) + return NULL; + for (ULONG i=0; i<count; i++){ + PyObject *subitem=(*converter)(A[i]); + if (subitem == NULL){ + Py_DECREF(ret); + return NULL; + } + PyList_SET_ITEM(ret, i, subitem); + } + return ret; +} + PyObject *PyObject_FromPROPVARIANT( PROPVARIANT *pVar ) { - PyObject *ob; switch (pVar->vt) { case VT_EMPTY: case VT_NULL: @@ -83,7 +133,7 @@ Py_INCREF(Py_None); return Py_None; case VT_I1: - return PyInt_FromLong(pVar->bVal); + return PyInt_FromLong(pVar->cVal); case VT_UI1: return PyInt_FromLong(pVar->bVal); case VT_I2: @@ -92,34 +142,57 @@ return PyInt_FromLong(pVar->uiVal); case VT_I4: return PyInt_FromLong(pVar->lVal); -// case VT_INT: -// return PyInt_FromLong(pVar->intVal); + case VT_I4|VT_VECTOR: + return VectorToSeq(pVar->cal.pElems, pVar->cal.cElems, PyInt_FromLong); + case VT_INT: + return PyInt_FromLong(pVar->intVal); case VT_UI4: - return PyInt_FromLong(pVar->ulVal); -// case VT_UINT: -// return PyInt_FromLong(pVar->uintVal); + return PyLong_FromUnsignedLong(pVar->ulVal); + case VT_UI4|VT_VECTOR: + return VectorToSeq(pVar->caul.pElems, pVar->caul.cElems, PyLong_FromUnsignedLong); + case VT_UINT: + return PyLong_FromUnsignedLong(pVar->uintVal); case VT_I8: return PyWinObject_FromLARGE_INTEGER(pVar->hVal); + case VT_I8|VT_VECTOR: + return VectorToSeq<LARGE_INTEGER>(pVar->cah.pElems, pVar->cah.cElems, PyWinObject_FromLARGE_INTEGER); case VT_UI8: return PyWinObject_FromULARGE_INTEGER(pVar->uhVal); + case VT_UI8|VT_VECTOR: + return VectorToSeq<ULARGE_INTEGER>(pVar->cauh.pElems, pVar->cauh.cElems, PyWinObject_FromULARGE_INTEGER); case VT_R4: return PyFloat_FromDouble(pVar->fltVal); + // Template parameter must match exactly, need to create an intermediate function. + // case VT_R4|VT_VECTOR: + // return VectorToSeq(pVar->caflt.pElems, pVar->caflt.cElems, PyFloat_FromDouble); case VT_R8: return PyFloat_FromDouble(pVar->dblVal); + case VT_R8|VT_VECTOR: + return VectorToSeq(pVar->cadbl.pElems, pVar->cadbl.cElems, PyFloat_FromDouble); case VT_CY: return PyObject_FromCurrency(pVar->cyVal); + case VT_CY|VT_VECTOR: + return VectorToSeq<CY>(pVar->cacy.pElems, pVar->cacy.cElems, PyObject_FromCurrency); case VT_DATE: return PyWinObject_FromDATE(pVar->date); + case VT_DATE|VT_VECTOR: + return VectorToSeq(pVar->cadate.pElems, pVar->cadate.cElems, PyWinObject_FromDATE); case VT_BSTR: return PyWinObject_FromBstr(pVar->bstrVal); - case VT_BOOL: + case VT_BOOL:{ + PyObject *ob; ob = pVar->boolVal ? Py_True : Py_False; Py_INCREF(ob); return ob; + } case VT_ERROR: return PyInt_FromLong(pVar->scode); + case VT_ERROR|VT_VECTOR: + return VectorToSeq(pVar->cascode.pElems, pVar->cascode.cElems, PyInt_FromLong); case VT_FILETIME: return PyWinObject_FromFILETIME(pVar->filetime); + case VT_FILETIME|VT_VECTOR: + return VectorToSeq<FILETIME>(pVar->cafiletime.pElems, pVar->cafiletime.cElems, PyWinObject_FromFILETIME); case VT_LPSTR: if (pVar->pszVal == NULL) { Py_INCREF(Py_None); @@ -158,6 +231,8 @@ } case VT_CLSID: return PyWinObject_FromIID(*pVar->puuid); + case VT_CLSID|VT_VECTOR: + return VectorToSeq<CLSID>(pVar->cauuid.pElems, pVar->cauuid.cElems, PyWinObject_FromIID); case VT_STREAM: case VT_STREAMED_OBJECT: return PyCom_PyObjectFromIUnknown(pVar->pStream, IID_IStream, TRUE); |
From: <pyw...@li...> - 2011-06-18 11:09:51
|
changeset 3cc6365d7461 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=3cc6365d7461 summary: Fix build error on Python 2.3 diffstat: com/win32comext/shell/src/shell.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (17 lines): diff -r 7176ed5cdddc -r 3cc6365d7461 com/win32comext/shell/src/shell.cpp --- a/com/win32comext/shell/src/shell.cpp Tue Jun 07 00:21:07 2011 -0400 +++ b/com/win32comext/shell/src/shell.cpp Sat Jun 18 07:08:30 2011 -0400 @@ -3216,11 +3216,11 @@ goto done; if (!PyObject_AsPIDL(obitem, &item, FALSE)) goto done; - + { PY_INTERFACE_PRECALL; hr = (*pfnSHCreateShellItem)(parent_pidl, parent_folder, item, &isi); PY_INTERFACE_POSTCALL; - + } if (FAILED(hr)) { PyCom_BuildPyException(hr); goto done; |
From: <pyw...@li...> - 2011-06-07 04:23:42
|
changeset 7176ed5cdddc in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=7176ed5cdddc summary: Add EvtCreateBookmark and EvtUpdateBookmark diffstat: win32/src/win32evtlog.i | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 44 insertions(+), 1 deletions(-) diffs (76 lines): diff -r 8cf199233556 -r 7176ed5cdddc win32/src/win32evtlog.i --- a/win32/src/win32evtlog.i Mon Jun 06 09:02:34 2011 -0400 +++ b/win32/src/win32evtlog.i Tue Jun 07 00:21:07 2011 -0400 @@ -619,7 +619,7 @@ PyObject *obpath, *obexport_path, *obquery=Py_None; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOk|OO&:EvtExportLog", keywords, &obpath, // @pyparm str|Path||Path of a live event log channel or exported log file - &obexport_path, // @pyparm str|TargetFilePath|None|Name of file in which cleared events will be archived, or None + &obexport_path, // @pyparm str|TargetFilePath||File to create, cannot already exist &flags, // @pyparm int|Flags||Combination of EvtExportLog* flags specifying the type of path &obquery, // @pyparm str|Query|None|Selects specific events to export PyWinObject_AsHANDLE, &session)) // @pyparm <o PyEVT_HANDLE>|Session|None|Handle to a remote session (see <om win32evtlog.EvtOpenSession>), or None for local machine. @@ -928,6 +928,45 @@ } PyCFunction pfnPyEvtSubscribe = (PyCFunction) PyEvtSubscribe; +// @pyswig <o PyEVT_HANDLE>|EvtCreateBookmark|Creates a bookmark +// @comm Accepts keyword args +static PyObject *PyEvtCreateBookmark(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[]={"BookmarkXML", NULL}; + EVT_HANDLE ret; + TmpWCHAR xml; + PyObject *obxml=Py_None; + // @pyparm str|BookmarkXML|None|XML representation of a bookmark as returned by <om win32evtlog.EvtRender>, or None for a new bookmark + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O:EvtCreateBookmark", keywords, + &obxml)) + return NULL; + if (!PyWinObject_AsWCHAR(obxml, &xml, TRUE)) + return NULL; + ret = EvtCreateBookmark(xml); + if (ret == NULL) + return PyWin_SetAPIError("EvtCreateBookmark"); + return PyWinObject_FromEVT_HANDLE(ret); +} +PyCFunction pfnPyEvtCreateBookmark = (PyCFunction) PyEvtCreateBookmark; + +// @pyswig <o PyEVT_HANDLE>|EvtUpdateBookmark|Repositions a bookmark to an event +// @comm Accepts keyword args +static PyObject *PyEvtUpdateBookmark(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[]={"Bookmark", "Event", NULL}; + EVT_HANDLE bookmark, evt; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&O&:EvtUpdateBookmark", keywords, + PyWinObject_AsHANDLE, &bookmark, // @pyparm <o PyEVT_HANDLE>|Bookmark||Handle to a bookmark + PyWinObject_AsHANDLE, &evt)) // @pyparm <o PyEVT_HANDLE>|Event||Handle to an event + return NULL; + + if (!EvtUpdateBookmark(bookmark, evt)) + return PyWin_SetAPIError("EvtUpdateBookmark"); + Py_INCREF(Py_None); + return Py_None; +} +PyCFunction pfnPyEvtUpdateBookmark = (PyCFunction) PyEvtUpdateBookmark; + %} %native (EvtOpenChannelEnum) pfnPyEvtOpenChannelEnum; @@ -942,6 +981,8 @@ %native (EvtSeek) pfnPyEvtSeek; %native (EvtRender) pfnPyEvtRender; %native (EvtSubscribe) pfnPyEvtSubscribe; +%native (EvtCreateBookmark) pfnPyEvtCreateBookmark; +%native (EvtUpdateBookmark) pfnPyEvtUpdateBookmark; %init %{ for (PyMethodDef *pmd = win32evtlogMethods;pmd->ml_name;pmd++) @@ -957,6 +998,8 @@ ||(strcmp(pmd->ml_name, "EvtSeek")==0) ||(strcmp(pmd->ml_name, "EvtRender")==0) ||(strcmp(pmd->ml_name, "EvtSubscribe")==0) + ||(strcmp(pmd->ml_name, "EvtCreateBookmark")==0) + ||(strcmp(pmd->ml_name, "EvtUpdateBookmark")==0) ){ pmd->ml_flags = METH_VARARGS | METH_KEYWORDS; } |
From: <pyw...@li...> - 2011-06-07 03:21:10
|
changeset 90fec908e944 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=90fec908e944 summary: Add some more Vista/Win7 event log functions changeset 8cf199233556 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=8cf199233556 summary: Demos showing how to use EvtSubscribe diffstat: win32/Demos/EvtSubscribe_pull.py | 21 +++ win32/Demos/EvtSubscribe_push.py | 16 ++ win32/src/win32evtlog.i | 290 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 323 insertions(+), 4 deletions(-) diffs (truncated from 388 to 300 lines): diff -r abb91f8e9851 -r 8cf199233556 win32/Demos/EvtSubscribe_pull.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32/Demos/EvtSubscribe_pull.py Mon Jun 06 09:02:34 2011 -0400 @@ -0,0 +1,21 @@ +## Demonstrates how to create a "pull" subscription +import win32evtlog, win32event, win32con +query_text='*[System[Provider[@Name="Microsoft-Windows-Winlogon"]]]' + +h=win32event.CreateEvent(None, 0, 0, None) +s=win32evtlog.EvtSubscribe('System', win32evtlog.EvtSubscribeStartAtOldestRecord, SignalEvent=h, Query=query_text) + +while 1: + while 1: + events=win32evtlog.EvtNext(s, 10) + if len(events)==0: + break + ##for event in events: + ## print (win32evtlog.EvtRender(event, win32evtlog.EvtRenderEventXml)) + print ('retrieved %s events' %len(events)) + while 1: + print ('waiting...') + w=win32event.WaitForSingleObjectEx(h, 2000, True) + if w==win32con.WAIT_OBJECT_0: + break + diff -r abb91f8e9851 -r 8cf199233556 win32/Demos/EvtSubscribe_push.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/win32/Demos/EvtSubscribe_push.py Mon Jun 06 09:02:34 2011 -0400 @@ -0,0 +1,16 @@ +## Demonstrates a "push" subscription with a callback function +import win32evtlog +query_text='*[System[Provider[@Name="Microsoft-Windows-Winlogon"]]]' + +def c(reason, context, evt): + if reason==win32evtlog.EvtSubscribeActionError: + print ('EvtSubscribeActionError') + elif reason==win32evtlog.EvtSubscribeActionDeliver: + print ('EvtSubscribeActionDeliver') + else: + print ('??? Unknown action ???', reason) + context.append(win32evtlog.EvtRender(evt, win32evtlog.EvtRenderEventXml)) + return 0 + +evttext=[] +s=win32evtlog.EvtSubscribe('System', win32evtlog.EvtSubscribeStartAtOldestRecord, Query='*', Callback=c, Context=evttext) diff -r abb91f8e9851 -r 8cf199233556 win32/src/win32evtlog.i --- a/win32/src/win32evtlog.i Fri Jun 03 23:52:26 2011 -0400 +++ b/win32/src/win32evtlog.i Mon Jun 06 09:02:34 2011 -0400 @@ -57,17 +57,25 @@ class PyEVT_HANDLE: public PyHANDLE { public: - PyEVT_HANDLE(HANDLE hInit) : PyHANDLE(hInit) {} + PyEVT_HANDLE(HANDLE hInit, PyObject *context) : PyHANDLE(hInit){ + callback_objects = context; + Py_XINCREF(callback_objects); + } virtual BOOL Close(void){ BOOL ret=EvtClose(m_handle); if (!ret) PyWin_SetAPIError("EvtClose"); m_handle = 0; + Py_XDECREF(callback_objects); + callback_objects=NULL; return ret; } virtual const char *GetTypeName(){ return "PyEVT_HANDLE"; } + // Only used with push subscription handles. Will be a 2-tuple + // that keeps references to the callback function and context object + PyObject *callback_objects; }; #define PyHANDLE HANDLE @@ -80,9 +88,9 @@ return ret; } -PyObject *PyWinObject_FromEVT_HANDLE(HANDLE h) +PyObject *PyWinObject_FromEVT_HANDLE(HANDLE h, PyObject *context=NULL) { - PyObject *ret=new PyEVT_HANDLE(h); + PyObject *ret=new PyEVT_HANDLE(h, context); if (ret==NULL){ EvtClose(h); PyErr_NoMemory(); @@ -686,6 +694,240 @@ free(msg); return ret; } + +// @pyswig <o PyEVT_HANDLE>|EvtQuery|Opens a query over a log channel or exported log file +// @comm Accepts keyword args +static PyObject *PyEvtQuery(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[]={"Path", "Flags", "Query", "Session", NULL}; + EVT_HANDLE ret, session=NULL; + DWORD flags; + TmpWCHAR path, query; + PyObject *obpath, *obquery=Py_None; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Ol|OO&:EvtQuery", keywords, + &obpath, // @pyparm str|Path||Log channel or exported log file, depending on Flags + &flags, // @pyparm int|Flags||Combination of EVT_QUERY_FLAGS (EvtQuery*) + &obquery, // @pyparm str|Query|None|Selects events to return, None or '*' for all events + PyWinObject_AsHANDLE, &session)) // @pyparm <o PyEVT_HANDLE>|Session|None|Handle to a remote session (see <om win32evtlog.EvtOpenSession>), or None for local machine. + return NULL; + if (!PyWinObject_AsWCHAR(obpath, &path, FALSE)) + return NULL; + if (!PyWinObject_AsWCHAR(obquery, &query, TRUE)) + return NULL; + + ret = EvtQuery(session, path, query, flags); + if (ret == NULL) + return PyWin_SetAPIError("EvtQuery"); + return PyWinObject_FromEVT_HANDLE(ret); +} +PyCFunction pfnPyEvtQuery = (PyCFunction) PyEvtQuery; + +// @pyswig (<o PyEVT_HANDLE>,...)|EvtNext|Returns events from a query +// @rdesc Returns a tuple of handles to events. If no items are available, returns +// an empty tuple instead of raising an exception. +// @comm Accepts keyword args +static PyObject *PyEvtNext(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[]={"ResultSet", "Count", "Timeout", "Flags", NULL}; + EVT_HANDLE query; + EVT_HANDLE *events =NULL; + DWORD nbr_requested, nbr_returned, flags=0, timeout=(DWORD)-1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k|kk:EvtNext", keywords, + PyWinObject_AsHANDLE, &query, // @pyparm <o PyEVT_HANDLE>|ResultSet||Handle to event query or subscription + &nbr_requested, // @pyparm int|Count||Number of events to return + &timeout, // @pyparm int|Timeout|-1|Time to wait in milliseconds, use -1 for infinite + &flags)) // @pyparm int|Flags|0|Reserved, use only 0 + return NULL; + events = (EVT_HANDLE *)malloc(nbr_requested * sizeof(EVT_HANDLE *)); + if (events==NULL){ + PyErr_NoMemory(); + return NULL; + } + + if (!EvtNext(query, nbr_requested, events, timeout, flags, &nbr_returned)){ + free(events); + DWORD err=GetLastError(); + if (err == ERROR_NO_MORE_ITEMS) + return PyTuple_New(0); + return PyWin_SetAPIError("EvtNext", err); + } + + // If tuple construction fails, any handle not yet wrapped in a PyEVT_HANDLE + // will be orphaned and remain open. Should be a rare occurence, though. + PyObject *ret=PyTuple_New(nbr_returned); + if (ret){ + for (DWORD i=0;i<nbr_returned;i++){ + PyObject *obevt=PyWinObject_FromEVT_HANDLE(events[i]); + if (obevt==NULL){ + Py_DECREF(ret); + ret=NULL; + break; + } + PyTuple_SET_ITEM(ret, i, obevt); + } + } + free(events); + return ret; +} +PyCFunction pfnPyEvtNext = (PyCFunction) PyEvtNext; + +// @pyswig |EvtSeek|Changes the current position in a result set +// @comm Accepts keyword args +static PyObject *PyEvtSeek(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[]={"ResultSet", "Position", "Flags", "Bookmark", "Timeout", NULL}; + EVT_HANDLE query, bookmark=NULL; + DWORD flags, timeout=0; + LONGLONG position; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&Lk|O&k:EvtSeek", keywords, + PyWinObject_AsHANDLE, &query, // @pyparm <o PyEVT_HANDLE>|ResultSet||Handle to event query or subscription + &position, // @pyparm int|Position||Offset (base from which to seek is specified by Flags) + &flags, // @pyparm int|Flags||EvtSeekRelative* flag indicating seek origin + PyWinObject_AsHANDLE, &bookmark, // @pyparm <o PyEVT_HANDLE>|Bookmark|None|Used as seek origin only if Flags contains EvtSeekRelativeToBookmark + &timeout)) // @pyparm int|Timeout|0|Reserved, use only 0 + return NULL; + if (!EvtSeek(query, position, bookmark, timeout, flags)) + return PyWin_SetAPIError("EvtSeek"); + Py_INCREF(Py_None); + return Py_None;; +} +PyCFunction pfnPyEvtSeek = (PyCFunction) PyEvtSeek; + +// @pyswig str|EvtRender|Formats an event into XML text +// @comm Accepts keyword args +// @comm Rendering event values (Flags=EvtRenderEventValues) is not currently supported +static PyObject *PyEvtRender(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[]={"Event", "Flags", NULL}; + EVT_HANDLE event; + void *buf=NULL; + DWORD flags, bufsize=2048, bufneeded, propcount; + PyObject *ret=NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&k:EvtRender", keywords, + PyWinObject_AsHANDLE, &event, // @pyparm <o PyEVT_HANDLE>|Event||Handle to an event or bookmark + &flags)) // @pyparm int|Flags||EvtRenderEventXml or EvtRenderBookmark indicating type of handle + return NULL; + if (flags==EvtRenderEventValues){ + // Requires yet another type of VARIANT + PyErr_Format(PyExc_NotImplementedError,"Rendering values is not yet supported"); + return NULL; + } + while(1){ + if (buf) + free(buf); + buf=malloc(bufsize); + if (buf==NULL){ + PyErr_NoMemory(); + return NULL; + } + if (EvtRender(NULL, event, flags, bufsize, buf, &bufneeded, &propcount)){ + ret=PyWinObject_FromWCHAR((WCHAR *)buf); + break; + } + DWORD err=GetLastError(); + if (err==ERROR_INSUFFICIENT_BUFFER) + bufsize=bufneeded; + else{ + PyWin_SetAPIError("EvtRender", err); + break; + } + } + free(buf); + return ret; +} +PyCFunction pfnPyEvtRender = (PyCFunction) PyEvtRender; + + +DWORD CALLBACK PyEvtSubscribe_callback( + EVT_SUBSCRIBE_NOTIFY_ACTION action, + void *context, + EVT_HANDLE event) +{ + CEnterLeavePython celp; + DWORD err=0; + PyObject *func = PyTuple_GET_ITEM((PyObject *)context, 0); + PyObject *obcontext = PyTuple_GET_ITEM((PyObject *)context, 1); + PyObject *args=Py_BuildValue("kOO", action, obcontext, PyWinLong_FromHANDLE(event)); + if (args==NULL){ + // ??? Docs don't specify what happens when you return an error from callback + // Need to check if subscription handle is closed ??? + PyErr_Print(); + return ERROR_OUTOFMEMORY; + } + PyObject *ret=PyObject_Call(func, args, NULL); + if (ret==NULL){ + // Nothing to be done about an exception raised by the python callback + PyErr_Print(); + err = ERROR_OUTOFMEMORY; + } + else if (ret!=Py_None){ + // Allow the callback to return an error + err=PyLong_AsUnsignedLong(ret); + if (err==(DWORD)-1 && PyErr_Occurred()){ + PyErr_Print(); + err = 0; + } + } + + Py_DECREF(args); + Py_XDECREF(ret); + return err; +} + +// @pyswig <o PyEVT_HANDLE>|EvtSubscribe|Requests notification for events +// @comm Accepts keyword args +// @comm The method used to receive events is determined by the parameters passed in. +// To create a push subscription, define a callback function that will be called with each event. +// The function will receive 3 args: +// First is an integer specifying why the function was called (EvtSubscribeActionError or EvtSubscribeActionDeliver) +// Second is the context object passed to EvtSubscribe. +// Third is the handle to an event log record (if not called due to an error) +// If an event handle is passed in, a pull subscription is created. The event handle will be +// signalled when events are available, and the subscription handle can be +// passed to <om win32evtlog.EvtNext> to obtain the events. + +static PyObject *PyEvtSubscribe(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[]={"ChannelPath", "Flags", "SignalEvent", "Callback", "Context", + "Query", "Session", "Bookmark", NULL}; + EVT_HANDLE session=NULL, bookmark=NULL, ret; + HANDLE signalevent=NULL; + TmpWCHAR path, query; + PyObject *obpath, *obcallback=Py_None, *obquery=Py_None, *obcontext=Py_None; + TmpPyObject obuserdata; // actual context passed to C++ callback - tuple of (function, context object) + DWORD flags; + EVT_SUBSCRIBE_CALLBACK pfncallback=NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Ok|O&OOOO&O&:EvtSubscribe", keywords, + &obpath, // @pyparm str|ChannelPath||Name of an event log channel + &flags, // @pyparm int|Flags||Combination of EvtSubscribe* flags determining how subscription is initiated + PyWinObject_AsHANDLE, &signalevent, // @pyparm <o Py_HANDLE>|SignalEvent|None|An event handle to be set when events are available (see <om win32event.CreateEvent>) |
From: <pyw...@li...> - 2011-06-04 03:57:30
|
changeset abb91f8e9851 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=abb91f8e9851 summary: Add more Evt* functions diffstat: win32/src/win32evtlog.i | 151 +++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 137 insertions(+), 14 deletions(-) diffs (232 lines): diff -r 4e410d25d6ad -r abb91f8e9851 win32/src/win32evtlog.i --- a/win32/src/win32evtlog.i Thu Jun 02 21:29:15 2011 -0400 +++ b/win32/src/win32evtlog.i Fri Jun 03 23:52:26 2011 -0400 @@ -1,7 +1,8 @@ /* File : win32evtlog.i */ %module win32evtlog // A module, encapsulating the Windows Win32 event log API. - +// <nl>The Evt* functions are only available on Vista and later. Attempting to call +// them on XP will result in the process exiting, rather than a python exception. %include "typemaps.i" %include "pywin32.i" @@ -14,6 +15,24 @@ #include "PyWinObjects.h" #include "WinEvt.h" +// Automatically freed WCHAR that can be used anywhere WCHAR * is required +class TmpWCHAR +{ +public: + WCHAR *tmp; + TmpWCHAR() { tmp=NULL; } + TmpWCHAR(WCHAR *t) { tmp=t; } + WCHAR * operator= (WCHAR *t){ + PyWinObject_FreeWCHAR(tmp); + tmp=t; + return t; + } + WCHAR ** operator& () {return &tmp;} + boolean operator== (WCHAR *t) { return tmp==t; } + operator WCHAR *() { return tmp; } + ~TmpWCHAR() { PyWinObject_FreeWCHAR(tmp); } +}; + // @object PyEVTLOG_HANDLE|Object representing a handle to the windows event log. // Identical to <o PyHANDLE>, but calls CloseEventLog() on destruction class PyEVTLOG_HANDLE: public PyHANDLE @@ -470,6 +489,7 @@ // New event log functions available on Vista and later // @pyswig <o PyEVT_HANDLE>|EvtOpenChannelEnum|Begins an enumeration of event channels +// @comm Accepts keyword args static PyObject *PyEvtOpenChannelEnum(PyObject *self, PyObject *args, PyObject *kwargs) { static char *keywords[]={"Session", "Flags", NULL}; @@ -488,6 +508,7 @@ // @pyswig str|EvtNextChannelPath|Retrieves a channel path from an enumeration // @rdesc Returns None at end of enumeration +// @comm Accepts keyword args static PyObject *PyEvtNextChannelPath(PyObject *self, PyObject *args, PyObject *kwargs) { static char *keywords[]={"ChannelEnum", NULL}; @@ -501,7 +522,7 @@ while (true){ if (buf) free(buf); - // MSDN docs say sized are in bytes, but it doesn't seem to be so ??? + // MSDN docs say sizes are in bytes, but it doesn't seem to be so ??? WCHAR *buf=(WCHAR *)malloc(allocated_size * sizeof(WCHAR)); if (!buf) return NULL; @@ -529,6 +550,7 @@ PyCFunction pfnPyEvtNextChannelPath = (PyCFunction) PyEvtNextChannelPath; // @pyswig <o PyEVT_HANDLE>|EvtOpenLog|Opens an event log or exported log archive +// @comm Accepts keyword args static PyObject *PyEvtOpenLog(PyObject *self, PyObject *args, PyObject *kwargs) { static char *keywords[]={"Path", "Flags", "Session", NULL}; @@ -552,39 +574,128 @@ PyCFunction pfnPyEvtOpenLog = (PyCFunction) PyEvtOpenLog; // @pyswig |EvtClearLog|Clears an event log and optionally exports events to an archive +// @comm Accepts keyword args static PyObject *PyEvtClearLog(PyObject *self, PyObject *args, PyObject *kwargs) { static char *keywords[]={"ChannelPath", "TargetFilePath", "Session", "Flags", NULL}; EVT_HANDLE session=NULL; DWORD flags=0; - WCHAR *path=NULL, *export_path=NULL; - PyObject *obpath, *obexport_path=Py_None, *ret=NULL; + TmpWCHAR path, export_path; + PyObject *obpath, *obexport_path=Py_None; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OO&k:EvtClearLog", keywords, &obpath, // @pyparm str|ChannelPath||Name of event log to be cleared &obexport_path, // @pyparm str|TargetFilePath|None|Name of file in which cleared events will be archived, or None PyWinObject_AsHANDLE, &session, // @pyparm <o PyEVT_HANDLE>|Session|None|Handle to a remote session (see <om win32evtlog.EvtOpenSession>), or None for local machine. &flags)) // @pyparm int|Flags|0|Reserved, use only 0 return NULL; - if (PyWinObject_AsWCHAR(obpath, &path, FALSE) - &&PyWinObject_AsWCHAR(obexport_path, &export_path, TRUE)){ - if (EvtClearLog(session, path, export_path, flags)){ - Py_INCREF(Py_None); - ret=Py_None; + if (!PyWinObject_AsWCHAR(obpath, &path, FALSE)) + return NULL; + if (!PyWinObject_AsWCHAR(obexport_path, &export_path, TRUE)) + return NULL; + if (EvtClearLog(session, path, export_path, flags)){ + Py_INCREF(Py_None); + return Py_None; + } + return PyWin_SetAPIError("EvtClearLog"); +} +PyCFunction pfnPyEvtClearLog = (PyCFunction) PyEvtClearLog; + +// @pyswig |EvtExportLog|Exports events from a channel or log file +// @comm Accepts keyword args +static PyObject *PyEvtExportLog(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[]={"Path", "TargetFilePath", "Flags", "Query", "Session", NULL}; + EVT_HANDLE session=NULL; + DWORD flags=0; + TmpWCHAR path, query, export_path; + PyObject *obpath, *obexport_path, *obquery=Py_None; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOk|OO&:EvtExportLog", keywords, + &obpath, // @pyparm str|Path||Path of a live event log channel or exported log file + &obexport_path, // @pyparm str|TargetFilePath|None|Name of file in which cleared events will be archived, or None + &flags, // @pyparm int|Flags||Combination of EvtExportLog* flags specifying the type of path + &obquery, // @pyparm str|Query|None|Selects specific events to export + PyWinObject_AsHANDLE, &session)) // @pyparm <o PyEVT_HANDLE>|Session|None|Handle to a remote session (see <om win32evtlog.EvtOpenSession>), or None for local machine. + return NULL; + if (!PyWinObject_AsWCHAR(obpath, &path, FALSE)) + return NULL; + if (!PyWinObject_AsWCHAR(obexport_path, &export_path, FALSE)) + return NULL; + if (!PyWinObject_AsWCHAR(obquery, &query, TRUE)) + return NULL; + if (EvtExportLog(session, path, query, export_path, flags)){ + Py_INCREF(Py_None); + return Py_None; + } + return PyWin_SetAPIError("EvtExportLog"); +} +PyCFunction pfnPyEvtExportLog = (PyCFunction) PyEvtExportLog; + +// @pyswig |EvtArchiveExportedLog|Localizes an exported event log file +// @comm Accepts keyword args +static PyObject *PyEvtArchiveExportedLog(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[]={"LogFilePath", "Locale", "Session", "Flags", NULL}; + EVT_HANDLE session=NULL; + DWORD flags=0; + TmpWCHAR path; + LCID lcid; + PyObject *obpath; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Ol|O&k:EvtArchiveExportedLog", keywords, + &obpath, // @pyparm str|LogFilePath||Filename of an exported log file + &lcid, // @pyparm int|Locale||Locale id + PyWinObject_AsHANDLE, &session, // @pyparm <o PyEVT_HANDLE>|Session|None|Handle to a remote session (see <om win32evtlog.EvtOpenSession>), or None for local machine. + &flags)) // @pyparm int|Flags|0|Reserved + return NULL; + if (!PyWinObject_AsWCHAR(obpath, &path, FALSE)) + return NULL; + if (EvtArchiveExportedLog(session, path, lcid, flags)){ + Py_INCREF(Py_None); + return Py_None; + } + return PyWin_SetAPIError("EvtArchiveExportedLog"); +} +PyCFunction pfnPyEvtArchiveExportedLog = (PyCFunction) PyEvtArchiveExportedLog; + +// @pyswig str|EvtGetExtendedStatus|Returns additional error info from last Evt* call +static PyObject *PyEvtGetExtendedStatus(PyObject *self, PyObject *args) +{ + DWORD buflen=0, bufneeded=1024; + WCHAR *msg=NULL; + PyObject *ret=NULL; + if (!PyArg_ParseTuple(args, ":EvtGetExtendedStatus")) + return NULL; + while (1){ + if (msg) + free(msg); + buflen=bufneeded; + msg=(WCHAR *)malloc(buflen * sizeof(WCHAR)); + if (msg==NULL){ + PyErr_NoMemory(); + return NULL; } - else - PyWin_SetAPIError("EvtClearLog"); + if (EvtGetExtendedStatus(buflen, msg, &bufneeded)){ + ret=PyWinObject_FromWCHAR(msg, bufneeded); + break; + } + if (bufneeded <= buflen){ + PyWin_SetAPIError("EvtGetExtendedStatus"); + break; + } } - PyWinObject_FreeWCHAR(path); - PyWinObject_FreeWCHAR(export_path); + if (msg) + free(msg); return ret; } -PyCFunction pfnPyEvtClearLog = (PyCFunction) PyEvtClearLog; %} %native (EvtOpenChannelEnum) pfnPyEvtOpenChannelEnum; %native (EvtNextChannelPath) pfnPyEvtNextChannelPath; %native (EvtOpenLog) pfnPyEvtOpenLog; %native (EvtClearLog) pfnPyEvtClearLog; +%native (EvtExportLog) pfnPyEvtExportLog; +%native (EvtArchiveExportedLog) pfnPyEvtArchiveExportedLog; +%native (EvtGetExtendedStatus) PyEvtGetExtendedStatus; + %init %{ for (PyMethodDef *pmd = win32evtlogMethods;pmd->ml_name;pmd++) @@ -593,7 +704,19 @@ ||(strcmp(pmd->ml_name, "EvtOpenLog")==0) ||(strcmp(pmd->ml_name, "EvtClearLog")==0) ||(strcmp(pmd->ml_name, "EvtOpenSession")==0) + ||(strcmp(pmd->ml_name, "EvtExportLog")==0) + ||(strcmp(pmd->ml_name, "EvtArchiveExportedLog")==0) ){ pmd->ml_flags = METH_VARARGS | METH_KEYWORDS; } %} + +// Used with EvtOpenLog +#define EvtOpenChannelPath EvtOpenChannelPath +#define EvtOpenFilePath EvtOpenFilePath + +// EVT_EXPORTLOG_FLAGS, used with EvtExportLog +#define EvtExportLogChannelPath EvtExportLogChannelPath +#define EvtExportLogFilePath EvtExportLogFilePath +#define EvtExportLogTolerateQueryErrors EvtExportLogTolerateQueryErrors + |
From: <pyw...@li...> - 2011-06-03 01:38:52
|
changeset 4e410d25d6ad in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=4e410d25d6ad summary: Return VT_LPSTR an unicode in Python 3 diffstat: com/win32com/src/extensions/PyIPropertyStorage.cpp | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (19 lines): diff -r 504901631d56 -r 4e410d25d6ad com/win32com/src/extensions/PyIPropertyStorage.cpp --- a/com/win32com/src/extensions/PyIPropertyStorage.cpp Tue May 31 23:20:39 2011 -0400 +++ b/com/win32com/src/extensions/PyIPropertyStorage.cpp Thu Jun 02 21:29:15 2011 -0400 @@ -125,13 +125,13 @@ Py_INCREF(Py_None); return Py_None; } - return PyString_FromString(pVar->pszVal); + return PyWinCoreString_FromString(pVar->pszVal); case VT_LPSTR|VT_VECTOR: { PyObject *ret = PyList_New(pVar->calpstr.cElems); if (ret==NULL) return NULL; for (ULONG i=0; i<pVar->calpstr.cElems;i++){ - PyObject *elem=PyString_FromString(pVar->calpstr.pElems[i]); + PyObject *elem=PyWinCoreString_FromString(pVar->calpstr.pElems[i]); if (elem==NULL){ Py_DECREF(ret); return NULL; |
From: <pyw...@li...> - 2011-06-03 00:13:10
|
changeset 504901631d56 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=504901631d56 summary: Create __file__ while script is running as python.exe does diffstat: Pythonwin/pywin/framework/scriptutils.py | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diffs (19 lines): diff -r aced4aa3ebde -r 504901631d56 Pythonwin/pywin/framework/scriptutils.py --- a/Pythonwin/pywin/framework/scriptutils.py Mon May 30 17:05:44 2011 -0400 +++ b/Pythonwin/pywin/framework/scriptutils.py Tue May 31 23:20:39 2011 -0400 @@ -315,6 +315,7 @@ _HandlePythonFailure("run script", script) # No code object which to run/debug. return + __main__.__file__=script try: if debuggingType == RS_DEBUGGER_STEP: debugger.run(codeObject, __main__.__dict__, start_stepping=1) @@ -349,6 +350,7 @@ interact.edit.currentView.AppendToPrompt([]) if debuggingType == RS_DEBUGGER_PM: debugger.pm() + del __main__.__file__ sys.argv = oldArgv if insertedPath0: del sys.path[0] |
From: <pyw...@li...> - 2011-05-30 21:10:15
|
changeset aced4aa3ebde in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=aced4aa3ebde summary: Handle some of the PROPVARIANT types that include VT_VECTOR diffstat: com/win32com/src/extensions/PyIPropertyStorage.cpp | 31 +++++++++++++++ 1 files changed, 31 insertions(+), 0 deletions(-) diffs (50 lines): diff -r 75105957d17a -r aced4aa3ebde com/win32com/src/extensions/PyIPropertyStorage.cpp --- a/com/win32com/src/extensions/PyIPropertyStorage.cpp Mon May 30 15:28:19 2011 -0400 +++ b/com/win32com/src/extensions/PyIPropertyStorage.cpp Mon May 30 17:05:44 2011 -0400 @@ -126,8 +126,36 @@ return Py_None; } return PyString_FromString(pVar->pszVal); + case VT_LPSTR|VT_VECTOR: + { + PyObject *ret = PyList_New(pVar->calpstr.cElems); + if (ret==NULL) return NULL; + for (ULONG i=0; i<pVar->calpstr.cElems;i++){ + PyObject *elem=PyString_FromString(pVar->calpstr.pElems[i]); + if (elem==NULL){ + Py_DECREF(ret); + return NULL; + } + PyList_SET_ITEM(ret, i, elem); + } + return ret; + } case VT_LPWSTR: return PyWinObject_FromOLECHAR(pVar->pwszVal); + case VT_LPWSTR|VT_VECTOR: + { + PyObject *ret = PyList_New(pVar->calpwstr.cElems); + if (ret==NULL) return NULL; + for (ULONG i=0; i<pVar->calpwstr.cElems;i++){ + PyObject *elem=PyWinObject_FromWCHAR(pVar->calpwstr.pElems[i]); + if (elem==NULL){ + Py_DECREF(ret); + return NULL; + } + PyList_SET_ITEM(ret, i, elem); + } + return ret; + } case VT_CLSID: return PyWinObject_FromIID(*pVar->puuid); case VT_STREAM: @@ -136,6 +164,9 @@ case VT_STORAGE: case VT_STORED_OBJECT: return PyCom_PyObjectFromIUnknown(pVar->pStorage, IID_IStorage, TRUE); + case VT_VECTOR | VT_VARIANT: + return PyObject_FromPROPVARIANTs(pVar->capropvar.pElems, pVar->capropvar.cElems); + // case VT_UNKNOWN: // return PyCom_PyObjectFromIUnknown(pVar->punkVal, IID_IUnknown, TRUE); // case VT_DISPATCH: |
From: <pyw...@li...> - 2011-05-30 19:29:24
|
changeset 75105957d17a in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=75105957d17a summary: Add some recent changes diffstat: CHANGES.txt | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diffs (14 lines): diff -r d7b5e4753239 -r 75105957d17a CHANGES.txt --- a/CHANGES.txt Mon May 30 15:17:46 2011 -0400 +++ b/CHANGES.txt Mon May 30 15:28:19 2011 -0400 @@ -37,6 +37,10 @@ * Source-code management moved from CVS to Mercurual. +* win32com.shell - Added SHCreateShellItem + +* win32evtlog - Added some of the new event log functions introduced in Vista/Windows 7 + Since build 215: ---------------- * New loader module for COM objects to avoid some CRT manifest issues. |
From: <pyw...@li...> - 2011-05-30 19:20:44
|
changeset bf45d00d1717 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=bf45d00d1717 summary: Add some new event log functions for Vista/Windows 7 changeset 7c7b484ae9df in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=7c7b484ae9df summary: Include propsys in chm changeset d7b5e4753239 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=d7b5e4753239 summary: Add SHCreateShellItem diffstat: AutoDuck/pywin32.mak | 1 + com/win32comext/shell/src/shell.cpp | 61 +++++++++++++++- setup.py | 13 ++- win32/src/win32evtlog.i | 161 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 231 insertions(+), 5 deletions(-) diffs (truncated from 330 to 300 lines): diff -r e6ffc1f9d677 -r d7b5e4753239 AutoDuck/pywin32.mak --- a/AutoDuck/pywin32.mak Sun May 29 19:43:15 2011 -0400 +++ b/AutoDuck/pywin32.mak Mon May 30 15:17:46 2011 -0400 @@ -60,6 +60,7 @@ $(WIN32COMEXT_DIR)\authorization\src\*.cpp \ $(WIN32COMEXT_DIR)\authorization\src\*.h \ $(WIN32COMEXT_DIR)\directsound\src\*.cpp \ + $(WIN32COMEXT_DIR)\propsys\src\*.cpp \ $(WIN32COM_DIR)\src\include\*.h \ $(MAPI_DIR)\src\*.cpp \ $(GENDIR)\mapi.d \ diff -r e6ffc1f9d677 -r d7b5e4753239 com/win32comext/shell/src/shell.cpp --- a/com/win32comext/shell/src/shell.cpp Sun May 29 19:43:15 2011 -0400 +++ b/com/win32comext/shell/src/shell.cpp Mon May 30 15:17:46 2011 -0400 @@ -156,6 +156,9 @@ typedef HRESULT (WINAPI *PFNSHGetIDListFromObject)(IUnknown *, PIDLIST_ABSOLUTE *); static PFNSHGetIDListFromObject pfnSHGetIDListFromObject = NULL; +typedef HRESULT (WINAPI *PFNSHCreateShellItem)(PCIDLIST_ABSOLUTE, IShellFolder *, PCUITEMID_CHILD, IShellItem **); +static PFNSHCreateShellItem pfnSHCreateShellItem = NULL; + void PyShell_FreeMem(void *p) { @@ -3184,6 +3187,60 @@ } + + +// @pymethod <o PyIShellItem>|shell|SHCreateShellItem|Creates an IShellItem interface from a PIDL +static PyObject *PySHCreateShellItem(PyObject *self, PyObject *args) +{ + // @comm This function is only available on XP and later; a + // COM exception with E_NOTIMPL will be thrown if the function can't be located. + if (pfnSHCreateShellItem==NULL) + return PyCom_BuildPyException(E_NOTIMPL); + + PyObject *ret = NULL; + PyObject *obparent_pidl, *obparent_folder, *obitem; + // @pyparm <o PyIDL>|pidlParent||PIDL of parent folder, can be None + // @pyparm <o PyIShellFolder>|sfParent||IShellFolder interface of parent folder, can be None + // @pyparm <o PyIDL>|Child||PIDL identifying desired item. Must be an absolute PIDL if parent is not specified. + if(!PyArg_ParseTuple(args, "OOO:SHCreateShellItem", &obparent_pidl, &obparent_folder, &obitem)) + return NULL; + + PIDLIST_ABSOLUTE parent_pidl=NULL; + IShellFolder *parent_folder=NULL; + PUITEMID_CHILD item=NULL; + IShellItem *isi=NULL; + HRESULT hr; + if (!PyObject_AsPIDL(obparent_pidl, &parent_pidl, TRUE)) + goto done; + if (!PyCom_InterfaceFromPyInstanceOrObject(obparent_folder, IID_IShellFolder, (void **)&parent_folder, TRUE)) + goto done; + if (!PyObject_AsPIDL(obitem, &item, FALSE)) + goto done; + + PY_INTERFACE_PRECALL; + hr = (*pfnSHCreateShellItem)(parent_pidl, parent_folder, item, &isi); + PY_INTERFACE_POSTCALL; + + if (FAILED(hr)) { + PyCom_BuildPyException(hr); + goto done; + } + ret = PyCom_PyObjectFromIUnknown((IUnknown *)isi, IID_IShellItem, FALSE); +done: + if (parent_folder) { + PY_INTERFACE_PRECALL; + parent_folder->Release(); + PY_INTERFACE_POSTCALL; + } + if (parent_pidl) + PyObject_FreePIDL(parent_pidl); + if (item) + PyObject_FreePIDL(item); + + return ret; +} + + /* List of module functions */ // @module shell|A module wrapping Windows Shell functions and interfaces static struct PyMethodDef shell_methods[]= @@ -3240,6 +3297,7 @@ { "ShellExecuteEx", (PyCFunction)PyShellExecuteEx, METH_VARARGS|METH_KEYWORDS}, // @pymeth ShellExecuteEx|Performs an action on a file. { "SHGetViewStatePropertyBag", PySHGetViewStatePropertyBag, METH_VARARGS}, // @pymeth SHGetViewStatePropertyBag|Retrieves an interface for a folder's view state { "SHILCreateFromPath", PySHILCreateFromPath, METH_VARARGS}, // @pymeth SHILCreateFromPath|Returns the PIDL and attributes of a path + { "SHCreateShellItem", PySHCreateShellItem, METH_VARARGS}, // @pymeth SHCreateShellItem|Creates an IShellItem interface from a PIDL { NULL, NULL }, }; @@ -3297,6 +3355,7 @@ PYCOM_INTERFACE_IID_ONLY(ShellCopyHookW), PYCOM_INTERFACE_IID_ONLY(ShellCopyHook), PYCOM_INTERFACE_FULL(ShellItem), + PYCOM_INTERFACE_CLSID_ONLY(ShellItem), PYCOM_INTERFACE_FULL(ShellItemArray), PYCOM_INTERFACE_CLIENT_ONLY(ShellLinkDataList), PYCOM_INTERFACE_CLIENT_ONLY(UniformResourceLocator), @@ -3371,7 +3430,7 @@ pfnSHCreateItemInKnownFolder =(PFNSHCreateItemInKnownFolder)GetProcAddress(shell32, "SHCreateItemInKnownFolder"); pfnSHCreateItemWithParent =(PFNSHCreateItemWithParent)GetProcAddress(shell32, "SHCreateItemWithParent"); pfnSHGetIDListFromObject =(PFNSHGetIDListFromObject)GetProcAddress(shell32, "SHGetIDListFromObject"); - + pfnSHCreateShellItem =(PFNSHCreateShellItem)GetProcAddress(shell32, "SHCreateShellItem"); } // SHGetFolderPath comes from shfolder.dll on older systems if (pfnSHGetFolderPath==NULL){ diff -r e6ffc1f9d677 -r d7b5e4753239 setup.py --- a/setup.py Sun May 29 19:43:15 2011 -0400 +++ b/setup.py Mon May 30 15:17:46 2011 -0400 @@ -1592,10 +1592,7 @@ """), ("win32event", "user32", None, None, "win32/src/win32event.i"), ("win32clipboard", "gdi32 user32 shell32", None), - ("win32evtlog", "advapi32 oleaut32", None, None, """ - win32\\src\\win32evtlog_messages.mc - win32\\src\\win32evtlog.i - """), + # win32gui handled below ("win32job", "user32", True, 0x0500, 'win32/src/win32job.i'), ("win32lz", "lz32", None), @@ -1651,6 +1648,14 @@ # The few that need slightly special treatment win32_extensions += [ + WinExt_win32("win32evtlog", + sources = """ + win32\\src\\win32evtlog_messages.mc win32\\src\\win32evtlog.i + """.split(), + libraries="advapi32 oleaut32", + delay_load_libraries="wevtapi", + windows_h_version=0x0600 + ), WinExt_win32("win32api", sources = """ win32/src/win32apimodule.cpp win32/src/win32api_display.cpp diff -r e6ffc1f9d677 -r d7b5e4753239 win32/src/win32evtlog.i --- a/win32/src/win32evtlog.i Sun May 29 19:43:15 2011 -0400 +++ b/win32/src/win32evtlog.i Mon May 30 15:17:46 2011 -0400 @@ -12,6 +12,7 @@ #undef PyHANDLE #include "PyWinObjects.h" +#include "WinEvt.h" // @object PyEVTLOG_HANDLE|Object representing a handle to the windows event log. // Identical to <o PyHANDLE>, but calls CloseEventLog() on destruction @@ -30,6 +31,26 @@ return "PyEVTLOG_HANDLE"; } }; + +// @object PyEVT_HANDLE|Handle to an event log, session, query, or any other object used with +// the Evt* event log functions on Vista and later. +// When the object is destroyed, EvtClose is called. +class PyEVT_HANDLE: public PyHANDLE +{ +public: + PyEVT_HANDLE(HANDLE hInit) : PyHANDLE(hInit) {} + virtual BOOL Close(void){ + BOOL ret=EvtClose(m_handle); + if (!ret) + PyWin_SetAPIError("EvtClose"); + m_handle = 0; + return ret; + } + virtual const char *GetTypeName(){ + return "PyEVT_HANDLE"; + } +}; + #define PyHANDLE HANDLE PyObject *PyWinObject_FromEVTLOG_HANDLE(HANDLE h) @@ -40,6 +61,15 @@ return ret; } +PyObject *PyWinObject_FromEVT_HANDLE(HANDLE h) +{ + PyObject *ret=new PyEVT_HANDLE(h); + if (ret==NULL){ + EvtClose(h); + PyErr_NoMemory(); + } + return ret; +} %} %typemap(python,except) PyEVTLOG_HANDLE { @@ -435,4 +465,135 @@ PyObject *obRawData // @pyparm str|RawData||Binary data for event, can be None ); +%{ + +// New event log functions available on Vista and later +// @pyswig <o PyEVT_HANDLE>|EvtOpenChannelEnum|Begins an enumeration of event channels +static PyObject *PyEvtOpenChannelEnum(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[]={"Session", "Flags", NULL}; + EVT_HANDLE session=NULL, enum_handle; + DWORD flags=0; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&k:EvtOpenChannelEnum", keywords, + PyWinObject_AsHANDLE, &session, // @pyparm <o PyEVT_HANDLE>|Session|None|Handle to a remote session (see <om win32evtlog.EvtOpenSession>), or None for local machine. + &flags)) // @pyparm int|Flags|0|Reserved, use only 0 + return NULL; + enum_handle=EvtOpenChannelEnum(session, flags); + if (enum_handle==NULL) + return PyWin_SetAPIError("EvtOpenChannelEnum"); + return PyWinObject_FromEVT_HANDLE(enum_handle); +} +PyCFunction pfnPyEvtOpenChannelEnum = (PyCFunction) PyEvtOpenChannelEnum; + +// @pyswig str|EvtNextChannelPath|Retrieves a channel path from an enumeration +// @rdesc Returns None at end of enumeration +static PyObject *PyEvtNextChannelPath(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[]={"ChannelEnum", NULL}; + EVT_HANDLE enum_handle; + DWORD allocated_size=256, returned_size, err; + WCHAR *buf=NULL; + PyObject *ret=NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&:EvtNextChannelPath", keywords, + PyWinObject_AsHANDLE, &enum_handle)) // @pyparm <o PyEVT_HANDLE>|ChannelEnum||Handle to an enumeration as returned by <om win32evtlog.EvtOpenChannelEnum> + return NULL; + while (true){ + if (buf) + free(buf); + // MSDN docs say sized are in bytes, but it doesn't seem to be so ??? + WCHAR *buf=(WCHAR *)malloc(allocated_size * sizeof(WCHAR)); + if (!buf) + return NULL; + if (EvtNextChannelPath(enum_handle, allocated_size, buf, &returned_size)){ + ret=PyWinObject_FromWCHAR(buf); + break; + } + err=GetLastError(); + if (err==ERROR_INSUFFICIENT_BUFFER){ + allocated_size=returned_size; + continue; + } + if (err==ERROR_NO_MORE_ITEMS){ + Py_INCREF(Py_None); + ret=Py_None; + break; + } + PyWin_SetAPIError("EvtNextChannelPath", err); + break; + } + if (buf) + free(buf); + return ret; +} +PyCFunction pfnPyEvtNextChannelPath = (PyCFunction) PyEvtNextChannelPath; + +// @pyswig <o PyEVT_HANDLE>|EvtOpenLog|Opens an event log or exported log archive +static PyObject *PyEvtOpenLog(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[]={"Path", "Flags", "Session", NULL}; + EVT_HANDLE session=NULL, log_handle; + DWORD flags=0; + WCHAR *path; + PyObject *obpath; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Ok|O&:EvtOpenLog", keywords, + &obpath, // @pyparm str|Path||Event log name or Path of an export file + &flags, // @pyparm int|Flags||EvtOpenChannelPath (1) or EvtOpenFilePath (2) + PyWinObject_AsHANDLE, &session)) // @pyparm <o PyEVT_HANDLE>|Session|None|Handle to a remote session (see <om win32evtlog.EvtOpenSession>), or None for local machine. + return NULL; + if (!PyWinObject_AsWCHAR(obpath, &path, FALSE)) + return NULL; + log_handle=EvtOpenLog(session, path, flags); + PyWinObject_FreeWCHAR(path); + if (log_handle==NULL) + return PyWin_SetAPIError("EvtOpenLog"); + return PyWinObject_FromEVT_HANDLE(log_handle); +} +PyCFunction pfnPyEvtOpenLog = (PyCFunction) PyEvtOpenLog; + +// @pyswig |EvtClearLog|Clears an event log and optionally exports events to an archive +static PyObject *PyEvtClearLog(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[]={"ChannelPath", "TargetFilePath", "Session", "Flags", NULL}; + EVT_HANDLE session=NULL; + DWORD flags=0; + WCHAR *path=NULL, *export_path=NULL; + PyObject *obpath, *obexport_path=Py_None, *ret=NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OO&k:EvtClearLog", keywords, + &obpath, // @pyparm str|ChannelPath||Name of event log to be cleared + &obexport_path, // @pyparm str|TargetFilePath|None|Name of file in which cleared events will be archived, or None + PyWinObject_AsHANDLE, &session, // @pyparm <o PyEVT_HANDLE>|Session|None|Handle to a remote session (see <om win32evtlog.EvtOpenSession>), or None for local machine. + &flags)) // @pyparm int|Flags|0|Reserved, use only 0 + return NULL; + if (PyWinObject_AsWCHAR(obpath, &path, FALSE) + &&PyWinObject_AsWCHAR(obexport_path, &export_path, TRUE)){ |
From: <pyw...@li...> - 2011-05-29 23:51:59
|
changeset e6ffc1f9d677 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=e6ffc1f9d677 summary: Linker parm /delayload should be the dll rather than the lib diffstat: setup.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 236b256c13bf -r e6ffc1f9d677 setup.py --- a/setup.py Mon May 02 12:39:21 2011 +1000 +++ b/setup.py Sun May 29 19:43:15 2011 -0400 @@ -456,7 +456,7 @@ if self.delay_load_libraries: self.libraries.append("delayimp") for delay_lib in self.delay_load_libraries: - self.extra_link_args.append("/delayload:%s.lib" % delay_lib) + self.extra_link_args.append("/delayload:%s.dll" % delay_lib) # If someone needs a specially named implib created, handle that if self.implib_name: |
From: <pyw...@li...> - 2011-05-02 02:41:12
|
changeset 11095402fa78 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=11095402fa78 summary: a single SWIG for py2k and py3k changeset 0c7c0fcba126 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=0c7c0fcba126 summary: get adsi building in py3k changeset 851ff06494eb in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=851ff06494eb summary: mapi and exchange modules working under py3k changeset 236b256c13bf in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=236b256c13bf summary: update CHANGES.txt for recent swig work diffstat: .hgignore | 2 +- CHANGES.txt | 5 + SWIG/pywin32_swig.patch | 240 ++++++++++++++++++++++++++++++++++ SWIG/swig.exe | SWIG/swig_py3k.exe | com/win32comext/adsi/src/PyADSIUtil.cpp | 82 +++++------ com/win32comext/adsi/src/PyDSOPObjects.cpp | 14 +- com/win32comext/adsi/src/adsi.i | 16 +- com/win32comext/mapi/src/PyIMAPIStatus.i | 2 +- com/win32comext/mapi/src/exchange.i | 31 ++-- com/win32comext/mapi/src/exchdapi.i | 16 +- com/win32comext/mapi/src/mapi.i | 34 ++-- com/win32comext/mapi/src/mapilib.i | 6 +- setup.py | 26 +--- 14 files changed, 346 insertions(+), 128 deletions(-) diffs (truncated from 881 to 300 lines): diff -r 521b09dc35f8 -r 236b256c13bf .hgignore --- a/.hgignore Fri Apr 29 21:40:01 2011 -0600 +++ b/.hgignore Mon May 02 12:39:21 2011 +1000 @@ -21,7 +21,7 @@ com/win32comext/adsi/src/*.h com/win32comext/mapi/src/*.cpp com/win32comext/mapi/src/*.h -win32/src/*_py2_swig.cpp +win32/src/*_swig.cpp # Generated from message files diff -r 521b09dc35f8 -r 236b256c13bf CHANGES.txt --- a/CHANGES.txt Fri Apr 29 21:40:01 2011 -0600 +++ b/CHANGES.txt Mon May 02 12:39:21 2011 +1000 @@ -7,6 +7,11 @@ Since build 216: ---------------- +* The win32com.adsi and win32com.mapi packages have been upgraded to work on + Python 3.x and as a result, there is a slight risk that regressions to + these packages have been introduced in the Python 2.x versions. Please + file a bug if any problems are found. + * Pythonwin now warns, but allows you to continue, when saving a file with an invalid encoding line (bug 3139486) diff -r 521b09dc35f8 -r 236b256c13bf SWIG/pywin32_swig.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SWIG/pywin32_swig.patch Mon May 02 12:39:21 2011 +1000 @@ -0,0 +1,242 @@ +This is a patch to create the customized version of SWIG used for pywin32. + +The patch is against SWIG-1.1p5 which can be found at: + + https://sourceforge.net/projects/swig/files/swig/1.1p5/ + +or + + http://starship.python.net/crew/mhammond/downloads/swig1.1p5.tar.gz + +To build the version of SWIG: + +* Unpack the swig tarball +* Apply this patch. +* Change to the "Win" directory +* Execute 'nmake -f makefile.vc +* Copy the newly created swig.exe from the swig tree to the pywin32 tree. + + +Huge thanks to Amaury Forgeot d'Arc and Roger Upole for rescuing this! + + +--- SWIG1.1p5-orig\Modules\python.cxx 1998-01-03 17:17:40.000000000 +1100 ++++ SWIG1.1p5\Modules\python.cxx 2011-04-29 23:28:30.860296500 +1000 +@@ -61,6 +61,8 @@ + + static int doc_index = 0; + static DocString *doc_strings = 0; ++static int PythonCom = 0; // Generate PyWin32 header files ++static char *PythonCom_Parent = "IUnknown"; + + static char *usage = "\ + Python Options (available with -python)\n\ +@@ -113,6 +115,14 @@ + } else if (strcmp(argv[i],"-docstring") == 0) { + docstring = 1; + mark_arg(i); ++ } else if (strcmp(argv[i],"-pythoncom") == 0) { ++ PythonCom = 1; ++ mark_arg(i); ++ } else if (strcmp(argv[i],"-com_interface_parent") == 0) { ++ mark_arg(i); ++ PythonCom_Parent = copy_string(argv[i+1]); ++ mark_arg(i+1); ++ i++; + } else if (strcmp(argv[i],"-help") == 0) { + fputs(usage,stderr); + } +@@ -258,6 +268,47 @@ + } + fprintf(f_wrappers,"\t { NULL, NULL }\n"); + fprintf(f_wrappers,"};\n"); ++ if (PythonCom) { ++ fprintf(f_wrappers,"PyComTypeObject Py%s::type(\"Py%s\",", module, module); ++ fprintf(f_wrappers,"\t&Py%s::type,\n", PythonCom_Parent); ++ fprintf(f_wrappers,"\tsizeof(Py%s),\n", module); ++ fprintf(f_wrappers,"\t%sMethods,\n", module); ++ fprintf(f_wrappers,"\tGET_PYCOM_CTOR(Py%s));", module); ++ } ++} ++ ++// --------------------------------------------------------------------- ++// PYTHON::print_com_header() ++// ++// Prints out the COM header file ++// --------------------------------------------------------------------- ++ ++void PYTHON::print_com_header() { ++ char fn_header[256]; ++ sprintf(fn_header, "Py%s.h", module); ++ FILE *f_header = fopen(fn_header, "w"); ++ ++ if (!f_header) { ++ fprintf(stderr, "Unable to open %s\n", fn_header); ++ SWIG_exit(1); ++ } ++ ++ fprintf(f_header, "class Py%s : public Py%s\n", module, PythonCom_Parent); ++ fprintf(f_header, "{\npublic:\nMAKE_PYCOM_CTOR(Py%s);\n", module); ++ fprintf(f_header, "static PyComTypeObject type;\nstatic %s *GetI(PyObject *self);\n", module); ++ ++ Method *n = head; ++ ++ n = head; ++ while (n) { ++ fprintf(f_header, "\tstatic PyObject *%s(PyObject *self, PyObject *args);\n", n->name); ++ n = n->next; ++ } ++ ++ fprintf(f_header, "protected:\n\tPy%s(IUnknown *);\n\t~Py%s();\n", module, module); ++ fprintf(f_header, "};\n\n"); ++ ++ fclose(f_header); + } + + // --------------------------------------------------------------------- +@@ -376,6 +427,8 @@ + void PYTHON::initialize_cmodule(void) + { + int i; ++ if (PythonCom) ++ return; + fprintf(f_header,"#define SWIG_init init%s\n\n", module); + fprintf(f_header,"#define SWIG_name \"%s\"\n", module); + +@@ -389,7 +442,13 @@ + fprintf(f_init,"extern \"C\" \n"); + fprintf(f_init,"#endif\n"); + ++ fprintf(f_init, "#if (PY_VERSION_HEX < 0x03000000)\n"); ++ fprintf(f_init, "#define MODINIT_ERROR_RETURN\n"); + fprintf(f_init,"SWIGEXPORT(void,init%s)() {\n",module); ++ fprintf(f_init, "#else\n"); ++ fprintf(f_init, "#define MODINIT_ERROR_RETURN NULL\n"); ++ fprintf(f_init,"SWIGEXPORT(PyObject*, PyInit_%s)(void) {\n",module); ++ fprintf(f_init, "#endif\n"); + fprintf(f_init,"\t PyObject *m, *d;\n"); + + if (InitNames) { +@@ -400,8 +459,26 @@ + } + } + fprintf(f_init,"\t SWIG_globals = SWIG_newvarlink();\n"); ++ fprintf(f_init, "#if (PY_VERSION_HEX < 0x03000000)\n"); + fprintf(f_init,"\t m = Py_InitModule(\"%s\", %sMethods);\n", module, module); + fprintf(f_init,"\t d = PyModule_GetDict(m);\n"); ++ fprintf(f_init, "#else\n"); ++ fprintf(f_init, ++ " static PyModuleDef %s_def = {\n" ++ " PyModuleDef_HEAD_INIT,\n" ++ " \"%s\",\n" ++ " \"\",\n" ++ " -1,\n" ++ " %sMethods,\n" ++ " };\n" ++ " m = PyModule_Create(&%s_def);\n" ++ " if (!m)\n" ++ " return NULL;\n" ++ " d = PyModule_GetDict(m);\n" ++ " if (!d)\n" ++ " return NULL;\n", ++ module, module, module, module); ++ fprintf(f_init, "#endif\n"); + } + + +@@ -417,6 +494,9 @@ + + print_methods(); + close_cmodule(); ++ if (PythonCom) { ++ print_com_header(); ++ } + if ((doc_entry) && (module)){ + String temp; + temp << "Python Module : "; +@@ -469,7 +549,13 @@ + // -------------------------------------------------------------------- + void PYTHON::close_cmodule(void) + { +- emit_ptr_equivalence(f_init); ++ if (PythonCom) ++ return; ++// pywin32 doesn't need the pointer type-equivalency mappings. ++// emit_ptr_equivalence(f_init); ++ fprintf(f_init, "#if (PY_VERSION_HEX > 0x03000000)\n"); ++ fprintf(f_init,"\treturn m;\n"); ++ fprintf(f_init, "#endif\n"); + fprintf(f_init,"}\n"); + } + +@@ -598,9 +684,12 @@ + // ---------------------------------------------------------------------- + void PYTHON::emit_function_header(WrapperFunction &emit_to, char *wname) + { +- emit_to.def << "static PyObject *" << wname ++ if (!PythonCom) ++ emit_to.def << "static "; ++ emit_to.def << "PyObject *" << wname + << "(PyObject *self, PyObject *args) {"; +- emit_to.code << tab4 << "self = self;\n"; ++ if (!PythonCom) ++ emit_to.code << tab4 << "self = self;\n"; + } + + // ---------------------------------------------------------------------- +@@ -612,8 +701,13 @@ + // + // Returns the name of the variable to use as the self pointer + // ---------------------------------------------------------------------- +-char *PYTHON::convert_self(WrapperFunction &) ++char *PYTHON::convert_self(WrapperFunction &f) + { ++ if (PythonCom) { ++ f.code << "\t" << module << " *_swig_self;\n"; ++ f.code << "\t" << "if ((_swig_self=GetI(self))==NULL) return NULL;\n"; ++ return "_swig_self->"; ++ } + // Default behaviour is no translation + return ""; + } +@@ -625,7 +719,14 @@ + // ---------------------------------------------------------------------- + char *PYTHON::make_funcname_wrapper(char *fnName) + { +- return name_wrapper(fnName,""); ++ if (PythonCom) { ++ String wrapper; ++ wrapper << "Py" << module << "::" << fnName; ++ return wrapper; ++ } ++ else { ++ return name_wrapper(fnName,""); ++ } + } + + // ---------------------------------------------------------------------- +@@ -1629,7 +1730,13 @@ + // ----------------------------------------------------------------------- + + void PYTHON::add_native(char *name, char *funcname) { +- add_method(name, funcname); ++ if (PythonCom) { ++ String method; ++ method << "Py" << module << "::" << funcname; ++ add_method(name, method); ++ } else { ++ add_method(name, funcname); ++ } + if (shadow) { + func << name << " = " << module << "." << name << "\n\n"; + } +--- SWIG1.1p5-orig\Modules\python.h 1997-07-25 15:18:50.000000000 +1000 ++++ SWIG1.1p5\Modules\python.h 2011-04-22 10:53:17.287056400 +1000 +@@ -140,6 +140,7 @@ + // Add for Python-COM support + virtual void initialize_cmodule(); + virtual void close_cmodule(); ++ virtual void print_com_header(); + virtual void emit_function_header(WrapperFunction &emit_to, char *wname); + virtual char *convert_self(WrapperFunction &f); + virtual char *make_funcname_wrapper(char *fnName); diff -r 521b09dc35f8 -r 236b256c13bf SWIG/swig.exe Binary file SWIG/swig.exe has changed diff -r 521b09dc35f8 -r 236b256c13bf SWIG/swig_py3k.exe Binary file SWIG/swig_py3k.exe has changed diff -r 521b09dc35f8 -r 236b256c13bf com/win32comext/adsi/src/PyADSIUtil.cpp --- a/com/win32comext/adsi/src/PyADSIUtil.cpp Fri Apr 29 21:40:01 2011 -0600 +++ b/com/win32comext/adsi/src/PyADSIUtil.cpp Mon May 02 12:39:21 2011 +1000 @@ -111,9 +111,14 @@ case ADSTYPE_OCTET_STRING: { void *buf; - ob = PyBuffer_New(v.OctetString.dwLength); - ob->ob_type->tp_as_buffer->bf_getwritebuffer(ob, 0, &buf); - memcpy(buf, v.OctetString.lpValue, v.OctetString.dwLength); + DWORD bufSize = v.OctetString.dwLength; + if (!(ob=PyBuffer_New(bufSize))) + return NULL; + if (!PyWinObject_AsWriteBuffer(ob, &buf, &bufSize)){ + Py_DECREF(ob); + return NULL; + } + memcpy(buf, v.OctetString.lpValue, bufSize); } break; case ADSTYPE_UTC_TIME: @@ -128,11 +133,16 @@ case ADSTYPE_PROV_SPECIFIC: |
From: <pyw...@li...> - 2011-04-30 03:40:30
|
changeset 521b09dc35f8 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=521b09dc35f8 summary: bugfix ID: 3292681 Subtle crash diffstat: adodbapi/adodbapi.py | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) diffs (39 lines): diff -r 1f726f95d353 -r 521b09dc35f8 adodbapi/adodbapi.py --- a/adodbapi/adodbapi.py Sun Apr 24 17:41:43 2011 +1000 +++ b/adodbapi/adodbapi.py Fri Apr 29 21:40:01 2011 -0600 @@ -26,7 +26,7 @@ or IronPython version 2.6 and later, or, after running through 2to3.py, CPython 3.0 or later. """ -__version__ = '2.4.2.0' +__version__ = '2.4.2.2' version = 'adodbapi v' + __version__ # N.O.T.E.:... # if you have been using an older version of adodbapi and are getting errors because @@ -395,10 +395,12 @@ p.AppendChunk(value) elif isinstance(value, decimal.Decimal): - ##s = str(value) - ##p.Value = s - ##p.Size = len(s) - p.Value = value + if onIronPython: + s = str(value) + p.Value = s + p.Size = len(s) + else: + p.Value = value exponent = value.as_tuple()[2] digit_count = len(value.as_tuple()[1]) p.Precision = digit_count @@ -496,8 +498,7 @@ self._closeAdoConnection() #v2.1 Rose except (Exception), e: self._raiseConnectionError(InternalError,e) - if not onIronPython: - pythoncom.CoUninitialize() #v2.1 Paj + self.adoConn = None #v2.4.2.2 fix subtle timeout bug def commit(self): """Commit any pending transaction to the database. |
From: <pyw...@li...> - 2011-04-24 07:43:12
|
changeset 1f726f95d353 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=1f726f95d353 summary: allow option to save as binary when encoding fails (bug 3139486) diffstat: CHANGES.txt | 5 ++ Pythonwin/pywin/framework/editor/document.py | 21 ++++++++-- Pythonwin/pywin/framework/editor/editor.py | 4 +- Pythonwin/pywin/scintilla/document.py | 37 +++++++++--------- Pythonwin/pywin/scintilla/view.py | 4 +- 5 files changed, 43 insertions(+), 28 deletions(-) diffs (145 lines): diff -r a5a35d18b1de -r 1f726f95d353 CHANGES.txt --- a/CHANGES.txt Sun Apr 24 16:25:15 2011 +1000 +++ b/CHANGES.txt Sun Apr 24 17:41:43 2011 +1000 @@ -7,6 +7,11 @@ Since build 216: ---------------- +* Pythonwin now warns, but allows you to continue, when saving a file with + an invalid encoding line (bug 3139486) + +* Fix win32com.client.WithEvents on py3k (bug bug 3199843) + * 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 diff -r a5a35d18b1de -r 1f726f95d353 Pythonwin/pywin/framework/editor/document.py --- a/Pythonwin/pywin/framework/editor/document.py Sun Apr 24 16:25:15 2011 +1000 +++ b/Pythonwin/pywin/framework/editor/document.py Sun Apr 24 17:41:43 2011 +1000 @@ -78,12 +78,23 @@ except IOError, details: win32ui.MessageBox("Error - could not save file\r\n\r\n%s"%details) return 0 - except UnicodeEncodeError, details: - win32ui.MessageBox("Encoding failed: \r\n%s"%details + + except (UnicodeEncodeError, LookupError), details: + rc = win32ui.MessageBox("Encoding failed: \r\n%s"%details + '\r\nPlease add desired source encoding as first line of file, eg \r\n' + - '# -*- coding: mbcs -*-', - "File save failed") - return 0 + '# -*- coding: mbcs -*-\r\n\r\n' + + 'If you continue, the file will be saved as binary and will\r\n' + + 'not be valid in the declared encoding.\r\n\r\n' + + 'Save the file as binary with an invalid encoding?', + "File save failed", + win32con.MB_YESNO | win32con.MB_DEFBUTTON2) + if rc==win32con.IDYES: + try: + self.SaveFile(fileName, encoding="latin-1") + except IOError, details: + win32ui.MessageBox("Error - could not save file\r\n\r\n%s"%details) + return 0 + else: + return 0 self.SetModifiedFlag(0) # No longer dirty self.bDeclinedReload = 0 # They probably want to know if it changes again! win32ui.AddToRecentFileList(fileName) diff -r a5a35d18b1de -r 1f726f95d353 Pythonwin/pywin/framework/editor/editor.py --- a/Pythonwin/pywin/framework/editor/editor.py Sun Apr 24 16:25:15 2011 +1000 +++ b/Pythonwin/pywin/framework/editor/editor.py Sun Apr 24 17:41:43 2011 +1000 @@ -109,10 +109,10 @@ else: return data - def SaveFile(self, fileName): + def SaveFile(self, fileName, encoding=None): if isRichText: view = self.GetFirstView() - view.SaveTextFile(fileName) + view.SaveTextFile(fileName, encoding=encoding) else: # Old style edit view window. self.GetFirstView().SaveFile(fileName) try: diff -r a5a35d18b1de -r 1f726f95d353 Pythonwin/pywin/scintilla/document.py --- a/Pythonwin/pywin/scintilla/document.py Sun Apr 24 16:25:15 2011 +1000 +++ b/Pythonwin/pywin/scintilla/document.py Sun Apr 24 17:41:43 2011 +1000 @@ -59,9 +59,9 @@ rc = win32ui.MessageBox("Cannot create the file %s" % filename) return 1 - def SaveFile(self, fileName): + def SaveFile(self, fileName, encoding=None): view = self.GetFirstView() - ok = view.SaveTextFile(fileName) + ok = view.SaveTextFile(fileName, encoding=encoding) if ok: view.SCISetSavePoint() return ok @@ -126,11 +126,9 @@ dec = text.decode(source_encoding) except UnicodeError: print "WARNING: Failed to decode bytes from '%s' encoding - treating as latin1" % source_encoding - print "WARNING: Do not modify this file - you will not be able to save it." dec = text.decode('latin1') except LookupError: print "WARNING: Invalid encoding '%s' specified - treating as latin1" % source_encoding - print "WARNING: Do not modify this file - you will not be able to save it." dec = text.decode('latin1') # and put it back as utf8 - this shouldn't fail. text = dec.encode(default_scintilla_encoding) @@ -148,23 +146,24 @@ # set EOL mode view.SendScintilla(scintillacon.SCI_SETEOLMODE, eol_mode) - def _SaveTextToFile(self, view, filename): + def _SaveTextToFile(self, view, filename, encoding=None): s = view.GetTextRange() # already decoded from scintilla's encoding - source_encoding = None - if self.bom: - source_encoding = self.source_encoding - else: - # no BOM - look for an encoding. - bits = re.split("[\r\n]*", s, 3) - for look in bits[:-1]: - match = re_encoding_text.search(look) - if match is not None: - source_encoding = match.group(1) - self.source_encoding = source_encoding - break - + source_encoding = encoding if source_encoding is None: - source_encoding = 'latin1' + if self.bom: + source_encoding = self.source_encoding + else: + # no BOM - look for an encoding. + bits = re.split("[\r\n]*", s, 3) + for look in bits[:-1]: + match = re_encoding_text.search(look) + if match is not None: + source_encoding = match.group(1) + self.source_encoding = source_encoding + break + + if source_encoding is None: + source_encoding = 'latin1' ## encode data before opening file so script is not lost if encoding fails file_contents = s.encode(source_encoding) diff -r a5a35d18b1de -r 1f726f95d353 Pythonwin/pywin/scintilla/view.py --- a/Pythonwin/pywin/scintilla/view.py Sun Apr 24 16:25:15 2011 +1000 +++ b/Pythonwin/pywin/scintilla/view.py Sun Apr 24 17:41:43 2011 +1000 @@ -384,9 +384,9 @@ self.SCIGotoLine(lineNo) return 0 - def SaveTextFile(self, filename): + def SaveTextFile(self, filename, encoding=None): doc = self.GetDocument() - doc._SaveTextToFile(self, filename) + doc._SaveTextToFile(self, filename, encoding=encoding) doc.SetModifiedFlag(0) return 1 |
From: <pyw...@li...> - 2011-04-24 06:27:49
|
changeset a5a35d18b1de in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=a5a35d18b1de summary: don't redirect stdin simply on a module import diffstat: Pythonwin/pywin/framework/app.py | 20 +++++++++++--------- 1 files changed, 11 insertions(+), 9 deletions(-) diffs (37 lines): diff -r 7f44ae5e7785 -r a5a35d18b1de Pythonwin/pywin/framework/app.py --- a/Pythonwin/pywin/framework/app.py Sun Apr 24 14:22:25 2011 +1000 +++ b/Pythonwin/pywin/framework/app.py Sun Apr 24 16:25:15 2011 +1000 @@ -124,6 +124,7 @@ def InitInstance(self): " Called to crank up the app " + HookInput() numMRU = win32ui.GetProfileVal("Settings","Recent File List Size", 10) win32ui.LoadStdProfileSettings(numMRU) # self._obj_.InitMDIInstance() @@ -373,15 +374,16 @@ "Provide input() for gui apps" return eval(raw_input(prompt)) -try: - raw_input - # must be py2x... - sys.modules['__builtin__'].raw_input=Win32RawInput - sys.modules['__builtin__'].input=Win32Input -except NameError: - # must be py3k - import code - sys.modules['builtins'].input=Win32RawInput +def HookInput(): + try: + raw_input + # must be py2x... + sys.modules['__builtin__'].raw_input=Win32RawInput + sys.modules['__builtin__'].input=Win32Input + except NameError: + # must be py3k + import code + sys.modules['builtins'].input=Win32RawInput def HaveGoodGUI(): """Returns true if we currently have a good gui available. |
From: <pyw...@li...> - 2011-04-24 04:23:46
|
changeset 6696da02c761 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=6696da02c761 summary: 3rd time lucky - do the right thing on py3k changeset 7f44ae5e7785 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=7f44ae5e7785 summary: Fix win32com.client.WithEvents() on py3k (bug 3199843) diffstat: CHANGES.txt | 2 ++ com/win32com/client/__init__.py | 7 +++++-- com/win32com/client/build.py | 6 ++++-- com/win32com/test/testPyComTest.py | 35 +++++++++++++++++++++-------------- 4 files changed, 32 insertions(+), 18 deletions(-) diffs (100 lines): diff -r 816b080c336b -r 7f44ae5e7785 CHANGES.txt --- a/CHANGES.txt Sun Apr 24 13:31:45 2011 +1000 +++ b/CHANGES.txt Sun Apr 24 14:22:25 2011 +1000 @@ -13,6 +13,8 @@ raised) and unsigned integers now allow for values with the high-bit set to be passed correctly. +* Fix win32com.client.WithEvents() on py3k. + * makepy may have generated syntax errors if 'helpstring' elements in typelibs had strange quoting or slashes (bug 3199631) diff -r 816b080c336b -r 7f44ae5e7785 com/win32com/client/__init__.py --- a/com/win32com/client/__init__.py Sun Apr 24 13:31:45 2011 +1000 +++ b/com/win32com/client/__init__.py Sun Apr 24 14:22:25 2011 +1000 @@ -317,11 +317,14 @@ clsid = disp_class.CLSID # Create a new class that derives from 2 classes - the event sink # class and the user class. - import new + try: + from types import ClassType as new_type + except ImportError: + new_type = type # py3k events_class = getevents(clsid) if events_class is None: raise ValueError("This COM object does not support events.") - result_class = new.classobj("COMEventClass", (events_class, user_event_class), {}) + result_class = new_type("COMEventClass", (events_class, user_event_class), {}) instance = result_class(disp) # This only calls the first base class __init__. if hasattr(user_event_class, "__init__"): user_event_class.__init__(instance) diff -r 816b080c336b -r 7f44ae5e7785 com/win32com/client/build.py --- a/com/win32com/client/build.py Sun Apr 24 13:31:45 2011 +1000 +++ b/com/win32com/client/build.py Sun Apr 24 14:22:25 2011 +1000 @@ -28,8 +28,10 @@ # It isn't really clear what the quoting rules are in a C/IDL string and # literals like a quote char and backslashes makes life a little painful to # always render the string perfectly - so just punt and fall-back to a repr() -def _makeDocString(s, encoding="mbcs"): - return repr(s.encode(encoding)) +def _makeDocString(s): + if sys.version_info < (3,): + s = s.encode("mbcs") + return repr(s) error = "PythonCOM.Client.Build error" class NotSupportedException(Exception): pass # Raised when we cant support a param type. diff -r 816b080c336b -r 7f44ae5e7785 com/win32com/test/testPyComTest.py --- a/com/win32com/test/testPyComTest.py Sun Apr 24 13:31:45 2011 +1000 +++ b/com/win32com/test/testPyComTest.py Sun Apr 24 14:22:25 2011 +1000 @@ -205,6 +205,22 @@ TestApplyResult(o.EarliestDate, (now, now), expect) +def TestEvents(o, handler): + sessions = [] + handler._Init() + try: + for i in range(3): + session = o.Start() + sessions.append(session) + time.sleep(.5) + finally: + # Stop the servers + for session in sessions: + o.Stop(session) + handler._DumpFireds() + handler.close() + + def TestGenerated(): # Create an instance of the server. from win32com.client.gencache import EnsureDispatch @@ -408,20 +424,11 @@ # Do the connection point thing... # Create a connection object. progress("Testing connection points") - sessions = [] - o = win32com.client.DispatchWithEvents( o, RandomEventHandler) - o._Init() - - try: - for i in range(3): - session = o.Start() - sessions.append(session) - time.sleep(.5) - finally: - # Stop the servers - for session in sessions: - o.Stop(session) - o._DumpFireds() + o2 = win32com.client.DispatchWithEvents(o, RandomEventHandler) + TestEvents(o2, o2) + # and a plain "WithEvents". + handler = win32com.client.WithEvents(o, RandomEventHandler) + TestEvents(o, handler) progress("Finished generated .py test.") def TestCounter(counter, bIsGenerated): |
From: <pyw...@li...> - 2011-04-24 03:33:07
|
changeset 816b080c336b in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=816b080c336b summary: fix encoding and comment from last checkin diffstat: com/win32com/client/build.py | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diffs (19 lines): diff -r 6859167bf2ab -r 816b080c336b com/win32com/client/build.py --- a/com/win32com/client/build.py Sat Apr 23 23:19:08 2011 +1000 +++ b/com/win32com/client/build.py Sun Apr 24 13:31:45 2011 +1000 @@ -25,11 +25,11 @@ import winerror import datetime -# A string ending with a quote can not be safely triple-quoted. (Indeed, we -# consider all things suspect (eg, \n chars, \t chars etc) - so just use -# repr! +# It isn't really clear what the quoting rules are in a C/IDL string and +# literals like a quote char and backslashes makes life a little painful to +# always render the string perfectly - so just punt and fall-back to a repr() def _makeDocString(s, encoding="mbcs"): - return repr(s.encode("mbcs")) + return repr(s.encode(encoding)) error = "PythonCOM.Client.Build error" class NotSupportedException(Exception): pass # Raised when we cant support a param type. |
From: <pyw...@li...> - 2011-04-23 13:20:15
|
changeset 6859167bf2ab in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=6859167bf2ab summary: avoid syntax errors if 'helpstring's had strange quoting/slashes (bug 3199631) diffstat: CHANGES.txt | 3 +++ com/TestSources/PyCOMTest/PyCOMTest.idl | 5 ++++- com/win32com/client/build.py | 13 +++++++------ com/win32com/client/genpy.py | 8 ++++---- 4 files changed, 18 insertions(+), 11 deletions(-) diffs (110 lines): diff -r 76aee4e897f0 -r 6859167bf2ab CHANGES.txt --- a/CHANGES.txt Sat Apr 23 22:51:20 2011 +1000 +++ b/CHANGES.txt Sat Apr 23 23:19:08 2011 +1000 @@ -13,6 +13,9 @@ raised) and unsigned integers now allow for values with the high-bit set to be passed correctly. +* makepy may have generated syntax errors if 'helpstring' elements in typelibs + had strange quoting or slashes (bug 3199631) + * Fixed that in some cases win32file.GetOpenFileName and GetSaveFileName could have returned trailing garbage after an embedded NULL character. (bug 3277647) diff -r 76aee4e897f0 -r 6859167bf2ab com/TestSources/PyCOMTest/PyCOMTest.idl --- a/com/TestSources/PyCOMTest/PyCOMTest.idl Sat Apr 23 22:51:20 2011 +1000 +++ b/com/TestSources/PyCOMTest/PyCOMTest.idl Sat Apr 23 23:19:08 2011 +1000 @@ -169,13 +169,16 @@ object, uuid(a0d9ceb0-5605-11d0-ae5f-cadd4c000000), dual, - helpstring("PyCOMTest Interface"), + helpstring("PyCOMTest Interface - with some fancy \tbackslash\chars\\"), pointer_default(unique) ] interface IPyCOMTest : IDispatch { import "oaidl.idl"; // Test simple alias. HCON is long. + [ + helpstring("docstring for Start - with some fancy \tslash chars\\") + ] HRESULT Start([out, retval] HCON * pnID); // Nested alaas - CONNECTID is HCON. HRESULT Stop([in] CONNECTID nID); diff -r 76aee4e897f0 -r 6859167bf2ab com/win32com/client/build.py --- a/com/win32com/client/build.py Sat Apr 23 22:51:20 2011 +1000 +++ b/com/win32com/client/build.py Sat Apr 23 23:19:08 2011 +1000 @@ -25,10 +25,11 @@ import winerror import datetime -# A string ending with a quote can not be safely triple-quoted. -def _safeQuotedString(s): - if s[-1]=='"': s = s[:-1]+'\\"' - return '"""%s"""' % s +# A string ending with a quote can not be safely triple-quoted. (Indeed, we +# consider all things suspect (eg, \n chars, \t chars etc) - so just use +# repr! +def _makeDocString(s, encoding="mbcs"): + return repr(s.encode("mbcs")) error = "PythonCOM.Client.Build error" class NotSupportedException(Exception): pass # Raised when we cant support a param type. @@ -318,7 +319,7 @@ s = linePrefix + 'def ' + name + '(self' + BuildCallList(fdesc, names, defNamedOptArg, defNamedNotOptArg, defUnnamedArg, defOutArg) + '):' ret.append(s) if doc and doc[1]: - ret.append(linePrefix + '\t' + _safeQuotedString(doc[1])) + ret.append(linePrefix + '\t' + _makeDocString(doc[1])) # print "fdesc is ", fdesc @@ -374,7 +375,7 @@ else: linePrefix = "" ret.append(linePrefix + 'def ' + name + '(' + argPrefix + ', *args):') - if doc and doc[1]: ret.append(linePrefix + '\t' + _safeQuotedString(doc[1])) + if doc and doc[1]: ret.append(linePrefix + '\t' + _makeDocString(doc[1])) if fdesc: invoketype = fdesc[4] else: diff -r 76aee4e897f0 -r 6859167bf2ab com/win32com/client/genpy.py --- a/com/win32com/client/genpy.py Sat Apr 23 22:51:20 2011 +1000 +++ b/com/win32com/client/genpy.py Sat Apr 23 23:19:08 2011 +1000 @@ -288,7 +288,7 @@ doc = self.doc stream = generator.file print >> stream, 'class ' + self.python_name + '(DispatchBaseClass):' - if doc[1]: print >> stream, '\t' + build._safeQuotedString(doc[1]) + if doc[1]: print >> stream, '\t' + build._makeDocString(doc[1]) try: progId = pythoncom.ProgIDFromCLSID(self.clsid) print >> stream, "\t# This class is creatable by the name '%s'" % (progId) @@ -307,7 +307,7 @@ doc = self.doc stream = generator.file print >> stream, 'class ' + self.python_name + ':' - if doc[1]: print >> stream, '\t' + build._safeQuotedString(doc[1]) + if doc[1]: print >> stream, '\t' + build._makeDocString(doc[1]) try: progId = pythoncom.ProgIDFromCLSID(self.clsid) print >> stream, "\t# This class is creatable by the name '%s'" % (progId) @@ -355,7 +355,7 @@ methName = MakeEventMethodName(entry.names[0]) print >> stream, '#\tdef ' + methName + '(self' + build.BuildCallList(fdesc, entry.names, "defaultNamedOptArg", "defaultNamedNotOptArg","defaultUnnamedArg", "pythoncom.Missing", is_comment = True) + '):' if entry.doc and entry.doc[1]: - print >> stream, '#\t\t' + build._safeQuotedString(entry.doc[1]) + print >> stream, '#\t\t' + build._makeDocString(entry.doc[1]) print >> stream self.bWritten = 1 @@ -828,7 +828,7 @@ print >> self.file, "# From type library '%s'" % (os.path.split(self.sourceFilename)[1],) print >> self.file, '# On %s' % time.ctime(time.time()) - print >> self.file, '"""' + docDesc + '"""' + print >> self.file, build._makeDocString(docDesc) print >> self.file, 'makepy_version =', repr(makepy_version) print >> self.file, 'python_version = 0x%x' % (sys.hexversion,) |
From: <pyw...@li...> - 2011-04-23 12:52:19
|
changeset 76aee4e897f0 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=76aee4e897f0 summary: bump makepy version for INT->UINT changes diffstat: com/win32com/client/genpy.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 62ea09011278 -r 76aee4e897f0 com/win32com/client/genpy.py --- a/com/win32com/client/genpy.py Sat Apr 23 22:40:29 2011 +1000 +++ b/com/win32com/client/genpy.py Sat Apr 23 22:51:20 2011 +1000 @@ -22,7 +22,7 @@ import build error = "makepy.error" -makepy_version = "0.5.00" # Written to generated file. +makepy_version = "0.5.01" # Written to generated file. GEN_FULL="full" GEN_DEMAND_BASE = "demand(base)" |
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) |
From: <pyw...@li...> - 2011-04-14 04:56:08
|
changeset bd629535294b in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=bd629535294b summary: force SWIG generated wrappers to be rebuilt if any SWIG .i files changed changeset cdbcf976e498 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=cdbcf976e498 summary: fix DWORD handling of 32bit longs with the MSB set diffstat: CHANGES.txt | 3 +++ SWIG/swig_lib/python/pywintypes.i | 10 ++++++++++ setup.py | 18 ++++++++++++++---- 3 files changed, 27 insertions(+), 4 deletions(-) diffs (82 lines): diff -r 945ffb215e08 -r cdbcf976e498 CHANGES.txt --- a/CHANGES.txt Mon Apr 11 14:26:48 2011 +1000 +++ b/CHANGES.txt Thu Apr 14 14:54:45 2011 +1000 @@ -11,6 +11,9 @@ could have returned trailing garbage after an embedded NULL character. (bug 3277647) +* Some functions which accepted a DWORD did not accept long integers which + fit in 32bits with the most signficant bit set (eg, 0x80000000). + * Source-code management moved from CVS to Mercurual. Since build 215: diff -r 945ffb215e08 -r cdbcf976e498 SWIG/swig_lib/python/pywintypes.i --- a/SWIG/swig_lib/python/pywintypes.i Mon Apr 11 14:26:48 2011 +1000 +++ b/SWIG/swig_lib/python/pywintypes.i Thu Apr 14 14:54:45 2011 +1000 @@ -44,6 +44,16 @@ #include "tchar.h" %} +// DWORDs can use longs so long as they fit in 32 unsigned bits +%typemap(python,in) DWORD { + // PyLong_AsUnsignedLongMask isn't ideal - no overflow checking - but + // this is what the 'k' format specifier in PyArg_ParseTuple uses, and + // that is what much of pywin32 uses for DWORDS, so we use it here too + $target = PyLong_AsUnsignedLongMask($source); + if ($target==(DWORD)-1 && PyErr_Occurred()) + return NULL; +} + // Override the SWIG default for this. %typemap(python,out) PyObject *{ if ($source==NULL) return NULL; // get out now! diff -r 945ffb215e08 -r cdbcf976e498 setup.py --- a/setup.py Mon Apr 11 14:26:48 2011 +1000 +++ b/setup.py Thu Apr 14 14:54:45 2011 +1000 @@ -1196,6 +1196,17 @@ ext.finalize_options(self) + # ensure the SWIG .i files are treated as dependencies. + for source in ext.sources: + if source.endswith(".i"): + self.find_swig() # for the side-effect of the environment value. + # Find the swig_lib .i files we care about for dependency tracking. + ext.swig_deps = glob.glob(os.path.join(os.environ["SWIG_LIB"], "python", "*.i")) + ext.depends.extend(ext.swig_deps) + break + else: + ext.swig_deps = None + # some source files are compiled for different extensions # with special defines. So we cannot use a shared # directory for objects, we must use a special one for each extension. @@ -1311,8 +1322,8 @@ # to the temp dir... target_ext = '.cpp' for source in sources: - (base, ext) = os.path.splitext(source) - if ext == ".i": # SWIG interface file + (base, sext) = os.path.splitext(source) + if sext == ".i": # SWIG interface file if os.path.split(base)[1] in swig_include_files: continue swig_sources.append(source) @@ -1340,7 +1351,6 @@ return new_sources swig = self.find_swig() - for source in swig_sources: swig_cmd = [swig, "-python", "-c++"] swig_cmd.append("-dnone",) # we never use the .doc files. @@ -1372,7 +1382,7 @@ # This could probably go once we generate .cpp into the temp dir. fqsource = os.path.abspath(source) fqtarget = os.path.abspath(target) - rebuild = self.force or newer(fqsource, fqtarget) + rebuild = self.force or newer_group(ext.swig_deps + [fqsource], fqtarget) log.debug("should swig %s->%s=%s", source, target, rebuild) if rebuild: swig_cmd.extend(["-o", fqtarget, fqsource]) |
From: <pyw...@li...> - 2011-04-11 04:27:57
|
changeset 945ffb215e08 in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=945ffb215e08 summary: add new FILE_ATTRIBUTE_* constants diffstat: win32/Lib/win32con.py | 12 +++++++++++- 1 files changed, 11 insertions(+), 1 deletions(-) diffs (26 lines): diff -r f3fdaae5e93d -r 945ffb215e08 win32/Lib/win32con.py --- a/win32/Lib/win32con.py Sun Apr 10 01:36:40 2011 -0700 +++ b/win32/Lib/win32con.py Mon Apr 11 14:26:48 2011 +1000 @@ -2129,11 +2129,21 @@ FILE_ATTRIBUTE_SYSTEM = 4 FILE_ATTRIBUTE_DIRECTORY = 16 FILE_ATTRIBUTE_ARCHIVE = 32 +FILE_ATTRIBUTE_DEVICE = 64 FILE_ATTRIBUTE_NORMAL = 128 FILE_ATTRIBUTE_TEMPORARY = 256 +FILE_ATTRIBUTE_SPARSE_FILE = 512 +FILE_ATTRIBUTE_REPARSE_POINT = 1024 +FILE_ATTRIBUTE_COMPRESSED = 2048 +FILE_ATTRIBUTE_OFFLINE = 4096 +FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 8192 +FILE_ATTRIBUTE_ENCRYPTED = 16384 +FILE_ATTRIBUTE_VIRTUAL = 65536 +# These FILE_ATTRIBUTE_* flags are apparently old definitions from Windows 95 +# and conflict with current values above - but they live on for b/w compat... FILE_ATTRIBUTE_ATOMIC_WRITE = 512 FILE_ATTRIBUTE_XACTION_WRITE = 1024 -FILE_ATTRIBUTE_COMPRESSED = 2048 + FILE_NOTIFY_CHANGE_FILE_NAME = 1 FILE_NOTIFY_CHANGE_DIR_NAME = 2 FILE_NOTIFY_CHANGE_ATTRIBUTES = 4 |
From: <pyw...@li...> - 2011-04-10 08:36:46
|
changeset f3fdaae5e93d in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=f3fdaae5e93d summary: fix \0 termination of the result filename buffer diffstat: CHANGES.txt | 4 ++++ win32/src/win32gui.i | 30 +++++++++++++++++++----------- 2 files changed, 23 insertions(+), 11 deletions(-) diffs (77 lines): diff -r 867f11320a2c -r f3fdaae5e93d CHANGES.txt --- a/CHANGES.txt Fri Apr 08 09:39:23 2011 -0700 +++ b/CHANGES.txt Sun Apr 10 01:36:40 2011 -0700 @@ -7,6 +7,10 @@ Since build 216: ---------------- +* Fixed that in some cases win32file.GetOpenFileName and GetSaveFileName + could have returned trailing garbage after an embedded NULL character. + (bug 3277647) + * Source-code management moved from CVS to Mercurual. Since build 215: diff -r 867f11320a2c -r f3fdaae5e93d win32/src/win32gui.i --- a/win32/src/win32gui.i Fri Apr 08 09:39:23 2011 -0700 +++ b/win32/src/win32gui.i Sun Apr 10 01:36:40 2011 -0700 @@ -4573,7 +4573,9 @@ // @pyswig int|GetOpenFileName|Creates an Open dialog box that lets the user specify the drive, directory, and the name of a file or set of files to open. -// @rdesc If the user presses OK, the function returns TRUE. Otherwise, use CommDlgExtendedError for error details. +// @comm The <om win32gui.GetOpenFileNameW> function is far more convenient to use. +// @rdesc If the user presses OK, the function returns TRUE. Otherwise, use CommDlgExtendedError for error details +// (ie, a win32gui.error is raised). If the user cancels the dialog, the winerror attribute of the exception will be zero. // @pyparm string/bytes|OPENFILENAME||A string packed into an OPENFILENAME structure, probably via the struct module. BOOL GetOpenFileName(OPENFILENAME *INPUT); @@ -6224,12 +6226,16 @@ PyObject *PyReturn_OPENFILENAMEW_Output(OPENFILENAMEW *pofn) { DWORD filechars, filterchars; - // there is no returned length, and lpstrFile can contain NULL's if multiple files are selected - // Walk the string backwards until a non-NULL is found - for (filechars=pofn->nMaxFile; filechars>0; filechars--) - if (pofn->lpstrFile[filechars-1]!=0) - break; - + // If OFN_ALLOWMULTISELECT is set, the terminator is 2 NULLs, + // otherwise a single NULL. + if (pofn->Flags & OFN_ALLOWMULTISELECT) { + for (filechars=0; + filechars < pofn->nMaxFile-1 && !(pofn->lpstrFile[filechars]==0 && pofn->lpstrFile[filechars+1]==0); + filechars++) + ; + } else { + filechars = wcslen(pofn->lpstrFile); + } if (pofn->lpstrCustomFilter==NULL) return Py_BuildValue("NOk", PyWinObject_FromWCHAR(pofn->lpstrFile, filechars), @@ -6256,9 +6262,14 @@ // @comm Accepts keyword arguments, all arguments optional // @rdesc Returns a tuple of 3 values (<o PyUNICODE>, <o PyUNICODE>, int):<nl> // First is the selected file(s). If multiple files are selected, returned string will be the directory followed by files names -// separated by nulls, otherwise it will be the full path.<nl> +// separated by nulls, otherwise it will be the full path. In other words, if you use the OFN_ALLOWMULTISELECT flag +// you should split this value on \0 characters and if the length of the result list is 1, it will be +// the full path, otherwise element 0 will be the directory and the rest of the elements will be filenames in +// this directory.<nl> // Second is a unicode string containing user-selected filter, will be None if CustomFilter was not specified<nl> // Third item contains flags pertaining to users input, such as OFN_READONLY and OFN_EXTENSIONDIFFERENT +// <nl>If the user presses cancel or an error occurs, a +// win32gui.error is raised. If the user pressed cancel, the error number (ie, the winerror attribute of the exception) will be zero. // @pyparm <o PyHANDLE>|hwndOwner|None|Handle to window that owns dialog // @pyparm <o PyHANDLE>|hInstance|None|Handle to module that contains dialog template // @pyparm <o PyUNICODE>|Filter|None|Contains pairs of descriptions and filespecs separated by NULLS, with a final trailing NULL. @@ -6296,9 +6307,6 @@ // @pyswig (<o PyUNICODE>,<o PyUNICODE>, int)|GetOpenFileNameW|Creates a dialog to allow user to select file(s) to open // @comm Accepts keyword arguments, all arguments optional // Input parameters and return values are identical to <om win32gui.GetSaveFileNameW> -// @rdesc The result is a tuple of (filename, filter, flags), where the first 2 elements are -// unicode strings, and the last an integer. If the user presses cancel or an error occurs, a -// win32gui.error is raised (and if the user pressed cancel, the error number will be zero) static PyObject *PyGetOpenFileNameW(PyObject *self, PyObject *args, PyObject *kwargs) { PyObject *ret=NULL; |
From: <pyw...@li...> - 2011-04-08 16:39:34
|
changeset 867f11320a2c in /hgrepo/p/py/pywin32/pywin32 details: http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/hgrepo/p/py/pywin32/pywin32?cmd=changeset;node=867f11320a2c summary: clarify error message loading dde module diffstat: Pythonwin/ddemodule.cpp | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r e4fd5f1a855c -r 867f11320a2c Pythonwin/ddemodule.cpp --- a/Pythonwin/ddemodule.cpp Thu Mar 31 12:13:43 2011 +1100 +++ b/Pythonwin/ddemodule.cpp Fri Apr 08 09:39:23 2011 -0700 @@ -165,7 +165,7 @@ PYWIN_MODULE_INIT_FUNC(dde) { if (AfxGetApp()==NULL) { - PyErr_SetString(PyExc_ImportError, "This must be an MFC application - try loading win32ui first"); + PyErr_SetString(PyExc_ImportError, "This must be an MFC application - try 'import win32ui' first"); PYWIN_MODULE_INIT_RETURN_ERROR; } PYWIN_MODULE_INIT_PREPARE(dde, dde_functions, |