comtypes 1.4.8__zip → 1.4.10__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.4.8 → comtypes-1.4.10}/CHANGES.txt +40 -0
- {comtypes-1.4.8/comtypes.egg-info → comtypes-1.4.10}/PKG-INFO +4 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/README.md +1 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/GUID.py +38 -16
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/__init__.py +36 -16
- comtypes-1.4.10/comtypes/_comobject.py +562 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_memberspec.py +93 -13
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_meta.py +1 -0
- comtypes-1.4.10/comtypes/_post_coinit/_cominterface_meta_patcher.py +152 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_post_coinit/bstr.py +12 -5
- comtypes-1.4.8/comtypes/_py_instance_method.py → comtypes-1.4.10/comtypes/_post_coinit/instancemethod.py +1 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_post_coinit/misc.py +60 -25
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_post_coinit/unknwn.py +26 -176
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_safearray.py +3 -4
- comtypes-1.4.10/comtypes/_vtbl.py +448 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/automation.py +46 -49
- comtypes-1.4.10/comtypes/client/__init__.py +42 -0
- comtypes-1.4.10/comtypes/client/_activeobj.py +46 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/_code_cache.py +10 -5
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/_constants.py +1 -1
- comtypes-1.4.10/comtypes/client/_create.py +147 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/_events.py +58 -13
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/_generate.py +7 -11
- comtypes-1.4.10/comtypes/client/_managing.py +114 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/dynamic.py +2 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/lazybind.py +12 -13
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/connectionpoints.py +2 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/errorinfo.py +22 -9
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/git.py +5 -5
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/hints.pyi +7 -15
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/logutil.py +15 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/messageloop.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/persist.py +3 -5
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/safearray.py +17 -5
- comtypes-1.4.10/comtypes/server/__init__.py +104 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/server/automation.py +1 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/server/connectionpoints.py +5 -5
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/server/inprocserver.py +25 -17
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/server/localserver.py +49 -19
- comtypes-1.4.10/comtypes/server/register.py +478 -0
- comtypes-1.4.10/comtypes/server/w_getopt.py +48 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/shelllink.py +16 -33
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/stream.py +7 -4
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestComServer.py +6 -7
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestDispServer.py +4 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/__init__.py +10 -12
- comtypes-1.4.10/comtypes/test/find_memleak.py +72 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/runtests.py +1 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/setup.py +2 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_BSTR.py +10 -23
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_GUID.py +1 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_QueryService.py +1 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_agilent.py +4 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_avmc.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_basic.py +12 -6
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_casesensitivity.py +3 -5
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_clear_cache.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_client.py +2 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_client_dynamic.py +2 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_client_regenerate_modules.py +2 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_collections.py +4 -4
- comtypes-1.4.10/comtypes/test/test_comobject.py +146 -0
- comtypes-1.4.10/comtypes/test/test_comserver.py +349 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_createwrappers.py +2 -4
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_dispifc_records.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_dispifc_safearrays.py +1 -1
- comtypes-1.4.10/comtypes/test/test_dispinterface.py +153 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_dyndispatch.py +1 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_excel.py +22 -12
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_findgendir.py +1 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_getactiveobj.py +4 -4
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_ie.py +19 -9
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_ienum.py +2 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_imfattributes.py +13 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_inout_args.py +8 -5
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_midl_safearray_create.py +14 -4
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_monikers.py +23 -9
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_msscript.py +2 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_npsupport.py +4 -4
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_outparam.py +37 -14
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_persist.py +2 -4
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_recordinfo.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_safearray.py +1 -90
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_sapi.py +4 -1
- comtypes-1.4.10/comtypes/test/test_server.py +350 -0
- comtypes-1.4.10/comtypes/test/test_server_register.py +524 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_shelllink.py +2 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_showevents.py +7 -17
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_storage.py +12 -6
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_stream.py +16 -5
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_subinterface.py +4 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_typeannotator.py +1 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_typeinfo.py +19 -7
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_urlhistory.py +7 -4
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_variant.py +3 -19
- comtypes-1.4.10/comtypes/test/test_w_getopt.py +29 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_win32com_interop.py +80 -36
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_wmi.py +0 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_word.py +1 -1
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/codegenerator.py +166 -440
- comtypes-1.4.10/comtypes/tools/codegenerator/comments.py +79 -0
- comtypes-1.4.10/comtypes/tools/codegenerator/heads.py +192 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/helpers.py +11 -14
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/namespaces.py +13 -5
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/packing.py +4 -4
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/typeannotator.py +19 -9
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/tlbparser.py +22 -23
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/typedesc.py +4 -8
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/typedesc_base.py +2 -2
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/typeinfo.py +159 -63
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/viewobject.py +3 -9
- {comtypes-1.4.8 → comtypes-1.4.10/comtypes.egg-info}/PKG-INFO +4 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes.egg-info/SOURCES.txt +11 -3
- {comtypes-1.4.8 → comtypes-1.4.10}/pyproject.toml +12 -19
- comtypes-1.4.8/comtypes/_comobject.py +0 -833
- comtypes-1.4.8/comtypes/_idl_stuff.py +0 -67
- comtypes-1.4.8/comtypes/client/__init__.py +0 -323
- comtypes-1.4.8/comtypes/server/__init__.py +0 -70
- comtypes-1.4.8/comtypes/server/register.py +0 -431
- comtypes-1.4.8/comtypes/server/w_getopt.py +0 -75
- comtypes-1.4.8/comtypes/test/find_memleak.py +0 -76
- comtypes-1.4.8/comtypes/test/test_comserver.py +0 -239
- comtypes-1.4.8/comtypes/test/test_dispinterface.py +0 -137
- comtypes-1.4.8/comtypes/test/test_propputref.py +0 -40
- comtypes-1.4.8/comtypes/test/test_server.py +0 -354
- {comtypes-1.4.8 → comtypes-1.4.10}/LICENSE.txt +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/MANIFEST.in +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_npsupport.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_post_coinit/__init__.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_tlib_version_checker.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/clear_cache.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/hresult.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/patcher.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestComServer.idl +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestComServer.tlb +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestDispServer.idl +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestDispServer.tlb +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/mylib.idl +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/mylib.tlb +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/mytypelib.idl +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_DISPPARAMS.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_dict.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_jscript.js +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_pump_events.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/urlhist.tlb +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/__init__.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/__init__.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/modulenamer.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/util.py +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes.egg-info/dependency_links.txt +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes.egg-info/entry_points.txt +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/comtypes.egg-info/top_level.txt +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/setup.cfg +0 -0
- {comtypes-1.4.8 → comtypes-1.4.10}/setup.py +0 -0
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import ctypes
|
|
2
|
-
from typing import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
from typing import (
|
|
3
|
+
Any,
|
|
4
|
+
Callable,
|
|
5
|
+
Dict,
|
|
6
|
+
Iterator,
|
|
7
|
+
List,
|
|
8
|
+
Literal,
|
|
9
|
+
NamedTuple,
|
|
10
|
+
Optional,
|
|
11
|
+
Tuple,
|
|
12
|
+
Type,
|
|
13
|
+
)
|
|
14
|
+
from typing import Union as _UnionT
|
|
6
15
|
|
|
7
|
-
from comtypes import _CData
|
|
8
16
|
import comtypes
|
|
9
|
-
|
|
17
|
+
from comtypes import _CData
|
|
10
18
|
|
|
11
19
|
_PositionalParamFlagType = Tuple[int, Optional[str]]
|
|
12
20
|
_OptionalParamFlagType = Tuple[int, Optional[str], Any]
|
|
@@ -64,7 +72,7 @@ def _resolve_argspec(
|
|
|
64
72
|
elif typ is ctypes.POINTER(VARIANT):
|
|
65
73
|
defval = ctypes.pointer(VARIANT.missing)
|
|
66
74
|
else:
|
|
67
|
-
# msg =
|
|
75
|
+
# msg = f"'optional' only allowed for VARIANT and VARIANT*, not for {typ.__name__}"
|
|
68
76
|
# warnings.warn(msg, IDLWarning, stacklevel=2)
|
|
69
77
|
defval = typ()
|
|
70
78
|
if defval is _NOTHING:
|
|
@@ -92,7 +100,7 @@ class _ComMemberSpec(NamedTuple):
|
|
|
92
100
|
class _DispMemberSpec(NamedTuple):
|
|
93
101
|
"""Specifier for a slot of dispinterface method or property."""
|
|
94
102
|
|
|
95
|
-
what:
|
|
103
|
+
what: Literal["DISPMETHOD", "DISPPROPERTY"]
|
|
96
104
|
name: str
|
|
97
105
|
idlflags: Tuple[_UnionT[str, int], ...]
|
|
98
106
|
restype: Optional[Type[_CData]]
|
|
@@ -118,6 +126,78 @@ def _is_spec_prop(m: _MemberSpec):
|
|
|
118
126
|
return any(f in ("propget", "propput", "propputref") for f in m.idlflags)
|
|
119
127
|
|
|
120
128
|
|
|
129
|
+
################################################################
|
|
130
|
+
# IDL stuff
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class helpstring(str):
|
|
134
|
+
"Specifies the helpstring for a COM method or property."
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class defaultvalue(object):
|
|
138
|
+
"Specifies the default value for parameters marked optional."
|
|
139
|
+
|
|
140
|
+
def __init__(self, value):
|
|
141
|
+
self.value = value
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class dispid(int):
|
|
145
|
+
"Specifies the DISPID of a method or property."
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
# XXX STDMETHOD, COMMETHOD, DISPMETHOD, and DISPPROPERTY should return
|
|
149
|
+
# instances with more methods or properties, and should not behave as an unpackable.
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def STDMETHOD(restype, name, argtypes=()) -> _ComMemberSpec:
|
|
153
|
+
"Specifies a COM method slot without idlflags"
|
|
154
|
+
return _ComMemberSpec(restype, name, argtypes, None, (), None)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def DISPMETHOD(idlflags, restype, name, *argspec) -> _DispMemberSpec:
|
|
158
|
+
"Specifies a method of a dispinterface"
|
|
159
|
+
return _DispMemberSpec("DISPMETHOD", name, tuple(idlflags), restype, argspec)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def DISPPROPERTY(idlflags, proptype, name) -> _DispMemberSpec:
|
|
163
|
+
"Specifies a property of a dispinterface"
|
|
164
|
+
return _DispMemberSpec("DISPPROPERTY", name, tuple(idlflags), proptype, ())
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
# tuple(idlflags) is for the method itself: (dispid, 'readonly')
|
|
168
|
+
|
|
169
|
+
# sample generated code:
|
|
170
|
+
# DISPPROPERTY([5, 'readonly'], OLE_YSIZE_HIMETRIC, 'Height'),
|
|
171
|
+
# DISPMETHOD(
|
|
172
|
+
# [6], None, 'Render', ([], c_int, 'hdc'), ([], c_int, 'x'), ([], c_int, 'y')
|
|
173
|
+
# )
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def COMMETHOD(idlflags, restype, methodname, *argspec) -> _ComMemberSpec:
|
|
177
|
+
"""Specifies a COM method slot with idlflags.
|
|
178
|
+
|
|
179
|
+
XXX should explain the sematics of the arguments.
|
|
180
|
+
"""
|
|
181
|
+
# collect all helpstring instances
|
|
182
|
+
# We should suppress docstrings when Python is started with -OO
|
|
183
|
+
# join them together(does this make sense?) and replace by None if empty.
|
|
184
|
+
helptext = "".join(t for t in idlflags if isinstance(t, helpstring)) or None
|
|
185
|
+
paramflags, argtypes = _resolve_argspec(argspec)
|
|
186
|
+
if "propget" in idlflags:
|
|
187
|
+
name = f"_get_{methodname}"
|
|
188
|
+
elif "propput" in idlflags:
|
|
189
|
+
name = f"_set_{methodname}"
|
|
190
|
+
elif "propputref" in idlflags:
|
|
191
|
+
name = f"_setref_{methodname}"
|
|
192
|
+
else:
|
|
193
|
+
name = methodname
|
|
194
|
+
return _ComMemberSpec(
|
|
195
|
+
restype, name, argtypes, paramflags, tuple(idlflags), helptext
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
################################################################
|
|
200
|
+
|
|
121
201
|
_PropFunc = Optional[Callable[..., Any]]
|
|
122
202
|
_DocType = Optional[str]
|
|
123
203
|
|
|
@@ -310,7 +390,7 @@ class PropertyGenerator(object):
|
|
|
310
390
|
# Hm, must be a descriptor where the __get__ method
|
|
311
391
|
# returns a bound object having __getitem__ and
|
|
312
392
|
# __setitem__ methods.
|
|
313
|
-
prop = named_property("
|
|
393
|
+
prop = named_property(f"{self._cls_name}.{name}", fget, fset, doc)
|
|
314
394
|
yield (name, prop)
|
|
315
395
|
|
|
316
396
|
def to_propget_keys(self, m: _MemberSpec) -> Tuple[str, _DocType, int]:
|
|
@@ -360,7 +440,7 @@ class DispPropertyGenerator(PropertyGenerator):
|
|
|
360
440
|
|
|
361
441
|
|
|
362
442
|
class ComMemberGenerator(object):
|
|
363
|
-
def __init__(self, cls_name: str, vtbl_offset: int, iid: comtypes.GUID) -> None:
|
|
443
|
+
def __init__(self, cls_name: str, vtbl_offset: int, iid: "comtypes.GUID") -> None:
|
|
364
444
|
self._vtbl_offset = vtbl_offset
|
|
365
445
|
self._iid = iid
|
|
366
446
|
self._props = ComPropertyGenerator(cls_name)
|
|
@@ -533,11 +613,11 @@ class bound_named_property(object):
|
|
|
533
613
|
self.fset(self.instance, index, value)
|
|
534
614
|
|
|
535
615
|
def __repr__(self):
|
|
536
|
-
return "<bound_named_property
|
|
616
|
+
return f"<bound_named_property {self.name!r} at {id(self):x}>"
|
|
537
617
|
|
|
538
618
|
def __iter__(self):
|
|
539
619
|
"""Explicitly disallow iteration."""
|
|
540
|
-
msg = "
|
|
620
|
+
msg = f"{self.name!r} is not iterable"
|
|
541
621
|
raise TypeError(msg)
|
|
542
622
|
|
|
543
623
|
|
|
@@ -558,4 +638,4 @@ class named_property(object):
|
|
|
558
638
|
raise AttributeError("Unsettable attribute")
|
|
559
639
|
|
|
560
640
|
def __repr__(self):
|
|
561
|
-
return "<named_property
|
|
641
|
+
return f"<named_property {self.name!r} at {id(self):x}>"
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import types
|
|
2
|
+
from _ctypes import COMError
|
|
3
|
+
from typing import Type
|
|
4
|
+
|
|
5
|
+
from comtypes import patcher
|
|
6
|
+
|
|
7
|
+
_all_slice = slice(None, None, None)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def case_insensitive(p: Type) -> None:
|
|
11
|
+
@patcher.Patch(p)
|
|
12
|
+
class CaseInsensitive(object):
|
|
13
|
+
# case insensitive attributes for COM methods and properties
|
|
14
|
+
def __getattr__(self, name):
|
|
15
|
+
"""Implement case insensitive access to methods and properties"""
|
|
16
|
+
try:
|
|
17
|
+
fixed_name = self.__map_case__[name.lower()]
|
|
18
|
+
except KeyError:
|
|
19
|
+
raise AttributeError(name) # Should we use exception-chaining?
|
|
20
|
+
if fixed_name != name: # prevent unbounded recursion
|
|
21
|
+
return getattr(self, fixed_name)
|
|
22
|
+
raise AttributeError(name)
|
|
23
|
+
|
|
24
|
+
# __setattr__ is pretty heavy-weight, because it is called for
|
|
25
|
+
# EVERY attribute assignment. Settings a non-com attribute
|
|
26
|
+
# through this function takes 8.6 usec, while without this
|
|
27
|
+
# function it takes 0.7 sec - 12 times slower.
|
|
28
|
+
#
|
|
29
|
+
# How much faster would this be if implemented in C?
|
|
30
|
+
def __setattr__(self, name, value):
|
|
31
|
+
"""Implement case insensitive access to methods and properties"""
|
|
32
|
+
object.__setattr__(self, self.__map_case__.get(name.lower(), name), value)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def reference_fix(pp: Type) -> None:
|
|
36
|
+
@patcher.Patch(pp)
|
|
37
|
+
class ReferenceFix(object):
|
|
38
|
+
def __setitem__(self, index, value):
|
|
39
|
+
# We override the __setitem__ method of the
|
|
40
|
+
# POINTER(POINTER(interface)) type, so that the COM
|
|
41
|
+
# reference count is managed correctly.
|
|
42
|
+
#
|
|
43
|
+
# This is so that we can implement COM methods that have to
|
|
44
|
+
# return COM pointers more easily and consistent. Instead of
|
|
45
|
+
# using CopyComPointer in the method implementation, we can
|
|
46
|
+
# simply do:
|
|
47
|
+
#
|
|
48
|
+
# def GetTypeInfo(self, this, ..., pptinfo):
|
|
49
|
+
# if not pptinfo: return E_POINTER
|
|
50
|
+
# pptinfo[0] = a_com_interface_pointer
|
|
51
|
+
# return S_OK
|
|
52
|
+
if index != 0:
|
|
53
|
+
# CopyComPointer, which is in _ctypes, does only
|
|
54
|
+
# handle an index of 0. This code does what
|
|
55
|
+
# CopyComPointer should do if index != 0.
|
|
56
|
+
if bool(value):
|
|
57
|
+
value.AddRef()
|
|
58
|
+
super(pp, self).__setitem__(index, value) # type: ignore
|
|
59
|
+
return
|
|
60
|
+
from _ctypes import CopyComPointer
|
|
61
|
+
|
|
62
|
+
CopyComPointer(value, self) # type: ignore
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def sized(itf: Type) -> None:
|
|
66
|
+
@patcher.Patch(itf)
|
|
67
|
+
class _(object):
|
|
68
|
+
def __len__(self):
|
|
69
|
+
"Return the the 'self.Count' property."
|
|
70
|
+
return self.Count
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def callable_and_subscriptable(itf: Type) -> None:
|
|
74
|
+
@patcher.Patch(itf)
|
|
75
|
+
class _(object):
|
|
76
|
+
# 'Item' is the 'default' value. Make it available by
|
|
77
|
+
# calling the instance (Not sure this makes sense, but
|
|
78
|
+
# win32com does this also).
|
|
79
|
+
def __call__(self, *args, **kw):
|
|
80
|
+
"Return 'self.Item(*args, **kw)'"
|
|
81
|
+
return self.Item(*args, **kw)
|
|
82
|
+
|
|
83
|
+
# does this make sense? It seems that all standard typelibs I've
|
|
84
|
+
# seen so far that support .Item also support ._NewEnum
|
|
85
|
+
@patcher.no_replace
|
|
86
|
+
def __getitem__(self, index):
|
|
87
|
+
"Return 'self.Item(index)'"
|
|
88
|
+
# Handle tuples and all-slice
|
|
89
|
+
if isinstance(index, tuple):
|
|
90
|
+
args = index
|
|
91
|
+
elif index == _all_slice:
|
|
92
|
+
args = ()
|
|
93
|
+
else:
|
|
94
|
+
args = (index,)
|
|
95
|
+
|
|
96
|
+
try:
|
|
97
|
+
result = self.Item(*args)
|
|
98
|
+
except COMError as err:
|
|
99
|
+
(hresult, text, details) = err.args
|
|
100
|
+
if hresult == -2147352565: # DISP_E_BADINDEX
|
|
101
|
+
raise IndexError("invalid index")
|
|
102
|
+
else:
|
|
103
|
+
raise
|
|
104
|
+
|
|
105
|
+
# Note that result may be NULL COM pointer. There is no way
|
|
106
|
+
# to interpret this properly, so it is returned as-is.
|
|
107
|
+
|
|
108
|
+
# Hm, should we call __ctypes_from_outparam__ on the
|
|
109
|
+
# result?
|
|
110
|
+
return result
|
|
111
|
+
|
|
112
|
+
@patcher.no_replace
|
|
113
|
+
def __setitem__(self, index, value):
|
|
114
|
+
"Attempt 'self.Item[index] = value'"
|
|
115
|
+
try:
|
|
116
|
+
self.Item[index] = value
|
|
117
|
+
except COMError as err:
|
|
118
|
+
(hresult, text, details) = err.args
|
|
119
|
+
if hresult == -2147352565: # DISP_E_BADINDEX
|
|
120
|
+
raise IndexError("invalid index")
|
|
121
|
+
else:
|
|
122
|
+
raise
|
|
123
|
+
except TypeError:
|
|
124
|
+
msg = f"{type(self)!r} object does not support item assignment"
|
|
125
|
+
raise TypeError(msg)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def iterator(itf: Type) -> None:
|
|
129
|
+
@patcher.Patch(itf)
|
|
130
|
+
class _(object):
|
|
131
|
+
def __iter__(self):
|
|
132
|
+
"Return an iterator over the _NewEnum collection."
|
|
133
|
+
# This method returns a pointer to _some_ _NewEnum interface.
|
|
134
|
+
# It relies on the fact that the code generator creates next()
|
|
135
|
+
# methods for them automatically.
|
|
136
|
+
#
|
|
137
|
+
# Better would maybe to return an object that
|
|
138
|
+
# implements the Python iterator protocol, and
|
|
139
|
+
# forwards the calls to the COM interface.
|
|
140
|
+
enum = self._NewEnum
|
|
141
|
+
if isinstance(enum, types.MethodType):
|
|
142
|
+
# _NewEnum should be a propget property, with dispid -4.
|
|
143
|
+
#
|
|
144
|
+
# Sometimes, however, it is a method.
|
|
145
|
+
enum = enum()
|
|
146
|
+
if hasattr(enum, "Next"):
|
|
147
|
+
return enum
|
|
148
|
+
# _NewEnum returns an IUnknown pointer, QueryInterface() it to
|
|
149
|
+
# IEnumVARIANT
|
|
150
|
+
from comtypes.automation import IEnumVARIANT
|
|
151
|
+
|
|
152
|
+
return enum.QueryInterface(IEnumVARIANT)
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
from ctypes import
|
|
2
|
-
from typing import Any, Callable
|
|
1
|
+
from ctypes import WinDLL, _SimpleCData
|
|
2
|
+
from typing import TYPE_CHECKING, Any, Callable
|
|
3
3
|
|
|
4
4
|
if TYPE_CHECKING:
|
|
5
5
|
from comtypes import hints # type: ignore
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
_oleaut32 = WinDLL("oleaut32")
|
|
9
|
+
|
|
10
|
+
_SysFreeString = _oleaut32.SysFreeString
|
|
11
|
+
|
|
12
|
+
|
|
8
13
|
class BSTR(_SimpleCData):
|
|
9
14
|
"""The windows BSTR data type"""
|
|
10
15
|
|
|
@@ -18,9 +23,7 @@ class BSTR(_SimpleCData):
|
|
|
18
23
|
self._needsfree = True
|
|
19
24
|
return self.value
|
|
20
25
|
|
|
21
|
-
def __del__(
|
|
22
|
-
self, _free: Callable[["BSTR"], Any] = windll.oleaut32.SysFreeString
|
|
23
|
-
) -> None:
|
|
26
|
+
def __del__(self, _free: Callable[["BSTR"], Any] = _SysFreeString) -> None:
|
|
24
27
|
# Free the string if self owns the memory
|
|
25
28
|
# or if instructed by __ctypes_from_outparam__.
|
|
26
29
|
if self._b_base_ is None or self._needsfree:
|
|
@@ -35,3 +38,7 @@ class BSTR(_SimpleCData):
|
|
|
35
38
|
# right thing, it doesn't ensure that SysFreeString is called
|
|
36
39
|
# on destruction.
|
|
37
40
|
return cls(value)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
_SysFreeString.argtypes = [BSTR]
|
|
44
|
+
_SysFreeString.restype = None
|
|
@@ -1,26 +1,28 @@
|
|
|
1
|
-
from ctypes import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
from ctypes import (
|
|
2
|
+
HRESULT,
|
|
3
|
+
POINTER,
|
|
4
|
+
OleDLL,
|
|
5
|
+
Structure,
|
|
6
|
+
byref,
|
|
7
|
+
c_ulong,
|
|
8
|
+
c_ushort,
|
|
9
|
+
c_void_p,
|
|
10
|
+
c_wchar_p,
|
|
11
|
+
cast,
|
|
12
|
+
pointer,
|
|
13
13
|
)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
from comtypes import hints as hints # noqa # type: ignore
|
|
14
|
+
from ctypes.wintypes import DWORD, LPCWSTR, LPVOID
|
|
15
|
+
from typing import TYPE_CHECKING, Any, Callable, Optional, Type, TypeVar, overload
|
|
17
16
|
|
|
18
|
-
from comtypes import GUID
|
|
19
|
-
from comtypes.
|
|
20
|
-
from comtypes import CLSCTX_SERVER, CLSCTX_LOCAL_SERVER, CLSCTX_REMOTE_SERVER
|
|
21
|
-
from comtypes import _ole32, oledll, DWORD
|
|
17
|
+
from comtypes import CLSCTX_LOCAL_SERVER, CLSCTX_REMOTE_SERVER, CLSCTX_SERVER, GUID
|
|
18
|
+
from comtypes._memberspec import COMMETHOD
|
|
22
19
|
from comtypes._post_coinit.unknwn import IUnknown
|
|
23
20
|
|
|
21
|
+
if TYPE_CHECKING:
|
|
22
|
+
from ctypes import _Pointer
|
|
23
|
+
|
|
24
|
+
from comtypes import hints as hints # noqa # type: ignore
|
|
25
|
+
|
|
24
26
|
|
|
25
27
|
def _is_object(obj):
|
|
26
28
|
"""This function determines if the argument is a COM object. It
|
|
@@ -98,7 +100,7 @@ def CoGetObject(displayname: str, interface: Optional[Type[IUnknown]]) -> IUnkno
|
|
|
98
100
|
interface = IUnknown
|
|
99
101
|
punk = POINTER(interface)()
|
|
100
102
|
# Do we need a way to specify the BIND_OPTS parameter?
|
|
101
|
-
|
|
103
|
+
_CoGetObject(str(displayname), None, byref(interface._iid_), byref(punk))
|
|
102
104
|
return punk # type: ignore
|
|
103
105
|
|
|
104
106
|
|
|
@@ -134,7 +136,7 @@ def CoCreateInstance(
|
|
|
134
136
|
interface = IUnknown
|
|
135
137
|
p = POINTER(interface)()
|
|
136
138
|
iid = interface._iid_
|
|
137
|
-
|
|
139
|
+
_CoCreateInstance(byref(clsid), punkouter, clsctx, byref(iid), byref(p))
|
|
138
140
|
return p # type: ignore
|
|
139
141
|
|
|
140
142
|
|
|
@@ -178,7 +180,7 @@ def GetActiveObject(
|
|
|
178
180
|
) -> IUnknown:
|
|
179
181
|
"""Retrieves a pointer to a running object"""
|
|
180
182
|
p = POINTER(IUnknown)()
|
|
181
|
-
|
|
183
|
+
_GetActiveObject(byref(clsid), None, byref(p))
|
|
182
184
|
if interface is not None:
|
|
183
185
|
p = p.QueryInterface(interface) # type: ignore
|
|
184
186
|
return p # type: ignore
|
|
@@ -236,6 +238,16 @@ class _COSERVERINFO(Structure):
|
|
|
236
238
|
dwReserved2: int
|
|
237
239
|
|
|
238
240
|
|
|
241
|
+
_oleaut32 = OleDLL("oleaut32")
|
|
242
|
+
|
|
243
|
+
REFCLSID = POINTER(GUID)
|
|
244
|
+
_GetActiveObject = _oleaut32.GetActiveObject
|
|
245
|
+
_GetActiveObject.argtypes = [REFCLSID, LPVOID, POINTER(POINTER(IUnknown))]
|
|
246
|
+
_GetActiveObject.restype = HRESULT
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
_ole32 = OleDLL("ole32")
|
|
250
|
+
|
|
239
251
|
COSERVERINFO = _COSERVERINFO
|
|
240
252
|
_CoGetClassObject = _ole32.CoGetClassObject
|
|
241
253
|
_CoGetClassObject.argtypes = [
|
|
@@ -245,6 +257,28 @@ _CoGetClassObject.argtypes = [
|
|
|
245
257
|
POINTER(GUID),
|
|
246
258
|
POINTER(c_void_p),
|
|
247
259
|
]
|
|
260
|
+
_CoGetClassObject.restype = HRESULT
|
|
261
|
+
|
|
262
|
+
_CoCreateInstance = _ole32.CoCreateInstance
|
|
263
|
+
_CoCreateInstance.argtypes = [
|
|
264
|
+
REFCLSID,
|
|
265
|
+
POINTER(IUnknown),
|
|
266
|
+
DWORD,
|
|
267
|
+
POINTER(GUID),
|
|
268
|
+
POINTER(LPVOID),
|
|
269
|
+
]
|
|
270
|
+
_CoCreateInstance.restype = HRESULT
|
|
271
|
+
|
|
272
|
+
_CoCreateInstanceEx = _ole32.CoCreateInstanceEx
|
|
273
|
+
_CoCreateInstanceEx.argtypes = [
|
|
274
|
+
REFCLSID,
|
|
275
|
+
POINTER(IUnknown),
|
|
276
|
+
DWORD,
|
|
277
|
+
POINTER(COSERVERINFO),
|
|
278
|
+
DWORD,
|
|
279
|
+
POINTER(MULTI_QI),
|
|
280
|
+
]
|
|
281
|
+
_CoCreateInstanceEx.restype = HRESULT
|
|
248
282
|
|
|
249
283
|
|
|
250
284
|
class tagBIND_OPTS(Structure):
|
|
@@ -258,6 +292,9 @@ class tagBIND_OPTS(Structure):
|
|
|
258
292
|
|
|
259
293
|
# XXX Add __init__ which sets cbStruct?
|
|
260
294
|
BIND_OPTS = tagBIND_OPTS
|
|
295
|
+
_CoGetObject = _ole32.CoGetObject
|
|
296
|
+
_CoGetObject.argtypes = [LPCWSTR, POINTER(BIND_OPTS), POINTER(GUID), POINTER(LPVOID)]
|
|
297
|
+
_CoGetObject.restype = HRESULT
|
|
261
298
|
|
|
262
299
|
|
|
263
300
|
class tagBIND_OPTS2(Structure):
|
|
@@ -360,7 +397,5 @@ def CoCreateInstanceEx(
|
|
|
360
397
|
interface = IUnknown
|
|
361
398
|
multiqi = MULTI_QI()
|
|
362
399
|
multiqi.pIID = pointer(interface._iid_) # type: ignore
|
|
363
|
-
|
|
364
|
-
byref(clsid), None, clsctx, pServerInfo, 1, byref(multiqi)
|
|
365
|
-
)
|
|
400
|
+
_CoCreateInstanceEx(byref(clsid), None, clsctx, pServerInfo, 1, byref(multiqi))
|
|
366
401
|
return cast(multiqi.pItf, POINTER(interface)) # type: ignore
|