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.
Files changed (145) hide show
  1. {comtypes-1.4.10 → comtypes-1.4.11}/CHANGES.txt +22 -0
  2. {comtypes-1.4.10/comtypes.egg-info → comtypes-1.4.11}/PKG-INFO +3 -2
  3. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/__init__.py +4 -4
  4. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_comobject.py +23 -25
  5. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_memberspec.py +100 -74
  6. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_meta.py +1 -1
  7. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_post_coinit/_cominterface_meta_patcher.py +3 -5
  8. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_post_coinit/unknwn.py +29 -20
  9. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_vtbl.py +52 -55
  10. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/automation.py +9 -10
  11. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/_code_cache.py +9 -23
  12. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/_events.py +87 -49
  13. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/_generate.py +0 -2
  14. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/connectionpoints.py +37 -3
  15. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/errorinfo.py +53 -15
  16. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/hints.pyi +15 -2
  17. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/hresult.py +16 -6
  18. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/messageloop.py +14 -12
  19. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/server/connectionpoints.py +68 -67
  20. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/server/inprocserver.py +8 -5
  21. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/server/localserver.py +14 -20
  22. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/server/register.py +2 -2
  23. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_GUID.py +6 -7
  24. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_basic.py +6 -3
  25. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_collections.py +6 -3
  26. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_comobject.py +19 -6
  27. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_comserver.py +25 -2
  28. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_dict.py +2 -1
  29. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_dyndispatch.py +4 -2
  30. comtypes-1.4.11/comtypes/test/test_errorinfo.py +115 -0
  31. comtypes-1.4.11/comtypes/test/test_hresult.py +48 -0
  32. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_inout_args.py +9 -2
  33. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_safearray.py +2 -1
  34. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_server_register.py +2 -1
  35. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_typeinfo.py +19 -2
  36. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_variant.py +2 -1
  37. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_w_getopt.py +4 -4
  38. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/tlbparser.py +7 -6
  39. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/typeinfo.py +14 -9
  40. {comtypes-1.4.10 → comtypes-1.4.11/comtypes.egg-info}/PKG-INFO +3 -2
  41. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes.egg-info/SOURCES.txt +2 -0
  42. {comtypes-1.4.10 → comtypes-1.4.11}/pyproject.toml +1 -6
  43. {comtypes-1.4.10 → comtypes-1.4.11}/LICENSE.txt +0 -0
  44. {comtypes-1.4.10 → comtypes-1.4.11}/MANIFEST.in +0 -0
  45. {comtypes-1.4.10 → comtypes-1.4.11}/README.md +0 -0
  46. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/GUID.py +0 -0
  47. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_npsupport.py +0 -0
  48. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_post_coinit/__init__.py +0 -0
  49. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_post_coinit/bstr.py +0 -0
  50. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_post_coinit/instancemethod.py +0 -0
  51. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_post_coinit/misc.py +0 -0
  52. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_safearray.py +0 -0
  53. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/_tlib_version_checker.py +0 -0
  54. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/clear_cache.py +0 -0
  55. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/__init__.py +0 -0
  56. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/_activeobj.py +0 -0
  57. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/_constants.py +0 -0
  58. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/_create.py +0 -0
  59. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/_managing.py +0 -0
  60. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/dynamic.py +0 -0
  61. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/client/lazybind.py +0 -0
  62. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/git.py +0 -0
  63. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/logutil.py +0 -0
  64. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/patcher.py +0 -0
  65. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/persist.py +0 -0
  66. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/safearray.py +0 -0
  67. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/server/__init__.py +0 -0
  68. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/server/automation.py +0 -0
  69. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/server/w_getopt.py +0 -0
  70. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/shelllink.py +0 -0
  71. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/stream.py +0 -0
  72. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/TestComServer.idl +0 -0
  73. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/TestComServer.py +0 -0
  74. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/TestComServer.tlb +0 -0
  75. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/TestDispServer.idl +0 -0
  76. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/TestDispServer.py +0 -0
  77. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/TestDispServer.tlb +0 -0
  78. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/__init__.py +0 -0
  79. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/find_memleak.py +0 -0
  80. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/mylib.idl +0 -0
  81. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/mylib.tlb +0 -0
  82. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/mytypelib.idl +0 -0
  83. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/runtests.py +0 -0
  84. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/setup.py +0 -0
  85. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_BSTR.py +0 -0
  86. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_DISPPARAMS.py +0 -0
  87. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_QueryService.py +0 -0
  88. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_agilent.py +0 -0
  89. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_avmc.py +0 -0
  90. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_casesensitivity.py +0 -0
  91. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_clear_cache.py +0 -0
  92. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_client.py +0 -0
  93. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_client_dynamic.py +0 -0
  94. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_client_regenerate_modules.py +0 -0
  95. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_createwrappers.py +0 -0
  96. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_dispifc_records.py +0 -0
  97. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_dispifc_safearrays.py +0 -0
  98. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_dispinterface.py +0 -0
  99. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_excel.py +0 -0
  100. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_findgendir.py +0 -0
  101. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_getactiveobj.py +0 -0
  102. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_ie.py +0 -0
  103. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_ienum.py +0 -0
  104. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_imfattributes.py +0 -0
  105. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_jscript.js +0 -0
  106. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_midl_safearray_create.py +0 -0
  107. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_monikers.py +0 -0
  108. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_msscript.py +0 -0
  109. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_npsupport.py +0 -0
  110. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_outparam.py +0 -0
  111. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_persist.py +0 -0
  112. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_pump_events.py +0 -0
  113. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_recordinfo.py +0 -0
  114. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_sapi.py +0 -0
  115. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_server.py +0 -0
  116. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_shelllink.py +0 -0
  117. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_showevents.py +0 -0
  118. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_storage.py +0 -0
  119. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_stream.py +0 -0
  120. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_subinterface.py +0 -0
  121. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_typeannotator.py +0 -0
  122. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_urlhistory.py +0 -0
  123. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_win32com_interop.py +0 -0
  124. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_wmi.py +0 -0
  125. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/test_word.py +0 -0
  126. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/test/urlhist.tlb +0 -0
  127. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/__init__.py +0 -0
  128. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/__init__.py +0 -0
  129. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/codegenerator.py +0 -0
  130. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/comments.py +0 -0
  131. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/heads.py +0 -0
  132. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/helpers.py +0 -0
  133. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/modulenamer.py +0 -0
  134. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/namespaces.py +0 -0
  135. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/packing.py +0 -0
  136. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/codegenerator/typeannotator.py +0 -0
  137. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/typedesc.py +0 -0
  138. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/tools/typedesc_base.py +0 -0
  139. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/util.py +0 -0
  140. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes/viewobject.py +0 -0
  141. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes.egg-info/dependency_links.txt +0 -0
  142. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes.egg-info/entry_points.txt +0 -0
  143. {comtypes-1.4.10 → comtypes-1.4.11}/comtypes.egg-info/top_level.txt +0 -0
  144. {comtypes-1.4.10 → comtypes-1.4.11}/setup.cfg +0 -0
  145. {comtypes-1.4.10 → comtypes-1.4.11}/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.
@@ -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,7 +283,7 @@ 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
@@ -283,18 +291,18 @@ class _compointer_base(c_void_p, metaclass=_compointer_meta):
283
291
  super(_compointer_base, self).value == super(_compointer_base, other).value
284
292
  )
285
293
 
286
- def __hash__(self):
294
+ def __hash__(self) -> int:
287
295
  """Return the hash value of the pointer."""
288
296
  # hash the pointer values
289
297
  return hash(super(_compointer_base, self).value)
290
298
 
291
299
  # redefine the .value property; return the object itself.
292
- def __get_value(self):
300
+ def __get_value(self) -> "hints.Self":
293
301
  return self
294
302
 
295
303
  value = property(__get_value, doc="""Return self.""")
296
304
 
297
- def __repr__(self):
305
+ def __repr__(self) -> str:
298
306
  ptr = super(_compointer_base, self).value
299
307
  return f"<{self.__class__.__name__} ptr=0x{ptr or 0:x} at {id(self):x}>"
300
308
 
@@ -302,13 +310,14 @@ class _compointer_base(c_void_p, metaclass=_compointer_meta):
302
310
  # wrapping the same COM interface. This could happen because some interfaces
303
311
  # are contained in multiple typelibs.
304
312
  #
305
- # It also allows to pass a CoClass instance to an api
306
- # expecting a COM interface.
313
+ # It also allows to pass a COMObject instance to an api expecting a COM interface.
307
314
  @classmethod
308
- def from_param(cls, value):
315
+ def from_param(
316
+ cls, value: "_UnionT[None, Literal[0], hints.Self, IUnknown, hints.COMObject]"
317
+ ) -> Any:
309
318
  """Convert 'value' into a COM pointer to the interface.
310
319
 
311
- This method accepts a COM pointer, or a CoClass instance
320
+ This method accepts a COM pointer, or a COMObject/CoClass instance
312
321
  which is QueryInterface()d."""
313
322
  if value is None:
314
323
  return None
@@ -322,9 +331,9 @@ class _compointer_base(c_void_p, metaclass=_compointer_meta):
322
331
  # Do we need more checks here?
323
332
  if cls._iid_ == getattr(value, "_iid_", None):
324
333
  return value
325
- # Accept an CoClass instance which exposes the interface required.
334
+ # Accept an COMObject instance which exposes the interface required.
326
335
  try:
327
- table = value._com_pointers_
336
+ table = value._com_pointers_ # type: ignore
328
337
  except AttributeError:
329
338
  pass
330
339
  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]:
@@ -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]:
@@ -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
@@ -878,7 +877,7 @@ class IDispatch(IUnknown):
878
877
  # objects referred to by rgvarg[ ] or placed in *pVarResult.
879
878
  #
880
879
  # For comtypes this is handled in DISPPARAMS.__del__ and VARIANT.__del__.
881
- _invkind = kw.pop("_invkind", 1) # DISPATCH_METHOD
880
+ _invkind = kw.pop("_invkind", DISPATCH_METHOD)
882
881
  _lcid = kw.pop("_lcid", 0)
883
882
  if kw:
884
883
  raise ValueError("named parameters not yet implemented")
@@ -949,7 +948,7 @@ _arraycode_to_vartype = {
949
948
  "B": VT_UI1,
950
949
  }
951
950
 
952
- _ctype_to_vartype: Dict[Type[_CData], int] = {
951
+ _ctype_to_vartype: Dict[Type["_CDataType"], int] = {
953
952
  c_byte: VT_I1,
954
953
  c_ubyte: VT_UI1,
955
954
  c_short: VT_I2,
@@ -986,7 +985,7 @@ _ctype_to_vartype: Dict[Type[_CData], int] = {
986
985
  # POINTER(IDispatch): VT_DISPATCH,
987
986
  }
988
987
 
989
- _vartype_to_ctype: Dict[int, Type[_CData]] = {}
988
+ _vartype_to_ctype: Dict[int, Type["_CDataType"]] = {}
990
989
  for c, v in _ctype_to_vartype.items():
991
990
  _vartype_to_ctype[v] = c
992
991
  _vartype_to_ctype[VT_INT] = _vartype_to_ctype[VT_I4]
@@ -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():
@@ -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"""