comtypes 1.4.8__zip → 1.4.10__zip

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