comtypes 1.4.2__zip → 1.4.3__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 (116) hide show
  1. {comtypes-1.4.2 → comtypes-1.4.3}/CHANGES.txt +16 -2
  2. {comtypes-1.4.2/comtypes.egg-info → comtypes-1.4.3}/PKG-INFO +29 -1
  3. {comtypes-1.4.2 → comtypes-1.4.3}/README.md +28 -0
  4. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/__init__.py +6 -8
  5. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/automation.py +26 -2
  6. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/hints.pyi +15 -0
  7. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_GUID.py +23 -2
  8. comtypes-1.4.3/comtypes/test/test_dispifc_records.py +90 -0
  9. comtypes-1.4.3/comtypes/test/test_findgendir.py +87 -0
  10. comtypes-1.4.3/comtypes/tools/codegenerator/__init__.py +5 -0
  11. {comtypes-1.4.2/comtypes/tools → comtypes-1.4.3/comtypes/tools/codegenerator}/codegenerator.py +56 -721
  12. comtypes-1.4.3/comtypes/tools/codegenerator/helpers.py +357 -0
  13. comtypes-1.4.3/comtypes/tools/codegenerator/modulenamer.py +24 -0
  14. comtypes-1.4.3/comtypes/tools/codegenerator/namespaces.py +212 -0
  15. comtypes-1.4.3/comtypes/tools/codegenerator/packing.py +81 -0
  16. {comtypes-1.4.2/comtypes/tools → comtypes-1.4.3/comtypes/tools/codegenerator}/typeannotator.py +18 -3
  17. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/tools/tlbparser.py +19 -49
  18. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/tools/typedesc.py +57 -9
  19. {comtypes-1.4.2 → comtypes-1.4.3/comtypes.egg-info}/PKG-INFO +29 -1
  20. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes.egg-info/SOURCES.txt +9 -3
  21. {comtypes-1.4.2 → comtypes-1.4.3}/setup.py +1 -0
  22. comtypes-1.4.2/comtypes/test/test_findgendir.py +0 -94
  23. {comtypes-1.4.2 → comtypes-1.4.3}/LICENSE.txt +0 -0
  24. {comtypes-1.4.2 → comtypes-1.4.3}/MANIFEST.in +0 -0
  25. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/GUID.py +0 -0
  26. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/_comobject.py +0 -0
  27. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/_memberspec.py +0 -0
  28. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/_meta.py +0 -0
  29. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/_npsupport.py +0 -0
  30. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/_safearray.py +0 -0
  31. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/clear_cache.py +0 -0
  32. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/client/__init__.py +0 -0
  33. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/client/_code_cache.py +0 -0
  34. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/client/_constants.py +0 -0
  35. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/client/_events.py +0 -0
  36. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/client/_generate.py +0 -0
  37. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/client/dynamic.py +0 -0
  38. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/client/lazybind.py +0 -0
  39. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/connectionpoints.py +0 -0
  40. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/errorinfo.py +0 -0
  41. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/git.py +0 -0
  42. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/hresult.py +0 -0
  43. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/logutil.py +0 -0
  44. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/messageloop.py +0 -0
  45. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/patcher.py +0 -0
  46. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/persist.py +0 -0
  47. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/safearray.py +0 -0
  48. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/server/__init__.py +0 -0
  49. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/server/automation.py +0 -0
  50. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/server/connectionpoints.py +0 -0
  51. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/server/inprocserver.py +0 -0
  52. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/server/localserver.py +0 -0
  53. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/server/register.py +0 -0
  54. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/server/w_getopt.py +0 -0
  55. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/shelllink.py +0 -0
  56. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/TestComServer.idl +0 -0
  57. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/TestComServer.py +0 -0
  58. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/TestComServer.tlb +0 -0
  59. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/TestDispServer.idl +0 -0
  60. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/TestDispServer.py +0 -0
  61. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/TestDispServer.tlb +0 -0
  62. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/__init__.py +0 -0
  63. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/find_memleak.py +0 -0
  64. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/mylib.idl +0 -0
  65. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/mytypelib.idl +0 -0
  66. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/runtests.py +0 -0
  67. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/setup.py +0 -0
  68. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_BSTR.py +0 -0
  69. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_DISPPARAMS.py +0 -0
  70. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_QueryService.py +0 -0
  71. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_agilent.py +0 -0
  72. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_avmc.py +0 -0
  73. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_basic.py +0 -0
  74. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_casesensitivity.py +0 -0
  75. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_clear_cache.py +0 -0
  76. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_client.py +0 -0
  77. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_client_dynamic.py +0 -0
  78. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_client_regenerate_modules.py +0 -0
  79. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_collections.py +0 -0
  80. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_comserver.py +0 -0
  81. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_createwrappers.py +0 -0
  82. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_dict.py +0 -0
  83. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_dispinterface.py +0 -0
  84. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_dyndispatch.py +0 -0
  85. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_excel.py +0 -0
  86. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_getactiveobj.py +0 -0
  87. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_ie.py +0 -0
  88. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_ienum.py +0 -0
  89. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_imfattributes.py +0 -0
  90. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_inout_args.py +0 -0
  91. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_jscript.js +0 -0
  92. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_msscript.py +0 -0
  93. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_npsupport.py +0 -0
  94. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_outparam.py +0 -0
  95. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_propputref.py +0 -0
  96. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_pump_events.py +0 -0
  97. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_safearray.py +0 -0
  98. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_sapi.py +0 -0
  99. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_server.py +0 -0
  100. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_showevents.py +0 -0
  101. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_subinterface.py +0 -0
  102. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_typeinfo.py +0 -0
  103. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_urlhistory.py +0 -0
  104. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_variant.py +0 -0
  105. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_win32com_interop.py +0 -0
  106. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_wmi.py +0 -0
  107. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/test/test_word.py +0 -0
  108. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/tools/__init__.py +0 -0
  109. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/tools/typedesc_base.py +0 -0
  110. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/typeinfo.py +0 -0
  111. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/util.py +0 -0
  112. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes/viewobject.py +0 -0
  113. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes.egg-info/dependency_links.txt +0 -0
  114. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes.egg-info/entry_points.txt +0 -0
  115. {comtypes-1.4.2 → comtypes-1.4.3}/comtypes.egg-info/top_level.txt +0 -0
  116. {comtypes-1.4.2 → comtypes-1.4.3}/setup.cfg +0 -0
@@ -216,6 +216,21 @@ class _MethodsAnnotator(abc.ABC, Generic[_T_MTD]):
216
216
  self._define_normal_prop(name, setter=setter)
217
217
 
218
218
 
219
+ def _to_outtype(typ: Any) -> str:
220
+ if isinstance(typ, typedesc.PointerType):
221
+ return _to_outtype(typ.typ)
222
+ elif isinstance(typ, typedesc.DispInterface):
223
+ return f"'{typ.name}'"
224
+ elif isinstance(typ, typedesc.ComInterface):
225
+ return f"'{typ.name}'"
226
+ elif isinstance(typ, typedesc.CoClass):
227
+ impl, _ = typedesc.groupby_impltypeflags(typ.interfaces)
228
+ if impl:
229
+ meta = f"hints.FirstComItfOf['{typ.name}']"
230
+ return f"hints.Annotated[{_to_outtype(impl[0])}, {meta}]"
231
+ return "hints.Incomplete"
232
+
233
+
219
234
  class ComMethodAnnotator(_MethodAnnotator[typedesc.ComMethod]):
220
235
  def _iter_outarg_specs(self) -> Iterator[Tuple[Any, str]]:
221
236
  for typ, name, flags, _ in self.method.arguments:
@@ -240,7 +255,7 @@ class ComMethodAnnotator(_MethodAnnotator[typedesc.ComMethod]):
240
255
  else:
241
256
  inargs.append(f"{argname}: hints.Incomplete = ...")
242
257
  has_optional = True
243
- outargs = ["hints.Incomplete" for _ in self._iter_outarg_specs()]
258
+ outargs = [_to_outtype(ot) for ot, _ in self._iter_outarg_specs()]
244
259
  if not outargs:
245
260
  out = "hints.Hresult"
246
261
  elif len(outargs) == 1:
@@ -283,7 +298,7 @@ class DispMethodAnnotator(_MethodAnnotator[typedesc.DispMethod]):
283
298
  else:
284
299
  inargs.append(f"{argname}: hints.Incomplete = ...")
285
300
  has_optional = True
286
- out = "hints.Incomplete"
301
+ out = _to_outtype(self.method.returns)
287
302
  in_ = ("self, " + ", ".join(inargs)) if inargs else "self"
288
303
  return f"def {name}({in_}) -> {out}: ..."
289
304
 
@@ -314,7 +329,7 @@ class DispInterfaceMembersAnnotator(object):
314
329
  property_lines: List[str] = []
315
330
  for mem in props:
316
331
  property_lines.append("@property # dispprop")
317
- out = "hints.Incomplete"
332
+ out = _to_outtype(mem.typ)
318
333
  property_lines.append(f"def {mem.name}(self) -> {out}: ...")
319
334
  dispprops = "\n".join(f" {p}" for p in property_lines)
320
335
  dispmethods = DispMethodsAnnotator().generate(methods)
@@ -1,20 +1,10 @@
1
- from __future__ import print_function
2
1
  import os
3
2
  import sys
4
- from typing import (
5
- Any,
6
- Callable,
7
- Dict,
8
- List,
9
- Optional,
10
- Type,
11
- TypeVar,
12
- Tuple,
13
- Union as _UnionT,
14
- )
15
- from ctypes import alignment, c_void_p, _Pointer, sizeof, windll
3
+ from typing import Any
4
+ from typing import Dict, List, Optional, Tuple
5
+ from ctypes import alignment, byref, c_void_p, sizeof, windll
16
6
 
17
- from comtypes import automation, _CData, COMError, typeinfo
7
+ from comtypes import automation, BSTR, COMError, typeinfo
18
8
  from comtypes.tools import typedesc
19
9
  from comtypes.client._code_cache import _get_module_filename
20
10
 
@@ -267,10 +257,8 @@ class Parser(object):
267
257
  assert vd.varkind == typeinfo.VAR_CONST
268
258
  typ = self.make_type(vd.elemdescVar.tdesc, tinfo)
269
259
  var_value = vd._.lpvarValue[0].value
270
- v = typedesc.Constant(name, typ, var_value)
260
+ v = typedesc.Constant(name, typ, var_value, var_doc)
271
261
  self._register(name, v)
272
- if var_doc is not None:
273
- v.doc = var_doc
274
262
 
275
263
  # TKIND_INTERFACE = 3
276
264
  def ParseInterface(
@@ -289,15 +277,9 @@ class Parser(object):
289
277
  warnings.warn(message, UserWarning)
290
278
  return None
291
279
 
292
- itf = typedesc.ComInterface(
293
- itf_name,
294
- members=[],
295
- base=None,
296
- iid=str(ta.guid),
297
- idlflags=self.interface_type_flags(ta.wTypeFlags),
298
- )
299
- if itf_doc:
300
- itf.doc = itf_doc
280
+ iid = str(ta.guid)
281
+ idlflags = self.interface_type_flags(ta.wTypeFlags)
282
+ itf = typedesc.ComInterface(itf_name, None, iid, idlflags, itf_doc)
301
283
  self._register(itf_name, itf)
302
284
 
303
285
  if ta.cImplTypes:
@@ -307,7 +289,7 @@ class Parser(object):
307
289
 
308
290
  assert ta.cVars == 0, "vars on an Interface?"
309
291
 
310
- members = []
292
+ members: List[Tuple[int, typedesc.ComMethod]] = []
311
293
  for i in range(ta.cFuncs):
312
294
  fd = tinfo.GetFuncDesc(i)
313
295
  func_name, func_doc = tinfo.GetDocumentation(fd.memid)[:2]
@@ -341,7 +323,7 @@ class Parser(object):
341
323
  # Sort the methods by oVft (VTable offset): Some typeinfo
342
324
  # don't list methods in VTable order.
343
325
  members.sort()
344
- itf.members.extend([m[1] for m in members])
326
+ itf.extend_members([m for _, m in members])
345
327
 
346
328
  return itf
347
329
 
@@ -351,20 +333,13 @@ class Parser(object):
351
333
  ) -> typedesc.DispInterface:
352
334
  itf_name, doc = tinfo.GetDocumentation(-1)[0:2]
353
335
  assert ta.cImplTypes == 1
354
-
355
336
  hr = tinfo.GetRefTypeOfImplType(0)
356
337
  tibase = tinfo.GetRefTypeInfo(hr)
357
338
  base = self.parse_typeinfo(tibase)
358
- members = []
359
- itf = typedesc.DispInterface(
360
- itf_name,
361
- members=members,
362
- base=base,
363
- iid=str(ta.guid),
364
- idlflags=self.interface_type_flags(ta.wTypeFlags),
365
- )
366
- if doc is not None:
367
- itf.doc = str(doc.split("\0")[0])
339
+ iid = str(ta.guid)
340
+ idlflags = self.interface_type_flags(ta.wTypeFlags)
341
+ doc = str(doc.split("\0")[0]) if doc is not None else doc
342
+ itf = typedesc.DispInterface(itf_name, base, iid, idlflags, doc)
368
343
  self._register(itf_name, itf)
369
344
 
370
345
  # This code can only handle pure dispinterfaces. Dual
@@ -379,7 +354,7 @@ class Parser(object):
379
354
  mth = typedesc.DispProperty(
380
355
  vd.memid, var_name, typ, self.var_flags(vd.wVarFlags), var_doc
381
356
  )
382
- itf.members.append(mth)
357
+ itf.add_member(mth)
383
358
 
384
359
  # At least the EXCEL typelib lists the IUnknown and IDispatch
385
360
  # methods even for this kind of interface. I didn't find any
@@ -430,7 +405,7 @@ class Parser(object):
430
405
  else:
431
406
  default = None
432
407
  mth.add_argument(typ, name, self.param_flags(flags), default)
433
- itf.members.append(mth)
408
+ itf.add_member(mth)
434
409
  return itf
435
410
 
436
411
  def inv_kind(self, invkind: int) -> List[str]:
@@ -548,11 +523,9 @@ class Parser(object):
548
523
  # version, control, hidden, and appobject
549
524
  coclass_name, doc = tinfo.GetDocumentation(-1)[0:2]
550
525
  tlibattr = tinfo.GetContainingTypeLib()[0].GetLibAttr()
551
- coclass = typedesc.CoClass(
552
- coclass_name, str(ta.guid), self.coclass_type_flags(ta.wTypeFlags), tlibattr
553
- )
554
- if doc is not None:
555
- coclass.doc = doc
526
+ clsid = str(ta.guid)
527
+ idlflags = self.coclass_type_flags(ta.wTypeFlags)
528
+ coclass = typedesc.CoClass(coclass_name, clsid, idlflags, tlibattr, doc)
556
529
  self._register(coclass_name, coclass)
557
530
 
558
531
  for i in range(ta.cImplTypes):
@@ -763,9 +736,6 @@ class TypeLibParser(Parser):
763
736
  def get_tlib_filename(tlib):
764
737
  # seems if the typelib is not registered, there's no way to
765
738
  # determine the filename.
766
- from ctypes import windll, byref
767
- from comtypes import BSTR
768
-
769
739
  la = tlib.GetLibAttr()
770
740
  name = BSTR()
771
741
  try:
@@ -2,8 +2,9 @@
2
2
  # in typedesc_base
3
3
 
4
4
  import ctypes
5
- from typing import Any, List, Optional, Tuple, Union as _UnionT
5
+ from typing import Any, List, Optional, Sequence, Tuple, Union as _UnionT
6
6
 
7
+ from comtypes import typeinfo
7
8
  from comtypes.typeinfo import ITypeLib, TLIBATTR
8
9
  from comtypes.tools.typedesc_base import *
9
10
 
@@ -29,11 +30,16 @@ class TypeLib(object):
29
30
 
30
31
  class Constant(object):
31
32
  def __init__(
32
- self, name: str, typ: _UnionT[Typedef, FundamentalType], value: Any
33
+ self,
34
+ name: str,
35
+ typ: _UnionT[Typedef, FundamentalType],
36
+ value: Any,
37
+ doc: Optional[str],
33
38
  ) -> None:
34
39
  self.name = name
35
40
  self.typ = typ
36
41
  self.value = value
42
+ self.doc = doc
37
43
 
38
44
 
39
45
  class External(object):
@@ -141,18 +147,22 @@ class DispInterface(object):
141
147
  def __init__(
142
148
  self,
143
149
  name: str,
144
- members: List[_UnionT[DispMethod, DispProperty]],
145
150
  base: Any,
146
151
  iid: str,
147
152
  idlflags: List[str],
153
+ doc: Optional[str],
148
154
  ) -> None:
149
155
  self.name = name
150
- self.members = members
156
+ self.members: List[_UnionT[DispMethod, DispProperty]] = []
151
157
  self.base = base
152
158
  self.iid = iid
153
159
  self.idlflags = idlflags
154
160
  self.itf_head = DispInterfaceHead(self)
155
161
  self.itf_body = DispInterfaceBody(self)
162
+ self.doc = doc
163
+
164
+ def add_member(self, member: _UnionT[DispMethod, DispProperty]) -> None:
165
+ self.members.append(member)
156
166
 
157
167
  def get_body(self) -> DispInterfaceBody:
158
168
  return self.itf_body
@@ -175,18 +185,22 @@ class ComInterface(object):
175
185
  def __init__(
176
186
  self,
177
187
  name: str,
178
- members: List[ComMethod],
179
188
  base: "Optional[ComInterface]",
180
189
  iid: str,
181
190
  idlflags: List[str],
191
+ doc: Optional[str],
182
192
  ) -> None:
183
193
  self.name = name
184
- self.members = members
194
+ self.members: List[ComMethod] = []
185
195
  self.base = base
186
196
  self.iid = iid
187
197
  self.idlflags = idlflags
188
198
  self.itf_head = ComInterfaceHead(self)
189
199
  self.itf_body = ComInterfaceBody(self)
200
+ self.doc = doc
201
+
202
+ def extend_members(self, members: Sequence[ComMethod]) -> None:
203
+ self.members.extend(members)
190
204
 
191
205
  def get_body(self) -> ComInterfaceBody:
192
206
  return self.itf_body
@@ -195,15 +209,49 @@ class ComInterface(object):
195
209
  return self.itf_head
196
210
 
197
211
 
212
+ _ImplTypeFlags = int
213
+ _Interface = _UnionT[ComInterface, DispInterface]
214
+
215
+
198
216
  class CoClass(object):
199
217
  def __init__(
200
- self, name: str, clsid: str, idlflags: List[str], tlibattr: TLIBATTR
218
+ self,
219
+ name: str,
220
+ clsid: str,
221
+ idlflags: List[str],
222
+ tlibattr: TLIBATTR,
223
+ doc: Optional[str],
201
224
  ) -> None:
202
225
  self.name = name
203
226
  self.clsid = clsid
204
227
  self.idlflags = idlflags
205
228
  self.tlibattr = tlibattr
206
- self.interfaces: List[Tuple[Any, int]] = []
229
+ self.interfaces: List[Tuple[_Interface, _ImplTypeFlags]] = []
230
+ self.doc = doc
207
231
 
208
- def add_interface(self, itf: Any, idlflags: int) -> None:
232
+ def add_interface(self, itf: _Interface, idlflags: _ImplTypeFlags) -> None:
209
233
  self.interfaces.append((itf, idlflags))
234
+
235
+
236
+ _ImplementedInterfaces = Sequence[_Interface]
237
+ _SourceInterfaces = Sequence[_Interface]
238
+
239
+
240
+ def groupby_impltypeflags(
241
+ seq: Sequence[Tuple[_Interface, _ImplTypeFlags]]
242
+ ) -> Tuple[_ImplementedInterfaces, _SourceInterfaces]:
243
+ implemented = []
244
+ sources = []
245
+ for itf, impltypeflags in seq:
246
+ if impltypeflags & typeinfo.IMPLTYPEFLAG_FSOURCE:
247
+ # source interface
248
+ where = sources
249
+ else:
250
+ # sink interface
251
+ where = implemented
252
+ if impltypeflags & typeinfo.IMPLTYPEFLAG_FDEFAULT:
253
+ # The default interface should be the first item on the list
254
+ where.insert(0, itf)
255
+ else:
256
+ where.append(itf)
257
+ return implemented, sources
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: comtypes
3
- Version: 1.4.2
3
+ Version: 1.4.3
4
4
  Summary: Pure Python COM package
5
5
  Home-page: https://github.com/enthought/comtypes
6
6
  Download-URL: https://github.com/enthought/comtypes/releases
@@ -75,6 +75,34 @@ This project and the maintainers of thousands of other packages are working with
75
75
 
76
76
  [Learn more](https://tidelift.com/subscription/pkg/pypi-comtypes?utm_source=pypi-comtypes&utm_medium=referral&utm_campaign=github).
77
77
 
78
+ ## Frequently Asked Questions
79
+
80
+ ### Q: Why does this package not support platforms other than Windows?
81
+ **A:** [The Microsoft Component Object Model (COM)](https://learn.microsoft.com/en-us/windows/win32/com/com-technical-overview) is a technology that is unique to Windows and is not supported on other platforms.
82
+
83
+ [The phrase _"COM is a platform-independent"_ in the MS documentation](https://learn.microsoft.com/en-us/windows/win32/com/component-object-model--com--portal) means that COM maintains compatibility across different versions of Windows, and does NOT imply that it is supported on Linux or Mac.
84
+
85
+ As long as COM is not supported outside of Windows, this project does not plan to port to other platforms.
86
+
87
+ ### Q: Why does `cannot import name 'COMError' from '_ctypes'` error occur when using this package on platforms other than Windows?
88
+ **A:** The [`_ctypes`](https://github.com/python/cpython/blob/main/Modules/_ctypes/_ctypes.c) is part of the internal implementation of the [`ctypes`](https://github.com/python/cpython/blob/main/Lib/ctypes/) standard library that exists for Python on all platforms.
89
+ However, `COMError` and COM-related features are implemented only in Python for Windows.
90
+
91
+ In cross-platform software development, care must be taken to ensure that codebase dependent on `comtypes` does not execute in environments other than Windows.
92
+
93
+ ### Q: Despite a script that depends on `comtypes` having run successfully before, a error (`ImportError`, `NameError`, or `SyntaxError`) is raised now, and the same error occurs again and again.
94
+
95
+ **A:** Executing `py -m comtypes.clear_cache` and then running the script again might resolve the problem.
96
+
97
+ When `comtypes.client.GetModule` is called (either directly or indirectly), `comtypes` generates Python module files.
98
+ If Python is forced to terminate or crashes in the middle of file generation, the codebase written to the file becomes partial.
99
+ When Python tries to import this unexecutable partial codebase module, an error occurs.
100
+
101
+ Executing `py -m comtypes.clear_cache` identifies the directories where the "cache module files" are stored and deletes them.
102
+ After deleting these partial modules and running the script again, `comtypes.client.GetModule` is called and executable modules are generated anew.
103
+
104
+ However, if the script implementation does not use `comtypes.client.GetModule` or processes generated files, it may not be a solution.
105
+
78
106
  ## Documentation:
79
107
 
80
108
  The documentation is currently hosted on pythonhosted at:
@@ -73,6 +73,7 @@ comtypes/test/test_collections.py
73
73
  comtypes/test/test_comserver.py
74
74
  comtypes/test/test_createwrappers.py
75
75
  comtypes/test/test_dict.py
76
+ comtypes/test/test_dispifc_records.py
76
77
  comtypes/test/test_dispinterface.py
77
78
  comtypes/test/test_dyndispatch.py
78
79
  comtypes/test/test_excel.py
@@ -100,8 +101,13 @@ comtypes/test/test_win32com_interop.py
100
101
  comtypes/test/test_wmi.py
101
102
  comtypes/test/test_word.py
102
103
  comtypes/tools/__init__.py
103
- comtypes/tools/codegenerator.py
104
104
  comtypes/tools/tlbparser.py
105
- comtypes/tools/typeannotator.py
106
105
  comtypes/tools/typedesc.py
107
- comtypes/tools/typedesc_base.py
106
+ comtypes/tools/typedesc_base.py
107
+ comtypes/tools/codegenerator/__init__.py
108
+ comtypes/tools/codegenerator/codegenerator.py
109
+ comtypes/tools/codegenerator/helpers.py
110
+ comtypes/tools/codegenerator/modulenamer.py
111
+ comtypes/tools/codegenerator/namespaces.py
112
+ comtypes/tools/codegenerator/packing.py
113
+ comtypes/tools/codegenerator/typeannotator.py
@@ -160,6 +160,7 @@ setup_params = dict(
160
160
  "comtypes.client",
161
161
  "comtypes.server",
162
162
  "comtypes.tools",
163
+ "comtypes.tools.codegenerator",
163
164
  "comtypes.test",
164
165
  ],
165
166
  )
@@ -1,94 +0,0 @@
1
- import os
2
- import sys
3
- import tempfile
4
- import types
5
- import unittest
6
-
7
- import comtypes
8
- import comtypes.client
9
- import comtypes.gen
10
-
11
- if sys.version_info >= (3, 4):
12
- from importlib import reload
13
- else:
14
- from imp import reload
15
-
16
- imgbase = os.path.splitext(os.path.basename(sys.executable))[0]
17
-
18
-
19
- class Test(unittest.TestCase):
20
- """Test the comtypes.client._find_gen_dir() function in several
21
- simulated environments.
22
- """
23
-
24
- def setUp(self):
25
- # save the original comtypes.gen modules and create a
26
- # substitute with an empty __path__.
27
- self.orig_comtypesgen = sys.modules["comtypes.gen"]
28
- del sys.modules["comtypes.gen"]
29
- del comtypes.gen
30
- mod = sys.modules["comtypes.gen"] = types.ModuleType("comtypes.gen")
31
- mod.__path__ = []
32
- comtypes.gen = mod
33
-
34
- def tearDown(self):
35
- # Delete py2exe-attributes that we have attached to the sys module
36
- for name in "frozen frozendllhandle".split():
37
- try:
38
- delattr(sys, name)
39
- except AttributeError:
40
- pass
41
- # restore the original comtypes.gen module
42
- comtypes.gen = self.orig_comtypesgen
43
- sys.modules["comtypes.gen"] = self.orig_comtypesgen
44
- reload(comtypes.gen)
45
-
46
- def test_script(self):
47
- # %APPDATA%\Python\Python25\comtypes_cache
48
- template = r"$APPDATA\Python\Python%d%d\comtypes_cache"
49
- path = os.path.expandvars(template % sys.version_info[:2])
50
- gen_dir = comtypes.client._find_gen_dir()
51
- self.assertEqual(path, gen_dir)
52
-
53
- def test_frozen_dll(self):
54
- sys.frozen = "dll"
55
- sys.frozendllhandle = sys.dllhandle
56
- ma, mi = sys.version_info[:2]
57
- # %TEMP%\comtypes_cache\<imagebasename>-25
58
- # the image is python25.dll
59
- path = os.path.join(
60
- tempfile.gettempdir(),
61
- r"comtypes_cache\%s%d%d-%d%d" % (imgbase, ma, mi, ma, mi),
62
- )
63
- gen_dir = comtypes.client._find_gen_dir()
64
- self.assertEqual(path, gen_dir)
65
-
66
- def test_frozen_console_exe(self):
67
- sys.frozen = "console_exe"
68
- # %TEMP%\comtypes_cache\<imagebasename>-25
69
- path = os.path.join(
70
- tempfile.gettempdir(),
71
- r"comtypes_cache\%s-%d%d"
72
- % (imgbase, sys.version_info[0], sys.version_info[1]),
73
- )
74
- gen_dir = comtypes.client._find_gen_dir()
75
- self.assertEqual(path, gen_dir)
76
-
77
- def test_frozen_windows_exe(self):
78
- sys.frozen = "windows_exe"
79
- # %TEMP%\comtypes_cache\<imagebasename>-25
80
- path = os.path.join(
81
- tempfile.gettempdir(),
82
- r"comtypes_cache\%s-%d%d"
83
- % (imgbase, sys.version_info[0], sys.version_info[1]),
84
- )
85
- gen_dir = comtypes.client._find_gen_dir()
86
- self.assertEqual(path, gen_dir)
87
-
88
-
89
- def main():
90
- unittest.main()
91
-
92
-
93
- if __name__ == "__main__":
94
- main()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes