comtypes 1.4.10__zip → 1.4.12__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.
Files changed (151) hide show
  1. {comtypes-1.4.10 → comtypes-1.4.12}/CHANGES.txt +48 -0
  2. {comtypes-1.4.10/comtypes.egg-info → comtypes-1.4.12}/PKG-INFO +4 -3
  3. {comtypes-1.4.10 → comtypes-1.4.12}/README.md +1 -1
  4. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/__init__.py +11 -5
  5. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_comobject.py +29 -31
  6. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_memberspec.py +107 -81
  7. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_meta.py +1 -1
  8. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_npsupport.py +12 -17
  9. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_post_coinit/_cominterface_meta_patcher.py +8 -10
  10. comtypes-1.4.12/comtypes/_post_coinit/activeobj.py +61 -0
  11. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_post_coinit/misc.py +1 -23
  12. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_post_coinit/unknwn.py +33 -26
  13. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_vtbl.py +55 -58
  14. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/automation.py +19 -23
  15. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/__init__.py +2 -1
  16. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/_activeobj.py +8 -0
  17. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/_code_cache.py +10 -24
  18. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/_constants.py +1 -1
  19. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/_events.py +92 -54
  20. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/_generate.py +1 -3
  21. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/dynamic.py +3 -3
  22. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/lazybind.py +3 -3
  23. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/connectionpoints.py +37 -3
  24. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/errorinfo.py +54 -16
  25. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/hints.pyi +15 -2
  26. comtypes-1.4.12/comtypes/hresult.py +159 -0
  27. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/messageloop.py +15 -13
  28. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/patcher.py +2 -2
  29. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/persist.py +9 -2
  30. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/safearray.py +10 -10
  31. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/server/__init__.py +5 -37
  32. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/server/automation.py +2 -2
  33. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/server/connectionpoints.py +71 -70
  34. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/server/inprocserver.py +10 -7
  35. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/server/localserver.py +16 -22
  36. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/server/register.py +7 -7
  37. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_GUID.py +6 -7
  38. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_agilent.py +1 -1
  39. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_basic.py +6 -3
  40. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_client_dynamic.py +1 -1
  41. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_collections.py +6 -3
  42. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_comobject.py +19 -6
  43. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_comserver.py +32 -4
  44. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_createwrappers.py +1 -1
  45. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_dict.py +2 -1
  46. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_dispifc_records.py +0 -2
  47. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_dispifc_safearrays.py +0 -2
  48. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_dispinterface.py +1 -1
  49. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_dyndispatch.py +4 -2
  50. comtypes-1.4.12/comtypes/test/test_errorinfo.py +115 -0
  51. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_excel.py +1 -3
  52. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_getactiveobj.py +19 -2
  53. comtypes-1.4.12/comtypes/test/test_hresult.py +87 -0
  54. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_inout_args.py +9 -2
  55. comtypes-1.4.12/comtypes/test/test_messageloop.py +117 -0
  56. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_midl_safearray_create.py +0 -2
  57. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_msscript.py +1 -1
  58. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_npsupport.py +22 -11
  59. comtypes-1.4.12/comtypes/test/test_persist.py +71 -0
  60. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_recordinfo.py +0 -2
  61. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_safearray.py +2 -1
  62. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_server.py +6 -6
  63. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_server_register.py +2 -1
  64. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_storage.py +1 -1
  65. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_stream.py +22 -2
  66. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_typeinfo.py +19 -2
  67. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_urlhistory.py +1 -1
  68. comtypes-1.4.12/comtypes/test/test_util.py +227 -0
  69. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_variant.py +43 -25
  70. comtypes-1.4.12/comtypes/test/test_viewobject.py +78 -0
  71. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_w_getopt.py +4 -4
  72. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_word.py +1 -1
  73. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/codegenerator.py +1 -1
  74. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/comments.py +1 -1
  75. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/heads.py +5 -5
  76. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/helpers.py +7 -7
  77. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/namespaces.py +3 -3
  78. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/typeannotator.py +2 -2
  79. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/tlbparser.py +8 -7
  80. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/typedesc.py +14 -14
  81. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/typedesc_base.py +19 -19
  82. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/typeinfo.py +14 -9
  83. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/util.py +38 -6
  84. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/viewobject.py +29 -5
  85. {comtypes-1.4.10 → comtypes-1.4.12/comtypes.egg-info}/PKG-INFO +4 -3
  86. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes.egg-info/SOURCES.txt +6 -0
  87. {comtypes-1.4.10 → comtypes-1.4.12}/pyproject.toml +13 -7
  88. comtypes-1.4.10/comtypes/hresult.py +0 -81
  89. comtypes-1.4.10/comtypes/test/test_persist.py +0 -38
  90. {comtypes-1.4.10 → comtypes-1.4.12}/LICENSE.txt +0 -0
  91. {comtypes-1.4.10 → comtypes-1.4.12}/MANIFEST.in +0 -0
  92. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/GUID.py +0 -0
  93. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_post_coinit/__init__.py +0 -0
  94. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_post_coinit/bstr.py +0 -0
  95. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_post_coinit/instancemethod.py +0 -0
  96. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_safearray.py +0 -0
  97. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_tlib_version_checker.py +0 -0
  98. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/clear_cache.py +0 -0
  99. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/_create.py +0 -0
  100. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/_managing.py +0 -0
  101. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/git.py +0 -0
  102. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/logutil.py +0 -0
  103. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/server/w_getopt.py +0 -0
  104. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/shelllink.py +0 -0
  105. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/stream.py +0 -0
  106. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/TestComServer.idl +0 -0
  107. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/TestComServer.py +0 -0
  108. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/TestComServer.tlb +0 -0
  109. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/TestDispServer.idl +0 -0
  110. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/TestDispServer.py +0 -0
  111. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/TestDispServer.tlb +0 -0
  112. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/__init__.py +0 -0
  113. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/find_memleak.py +0 -0
  114. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/mylib.idl +0 -0
  115. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/mylib.tlb +0 -0
  116. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/mytypelib.idl +0 -0
  117. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/runtests.py +0 -0
  118. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/setup.py +0 -0
  119. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_BSTR.py +0 -0
  120. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_DISPPARAMS.py +0 -0
  121. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_QueryService.py +0 -0
  122. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_avmc.py +0 -0
  123. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_casesensitivity.py +0 -0
  124. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_clear_cache.py +0 -0
  125. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_client.py +0 -0
  126. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_client_regenerate_modules.py +0 -0
  127. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_findgendir.py +0 -0
  128. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_ie.py +0 -0
  129. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_ienum.py +0 -0
  130. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_imfattributes.py +0 -0
  131. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_jscript.js +0 -0
  132. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_monikers.py +0 -0
  133. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_outparam.py +0 -0
  134. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_pump_events.py +0 -0
  135. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_sapi.py +0 -0
  136. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_shelllink.py +0 -0
  137. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_showevents.py +0 -0
  138. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_subinterface.py +0 -0
  139. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_typeannotator.py +0 -0
  140. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_win32com_interop.py +0 -0
  141. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_wmi.py +0 -0
  142. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/urlhist.tlb +0 -0
  143. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/__init__.py +0 -0
  144. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/__init__.py +0 -0
  145. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/modulenamer.py +0 -0
  146. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/packing.py +0 -0
  147. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes.egg-info/dependency_links.txt +0 -0
  148. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes.egg-info/entry_points.txt +0 -0
  149. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes.egg-info/top_level.txt +0 -0
  150. {comtypes-1.4.10 → comtypes-1.4.12}/setup.cfg +0 -0
  151. {comtypes-1.4.10 → comtypes-1.4.12}/setup.py +0 -0
@@ -2,14 +2,19 @@
2
2
 
3
3
  import logging
4
4
  from ctypes import HRESULT, POINTER, byref, c_ulong, c_void_p
5
- from typing import TYPE_CHECKING, ClassVar, List, Optional, Type, TypeVar
5
+ from typing import TYPE_CHECKING, Any, ClassVar, List, Optional, Type, TypeVar
6
6
 
7
- from comtypes import GUID, _CoUninitialize, com_interface_registry
7
+ import comtypes
8
+ from comtypes import GUID, _CoUninitialize
8
9
  from comtypes._memberspec import STDMETHOD, ComMemberGenerator, DispMemberGenerator
9
10
  from comtypes._post_coinit import _cominterface_meta_patcher as _meta_patch
10
11
  from comtypes._post_coinit.instancemethod import instancemethod
11
12
 
12
13
  if TYPE_CHECKING:
14
+ from typing import Literal
15
+ from typing import Union as _UnionT
16
+
17
+ from comtypes import hints # type: ignore
13
18
  from comtypes._memberspec import _ComMemberSpec, _DispMemberSpec
14
19
 
15
20
  logger = logging.getLogger(__name__)
@@ -18,7 +23,7 @@ logger = logging.getLogger(__name__)
18
23
  def _shutdown(
19
24
  func=_CoUninitialize,
20
25
  _debug=logger.debug,
21
- ):
26
+ ) -> None:
22
27
  # Sometimes, CoUninitialize, running at Python shutdown,
23
28
  # raises an exception. We suppress this when __debug__ is
24
29
  # False.
@@ -28,7 +33,7 @@ def _shutdown(
28
33
  else:
29
34
  try:
30
35
  func()
31
- except WindowsError:
36
+ except OSError:
32
37
  pass
33
38
  # Set the flag which means that calling obj.Release() is no longer
34
39
  # needed.
@@ -131,7 +136,7 @@ class _cominterface_meta(type):
131
136
 
132
137
  return self
133
138
 
134
- def __setattr__(self, name, value):
139
+ def __setattr__(self, name: str, value: Any) -> None:
135
140
  if name == "_methods_":
136
141
  # XXX I'm no longer sure why the code generator generates
137
142
  # "_methods_ = []" in the interface definition, and later
@@ -145,11 +150,11 @@ class _cominterface_meta(type):
145
150
  self._make_specials()
146
151
  type.__setattr__(self, name, value)
147
152
 
148
- def _make_specials(self):
153
+ def _make_specials(self) -> None:
149
154
  # This call installs methods that forward the Python protocols
150
155
  # to COM protocols.
151
156
 
152
- def has_name(name):
157
+ def has_name(name: str) -> bool:
153
158
  # Determine whether a property or method named 'name'
154
159
  # exists
155
160
  if self._case_insensitive_:
@@ -164,7 +169,7 @@ class _cominterface_meta(type):
164
169
  if has_name("_NewEnum"):
165
170
  _meta_patch.iterator(self)
166
171
 
167
- def _make_case_insensitive(self):
172
+ def _make_case_insensitive(self) -> None:
168
173
  # The __map_case__ dictionary maps lower case names to the
169
174
  # names in the original spelling to enable case insensitive
170
175
  # method and attribute access.
@@ -197,7 +202,7 @@ class _cominterface_meta(type):
197
202
  if self._case_insensitive_:
198
203
  self.__map_case__[name.lower()] = name
199
204
 
200
- def __get_baseinterface_methodcount(self):
205
+ def __get_baseinterface_methodcount(self) -> int:
201
206
  "Return the number of com methods in the base interfaces"
202
207
  result = 0
203
208
  for itf in self.mro()[1:-1]:
@@ -216,7 +221,7 @@ class _cominterface_meta(type):
216
221
  except KeyError:
217
222
  raise AttributeError("this class must define an _iid_")
218
223
  else:
219
- com_interface_registry[str(iid)] = self
224
+ comtypes.com_interface_registry[str(iid)] = self # type: ignore
220
225
  # create members
221
226
  vtbl_offset = self.__get_baseinterface_methodcount()
222
227
  member_gen = ComMemberGenerator(self.__name__, vtbl_offset, self._iid_)
@@ -261,7 +266,10 @@ class _compointer_meta(type(c_void_p), _cominterface_meta):
261
266
  class _compointer_base(c_void_p, metaclass=_compointer_meta):
262
267
  "base class for COM interface pointer classes"
263
268
 
264
- def __del__(self, _debug=logger.debug):
269
+ if TYPE_CHECKING:
270
+ __com_interface__: ClassVar[Type["IUnknown"]]
271
+
272
+ def __del__(self, _debug=logger.debug) -> None:
265
273
  "Release the COM refcount we own."
266
274
  if self:
267
275
  # comtypes calls CoUninitialize() when the atexit handlers
@@ -275,40 +283,39 @@ class _compointer_base(c_void_p, metaclass=_compointer_meta):
275
283
  _debug("Release %s", self)
276
284
  self.Release() # type: ignore
277
285
 
278
- def __eq__(self, other):
286
+ def __eq__(self, other) -> bool:
279
287
  if not isinstance(other, _compointer_base):
280
288
  return False
281
289
  # get the value property of the c_void_p baseclass, this is the pointer value
282
- return (
283
- super(_compointer_base, self).value == super(_compointer_base, other).value
284
- )
290
+ return super().value == super(_compointer_base, other).value
285
291
 
286
- def __hash__(self):
292
+ def __hash__(self) -> int:
287
293
  """Return the hash value of the pointer."""
288
294
  # hash the pointer values
289
- return hash(super(_compointer_base, self).value)
295
+ return hash(super().value)
290
296
 
291
297
  # redefine the .value property; return the object itself.
292
- def __get_value(self):
298
+ def __get_value(self) -> "hints.Self":
293
299
  return self
294
300
 
295
301
  value = property(__get_value, doc="""Return self.""")
296
302
 
297
- def __repr__(self):
298
- ptr = super(_compointer_base, self).value
303
+ def __repr__(self) -> str:
304
+ ptr = super().value
299
305
  return f"<{self.__class__.__name__} ptr=0x{ptr or 0:x} at {id(self):x}>"
300
306
 
301
307
  # This fixes the problem when there are multiple python interface types
302
308
  # wrapping the same COM interface. This could happen because some interfaces
303
309
  # are contained in multiple typelibs.
304
310
  #
305
- # It also allows to pass a CoClass instance to an api
306
- # expecting a COM interface.
311
+ # It also allows to pass a COMObject instance to an api expecting a COM interface.
307
312
  @classmethod
308
- def from_param(cls, value):
313
+ def from_param(
314
+ cls, value: "_UnionT[None, Literal[0], hints.Self, IUnknown, hints.COMObject]"
315
+ ) -> Any:
309
316
  """Convert 'value' into a COM pointer to the interface.
310
317
 
311
- This method accepts a COM pointer, or a CoClass instance
318
+ This method accepts a COM pointer, or a COMObject/CoClass instance
312
319
  which is QueryInterface()d."""
313
320
  if value is None:
314
321
  return None
@@ -322,9 +329,9 @@ class _compointer_base(c_void_p, metaclass=_compointer_meta):
322
329
  # Do we need more checks here?
323
330
  if cls._iid_ == getattr(value, "_iid_", None):
324
331
  return value
325
- # Accept an CoClass instance which exposes the interface required.
332
+ # Accept an COMObject instance which exposes the interface required.
326
333
  try:
327
- table = value._com_pointers_
334
+ table = value._com_pointers_ # type: ignore
328
335
  except AttributeError:
329
336
  pass
330
337
  else:
@@ -17,29 +17,26 @@ from typing import Union as _UnionT
17
17
 
18
18
  import comtypes
19
19
  from comtypes import GUID, IUnknown, hresult
20
- from comtypes._memberspec import _encode_idl
20
+ from comtypes._memberspec import (
21
+ DISPATCH_METHOD,
22
+ DISPATCH_PROPERTYGET,
23
+ DISPATCH_PROPERTYPUT,
24
+ DISPATCH_PROPERTYPUTREF,
25
+ _encode_idl,
26
+ )
21
27
  from comtypes.errorinfo import ReportError, ReportException
22
28
 
23
29
  if TYPE_CHECKING:
24
30
  from ctypes import _FuncPointer
25
31
 
26
32
  from comtypes import hints # type: ignore
27
- from comtypes._memberspec import _ArgSpecElmType, _DispMemberSpec, _ParamFlagType
33
+ from comtypes._memberspec import _ComIdlFlags, _DispIdlFlags, _DispMemberSpec
28
34
 
29
35
  logger = logging.getLogger(__name__)
30
36
  _debug = logger.debug
31
37
  _warning = logger.warning
32
38
  _error = logger.error
33
39
 
34
- ################################################################
35
- # COM object implementation
36
-
37
- # so we don't have to import comtypes.automation
38
- DISPATCH_METHOD = 1
39
- DISPATCH_PROPERTYGET = 2
40
- DISPATCH_PROPERTYPUT = 4
41
- DISPATCH_PROPERTYPUTREF = 8
42
-
43
40
 
44
41
  class E_NotImplemented(Exception):
45
42
  """COM method is not implemented"""
@@ -84,7 +81,7 @@ def _do_implement(interface_name: str, method_name: str) -> Callable[..., int]:
84
81
  def catch_errors(
85
82
  obj: "hints.COMObject",
86
83
  mth: Callable[..., Any],
87
- paramflags: Optional[Tuple["_ParamFlagType", ...]],
84
+ paramflags: Optional[Tuple["hints.ParamFlagType", ...]],
88
85
  interface: Type[IUnknown],
89
86
  mthname: str,
90
87
  ) -> Callable[..., Any]:
@@ -96,7 +93,7 @@ def catch_errors(
96
93
  except comtypes.ReturnHRESULT as err:
97
94
  (hr, text) = err.args
98
95
  return ReportError(text, iid=interface._iid_, clsid=clsid, hresult=hr)
99
- except (COMError, WindowsError) as details:
96
+ except (OSError, COMError) as details:
100
97
  _error(
101
98
  "Exception in %s.%s implementation:",
102
99
  interface.__name__,
@@ -133,7 +130,7 @@ def catch_errors(
133
130
  def hack(
134
131
  inst: "hints.COMObject",
135
132
  mth: Callable[..., Any],
136
- paramflags: Optional[Tuple["_ParamFlagType", ...]],
133
+ paramflags: Optional[Tuple["hints.ParamFlagType", ...]],
137
134
  interface: Type[IUnknown],
138
135
  mthname: str,
139
136
  ) -> Callable[..., Any]:
@@ -204,7 +201,7 @@ def hack(
204
201
  msg = f"{source}: {descr}"
205
202
  hr = HRESULT_FROM_WIN32(hr)
206
203
  return ReportError(msg, iid=interface._iid_, clsid=clsid, hresult=hr)
207
- except WindowsError as details:
204
+ except OSError as details:
208
205
  _error(
209
206
  "Exception in %s.%s implementation:",
210
207
  interface.__name__,
@@ -231,7 +228,7 @@ def hack(
231
228
  return call_without_this
232
229
 
233
230
 
234
- class _MethodFinder(object):
231
+ class _MethodFinder:
235
232
  def __init__(self, inst: "hints.COMObject") -> None:
236
233
  self.inst = inst
237
234
  # map lower case names to names with correct spelling.
@@ -241,8 +238,8 @@ class _MethodFinder(object):
241
238
  self,
242
239
  interface: Type[IUnknown],
243
240
  mthname: str,
244
- paramflags: Optional[Tuple["_ParamFlagType", ...]],
245
- idlflags: Tuple[_UnionT[str, int], ...],
241
+ paramflags: Optional[Tuple["hints.ParamFlagType", ...]],
242
+ idlflags: _UnionT["_ComIdlFlags", "_DispIdlFlags"],
246
243
  ) -> Callable[..., Any]:
247
244
  mth = self.find_impl(interface, mthname, paramflags, idlflags)
248
245
  if mth is None:
@@ -263,8 +260,8 @@ class _MethodFinder(object):
263
260
  self,
264
261
  interface: Type[IUnknown],
265
262
  mthname: str,
266
- paramflags: Optional[Tuple["_ParamFlagType", ...]],
267
- idlflags: Tuple[_UnionT[str, int], ...],
263
+ paramflags: Optional[Tuple["hints.ParamFlagType", ...]],
264
+ idlflags: _UnionT["_ComIdlFlags", "_DispIdlFlags"],
268
265
  ) -> Optional[Callable[..., Any]]:
269
266
  fq_name = f"{interface.__name__}_{mthname}"
270
267
  if interface._case_insensitive_:
@@ -340,25 +337,29 @@ def create_vtbl_mapping(
340
337
  methods: List[Callable[..., Any]] = [] # method implementations
341
338
  fields: List[Tuple[str, Type["_FuncPointer"]]] = [] # virtual function table
342
339
  iids: List[GUID] = [] # interface identifiers.
343
- # iterate over interface inheritance in reverse order to build the
344
- # virtual function table, and leave out the 'object' base class.
345
- for interface in itf.__mro__[-2::-1]:
340
+ for interface in _walk_itf_bases(itf):
346
341
  iids.append(interface._iid_)
347
342
  for m in interface._methods_:
348
- restype, mthname, argtypes, paramflags, idlflags, helptext = m
349
- proto = WINFUNCTYPE(restype, c_void_p, *argtypes)
350
- fields.append((mthname, proto))
351
- mth = finder.get_impl(interface, mthname, paramflags, idlflags)
343
+ proto = WINFUNCTYPE(m.restype, c_void_p, *m.argtypes)
344
+ fields.append((m.name, proto))
345
+ mth = finder.get_impl(interface, m.name, m.paramflags, m.idlflags)
352
346
  methods.append(proto(mth))
353
347
  Vtbl = _create_vtbl_type(tuple(fields), itf)
354
348
  vtbl = Vtbl(*methods)
355
349
  return (iids, vtbl)
356
350
 
357
351
 
352
+ def _walk_itf_bases(itf: Type[IUnknown]) -> Iterator[Type[IUnknown]]:
353
+ """Iterates over interface inheritance in reverse order to build the
354
+ virtual function table, and leave out the 'object' base class.
355
+ """
356
+ yield from itf.__mro__[-2::-1]
357
+
358
+
358
359
  def create_dispimpl(
359
360
  itf: Type[IUnknown], finder: _MethodFinder
360
- ) -> Dict[Tuple[int, int], Callable[..., Any]]:
361
- dispimpl: Dict[Tuple[int, int], Callable[..., Any]] = {}
361
+ ) -> Dict[Tuple[comtypes.dispid, int], Callable[..., Any]]:
362
+ dispimpl: Dict[Tuple[comtypes.dispid, int], Callable[..., Any]] = {}
362
363
  for m in itf._disp_methods_:
363
364
  #################
364
365
  # What we have:
@@ -374,13 +375,6 @@ def create_dispimpl(
374
375
  #
375
376
  # paramflags must be a sequence
376
377
  # of (F_IN|F_OUT|F_RETVAL, paramname[, default-value]) tuples
377
- #
378
- # comtypes has this function which helps:
379
- # def _encode_idl(names):
380
- # # convert to F_xxx and sum up "in", "out",
381
- # # "retval" values found in _PARAMFLAGS, ignoring
382
- # # other stuff.
383
- # return sum([_PARAMFLAGS.get(n, 0) for n in names])
384
378
  #################
385
379
 
386
380
  if m.what == "DISPMETHOD":
@@ -392,37 +386,40 @@ def create_dispimpl(
392
386
 
393
387
  def _make_dispmthentry(
394
388
  itf: Type[IUnknown], finder: _MethodFinder, m: "_DispMemberSpec"
395
- ) -> Iterator[Tuple[Tuple[int, int], Callable[..., Any]]]:
396
- _, mthname, idlflags, restype, argspec = m
397
- if "propget" in idlflags:
389
+ ) -> Iterator[Tuple[Tuple[comtypes.dispid, int], Callable[..., Any]]]:
390
+ if "propget" in m.idlflags:
398
391
  invkind = DISPATCH_PROPERTYGET
399
- mthname = f"_get_{mthname}"
400
- elif "propput" in idlflags:
392
+ mthname = f"_get_{m.name}"
393
+ elif "propput" in m.idlflags:
401
394
  invkind = DISPATCH_PROPERTYPUT
402
- mthname = f"_set_{mthname}"
403
- elif "propputref" in idlflags:
395
+ mthname = f"_set_{m.name}"
396
+ elif "propputref" in m.idlflags:
404
397
  invkind = DISPATCH_PROPERTYPUTREF
405
- mthname = f"_setref_{mthname}"
398
+ mthname = f"_setref_{m.name}"
406
399
  else:
407
400
  invkind = DISPATCH_METHOD
408
- if restype:
409
- argspec = argspec + ((["out"], restype, ""),)
410
- yield from _make_dispentry(finder, itf, mthname, idlflags, argspec, invkind)
401
+ if m.restype:
402
+ argspec = m.argspec + ((["out"], m.restype, ""),)
403
+ else:
404
+ argspec = m.argspec
405
+ mthname = m.name
406
+ yield from _make_dispentry(finder, itf, mthname, m.idlflags, argspec, invkind)
411
407
 
412
408
 
413
409
  def _make_disppropentry(
414
410
  itf: Type[IUnknown], finder: _MethodFinder, m: "_DispMemberSpec"
415
- ) -> Iterator[Tuple[Tuple[int, int], Callable[..., Any]]]:
416
- _, mthname, idlflags, restype, argspec = m
417
- # DISPPROPERTY have implicit "out"
418
- if restype:
419
- argspec += ((["out"], restype, ""),)
411
+ ) -> Iterator[Tuple[Tuple[comtypes.dispid, int], Callable[..., Any]]]:
412
+ if m.restype:
413
+ # DISPPROPERTY have implicit "out"
414
+ argspec = m.argspec + ((["out"], m.restype, ""),)
415
+ else:
416
+ argspec = m.argspec
420
417
  yield from _make_dispentry(
421
- finder, itf, f"_get_{mthname}", idlflags, argspec, DISPATCH_PROPERTYGET
418
+ finder, itf, f"_get_{m.name}", m.idlflags, argspec, DISPATCH_PROPERTYGET
422
419
  )
423
- if "readonly" not in idlflags:
420
+ if "readonly" not in m.idlflags:
424
421
  yield from _make_dispentry(
425
- finder, itf, f"_set_{mthname}", idlflags, argspec, DISPATCH_PROPERTYPUT
422
+ finder, itf, f"_set_{m.name}", m.idlflags, argspec, DISPATCH_PROPERTYPUT
426
423
  )
427
424
  # Add DISPATCH_PROPERTYPUTREF also?
428
425
 
@@ -431,10 +428,10 @@ def _make_dispentry(
431
428
  finder: _MethodFinder,
432
429
  interface: Type[IUnknown],
433
430
  mthname: str,
434
- idlflags: Tuple[_UnionT[str, int], ...],
435
- argspec: Tuple["_ArgSpecElmType", ...],
431
+ idlflags: "_DispIdlFlags",
432
+ argspec: Tuple["hints.ArgSpecElmType", ...],
436
433
  invkind: int,
437
- ) -> Iterator[Tuple[Tuple[int, int], Callable[..., Any]]]:
434
+ ) -> Iterator[Tuple[Tuple[comtypes.dispid, int], Callable[..., Any]]]:
438
435
  # We build a _dispmap_ entry now that maps invkind and dispid to
439
436
  # implementations that the finder finds; IDispatch_Invoke will later call it.
440
437
  paramflags = tuple(((_encode_idl(x[0]), x[1]) + tuple(x[3:])) for x in argspec)
@@ -11,12 +11,16 @@ from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Optional, Type
11
11
 
12
12
  import comtypes
13
13
  import comtypes.patcher
14
- from comtypes import BSTR, COMMETHOD, GUID, IID, STDMETHOD, IUnknown, _CData, _safearray
14
+ from comtypes import BSTR, COMMETHOD, GUID, IID, STDMETHOD, IUnknown, _safearray
15
15
  from comtypes import hresult as hresult
16
+ from comtypes._memberspec import DISPATCH_METHOD as DISPATCH_METHOD
17
+ from comtypes._memberspec import DISPATCH_PROPERTYGET as DISPATCH_PROPERTYGET
18
+ from comtypes._memberspec import DISPATCH_PROPERTYPUT as DISPATCH_PROPERTYPUT
19
+ from comtypes._memberspec import DISPATCH_PROPERTYPUTREF as DISPATCH_PROPERTYPUTREF
16
20
  from comtypes.safearray import _midlSAFEARRAY
17
21
 
18
22
  if TYPE_CHECKING:
19
- from ctypes import _CArgObject
23
+ from ctypes import _CArgObject, _CDataType
20
24
 
21
25
  from comtypes import hints # type: ignore
22
26
  from comtypes._memberspec import _DispMemberSpec
@@ -30,11 +34,6 @@ SCODE = LONG
30
34
 
31
35
  VARTYPE = c_ushort
32
36
 
33
- DISPATCH_METHOD = 1
34
- DISPATCH_PROPERTYGET = 2
35
- DISPATCH_PROPERTYPUT = 4
36
- DISPATCH_PROPERTYPUTREF = 8
37
-
38
37
  tagINVOKEKIND = c_int
39
38
  INVOKE_FUNC = DISPATCH_METHOD
40
39
  INVOKE_PROPERTYGET = DISPATCH_PROPERTYGET
@@ -246,9 +245,6 @@ class tagVARIANT(Structure):
246
245
  elif isinstance(value, bool):
247
246
  self.vt = VT_BOOL
248
247
  self._.VT_BOOL = value
249
- elif isinstance(value, (int, c_int)):
250
- self.vt = VT_I4
251
- self._.VT_I4 = value
252
248
  elif isinstance(value, int):
253
249
  u = self._
254
250
  # try VT_I4 first.
@@ -265,12 +261,11 @@ class tagVARIANT(Structure):
265
261
  self.vt = VT_UI4
266
262
  return
267
263
  # try VT_I8 next.
268
- if value >= 0:
269
- u.VT_I8 = value
270
- if u.VT_I8 == value:
271
- # did work.
272
- self.vt = VT_I8
273
- return
264
+ u.VT_I8 = value
265
+ if u.VT_I8 == value:
266
+ # did work.
267
+ self.vt = VT_I8
268
+ return
274
269
  # try VT_UI8 next.
275
270
  if value >= 0:
276
271
  u.VT_UI8 = value
@@ -278,9 +273,7 @@ class tagVARIANT(Structure):
278
273
  # did work.
279
274
  self.vt = VT_UI8
280
275
  return
281
- # VT_R8 is last resort.
282
- self.vt = VT_R8
283
- u.VT_R8 = float(value)
276
+ raise TypeError(f"Cannot put {value!r} in VARIANT")
284
277
  elif isinstance(value, (float, c_double)):
285
278
  self.vt = VT_R8
286
279
  self._.VT_R8 = value
@@ -365,6 +358,9 @@ class tagVARIANT(Structure):
365
358
  elif isinstance(value, c_uint):
366
359
  self.vt = VT_UI4
367
360
  self._.VT_UI4 = value
361
+ elif isinstance(value, c_int):
362
+ self.vt = VT_I4
363
+ self._.VT_I4 = value
368
364
  elif isinstance(value, c_float):
369
365
  self.vt = VT_R4
370
366
  self._.VT_R4 = value
@@ -609,7 +605,7 @@ del v
609
605
 
610
606
 
611
607
  @comtypes.patcher.Patch(POINTER(VARIANT))
612
- class _(object):
608
+ class _:
613
609
  # Override the default .from_param classmethod of POINTER(VARIANT).
614
610
  # This allows to pass values which can be stored in VARIANTs as
615
611
  # function parameters declared as POINTER(VARIANT). See
@@ -878,7 +874,7 @@ class IDispatch(IUnknown):
878
874
  # objects referred to by rgvarg[ ] or placed in *pVarResult.
879
875
  #
880
876
  # For comtypes this is handled in DISPPARAMS.__del__ and VARIANT.__del__.
881
- _invkind = kw.pop("_invkind", 1) # DISPATCH_METHOD
877
+ _invkind = kw.pop("_invkind", DISPATCH_METHOD)
882
878
  _lcid = kw.pop("_lcid", 0)
883
879
  if kw:
884
880
  raise ValueError("named parameters not yet implemented")
@@ -949,7 +945,7 @@ _arraycode_to_vartype = {
949
945
  "B": VT_UI1,
950
946
  }
951
947
 
952
- _ctype_to_vartype: Dict[Type[_CData], int] = {
948
+ _ctype_to_vartype: Dict[Type["_CDataType"], int] = {
953
949
  c_byte: VT_I1,
954
950
  c_ubyte: VT_UI1,
955
951
  c_short: VT_I2,
@@ -986,7 +982,7 @@ _ctype_to_vartype: Dict[Type[_CData], int] = {
986
982
  # POINTER(IDispatch): VT_DISPATCH,
987
983
  }
988
984
 
989
- _vartype_to_ctype: Dict[int, Type[_CData]] = {}
985
+ _vartype_to_ctype: Dict[int, Type["_CDataType"]] = {}
990
986
  for c, v in _ctype_to_vartype.items():
991
987
  _vartype_to_ctype[v] = c
992
988
  _vartype_to_ctype[VT_INT] = _vartype_to_ctype[VT_I4]
@@ -3,8 +3,9 @@
3
3
  import ctypes
4
4
  import logging
5
5
 
6
- from comtypes import automation
6
+ from comtypes import RevokeActiveObject, automation # noqa
7
7
  from comtypes.client import dynamic, lazybind # noqa
8
+ from comtypes.client._activeobj import RegisterActiveObject # noqa
8
9
  from comtypes.client._code_cache import _find_gen_dir
9
10
  from comtypes.client._constants import Constants # noqa
10
11
  from comtypes.client._events import GetEvents, PumpEvents, ShowEvents
@@ -44,3 +44,11 @@ def GetActiveObject(
44
44
  if dynamic:
45
45
  return comtypes.client.dynamic.Dispatch(obj)
46
46
  return _manage(obj, clsid, interface=interface)
47
+
48
+
49
+ def RegisterActiveObject(
50
+ punk: IUnknown, progid: _UnionT[str, Type[CoClass], GUID], weak: bool = True
51
+ ) -> int:
52
+ clsid = GUID.from_progid(progid)
53
+ flags = comtypes.ACTIVEOBJECT_WEAK if weak else comtypes.ACTIVEOBJECT_STRONG
54
+ return comtypes.RegisterActiveObject(punk, clsid, flags)
@@ -11,7 +11,9 @@ import os
11
11
  import sys
12
12
  import tempfile
13
13
  import types
14
- from ctypes import wintypes
14
+ from ctypes.wintypes import BOOL, HWND, LPWSTR, MAX_PATH
15
+
16
+ from comtypes import typeinfo
15
17
 
16
18
  logger = logging.getLogger(__name__)
17
19
 
@@ -54,14 +56,14 @@ def _find_gen_dir():
54
56
  # where generated modules are placed.
55
57
  ftype = getattr(sys, "frozen", None)
56
58
  pymaj, pymin = sys.version_info[:2]
57
- if ftype == None:
59
+ if ftype is None:
58
60
  # Python script
59
61
  subdir = rf"Python\Python{pymaj:d}{pymin:d}\comtypes_cache"
60
62
  basedir = _get_appdata_dir()
61
63
 
62
64
  elif ftype == "dll":
63
65
  # dll created with py2exe
64
- path = _get_module_filename(sys.frozendllhandle)
66
+ path = typeinfo.GetModuleFileName(sys.frozendllhandle, MAX_PATH)
65
67
  base = os.path.splitext(os.path.basename(path))[0]
66
68
  subdir = rf"comtypes_cache\{base}-{pymaj:d}{pymin:d}"
67
69
  basedir = tempfile.gettempdir()
@@ -84,19 +86,12 @@ def _find_gen_dir():
84
86
 
85
87
  ################################################################
86
88
 
87
- SHGetSpecialFolderPath = ctypes.OleDLL("shell32.dll").SHGetSpecialFolderPathW
88
- GetModuleFileName = ctypes.WinDLL("kernel32.dll").GetModuleFileNameW
89
- SHGetSpecialFolderPath.argtypes = [
90
- ctypes.c_ulong,
91
- ctypes.c_wchar_p,
92
- ctypes.c_int,
93
- ctypes.c_int,
94
- ]
95
- GetModuleFileName.restype = ctypes.c_ulong
96
- GetModuleFileName.argtypes = [wintypes.HMODULE, ctypes.c_wchar_p, ctypes.c_ulong]
89
+ _shell32 = ctypes.OleDLL("shell32.dll")
90
+ SHGetSpecialFolderPath = _shell32.SHGetSpecialFolderPathW
91
+ SHGetSpecialFolderPath.argtypes = [HWND, LPWSTR, ctypes.c_int, BOOL]
92
+ SHGetSpecialFolderPath.restype = BOOL
97
93
 
98
94
  CSIDL_APPDATA = 26
99
- MAX_PATH = 260
100
95
 
101
96
 
102
97
  def _create_comtypes_gen_package():
@@ -120,7 +115,7 @@ def _create_comtypes_gen_package():
120
115
  ofi = open(comtypes_init, "w")
121
116
  ofi.write("# comtypes.gen package, directory for generated files.\n")
122
117
  ofi.close()
123
- except (OSError, IOError) as details:
118
+ except OSError as details:
124
119
  logger.info("Creating comtypes.gen package failed: %s", details)
125
120
  module = sys.modules["comtypes.gen"] = types.ModuleType("comtypes.gen")
126
121
  comtypes.gen = module
@@ -137,15 +132,6 @@ def _is_writeable(path):
137
132
  return os.access(path[0], os.W_OK)
138
133
 
139
134
 
140
- def _get_module_filename(hmodule):
141
- """Call the Windows GetModuleFileName function which determines
142
- the path from a module handle."""
143
- path = ctypes.create_unicode_buffer(MAX_PATH)
144
- if GetModuleFileName(hmodule, path, MAX_PATH):
145
- return path.value
146
- raise ctypes.WinError()
147
-
148
-
149
135
  def _get_appdata_dir():
150
136
  """Return the 'file system directory that serves as a common
151
137
  repository for application-specific data' - CSIDL_APPDATA"""
@@ -43,7 +43,7 @@ class _frozen_attr_dict(dict):
43
43
  raise TypeError
44
44
 
45
45
 
46
- class Constants(object):
46
+ class Constants:
47
47
  """This class loads the type library from the supplied object,
48
48
  then exposes constants and enumerations in the type library
49
49
  as attributes.