comtypes 1.4.10__zip → 1.4.11__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.10 → comtypes-1.4.11}/CHANGES.txt +22 -0
- {comtypes-1.4.10/comtypes.egg-info → comtypes-1.4.11}/PKG-INFO +3 -2
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/__init__.py +4 -4
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_comobject.py +23 -25
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_memberspec.py +100 -74
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_meta.py +1 -1
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_post_coinit/_cominterface_meta_patcher.py +3 -5
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_post_coinit/unknwn.py +29 -20
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_vtbl.py +52 -55
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/automation.py +9 -10
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/_code_cache.py +9 -23
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/_events.py +87 -49
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/_generate.py +0 -2
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/connectionpoints.py +37 -3
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/errorinfo.py +53 -15
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/hints.pyi +15 -2
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/hresult.py +16 -6
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/messageloop.py +14 -12
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/server/connectionpoints.py +68 -67
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/server/inprocserver.py +8 -5
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/server/localserver.py +14 -20
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/server/register.py +2 -2
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_GUID.py +6 -7
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_basic.py +6 -3
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_collections.py +6 -3
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_comobject.py +19 -6
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_comserver.py +25 -2
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_dict.py +2 -1
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_dyndispatch.py +4 -2
- comtypes-1.4.11/comtypes/test/test_errorinfo.py +115 -0
- comtypes-1.4.11/comtypes/test/test_hresult.py +48 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_inout_args.py +9 -2
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_safearray.py +2 -1
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_server_register.py +2 -1
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_typeinfo.py +19 -2
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_variant.py +2 -1
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_w_getopt.py +4 -4
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/tlbparser.py +7 -6
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/typeinfo.py +14 -9
- {comtypes-1.4.10 → comtypes-1.4.11/comtypes.egg-info}/PKG-INFO +3 -2
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes.egg-info/SOURCES.txt +2 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/pyproject.toml +1 -6
- {comtypes-1.4.10 → comtypes-1.4.11}/LICENSE.txt +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/MANIFEST.in +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/README.md +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/GUID.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_npsupport.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_post_coinit/__init__.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_post_coinit/bstr.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_post_coinit/instancemethod.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_post_coinit/misc.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_safearray.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_tlib_version_checker.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/clear_cache.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/__init__.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/_activeobj.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/_constants.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/_create.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/_managing.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/dynamic.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/lazybind.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/git.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/logutil.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/patcher.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/persist.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/safearray.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/server/__init__.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/server/automation.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/server/w_getopt.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/shelllink.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/stream.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/TestComServer.idl +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/TestComServer.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/TestComServer.tlb +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/TestDispServer.idl +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/TestDispServer.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/TestDispServer.tlb +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/__init__.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/find_memleak.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/mylib.idl +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/mylib.tlb +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/mytypelib.idl +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/runtests.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/setup.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_BSTR.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_DISPPARAMS.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_QueryService.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_agilent.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_avmc.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_casesensitivity.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_clear_cache.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_client.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_client_dynamic.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_client_regenerate_modules.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_createwrappers.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_dispifc_records.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_dispifc_safearrays.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_dispinterface.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_excel.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_findgendir.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_getactiveobj.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_ie.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_ienum.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_imfattributes.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_jscript.js +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_midl_safearray_create.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_monikers.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_msscript.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_npsupport.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_outparam.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_persist.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_pump_events.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_recordinfo.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_sapi.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_server.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_shelllink.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_showevents.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_storage.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_stream.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_subinterface.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_typeannotator.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_urlhistory.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_win32com_interop.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_wmi.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_word.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/urlhist.tlb +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/__init__.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/__init__.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/codegenerator.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/comments.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/heads.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/helpers.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/modulenamer.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/namespaces.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/packing.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/typeannotator.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/typedesc.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/typedesc_base.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/util.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/viewobject.py +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes.egg-info/dependency_links.txt +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes.egg-info/entry_points.txt +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/comtypes.egg-info/top_level.txt +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/setup.cfg +0 -0
- {comtypes-1.4.10 → comtypes-1.4.11}/setup.py +0 -0
|
@@ -1,11 +1,22 @@
|
|
|
1
|
+
import functools
|
|
1
2
|
import logging
|
|
2
|
-
from
|
|
3
|
+
from _ctypes import COMError
|
|
4
|
+
from ctypes import c_void_p, pointer
|
|
5
|
+
from ctypes.wintypes import DWORD
|
|
6
|
+
from typing import TYPE_CHECKING, Any, Callable, Dict, Iterator, List, Tuple, Type
|
|
7
|
+
from typing import Union as _UnionT
|
|
3
8
|
|
|
4
|
-
from comtypes import
|
|
9
|
+
from comtypes import GUID, COMObject, IUnknown
|
|
5
10
|
from comtypes.automation import IDispatch
|
|
6
11
|
from comtypes.connectionpoints import IConnectionPoint
|
|
7
12
|
from comtypes.hresult import *
|
|
8
|
-
from comtypes.typeinfo import LoadRegTypeLib
|
|
13
|
+
from comtypes.typeinfo import ITypeInfo, LoadRegTypeLib
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from ctypes import _Pointer
|
|
17
|
+
from typing import ClassVar
|
|
18
|
+
|
|
19
|
+
from comtypes import hints # type: ignore
|
|
9
20
|
|
|
10
21
|
logger = logging.getLogger(__name__)
|
|
11
22
|
|
|
@@ -17,9 +28,11 @@ class ConnectionPointImpl(COMObject):
|
|
|
17
28
|
|
|
18
29
|
_com_interfaces_ = [IConnectionPoint]
|
|
19
30
|
|
|
20
|
-
def __init__(
|
|
31
|
+
def __init__(
|
|
32
|
+
self, sink_interface: Type[IUnknown], sink_typeinfo: ITypeInfo
|
|
33
|
+
) -> None:
|
|
21
34
|
super(ConnectionPointImpl, self).__init__()
|
|
22
|
-
self._connections = {}
|
|
35
|
+
self._connections: Dict[int, IUnknown] = {}
|
|
23
36
|
self._cookie = 0
|
|
24
37
|
self._sink_interface = sink_interface
|
|
25
38
|
self._typeinfo = sink_typeinfo
|
|
@@ -27,7 +40,9 @@ class ConnectionPointImpl(COMObject):
|
|
|
27
40
|
# per MSDN, all interface methods *must* be implemented, E_NOTIMPL
|
|
28
41
|
# is no allowed return value
|
|
29
42
|
|
|
30
|
-
def IConnectionPoint_Advise(
|
|
43
|
+
def IConnectionPoint_Advise(
|
|
44
|
+
self, this: Any, pUnk: IUnknown, pdwCookie: "_Pointer[DWORD]"
|
|
45
|
+
) -> "hints.Hresult":
|
|
31
46
|
if not pUnk or not pdwCookie:
|
|
32
47
|
return E_POINTER
|
|
33
48
|
logger.debug("Advise")
|
|
@@ -39,7 +54,7 @@ class ConnectionPointImpl(COMObject):
|
|
|
39
54
|
self._connections[self._cookie] = ptr
|
|
40
55
|
return S_OK
|
|
41
56
|
|
|
42
|
-
def IConnectionPoint_Unadvise(self, this, dwCookie):
|
|
57
|
+
def IConnectionPoint_Unadvise(self, this: Any, dwCookie: int) -> "hints.Hresult":
|
|
43
58
|
logger.debug("Unadvise %s", dwCookie)
|
|
44
59
|
try:
|
|
45
60
|
del self._connections[dwCookie]
|
|
@@ -47,13 +62,17 @@ class ConnectionPointImpl(COMObject):
|
|
|
47
62
|
return CONNECT_E_NOCONNECTION
|
|
48
63
|
return S_OK
|
|
49
64
|
|
|
50
|
-
def IConnectionPoint_GetConnectionPointContainer(
|
|
65
|
+
def IConnectionPoint_GetConnectionPointContainer(
|
|
66
|
+
self, this: Any, ppCPC: c_void_p
|
|
67
|
+
) -> "hints.Hresult":
|
|
51
68
|
return E_NOTIMPL
|
|
52
69
|
|
|
53
|
-
def IConnectionPoint_GetConnectionInterface(
|
|
70
|
+
def IConnectionPoint_GetConnectionInterface(
|
|
71
|
+
self, this: Any, pIID: "_Pointer[GUID]"
|
|
72
|
+
) -> "hints.Hresult":
|
|
54
73
|
return E_NOTIMPL
|
|
55
74
|
|
|
56
|
-
def _call_sinks(self, name, *args, **kw):
|
|
75
|
+
def _call_sinks(self, name: str, *args: Any, **kw: Any) -> List[Any]:
|
|
57
76
|
results = []
|
|
58
77
|
logger.debug("_call_sinks(%s, %s, *%s, **%s)", self, name, args, kw)
|
|
59
78
|
# Is it an IDispatch derived interface? Then, events have to be delivered
|
|
@@ -62,61 +81,33 @@ class ConnectionPointImpl(COMObject):
|
|
|
62
81
|
# for better performance, we could cache the dispids.
|
|
63
82
|
dispid = self._typeinfo.GetIDsOfNames(name)[0]
|
|
64
83
|
for key, p in self._connections.items():
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
except COMError as details:
|
|
68
|
-
if details.hresult == -2147023174:
|
|
69
|
-
logger.warning(
|
|
70
|
-
"_call_sinks(%s, %s, *%s, **%s) failed; removing connection",
|
|
71
|
-
self,
|
|
72
|
-
name,
|
|
73
|
-
args,
|
|
74
|
-
kw,
|
|
75
|
-
exc_info=True,
|
|
76
|
-
)
|
|
77
|
-
try:
|
|
78
|
-
del self._connections[key]
|
|
79
|
-
except KeyError:
|
|
80
|
-
pass # connection already gone
|
|
81
|
-
else:
|
|
82
|
-
logger.warning(
|
|
83
|
-
"_call_sinks(%s, %s, *%s, **%s)",
|
|
84
|
-
self,
|
|
85
|
-
name,
|
|
86
|
-
args,
|
|
87
|
-
kw,
|
|
88
|
-
exc_info=True,
|
|
89
|
-
)
|
|
90
|
-
else:
|
|
91
|
-
results.append(result)
|
|
84
|
+
mth = functools.partial(p.Invoke, dispid) # type: ignore
|
|
85
|
+
results.extend(self._call_sink(name, key, mth, *args, **kw))
|
|
92
86
|
else:
|
|
93
|
-
for p in self._connections.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
except COMError as details:
|
|
97
|
-
if details.hresult == -2147023174:
|
|
98
|
-
logger.warning(
|
|
99
|
-
"_call_sinks(%s, %s, *%s, **%s) failed; removing connection",
|
|
100
|
-
self,
|
|
101
|
-
name,
|
|
102
|
-
args,
|
|
103
|
-
kw,
|
|
104
|
-
exc_info=True,
|
|
105
|
-
)
|
|
106
|
-
del self._connections[key]
|
|
107
|
-
else:
|
|
108
|
-
logger.warning(
|
|
109
|
-
"_call_sinks(%s, %s, *%s, **%s)",
|
|
110
|
-
self,
|
|
111
|
-
name,
|
|
112
|
-
args,
|
|
113
|
-
kw,
|
|
114
|
-
exc_info=True,
|
|
115
|
-
)
|
|
116
|
-
else:
|
|
117
|
-
results.append(result)
|
|
87
|
+
for key, p in self._connections.items():
|
|
88
|
+
mth = getattr(p, name)
|
|
89
|
+
results.extend(self._call_sink(name, key, mth, *args, **kw))
|
|
118
90
|
return results
|
|
119
91
|
|
|
92
|
+
def _call_sink(
|
|
93
|
+
self, name: str, key: int, mth: Callable[..., Any], *args: Any, **kw: Any
|
|
94
|
+
) -> Iterator[Any]:
|
|
95
|
+
try:
|
|
96
|
+
result = mth(*args, **kw)
|
|
97
|
+
except COMError as details:
|
|
98
|
+
if details.hresult == RPC_S_SERVER_UNAVAILABLE:
|
|
99
|
+
warn_msg = "_call_sinks(%s, %s, *%s, **%s) failed; removing connection"
|
|
100
|
+
logger.warning(warn_msg, self, name, args, kw, exc_info=True)
|
|
101
|
+
try:
|
|
102
|
+
del self._connections[key]
|
|
103
|
+
except KeyError:
|
|
104
|
+
pass # connection already gone
|
|
105
|
+
else:
|
|
106
|
+
warn_msg = "_call_sinks(%s, %s, *%s, **%s)"
|
|
107
|
+
logger.warning(warn_msg, self, name, args, kw, exc_info=True)
|
|
108
|
+
else:
|
|
109
|
+
yield result
|
|
110
|
+
|
|
120
111
|
|
|
121
112
|
class ConnectableObjectMixin(object):
|
|
122
113
|
"""Mixin which implements IConnectionPointContainer.
|
|
@@ -126,22 +117,30 @@ class ConnectableObjectMixin(object):
|
|
|
126
117
|
integer index into the _outgoing_interfaces_ list.
|
|
127
118
|
"""
|
|
128
119
|
|
|
129
|
-
|
|
120
|
+
if TYPE_CHECKING:
|
|
121
|
+
_outgoing_interfaces_: ClassVar[List[Type[IDispatch]]]
|
|
122
|
+
_reg_typelib_: ClassVar[Tuple[str, int, int]]
|
|
123
|
+
|
|
124
|
+
def __init__(self) -> None:
|
|
130
125
|
super(ConnectableObjectMixin, self).__init__()
|
|
131
|
-
self.__connections = {}
|
|
126
|
+
self.__connections: Dict[Type[IDispatch], ConnectionPointImpl] = {}
|
|
132
127
|
|
|
133
128
|
tlib = LoadRegTypeLib(*self._reg_typelib_)
|
|
134
129
|
for itf in self._outgoing_interfaces_:
|
|
135
130
|
typeinfo = tlib.GetTypeInfoOfGuid(itf._iid_)
|
|
136
131
|
self.__connections[itf] = ConnectionPointImpl(itf, typeinfo)
|
|
137
132
|
|
|
138
|
-
def IConnectionPointContainer_EnumConnectionPoints(
|
|
133
|
+
def IConnectionPointContainer_EnumConnectionPoints(
|
|
134
|
+
self, this: Any, ppEnum: c_void_p
|
|
135
|
+
) -> "hints.Hresult":
|
|
139
136
|
# according to MSDN, E_NOTIMPL is specificially disallowed
|
|
140
137
|
# because, without typeinfo, there's no way for the caller to
|
|
141
138
|
# find out.
|
|
142
139
|
return E_NOTIMPL
|
|
143
140
|
|
|
144
|
-
def IConnectionPointContainer_FindConnectionPoint(
|
|
141
|
+
def IConnectionPointContainer_FindConnectionPoint(
|
|
142
|
+
self, this: Any, refiid: "_Pointer[GUID]", ppcp: c_void_p
|
|
143
|
+
) -> "hints.Hresult":
|
|
145
144
|
iid = refiid[0]
|
|
146
145
|
logger.debug("FindConnectionPoint %s", iid)
|
|
147
146
|
if not ppcp:
|
|
@@ -161,7 +160,9 @@ class ConnectableObjectMixin(object):
|
|
|
161
160
|
logger.debug("No connectionpoint found")
|
|
162
161
|
return CONNECT_E_NOCONNECTION
|
|
163
162
|
|
|
164
|
-
def Fire_Event(
|
|
163
|
+
def Fire_Event(
|
|
164
|
+
self, itf: _UnionT[int, Type[IDispatch]], name: str, *args: Any, **kw: Any
|
|
165
|
+
) -> Any:
|
|
165
166
|
# Fire event 'name' with arguments *args and **kw.
|
|
166
167
|
# Accepts either an interface index or an interface as first argument.
|
|
167
168
|
# Returns a list of results.
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import ctypes
|
|
2
1
|
import logging
|
|
3
2
|
import sys
|
|
4
3
|
import winreg
|
|
4
|
+
from ctypes import c_void_p, pointer
|
|
5
5
|
from typing import TYPE_CHECKING, Any, Literal, Optional, Type
|
|
6
6
|
|
|
7
7
|
from comtypes import GUID, COMObject, IUnknown, hresult
|
|
8
|
+
from comtypes._comobject import InprocServer as _InprocRefCounter
|
|
8
9
|
from comtypes.server import IClassFactory
|
|
9
10
|
|
|
10
11
|
if TYPE_CHECKING:
|
|
@@ -29,7 +30,7 @@ class ClassFactory(COMObject):
|
|
|
29
30
|
this: Any,
|
|
30
31
|
punkOuter: Optional[Type["_Pointer[IUnknown]"]],
|
|
31
32
|
riid: "_Pointer[GUID]",
|
|
32
|
-
ppv:
|
|
33
|
+
ppv: c_void_p,
|
|
33
34
|
) -> int:
|
|
34
35
|
_debug("ClassFactory.CreateInstance(%s)", riid[0])
|
|
35
36
|
result = self._cls().IUnknown_QueryInterface(None, riid, ppv)
|
|
@@ -37,6 +38,7 @@ class ClassFactory(COMObject):
|
|
|
37
38
|
return result
|
|
38
39
|
|
|
39
40
|
def IClassFactory_LockServer(self, this: Any, fLock: bool) -> Literal[0]:
|
|
41
|
+
assert COMObject.__server__ is not None, "The inprocserver is not running yet"
|
|
40
42
|
if fLock:
|
|
41
43
|
COMObject.__server__.Lock()
|
|
42
44
|
else:
|
|
@@ -58,7 +60,7 @@ def inproc_find_class(clsid: GUID) -> Type[COMObject]:
|
|
|
58
60
|
except:
|
|
59
61
|
_debug("NO path to insert")
|
|
60
62
|
else:
|
|
61
|
-
if not
|
|
63
|
+
if pathdir not in sys.path:
|
|
62
64
|
sys.path.insert(0, str(pathdir))
|
|
63
65
|
_debug("insert path %r", pathdir)
|
|
64
66
|
else:
|
|
@@ -138,7 +140,7 @@ def DllGetClassObject(rclsid: int, riid: int, ppv: int) -> int:
|
|
|
138
140
|
return hresult.CLASS_E_CLASSNOTAVAILABLE
|
|
139
141
|
|
|
140
142
|
result = ClassFactory(cls).IUnknown_QueryInterface(
|
|
141
|
-
None,
|
|
143
|
+
None, pointer(iid), c_void_p(ppv)
|
|
142
144
|
)
|
|
143
145
|
_debug("DllGetClassObject() -> %s", result)
|
|
144
146
|
return result
|
|
@@ -149,7 +151,8 @@ def DllGetClassObject(rclsid: int, riid: int, ppv: int) -> int:
|
|
|
149
151
|
|
|
150
152
|
def DllCanUnloadNow() -> Literal[1]: # S_FALSE
|
|
151
153
|
COMObject.__run_inprocserver__()
|
|
152
|
-
|
|
154
|
+
assert isinstance(COMObject.__server__, _InprocRefCounter)
|
|
155
|
+
result = COMObject.__server__.DllCanUnloadNow() # noqa
|
|
153
156
|
# To avoid a memory leak when PyInitialize()/PyUninitialize() are
|
|
154
157
|
# called several times, we refuse to unload the dll.
|
|
155
158
|
return hresult.S_FALSE
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import queue
|
|
3
|
-
from ctypes import
|
|
4
|
-
HRESULT,
|
|
5
|
-
POINTER,
|
|
6
|
-
OleDLL,
|
|
7
|
-
byref,
|
|
8
|
-
c_ulong,
|
|
9
|
-
c_void_p,
|
|
10
|
-
)
|
|
3
|
+
from ctypes import HRESULT, POINTER, OleDLL, byref, c_ulong, c_void_p
|
|
11
4
|
from ctypes.wintypes import DWORD, LPDWORD
|
|
12
5
|
from typing import TYPE_CHECKING, Any, Literal, Optional, Sequence, Type
|
|
13
6
|
|
|
14
7
|
import comtypes
|
|
15
|
-
from comtypes import GUID, hresult
|
|
8
|
+
from comtypes import GUID, COMObject, IUnknown, hresult
|
|
16
9
|
from comtypes.server import IClassFactory
|
|
17
10
|
|
|
18
11
|
if TYPE_CHECKING:
|
|
@@ -40,18 +33,18 @@ _CoRevokeClassObject.argtypes = [DWORD]
|
|
|
40
33
|
_CoRevokeClassObject.restype = HRESULT
|
|
41
34
|
|
|
42
35
|
|
|
43
|
-
def run(classes: Sequence[Type[
|
|
36
|
+
def run(classes: Sequence[Type[COMObject]]) -> None:
|
|
44
37
|
classobjects = [ClassFactory(cls) for cls in classes]
|
|
45
|
-
|
|
38
|
+
COMObject.__run_localserver__(classobjects)
|
|
46
39
|
|
|
47
40
|
|
|
48
|
-
class ClassFactory(
|
|
41
|
+
class ClassFactory(COMObject):
|
|
49
42
|
_com_interfaces_ = [IClassFactory]
|
|
50
43
|
_locks: int = 0
|
|
51
44
|
_queue: Optional[queue.Queue] = None
|
|
52
45
|
regcls: int = REGCLS_MULTIPLEUSE
|
|
53
46
|
|
|
54
|
-
def __init__(self, cls: Type[
|
|
47
|
+
def __init__(self, cls: Type[COMObject], *args, **kw) -> None:
|
|
55
48
|
super(ClassFactory, self).__init__()
|
|
56
49
|
self._cls = cls
|
|
57
50
|
self._register_class()
|
|
@@ -67,11 +60,11 @@ class ClassFactory(comtypes.COMObject):
|
|
|
67
60
|
def _register_class(self) -> None:
|
|
68
61
|
regcls = getattr(self._cls, "_regcls_", self.regcls)
|
|
69
62
|
cookie = c_ulong()
|
|
70
|
-
ptr = self._com_pointers_[
|
|
71
|
-
clsctx = self._cls._reg_clsctx_
|
|
63
|
+
ptr = self._com_pointers_[IUnknown._iid_]
|
|
64
|
+
clsctx = self._cls._reg_clsctx_ # type: ignore
|
|
72
65
|
clsctx &= ~comtypes.CLSCTX_INPROC # reset the inproc flags
|
|
73
66
|
_CoRegisterClassObject(
|
|
74
|
-
byref(
|
|
67
|
+
byref(GUID(self._cls._reg_clsid_)),
|
|
75
68
|
ptr,
|
|
76
69
|
clsctx,
|
|
77
70
|
regcls,
|
|
@@ -85,8 +78,8 @@ class ClassFactory(comtypes.COMObject):
|
|
|
85
78
|
def CreateInstance(
|
|
86
79
|
self,
|
|
87
80
|
this: Any,
|
|
88
|
-
punkOuter: Optional[Type["_Pointer[
|
|
89
|
-
riid: "_Pointer[
|
|
81
|
+
punkOuter: Optional[Type["_Pointer[IUnknown]"]],
|
|
82
|
+
riid: "_Pointer[GUID]",
|
|
90
83
|
ppv: c_void_p,
|
|
91
84
|
) -> int:
|
|
92
85
|
_debug("ClassFactory.CreateInstance(%s)", riid[0])
|
|
@@ -96,8 +89,9 @@ class ClassFactory(comtypes.COMObject):
|
|
|
96
89
|
return result
|
|
97
90
|
|
|
98
91
|
def LockServer(self, this: Any, fLock: bool) -> Literal[0]:
|
|
92
|
+
assert COMObject.__server__ is not None, "The localserver is not running yet"
|
|
99
93
|
if fLock:
|
|
100
|
-
|
|
94
|
+
COMObject.__server__.Lock()
|
|
101
95
|
else:
|
|
102
|
-
|
|
96
|
+
COMObject.__server__.Unlock()
|
|
103
97
|
return hresult.S_OK
|
|
@@ -43,7 +43,7 @@ import os
|
|
|
43
43
|
import sys
|
|
44
44
|
import winreg
|
|
45
45
|
from ctypes import WinDLL, WinError
|
|
46
|
-
from ctypes.wintypes import HKEY, LONG, LPCWSTR
|
|
46
|
+
from ctypes.wintypes import HKEY, LONG, LPCWSTR, MAX_PATH
|
|
47
47
|
from typing import Iterable, Iterator, List, Optional, Tuple, Type, Union
|
|
48
48
|
from winreg import HKEY_CLASSES_ROOT as HKCR
|
|
49
49
|
from winreg import HKEY_CURRENT_USER as HKCU
|
|
@@ -242,7 +242,7 @@ class Registrar(object):
|
|
|
242
242
|
|
|
243
243
|
def _get_serverdll(handle: int) -> str:
|
|
244
244
|
"""Return the pathname of the dll hosting the COM object."""
|
|
245
|
-
return GetModuleFileName(handle,
|
|
245
|
+
return GetModuleFileName(handle, MAX_PATH)
|
|
246
246
|
|
|
247
247
|
|
|
248
248
|
class RegistryEntries(abc.ABC):
|
|
@@ -30,25 +30,24 @@ class Test(unittest.TestCase):
|
|
|
30
30
|
)
|
|
31
31
|
|
|
32
32
|
def test_invalid_constructor_arg(self):
|
|
33
|
-
self.assertRaises(WindowsError
|
|
33
|
+
with self.assertRaises(WindowsError):
|
|
34
|
+
GUID("abc")
|
|
34
35
|
|
|
35
36
|
def test_from_progid(self):
|
|
36
37
|
self.assertEqual(
|
|
37
38
|
GUID.from_progid("Scripting.FileSystemObject"),
|
|
38
39
|
GUID("{0D43FE01-F093-11CF-8940-00A0C9054228}"),
|
|
39
40
|
)
|
|
40
|
-
self.assertRaises(WindowsError
|
|
41
|
+
with self.assertRaises(WindowsError):
|
|
42
|
+
GUID.from_progid("abc")
|
|
41
43
|
|
|
42
44
|
def test_as_progid(self):
|
|
43
45
|
self.assertEqual(
|
|
44
46
|
GUID("{0D43FE01-F093-11CF-8940-00A0C9054228}").as_progid(),
|
|
45
47
|
"Scripting.FileSystemObject",
|
|
46
48
|
)
|
|
47
|
-
self.assertRaises(
|
|
48
|
-
|
|
49
|
-
lambda guid: guid.as_progid(),
|
|
50
|
-
GUID("{00000000-0000-0000-C000-000000000046}"),
|
|
51
|
-
)
|
|
49
|
+
with self.assertRaises(WindowsError):
|
|
50
|
+
GUID("{00000000-0000-0000-C000-000000000046}").as_progid()
|
|
52
51
|
|
|
53
52
|
def test_create_new(self):
|
|
54
53
|
self.assertNotEqual(GUID.create_new(), GUID.create_new())
|
|
@@ -61,7 +61,8 @@ class BasicTest(ut.TestCase):
|
|
|
61
61
|
self.assertEqual(method_count(IMyInterface), 3)
|
|
62
62
|
|
|
63
63
|
# assigning _methods_ does not work until we have an _iid_!
|
|
64
|
-
self.assertRaises(AttributeError
|
|
64
|
+
with self.assertRaises(AttributeError):
|
|
65
|
+
setattr(IMyInterface, "_methods_", [])
|
|
65
66
|
IMyInterface._iid_ = GUID.create_new()
|
|
66
67
|
IMyInterface._methods_ = []
|
|
67
68
|
self.assertEqual(method_count(IMyInterface), 3)
|
|
@@ -96,9 +97,11 @@ class BasicTest(ut.TestCase):
|
|
|
96
97
|
_iid_ = GUID.create_new()
|
|
97
98
|
|
|
98
99
|
# We cannot assign _methods_ to IDerived before IBase has it's _methods_:
|
|
99
|
-
self.assertRaises(TypeError
|
|
100
|
+
with self.assertRaises(TypeError):
|
|
101
|
+
setattr(IDerived, "_methods_", [])
|
|
100
102
|
# Make sure that setting _methods_ failed completely.
|
|
101
|
-
self.assertRaises(KeyError
|
|
103
|
+
with self.assertRaises(KeyError):
|
|
104
|
+
IDerived.__dict__["_methods_"]
|
|
102
105
|
IBase._methods_ = []
|
|
103
106
|
# Now it works:
|
|
104
107
|
IDerived._methods_ = []
|
|
@@ -60,7 +60,8 @@ class Test(unittest.TestCase):
|
|
|
60
60
|
|
|
61
61
|
# slicing is not (yet?) supported
|
|
62
62
|
cv.Reset()
|
|
63
|
-
self.assertRaises(ArgumentError
|
|
63
|
+
with self.assertRaises(ArgumentError):
|
|
64
|
+
cv[:]
|
|
64
65
|
|
|
65
66
|
@unittest.skip("This test takes a long time. Do we need it? Can it be rewritten?")
|
|
66
67
|
def test_leaks_1(self):
|
|
@@ -151,10 +152,12 @@ class TestCollectionInterface(unittest.TestCase):
|
|
|
151
152
|
self.assertAccessInterface(d)
|
|
152
153
|
|
|
153
154
|
def test_named_property_no_length(self):
|
|
154
|
-
self.assertRaises(TypeError
|
|
155
|
+
with self.assertRaises(TypeError):
|
|
156
|
+
len(self.d.Item)
|
|
155
157
|
|
|
156
158
|
def test_named_property_not_iterable(self):
|
|
157
|
-
self.assertRaises(TypeError
|
|
159
|
+
with self.assertRaises(TypeError):
|
|
160
|
+
list(self.d.Item)
|
|
158
161
|
|
|
159
162
|
|
|
160
163
|
if __name__ == "__main__":
|
|
@@ -4,9 +4,10 @@ from ctypes import POINTER, byref, pointer
|
|
|
4
4
|
from unittest import mock
|
|
5
5
|
|
|
6
6
|
import comtypes.client
|
|
7
|
-
from comtypes import CLSCTX_SERVER, COMObject, IUnknown, hresult
|
|
7
|
+
from comtypes import CLSCTX_SERVER, COMObject, IPersist, IUnknown, hresult
|
|
8
8
|
from comtypes._post_coinit.misc import _CoCreateInstance
|
|
9
9
|
from comtypes.automation import IDispatch
|
|
10
|
+
from comtypes.typeinfo import GUIDKIND_DEFAULT_SOURCE_DISP_IID
|
|
10
11
|
|
|
11
12
|
comtypes.client.GetModule("UIAutomationCore.dll")
|
|
12
13
|
comtypes.client.GetModule("scrrun.dll")
|
|
@@ -131,11 +132,9 @@ class Test_IProvideClassInfo_GetClassInfo(ut.TestCase):
|
|
|
131
132
|
|
|
132
133
|
class Test_IProvideClassInfo2_GetGUID(ut.TestCase):
|
|
133
134
|
def test(self):
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
stdole.FontEvents._iid_,
|
|
138
|
-
)
|
|
135
|
+
obj = stdole.StdFont()
|
|
136
|
+
actual = obj.IProvideClassInfo2_GetGUID(GUIDKIND_DEFAULT_SOURCE_DISP_IID)
|
|
137
|
+
self.assertEqual(actual, stdole.FontEvents._iid_)
|
|
139
138
|
|
|
140
139
|
|
|
141
140
|
class Test_IPersist_GetClassID(ut.TestCase):
|
|
@@ -144,3 +143,17 @@ class Test_IPersist_GetClassID(ut.TestCase):
|
|
|
144
143
|
uiac.CUIAutomation().IPersist_GetClassID(),
|
|
145
144
|
uiac.CUIAutomation._reg_clsid_,
|
|
146
145
|
)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class Test_Vtbl(ut.TestCase):
|
|
149
|
+
def test_com_pointers(self):
|
|
150
|
+
stdpic = stdole.StdPicture()
|
|
151
|
+
cuia = uiac.CUIAutomation()
|
|
152
|
+
self.assertIs(
|
|
153
|
+
type(stdpic._com_pointers_[IPersist._iid_]),
|
|
154
|
+
type(cuia._com_pointers_[IPersist._iid_]),
|
|
155
|
+
)
|
|
156
|
+
self.assertIn(IDispatch._iid_, stdpic._com_pointers_)
|
|
157
|
+
self.assertNotIn(IDispatch._iid_, cuia._com_pointers_)
|
|
158
|
+
self.assertIn(stdole.IPictureDisp._iid_, stdpic._com_pointers_)
|
|
159
|
+
self.assertIn(uiac.IUIAutomation._iid_, cuia._com_pointers_)
|
|
@@ -5,7 +5,7 @@ from typing import Any
|
|
|
5
5
|
|
|
6
6
|
import comtypes.server
|
|
7
7
|
import comtypes.test.TestComServer
|
|
8
|
-
from comtypes import BSTR
|
|
8
|
+
from comtypes import BSTR, errorinfo, hresult, shelllink
|
|
9
9
|
from comtypes.automation import VARIANT, _midlSAFEARRAY
|
|
10
10
|
from comtypes.client import CreateObject, GetActiveObject
|
|
11
11
|
from comtypes.server.register import register, unregister
|
|
@@ -201,6 +201,26 @@ class ActiveObjTest(unittest.TestCase):
|
|
|
201
201
|
self._doit(weak=False)
|
|
202
202
|
|
|
203
203
|
|
|
204
|
+
class SupportErrorInfoTest(unittest.TestCase):
|
|
205
|
+
def create_object(self):
|
|
206
|
+
return CreateObject(
|
|
207
|
+
comtypes.test.TestComServer.TestComServer,
|
|
208
|
+
interface=comtypes.test.TestComServer.ITestComServer,
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
def test_returns_S_OK(self):
|
|
212
|
+
psei = self.create_object().QueryInterface(errorinfo.ISupportErrorInfo)
|
|
213
|
+
iid = comtypes.test.TestComServer.ITestComServer._iid_
|
|
214
|
+
hr = psei.InterfaceSupportsErrorInfo(iid)
|
|
215
|
+
self.assertEqual(hr, hresult.S_OK)
|
|
216
|
+
|
|
217
|
+
def test_returns_S_FALSE(self):
|
|
218
|
+
psei = self.create_object().QueryInterface(errorinfo.ISupportErrorInfo)
|
|
219
|
+
iid = shelllink.IShellLinkW._iid_
|
|
220
|
+
hr = psei.InterfaceSupportsErrorInfo(iid)
|
|
221
|
+
self.assertEqual(hr, hresult.S_FALSE)
|
|
222
|
+
|
|
223
|
+
|
|
204
224
|
class VariantTest(unittest.TestCase):
|
|
205
225
|
def test_UDT(self):
|
|
206
226
|
from comtypes.gen.TestComServerLib import MYCOLOR
|
|
@@ -277,7 +297,10 @@ class TestEvents(unittest.TestCase):
|
|
|
277
297
|
import comtypes.test.test_comserver
|
|
278
298
|
|
|
279
299
|
doctest.testmod(
|
|
280
|
-
comtypes.test.test_comserver,
|
|
300
|
+
comtypes.test.test_comserver,
|
|
301
|
+
verbose=False,
|
|
302
|
+
optionflags=doctest.ELLIPSIS,
|
|
303
|
+
raise_on_error=True,
|
|
281
304
|
)
|
|
282
305
|
|
|
283
306
|
|
|
@@ -14,7 +14,8 @@ class Test(unittest.TestCase):
|
|
|
14
14
|
|
|
15
15
|
# Count is a normal propget, no propput
|
|
16
16
|
self.assertEqual(d.Count, 0)
|
|
17
|
-
self.assertRaises(AttributeError
|
|
17
|
+
with self.assertRaises(AttributeError):
|
|
18
|
+
setattr(d, "Count", -1)
|
|
18
19
|
|
|
19
20
|
# HashVal is a 'named' propget, no propput
|
|
20
21
|
##d.HashVal
|
|
@@ -66,10 +66,12 @@ class Test(unittest.TestCase):
|
|
|
66
66
|
self.assertEqual(d3.Item["baz"], 3.14)
|
|
67
67
|
|
|
68
68
|
def test_named_property_no_length(self):
|
|
69
|
-
self.assertRaises(TypeError
|
|
69
|
+
with self.assertRaises(TypeError):
|
|
70
|
+
len(self.d.Item)
|
|
70
71
|
|
|
71
72
|
def test_named_property_not_iterable(self):
|
|
72
|
-
self.assertRaises(TypeError
|
|
73
|
+
with self.assertRaises(TypeError):
|
|
74
|
+
list(self.d.Item)
|
|
73
75
|
|
|
74
76
|
def assertAccessInterface(self, d):
|
|
75
77
|
"""Asserts access via indexing and named property"""
|