comtypes 1.1.0__zip → 1.1.3__zip
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- comtypes-1.1.3/CHANGES.txt +1061 -0
- comtypes-1.1.3/LICENSE.txt +24 -0
- comtypes-1.1.3/MANIFEST.in +1 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/PKG-INFO +1 -1
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/__init__.py +7 -2
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/_comobject.py +112 -74
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/automation.py +5 -1
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/client/_code_cache.py +1 -1
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/npsupport.py +20 -15
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/patcher.py +26 -2
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/safearray.py +6 -10
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/TestComServer.py +3 -4
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_variant.py +5 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/tools/codegenerator.py +8 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/typeinfo.py +6 -1
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes.egg-info/PKG-INFO +1 -1
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes.egg-info/SOURCES.txt +3 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/README +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/clear_comtypes_cache.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/GUID.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/_meta.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/_safearray.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/client/__init__.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/client/_events.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/client/_generate.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/client/dynamic.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/client/lazybind.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/connectionpoints.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/errorinfo.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/git.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/hresult.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/logutil.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/messageloop.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/persist.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/server/__init__.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/server/automation.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/server/connectionpoints.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/server/inprocserver.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/server/localserver.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/server/register.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/server/w_getopt.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/shelllink.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/TestComServer.idl +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/TestComServer.tlb +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/TestDispServer.idl +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/TestDispServer.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/TestDispServer.tlb +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/__init__.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/find_memleak.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/mylib.idl +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/mytypelib.idl +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/runtests.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/setup.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_BSTR.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_DISPPARAMS.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_GUID.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_QueryService.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_agilent.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_avmc.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_basic.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_casesensitivity.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_client.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_collections.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_comserver.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_createwrappers.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_dict.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_dispinterface.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_dyndispatch.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_excel.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_findgendir.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_getactiveobj.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_ie.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_jscript.js +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_msscript.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_outparam.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_propputref.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_pump_events.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_safearray.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_sapi.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_server.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_showevents.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_subinterface.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_typeinfo.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_urlhistory.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_win32com_interop.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_wmi.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/test/test_word.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/tools/__init__.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/tools/tlbparser.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/tools/typedesc.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/tools/typedesc_base.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/util.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes/viewobject.py +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes.egg-info/dependency_links.txt +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/comtypes.egg-info/top_level.txt +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/setup.cfg +0 -0
- {comtypes-1.1.0 → comtypes-1.1.3}/setup.py +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
This software is OSI Certified Open Source Software.
|
|
2
|
+
OSI Certified is a certification mark of the Open Source Initiative.
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2006-2013, Thomas Heller.
|
|
5
|
+
Copyright (c) 2014, Comtypes Developers.
|
|
6
|
+
All rights reserved.
|
|
7
|
+
|
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
10
|
+
in the Software without restriction, including without limitation the rights
|
|
11
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
furnished to do so, subject to the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be included in
|
|
16
|
+
all copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
24
|
+
THE SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
include *.txt
|
|
@@ -2,8 +2,8 @@ import types
|
|
|
2
2
|
import sys
|
|
3
3
|
import os
|
|
4
4
|
|
|
5
|
-
# comtypes version numbers follow semver (http://semver.org/)
|
|
6
|
-
__version__ = "1.1.
|
|
5
|
+
# comtypes version numbers follow semver (http://semver.org/) and PEP 440
|
|
6
|
+
__version__ = "1.1.3"
|
|
7
7
|
|
|
8
8
|
import logging
|
|
9
9
|
class NullHandler(logging.Handler):
|
|
@@ -653,6 +653,11 @@ class _cominterface_meta(type):
|
|
|
653
653
|
outnum += 1
|
|
654
654
|
|
|
655
655
|
rescode = func(self_, *args, **kw)
|
|
656
|
+
# If there is only a single output value, then do not expect it to
|
|
657
|
+
# be iterable.
|
|
658
|
+
if len(outargs) == 1: # rescode is not iterable
|
|
659
|
+
return rescode.__ctypes_from_outparam__()
|
|
660
|
+
|
|
656
661
|
rescode = list(rescode)
|
|
657
662
|
for outnum, o in outargs.items():
|
|
658
663
|
rescode[outnum] = o.__ctypes_from_outparam__()
|
|
@@ -1,8 +1,21 @@
|
|
|
1
|
-
from ctypes import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
from ctypes import (
|
|
2
|
+
FormatError, POINTER, Structure, WINFUNCTYPE, byref, c_long, c_void_p,
|
|
3
|
+
oledll, pointer, windll
|
|
4
|
+
)
|
|
5
|
+
from _ctypes import CopyComPointer
|
|
5
6
|
import logging
|
|
7
|
+
import os
|
|
8
|
+
|
|
9
|
+
from comtypes import COMError, ReturnHRESULT, instancemethod, _encode_idl
|
|
10
|
+
from comtypes.errorinfo import ISupportErrorInfo, ReportException, ReportError
|
|
11
|
+
from comtypes import IPersist
|
|
12
|
+
from comtypes.hresult import (
|
|
13
|
+
DISP_E_BADINDEX, DISP_E_MEMBERNOTFOUND, E_FAIL, E_NOINTERFACE,
|
|
14
|
+
E_INVALIDARG, E_NOTIMPL, RPC_E_CHANGED_MODE, S_FALSE, S_OK
|
|
15
|
+
)
|
|
16
|
+
from comtypes.typeinfo import IProvideClassInfo, IProvideClassInfo2
|
|
17
|
+
|
|
18
|
+
|
|
6
19
|
logger = logging.getLogger(__name__)
|
|
7
20
|
_debug = logger.debug
|
|
8
21
|
_warning = logger.warning
|
|
@@ -10,12 +23,6 @@ _error = logger.error
|
|
|
10
23
|
|
|
11
24
|
################################################################
|
|
12
25
|
# COM object implementation
|
|
13
|
-
from _ctypes import CopyComPointer
|
|
14
|
-
|
|
15
|
-
from comtypes import COMError, ReturnHRESULT, instancemethod, _encode_idl
|
|
16
|
-
from comtypes.errorinfo import ISupportErrorInfo, ReportException, ReportError
|
|
17
|
-
from comtypes.typeinfo import IProvideClassInfo, IProvideClassInfo2
|
|
18
|
-
from comtypes import IPersist
|
|
19
26
|
|
|
20
27
|
# so we don't have to import comtypes.automation
|
|
21
28
|
DISPATCH_METHOD = 1
|
|
@@ -23,9 +30,11 @@ DISPATCH_PROPERTYGET = 2
|
|
|
23
30
|
DISPATCH_PROPERTYPUT = 4
|
|
24
31
|
DISPATCH_PROPERTYPUTREF = 8
|
|
25
32
|
|
|
33
|
+
|
|
26
34
|
class E_NotImplemented(Exception):
|
|
27
35
|
"""COM method is not implemented"""
|
|
28
36
|
|
|
37
|
+
|
|
29
38
|
def HRESULT_FROM_WIN32(errcode):
|
|
30
39
|
"Convert a Windows error code into a HRESULT value."
|
|
31
40
|
if errcode is None:
|
|
@@ -34,6 +43,7 @@ def HRESULT_FROM_WIN32(errcode):
|
|
|
34
43
|
return errcode
|
|
35
44
|
return (errcode & 0xFFFF) | 0x80070000
|
|
36
45
|
|
|
46
|
+
|
|
37
47
|
def winerror(exc):
|
|
38
48
|
"""Return the windows error code from a WindowsError or COMError
|
|
39
49
|
instance."""
|
|
@@ -48,34 +58,42 @@ def winerror(exc):
|
|
|
48
58
|
# cases we return a generic error code.
|
|
49
59
|
return E_FAIL
|
|
50
60
|
|
|
61
|
+
|
|
51
62
|
def _do_implement(interface_name, method_name):
|
|
52
63
|
def _not_implemented(*args):
|
|
53
64
|
"""Return E_NOTIMPL because the method is not implemented."""
|
|
54
|
-
_debug("unimplemented method %s_%s called", interface_name,
|
|
65
|
+
_debug("unimplemented method %s_%s called", interface_name,
|
|
66
|
+
method_name)
|
|
55
67
|
return E_NOTIMPL
|
|
56
68
|
return _not_implemented
|
|
57
69
|
|
|
70
|
+
|
|
58
71
|
def catch_errors(obj, mth, paramflags, interface, mthname):
|
|
59
72
|
clsid = getattr(obj, "_reg_clsid_", None)
|
|
73
|
+
|
|
60
74
|
def call_with_this(*args, **kw):
|
|
61
75
|
try:
|
|
62
76
|
result = mth(*args, **kw)
|
|
63
77
|
except ReturnHRESULT, err:
|
|
64
78
|
(hresult, text) = err.args
|
|
65
|
-
return ReportError(text, iid=interface._iid_, clsid=clsid,
|
|
79
|
+
return ReportError(text, iid=interface._iid_, clsid=clsid,
|
|
80
|
+
hresult=hresult)
|
|
66
81
|
except (COMError, WindowsError), details:
|
|
67
|
-
_error("Exception in %s.%s implementation:", interface.__name__,
|
|
82
|
+
_error("Exception in %s.%s implementation:", interface.__name__,
|
|
83
|
+
mthname, exc_info=True)
|
|
68
84
|
return HRESULT_FROM_WIN32(winerror(details))
|
|
69
85
|
except E_NotImplemented:
|
|
70
|
-
_warning("Unimplemented method %s.%s called", interface.__name__,
|
|
86
|
+
_warning("Unimplemented method %s.%s called", interface.__name__,
|
|
87
|
+
mthname)
|
|
71
88
|
return E_NOTIMPL
|
|
72
89
|
except:
|
|
73
|
-
_error("Exception in %s.%s implementation:", interface.__name__,
|
|
90
|
+
_error("Exception in %s.%s implementation:", interface.__name__,
|
|
91
|
+
mthname, exc_info=True)
|
|
74
92
|
return ReportException(E_FAIL, interface._iid_, clsid=clsid)
|
|
75
93
|
if result is None:
|
|
76
94
|
return S_OK
|
|
77
95
|
return result
|
|
78
|
-
if paramflags
|
|
96
|
+
if paramflags is None:
|
|
79
97
|
has_outargs = False
|
|
80
98
|
else:
|
|
81
99
|
has_outargs = bool([x[0] for x in paramflags
|
|
@@ -83,6 +101,7 @@ def catch_errors(obj, mth, paramflags, interface, mthname):
|
|
|
83
101
|
call_with_this.has_outargs = has_outargs
|
|
84
102
|
return call_with_this
|
|
85
103
|
|
|
104
|
+
|
|
86
105
|
################################################################
|
|
87
106
|
|
|
88
107
|
def hack(inst, mth, paramflags, interface, mthname):
|
|
@@ -97,9 +116,9 @@ def hack(inst, mth, paramflags, interface, mthname):
|
|
|
97
116
|
# direction flag is either exactly '0' or has the '1' bit set:
|
|
98
117
|
# Output arguments have flag '2'
|
|
99
118
|
|
|
100
|
-
args_out_idx=[]
|
|
101
|
-
args_in_idx=[]
|
|
102
|
-
for i,a in enumerate(dirflags):
|
|
119
|
+
args_out_idx = []
|
|
120
|
+
args_in_idx = []
|
|
121
|
+
for i, a in enumerate(dirflags):
|
|
103
122
|
if a&2:
|
|
104
123
|
args_out_idx.append(i)
|
|
105
124
|
if a&1 or a==0:
|
|
@@ -111,6 +130,7 @@ def hack(inst, mth, paramflags, interface, mthname):
|
|
|
111
130
|
## return catch_errors(inst, mth, interface, mthname)
|
|
112
131
|
|
|
113
132
|
clsid = getattr(inst, "_reg_clsid_", None)
|
|
133
|
+
|
|
114
134
|
def call_without_this(this, *args):
|
|
115
135
|
# Method implementations could check for and return E_POINTER
|
|
116
136
|
# themselves. Or an error will be raised when
|
|
@@ -120,7 +140,7 @@ def hack(inst, mth, paramflags, interface, mthname):
|
|
|
120
140
|
## return E_POINTER
|
|
121
141
|
|
|
122
142
|
#make argument list for handler by index array built above
|
|
123
|
-
inargs=[]
|
|
143
|
+
inargs = []
|
|
124
144
|
for a in args_in_idx:
|
|
125
145
|
inargs.append(args[a])
|
|
126
146
|
try:
|
|
@@ -129,15 +149,18 @@ def hack(inst, mth, paramflags, interface, mthname):
|
|
|
129
149
|
args[args_out_idx[0]][0] = result
|
|
130
150
|
elif args_out != 0:
|
|
131
151
|
if len(result) != args_out:
|
|
132
|
-
|
|
152
|
+
msg = "Method should have returned a %s-tuple" % args_out
|
|
153
|
+
raise ValueError(msg)
|
|
133
154
|
for i, value in enumerate(result):
|
|
134
155
|
args[args_out_idx[i]][0] = value
|
|
135
156
|
except ReturnHRESULT, err:
|
|
136
157
|
(hresult, text) = err.args
|
|
137
|
-
return ReportError(text, iid=interface._iid_, clsid=clsid,
|
|
158
|
+
return ReportError(text, iid=interface._iid_, clsid=clsid,
|
|
159
|
+
hresult=hresult)
|
|
138
160
|
except COMError, err:
|
|
139
161
|
(hr, text, details) = err.args
|
|
140
|
-
_error("Exception in %s.%s implementation:", interface.__name__,
|
|
162
|
+
_error("Exception in %s.%s implementation:", interface.__name__,
|
|
163
|
+
mthname, exc_info=True)
|
|
141
164
|
try:
|
|
142
165
|
descr, source, helpfile, helpcontext, progid = details
|
|
143
166
|
except (ValueError, TypeError):
|
|
@@ -145,22 +168,27 @@ def hack(inst, mth, paramflags, interface, mthname):
|
|
|
145
168
|
else:
|
|
146
169
|
msg = "%s: %s" % (source, descr)
|
|
147
170
|
hr = HRESULT_FROM_WIN32(hr)
|
|
148
|
-
return ReportError(msg, iid=interface._iid_, clsid=clsid,
|
|
171
|
+
return ReportError(msg, iid=interface._iid_, clsid=clsid,
|
|
172
|
+
hresult=hr)
|
|
149
173
|
except WindowsError, details:
|
|
150
|
-
_error("Exception in %s.%s implementation:", interface.__name__,
|
|
174
|
+
_error("Exception in %s.%s implementation:", interface.__name__,
|
|
175
|
+
mthname, exc_info=True)
|
|
151
176
|
hr = HRESULT_FROM_WIN32(winerror(details))
|
|
152
177
|
return ReportException(hr, interface._iid_, clsid=clsid)
|
|
153
178
|
except E_NotImplemented:
|
|
154
|
-
_warning("Unimplemented method %s.%s called", interface.__name__,
|
|
179
|
+
_warning("Unimplemented method %s.%s called", interface.__name__,
|
|
180
|
+
mthname)
|
|
155
181
|
return E_NOTIMPL
|
|
156
182
|
except:
|
|
157
|
-
_error("Exception in %s.%s implementation:", interface.__name__,
|
|
183
|
+
_error("Exception in %s.%s implementation:", interface.__name__,
|
|
184
|
+
mthname, exc_info=True)
|
|
158
185
|
return ReportException(E_FAIL, interface._iid_, clsid=clsid)
|
|
159
186
|
return S_OK
|
|
160
187
|
if args_out:
|
|
161
188
|
call_without_this.has_outargs = True
|
|
162
189
|
return call_without_this
|
|
163
190
|
|
|
191
|
+
|
|
164
192
|
class _MethodFinder(object):
|
|
165
193
|
def __init__(self, inst):
|
|
166
194
|
self.inst = inst
|
|
@@ -195,7 +223,7 @@ class _MethodFinder(object):
|
|
|
195
223
|
return self.find_method(fq_name, mthname)
|
|
196
224
|
except AttributeError:
|
|
197
225
|
pass
|
|
198
|
-
propname = mthname[5:]
|
|
226
|
+
propname = mthname[5:] # strip the '_get_' or '_set' prefix
|
|
199
227
|
if interface._case_insensitive_:
|
|
200
228
|
propname = self.names.get(propname.lower(), propname)
|
|
201
229
|
# propput and propget is done with 'normal' attribute access,
|
|
@@ -206,7 +234,8 @@ class _MethodFinder(object):
|
|
|
206
234
|
return self.getter(propname)
|
|
207
235
|
if "propput" in idlflags and len(paramflags) == 1:
|
|
208
236
|
return self.setter(propname)
|
|
209
|
-
_debug("%r: %s.%s not implemented", self.inst, interface.__name__,
|
|
237
|
+
_debug("%r: %s.%s not implemented", self.inst, interface.__name__,
|
|
238
|
+
mthname)
|
|
210
239
|
return None
|
|
211
240
|
|
|
212
241
|
def setter(self, propname):
|
|
@@ -221,7 +250,6 @@ class _MethodFinder(object):
|
|
|
221
250
|
return instancemethod(set, self.inst, type(self.inst))
|
|
222
251
|
|
|
223
252
|
def getter(self, propname):
|
|
224
|
-
#
|
|
225
253
|
def get(self):
|
|
226
254
|
try:
|
|
227
255
|
return getattr(self, propname)
|
|
@@ -229,6 +257,7 @@ class _MethodFinder(object):
|
|
|
229
257
|
raise E_NotImplemented()
|
|
230
258
|
return instancemethod(get, self.inst, type(self.inst))
|
|
231
259
|
|
|
260
|
+
|
|
232
261
|
def _create_vtbl_type(fields, itf):
|
|
233
262
|
try:
|
|
234
263
|
return _vtbl_types[fields]
|
|
@@ -257,12 +286,14 @@ except AttributeError:
|
|
|
257
286
|
_acquire = _lock.acquire
|
|
258
287
|
_release = _lock.release
|
|
259
288
|
# win 64 doesn't have these functions
|
|
289
|
+
|
|
260
290
|
def _InterlockedIncrement(ob):
|
|
261
291
|
_acquire()
|
|
262
292
|
refcnt = ob.value + 1
|
|
263
293
|
ob.value = refcnt
|
|
264
294
|
_release()
|
|
265
295
|
return refcnt
|
|
296
|
+
|
|
266
297
|
def _InterlockedDecrement(ob):
|
|
267
298
|
_acquire()
|
|
268
299
|
refcnt = ob.value - 1
|
|
@@ -275,9 +306,11 @@ else:
|
|
|
275
306
|
_InterlockedIncrement.restype = c_long
|
|
276
307
|
_InterlockedDecrement.restype = c_long
|
|
277
308
|
|
|
309
|
+
|
|
278
310
|
class LocalServer(object):
|
|
279
311
|
|
|
280
312
|
_queue = None
|
|
313
|
+
|
|
281
314
|
def run(self, classobjects):
|
|
282
315
|
# Use windll instead of oledll so that we don't get an
|
|
283
316
|
# exception on a FAILED hresult:
|
|
@@ -290,7 +323,8 @@ class LocalServer(object):
|
|
|
290
323
|
# we're running in STA: need a message pump
|
|
291
324
|
_debug("Server running in STA")
|
|
292
325
|
if result >= 0:
|
|
293
|
-
# we need a matching CoUninitialize() call for a successful
|
|
326
|
+
# we need a matching CoUninitialize() call for a successful
|
|
327
|
+
# CoInitialize().
|
|
294
328
|
windll.ole32.CoUninitialize()
|
|
295
329
|
self.run_sta()
|
|
296
330
|
|
|
@@ -317,6 +351,7 @@ class LocalServer(object):
|
|
|
317
351
|
else:
|
|
318
352
|
windll.user32.PostQuitMessage(0)
|
|
319
353
|
|
|
354
|
+
|
|
320
355
|
class InprocServer(object):
|
|
321
356
|
|
|
322
357
|
def __init__(self):
|
|
@@ -335,6 +370,7 @@ class InprocServer(object):
|
|
|
335
370
|
return S_FALSE
|
|
336
371
|
return S_OK
|
|
337
372
|
|
|
373
|
+
|
|
338
374
|
class COMObject(object):
|
|
339
375
|
_instances_ = {}
|
|
340
376
|
|
|
@@ -364,7 +400,8 @@ class COMObject(object):
|
|
|
364
400
|
# - ISupportErrorInfo
|
|
365
401
|
# - IPersist (if the subclass has a _reg_clsid_ attribute)
|
|
366
402
|
# - IProvideClassInfo (if the subclass has a _reg_clsid_ attribute)
|
|
367
|
-
# - IProvideClassInfo2 (if the subclass has a _outgoing_interfaces_
|
|
403
|
+
# - IProvideClassInfo2 (if the subclass has a _outgoing_interfaces_
|
|
404
|
+
# attribute)
|
|
368
405
|
#
|
|
369
406
|
# Add these if they are not listed in _com_interfaces_.
|
|
370
407
|
interfaces = tuple(self._com_interfaces_)
|
|
@@ -386,9 +423,9 @@ class COMObject(object):
|
|
|
386
423
|
self.__make_interface_pointer(itf)
|
|
387
424
|
|
|
388
425
|
def __make_interface_pointer(self, itf):
|
|
389
|
-
methods = []
|
|
390
|
-
fields = []
|
|
391
|
-
iids = []
|
|
426
|
+
methods = [] # method implementations
|
|
427
|
+
fields = [] # (name, prototype) for virtual function table
|
|
428
|
+
iids = [] # interface identifiers.
|
|
392
429
|
# iterate over interface inheritance in reverse order to build the
|
|
393
430
|
# virtual function table, and leave out the 'object' base class.
|
|
394
431
|
finder = self._get_method_finder_(itf)
|
|
@@ -412,7 +449,8 @@ class COMObject(object):
|
|
|
412
449
|
# What we have:
|
|
413
450
|
#
|
|
414
451
|
# restypes is a ctypes type or None
|
|
415
|
-
# argspec is seq. of (['in'], paramtype, paramname) tuples (or
|
|
452
|
+
# argspec is seq. of (['in'], paramtype, paramname) tuples (or
|
|
453
|
+
# lists?)
|
|
416
454
|
#################
|
|
417
455
|
# What we need:
|
|
418
456
|
#
|
|
@@ -432,43 +470,46 @@ class COMObject(object):
|
|
|
432
470
|
|
|
433
471
|
if what == "DISPMETHOD":
|
|
434
472
|
if 'propget' in idlflags:
|
|
435
|
-
invkind = 2
|
|
473
|
+
invkind = 2 # DISPATCH_PROPERTYGET
|
|
436
474
|
mthname = "_get_" + mthname
|
|
437
475
|
elif 'propput' in idlflags:
|
|
438
|
-
invkind = 4
|
|
476
|
+
invkind = 4 # DISPATCH_PROPERTYPUT
|
|
439
477
|
mthname = "_set_" + mthname
|
|
440
478
|
elif 'propputref' in idlflags:
|
|
441
|
-
invkind = 8
|
|
479
|
+
invkind = 8 # DISPATCH_PROPERTYPUTREF
|
|
442
480
|
mthname = "_setref_" + mthname
|
|
443
481
|
else:
|
|
444
|
-
invkind = 1
|
|
482
|
+
invkind = 1 # DISPATCH_METHOD
|
|
445
483
|
if restype:
|
|
446
484
|
argspec = argspec + ((['out'], restype, ""),)
|
|
447
485
|
self.__make_dispentry(finder, interface, mthname,
|
|
448
486
|
idlflags, argspec, invkind)
|
|
449
487
|
elif what == "DISPPROPERTY":
|
|
488
|
+
# DISPPROPERTY have implicit "out"
|
|
489
|
+
if restype:
|
|
490
|
+
argspec += ((['out'], restype, ""),)
|
|
450
491
|
self.__make_dispentry(finder, interface,
|
|
451
492
|
"_get_" + mthname,
|
|
452
493
|
idlflags, argspec,
|
|
453
|
-
2
|
|
494
|
+
2 # DISPATCH_PROPERTYGET
|
|
454
495
|
)
|
|
455
496
|
if not 'readonly' in idlflags:
|
|
456
497
|
self.__make_dispentry(finder, interface,
|
|
457
498
|
"_set_" + mthname,
|
|
458
499
|
idlflags, argspec,
|
|
459
|
-
4)
|
|
500
|
+
4) # DISPATCH_PROPERTYPUT
|
|
460
501
|
# Add DISPATCH_PROPERTYPUTREF also?
|
|
461
502
|
|
|
462
|
-
|
|
463
503
|
def __make_dispentry(self,
|
|
464
504
|
finder, interface, mthname,
|
|
465
505
|
idlflags, argspec, invkind):
|
|
466
506
|
# We build a _dispmap_ entry now that maps invkind and
|
|
467
507
|
# dispid to implementations that the finder finds;
|
|
468
508
|
# IDispatch_Invoke will later call it.
|
|
469
|
-
paramflags = [((_encode_idl(x[0]), x[1]) + tuple(x[3:]))
|
|
470
|
-
|
|
471
|
-
|
|
509
|
+
paramflags = [((_encode_idl(x[0]), x[1]) + tuple(x[3:]))
|
|
510
|
+
for x in argspec]
|
|
511
|
+
# XXX can the dispid be at a different index? Check codegenerator.
|
|
512
|
+
dispid = idlflags[0]
|
|
472
513
|
impl = finder.get_impl(interface, mthname, paramflags, idlflags)
|
|
473
514
|
self._dispimpl_[(dispid, invkind)] = impl
|
|
474
515
|
# invkind is really a set of flags; we allow both
|
|
@@ -485,7 +526,8 @@ class COMObject(object):
|
|
|
485
526
|
################################################################
|
|
486
527
|
# LocalServer / InprocServer stuff
|
|
487
528
|
__server__ = None
|
|
488
|
-
|
|
529
|
+
|
|
530
|
+
@staticmethod
|
|
489
531
|
def __run_inprocserver__():
|
|
490
532
|
if COMObject.__server__ is None:
|
|
491
533
|
COMObject.__server__ = InprocServer()
|
|
@@ -493,37 +535,35 @@ class COMObject(object):
|
|
|
493
535
|
pass
|
|
494
536
|
else:
|
|
495
537
|
raise RuntimeError("Wrong server type")
|
|
496
|
-
__run_inprocserver__ = staticmethod(__run_inprocserver__)
|
|
497
538
|
|
|
498
|
-
|
|
539
|
+
@staticmethod
|
|
499
540
|
def __run_localserver__(classobjects):
|
|
500
541
|
assert COMObject.__server__ is None
|
|
501
542
|
# XXX Decide whether we are in STA or MTA
|
|
502
543
|
server = COMObject.__server__ = LocalServer()
|
|
503
544
|
server.run(classobjects)
|
|
504
545
|
COMObject.__server__ = None
|
|
505
|
-
__run_localserver__ = staticmethod(__run_localserver__)
|
|
506
546
|
|
|
507
|
-
|
|
547
|
+
@staticmethod
|
|
508
548
|
def __keep__(obj):
|
|
509
549
|
COMObject._instances_[obj] = None
|
|
510
|
-
_debug("%d active COM objects: Added %r", len(COMObject._instances_),
|
|
550
|
+
_debug("%d active COM objects: Added %r", len(COMObject._instances_),
|
|
551
|
+
obj)
|
|
511
552
|
if COMObject.__server__:
|
|
512
553
|
COMObject.__server__.Lock()
|
|
513
|
-
__keep__ = staticmethod(__keep__)
|
|
514
554
|
|
|
515
|
-
|
|
555
|
+
@staticmethod
|
|
516
556
|
def __unkeep__(obj):
|
|
517
557
|
try:
|
|
518
558
|
del COMObject._instances_[obj]
|
|
519
559
|
except AttributeError:
|
|
520
560
|
_debug("? active COM objects: Removed %r", obj)
|
|
521
561
|
else:
|
|
522
|
-
_debug("%d active COM objects: Removed %r",
|
|
562
|
+
_debug("%d active COM objects: Removed %r",
|
|
563
|
+
len(COMObject._instances_), obj)
|
|
523
564
|
_debug("Remaining: %s", COMObject._instances_.keys())
|
|
524
565
|
if COMObject.__server__:
|
|
525
566
|
COMObject.__server__.Unlock()
|
|
526
|
-
__unkeep__ = staticmethod(__unkeep__)
|
|
527
567
|
#
|
|
528
568
|
################################################################
|
|
529
569
|
|
|
@@ -545,7 +585,7 @@ class COMObject(object):
|
|
|
545
585
|
|
|
546
586
|
def IUnknown_Release(self, this,
|
|
547
587
|
__InterlockedDecrement=_InterlockedDecrement,
|
|
548
|
-
|
|
588
|
+
_debug=_debug):
|
|
549
589
|
# If this is called at COM shutdown, _InterlockedDecrement()
|
|
550
590
|
# must still be available, although module level variables may
|
|
551
591
|
# have been deleted already - so we supply it as default
|
|
@@ -559,8 +599,7 @@ class COMObject(object):
|
|
|
559
599
|
self._com_pointers_ = {}
|
|
560
600
|
return result
|
|
561
601
|
|
|
562
|
-
def IUnknown_QueryInterface(self, this, riid, ppvObj,
|
|
563
|
-
_debug=_debug):
|
|
602
|
+
def IUnknown_QueryInterface(self, this, riid, ppvObj, _debug=_debug):
|
|
564
603
|
# XXX This is probably too slow.
|
|
565
604
|
# riid[0].hashcode() alone takes 33 us!
|
|
566
605
|
iid = riid[0]
|
|
@@ -614,13 +653,12 @@ class COMObject(object):
|
|
|
614
653
|
|
|
615
654
|
################################################################
|
|
616
655
|
# IDispatch methods
|
|
617
|
-
|
|
656
|
+
@property
|
|
618
657
|
def __typeinfo(self):
|
|
619
658
|
# XXX Looks like this better be a static property, set by the
|
|
620
659
|
# code that sets __typelib also...
|
|
621
660
|
iid = self._com_interfaces_[0]._iid_
|
|
622
661
|
return self.__typelib.GetTypeInfoOfGuid(iid)
|
|
623
|
-
__typeinfo = property(__typeinfo)
|
|
624
662
|
|
|
625
663
|
def IDispatch_GetTypeInfoCount(self):
|
|
626
664
|
try:
|
|
@@ -639,7 +677,8 @@ class COMObject(object):
|
|
|
639
677
|
except AttributeError:
|
|
640
678
|
return E_NOTIMPL
|
|
641
679
|
|
|
642
|
-
def IDispatch_GetIDsOfNames(self, this, riid, rgszNames, cNames, lcid,
|
|
680
|
+
def IDispatch_GetIDsOfNames(self, this, riid, rgszNames, cNames, lcid,
|
|
681
|
+
rgDispId):
|
|
643
682
|
# This call uses windll instead of oledll so that a failed
|
|
644
683
|
# call to DispGetIDsOfNames will return a HRESULT instead of
|
|
645
684
|
# raising an error.
|
|
@@ -669,10 +708,10 @@ class COMObject(object):
|
|
|
669
708
|
# an error.
|
|
670
709
|
interface = self._com_interfaces_[0]
|
|
671
710
|
ptr = self._com_pointers_[interface._iid_]
|
|
672
|
-
return windll.oleaut32.DispInvoke(
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
711
|
+
return windll.oleaut32.DispInvoke(
|
|
712
|
+
ptr, tinfo, dispIdMember, wFlags, pDispParams, pVarResult,
|
|
713
|
+
pExcepInfo, puArgErr
|
|
714
|
+
)
|
|
676
715
|
|
|
677
716
|
try:
|
|
678
717
|
# XXX Hm, wFlags should be considered a SET of flags...
|
|
@@ -699,11 +738,8 @@ class COMObject(object):
|
|
|
699
738
|
# How are the parameters unpacked for propertyput
|
|
700
739
|
# operations with additional parameters? Can propput
|
|
701
740
|
# have additional args?
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
# correctly, so use 'list(range)[::-1]' instead (will be
|
|
705
|
-
# fixed in Python 3.1, probably):
|
|
706
|
-
args = [params.rgvarg[i].value for i in list(range(params.cNamedArgs))[::-1]]
|
|
741
|
+
args = [params.rgvarg[i].value
|
|
742
|
+
for i in reversed(range(params.cNamedArgs))]
|
|
707
743
|
# MSDN: pVarResult is ignored if DISPATCH_PROPERTYPUT or
|
|
708
744
|
# DISPATCH_PROPERTYPUTREF is specified.
|
|
709
745
|
return mth(this, *args)
|
|
@@ -716,13 +752,15 @@ class COMObject(object):
|
|
|
716
752
|
# 2to3 has problems to translate 'range(...)[::-1]'
|
|
717
753
|
# correctly, so use 'list(range)[::-1]' instead (will be
|
|
718
754
|
# fixed in Python 3.1, probably):
|
|
719
|
-
named_indexes = [params.rgdispidNamedArgs[i]
|
|
755
|
+
named_indexes = [params.rgdispidNamedArgs[i]
|
|
756
|
+
for i in range(params.cNamedArgs)]
|
|
720
757
|
# the positions of unnamed arguments
|
|
721
|
-
|
|
758
|
+
num_unnamed = params.cArgs - params.cNamedArgs
|
|
759
|
+
unnamed_indexes = list(reversed(range(num_unnamed)))
|
|
722
760
|
# It seems that this code calculates the indexes of the
|
|
723
761
|
# parameters in the params.rgvarg array correctly.
|
|
724
762
|
indexes = named_indexes + unnamed_indexes
|
|
725
|
-
args = [params.rgvarg[i].value for i in
|
|
763
|
+
args = [params.rgvarg[i].value for i in indexes]
|
|
726
764
|
|
|
727
765
|
if pVarResult and getattr(mth, "has_outargs", False):
|
|
728
766
|
args.append(pVarResult)
|
|
@@ -218,7 +218,8 @@ class tagVARIANT(Structure):
|
|
|
218
218
|
_VariantClear(self)
|
|
219
219
|
if value is None:
|
|
220
220
|
self.vt = VT_NULL
|
|
221
|
-
elif hasattr(value, '__len__') and len(value) == 0
|
|
221
|
+
elif (hasattr(value, '__len__') and len(value) == 0
|
|
222
|
+
and not isinstance(value, basestring)):
|
|
222
223
|
self.vt = VT_NULL
|
|
223
224
|
# since bool is a subclass of int, this check must come before
|
|
224
225
|
# the check for int
|
|
@@ -857,6 +858,9 @@ _ctype_to_vartype = {
|
|
|
857
858
|
# such an array cannot be created.
|
|
858
859
|
POINTER(VARIANT): VT_BYREF|VT_VARIANT,
|
|
859
860
|
|
|
861
|
+
# This is needed to import Esri ArcObjects (esriSystem.olb).
|
|
862
|
+
POINTER(BSTR): VT_BYREF|VT_BSTR,
|
|
863
|
+
|
|
860
864
|
# These are not yet implemented:
|
|
861
865
|
## POINTER(IUnknown): VT_UNKNOWN,
|
|
862
866
|
## POINTER(IDispatch): VT_DISPATCH,
|
|
@@ -11,6 +11,7 @@ HAVE_NUMPY = numpy is not None
|
|
|
11
11
|
|
|
12
12
|
is_64bits = sys.maxsize > 2**32
|
|
13
13
|
|
|
14
|
+
|
|
14
15
|
def _make_variant_dtype():
|
|
15
16
|
""" Create a dtype for VARIANT. This requires support for Unions, which is
|
|
16
17
|
available in numpy version 1.7 or greater.
|
|
@@ -32,14 +33,14 @@ def _make_variant_dtype():
|
|
|
32
33
|
# overlapping typecodes only allowed in numpy version 1.7 or greater
|
|
33
34
|
U_VARIANT_format = dict(
|
|
34
35
|
names=[
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
'VT_BOOL', 'VT_I1', 'VT_I2', 'VT_I4', 'VT_I8', 'VT_INT', 'VT_UI1',
|
|
37
|
+
'VT_UI2', 'VT_UI4', 'VT_UI8', 'VT_UINT', 'VT_R4', 'VT_R8', 'VT_CY',
|
|
38
|
+
'c_wchar_p', 'c_void_p', 'pparray', 'bstrVal', '_tagBRECORD',
|
|
38
39
|
],
|
|
39
40
|
formats=[
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
'<i2', '<i1', '<i2', '<i4', '<i8', '<i4', '<u1', '<u2', '<u4',
|
|
42
|
+
'<u8', '<u4', '<f4', '<f8', '<i8', ptr_typecode, ptr_typecode,
|
|
43
|
+
ptr_typecode, ptr_typecode, _tagBRECORD_format,
|
|
43
44
|
],
|
|
44
45
|
offsets=[0] * 19 # This is what makes it a union
|
|
45
46
|
)
|
|
@@ -72,9 +73,15 @@ def isdatetime64(value):
|
|
|
72
73
|
This cannot succeed if datetime64 is not available.
|
|
73
74
|
|
|
74
75
|
"""
|
|
76
|
+
if not HAVE_NUMPY:
|
|
77
|
+
return False
|
|
75
78
|
return isinstance(value, datetime64)
|
|
76
79
|
|
|
77
80
|
|
|
81
|
+
com_null_date64 = None
|
|
82
|
+
datetime64 = None
|
|
83
|
+
VARIANT_dtype = None
|
|
84
|
+
|
|
78
85
|
if HAVE_NUMPY:
|
|
79
86
|
|
|
80
87
|
# dtype for VARIANT. This allows for packing of variants into an array, and
|
|
@@ -82,18 +89,16 @@ if HAVE_NUMPY:
|
|
|
82
89
|
try:
|
|
83
90
|
VARIANT_dtype = _make_variant_dtype()
|
|
84
91
|
except ValueError:
|
|
85
|
-
|
|
92
|
+
pass
|
|
86
93
|
|
|
87
94
|
# This simplifies dependent modules
|
|
88
95
|
try:
|
|
89
96
|
from numpy import datetime64
|
|
90
97
|
except ImportError:
|
|
91
|
-
|
|
92
|
-
com_null_date64 = None
|
|
98
|
+
pass
|
|
93
99
|
else:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
datetime64 = None
|
|
100
|
+
try:
|
|
101
|
+
# This does not work on numpy 1.6
|
|
102
|
+
com_null_date64 = datetime64("1899-12-30T00:00:00", "ns")
|
|
103
|
+
except TypeError:
|
|
104
|
+
pass
|