comtypes 1.4.9__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 (148) hide show
  1. {comtypes-1.4.9 → comtypes-1.4.11}/CHANGES.txt +41 -0
  2. {comtypes-1.4.9/comtypes.egg-info → comtypes-1.4.11}/PKG-INFO +4 -2
  3. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/GUID.py +34 -13
  4. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/__init__.py +25 -16
  5. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/_comobject.py +92 -39
  6. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/_memberspec.py +112 -78
  7. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/_meta.py +2 -1
  8. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/_post_coinit/_cominterface_meta_patcher.py +3 -6
  9. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/_post_coinit/bstr.py +12 -5
  10. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/_post_coinit/instancemethod.py +1 -2
  11. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/_post_coinit/misc.py +59 -24
  12. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/_post_coinit/unknwn.py +30 -25
  13. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/_safearray.py +2 -2
  14. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/_vtbl.py +52 -55
  15. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/automation.py +19 -14
  16. comtypes-1.4.11/comtypes/client/__init__.py +42 -0
  17. comtypes-1.4.11/comtypes/client/_activeobj.py +46 -0
  18. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/client/_code_cache.py +15 -24
  19. comtypes-1.4.11/comtypes/client/_create.py +147 -0
  20. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/client/_events.py +140 -57
  21. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/client/_generate.py +3 -5
  22. comtypes-1.4.11/comtypes/client/_managing.py +114 -0
  23. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/client/dynamic.py +2 -3
  24. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/client/lazybind.py +10 -11
  25. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/connectionpoints.py +38 -3
  26. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/errorinfo.py +72 -21
  27. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/git.py +4 -3
  28. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/hints.pyi +15 -2
  29. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/hresult.py +16 -6
  30. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/logutil.py +15 -3
  31. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/messageloop.py +15 -13
  32. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/persist.py +3 -5
  33. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/safearray.py +8 -6
  34. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/server/__init__.py +22 -4
  35. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/server/automation.py +1 -2
  36. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/server/connectionpoints.py +71 -70
  37. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/server/inprocserver.py +14 -8
  38. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/server/localserver.py +28 -16
  39. comtypes-1.4.11/comtypes/server/register.py +478 -0
  40. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/shelllink.py +13 -7
  41. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/stream.py +7 -4
  42. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/TestComServer.py +6 -7
  43. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/TestDispServer.py +4 -2
  44. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/__init__.py +1 -1
  45. comtypes-1.4.11/comtypes/test/find_memleak.py +72 -0
  46. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/runtests.py +1 -0
  47. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/setup.py +2 -1
  48. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_BSTR.py +7 -17
  49. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_GUID.py +7 -7
  50. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_QueryService.py +1 -0
  51. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_agilent.py +4 -3
  52. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_basic.py +18 -9
  53. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_clear_cache.py +1 -1
  54. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_client.py +2 -2
  55. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_client_dynamic.py +2 -2
  56. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_client_regenerate_modules.py +2 -2
  57. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_collections.py +7 -4
  58. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_comobject.py +22 -9
  59. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_comserver.py +56 -3
  60. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_dict.py +2 -1
  61. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_dispifc_records.py +1 -1
  62. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_dispifc_safearrays.py +1 -1
  63. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_dyndispatch.py +5 -2
  64. comtypes-1.4.11/comtypes/test/test_errorinfo.py +115 -0
  65. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_findgendir.py +1 -2
  66. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_getactiveobj.py +4 -4
  67. comtypes-1.4.11/comtypes/test/test_hresult.py +48 -0
  68. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_ie.py +19 -6
  69. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_ienum.py +2 -2
  70. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_imfattributes.py +13 -3
  71. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_inout_args.py +10 -3
  72. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_midl_safearray_create.py +6 -4
  73. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_monikers.py +23 -9
  74. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_msscript.py +2 -1
  75. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_npsupport.py +4 -4
  76. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_outparam.py +22 -6
  77. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_persist.py +2 -4
  78. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_recordinfo.py +1 -1
  79. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_safearray.py +2 -1
  80. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_sapi.py +4 -1
  81. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_server_register.py +114 -125
  82. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_shelllink.py +2 -3
  83. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_storage.py +12 -6
  84. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_stream.py +16 -5
  85. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_subinterface.py +4 -2
  86. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_typeannotator.py +1 -2
  87. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_typeinfo.py +36 -7
  88. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_urlhistory.py +7 -4
  89. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_variant.py +5 -3
  90. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_w_getopt.py +4 -4
  91. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_word.py +1 -1
  92. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/tools/codegenerator/codegenerator.py +167 -435
  93. comtypes-1.4.11/comtypes/tools/codegenerator/comments.py +79 -0
  94. comtypes-1.4.11/comtypes/tools/codegenerator/heads.py +192 -0
  95. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/tools/codegenerator/helpers.py +3 -6
  96. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/tools/codegenerator/namespaces.py +13 -5
  97. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/tools/codegenerator/typeannotator.py +13 -3
  98. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/tools/tlbparser.py +25 -25
  99. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/tools/typedesc.py +3 -2
  100. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/tools/typedesc_base.py +2 -2
  101. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/typeinfo.py +163 -51
  102. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/viewobject.py +2 -4
  103. {comtypes-1.4.9 → comtypes-1.4.11/comtypes.egg-info}/PKG-INFO +4 -2
  104. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes.egg-info/SOURCES.txt +7 -0
  105. {comtypes-1.4.9 → comtypes-1.4.11}/pyproject.toml +10 -23
  106. comtypes-1.4.9/comtypes/client/__init__.py +0 -323
  107. comtypes-1.4.9/comtypes/server/register.py +0 -419
  108. comtypes-1.4.9/comtypes/test/find_memleak.py +0 -76
  109. {comtypes-1.4.9 → comtypes-1.4.11}/LICENSE.txt +0 -0
  110. {comtypes-1.4.9 → comtypes-1.4.11}/MANIFEST.in +0 -0
  111. {comtypes-1.4.9 → comtypes-1.4.11}/README.md +0 -0
  112. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/_npsupport.py +0 -0
  113. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/_post_coinit/__init__.py +0 -0
  114. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/_tlib_version_checker.py +0 -0
  115. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/clear_cache.py +0 -0
  116. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/client/_constants.py +0 -0
  117. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/patcher.py +0 -0
  118. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/server/w_getopt.py +0 -0
  119. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/TestComServer.idl +0 -0
  120. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/TestComServer.tlb +0 -0
  121. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/TestDispServer.idl +0 -0
  122. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/TestDispServer.tlb +0 -0
  123. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/mylib.idl +0 -0
  124. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/mylib.tlb +0 -0
  125. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/mytypelib.idl +0 -0
  126. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_DISPPARAMS.py +0 -0
  127. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_avmc.py +0 -0
  128. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_casesensitivity.py +0 -0
  129. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_createwrappers.py +0 -0
  130. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_dispinterface.py +0 -0
  131. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_excel.py +0 -0
  132. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_jscript.js +0 -0
  133. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_pump_events.py +0 -0
  134. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_server.py +0 -0
  135. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_showevents.py +0 -0
  136. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_win32com_interop.py +0 -0
  137. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/test_wmi.py +0 -0
  138. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/test/urlhist.tlb +0 -0
  139. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/tools/__init__.py +0 -0
  140. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/tools/codegenerator/__init__.py +0 -0
  141. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/tools/codegenerator/modulenamer.py +0 -0
  142. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/tools/codegenerator/packing.py +0 -0
  143. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes/util.py +0 -0
  144. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes.egg-info/dependency_links.txt +0 -0
  145. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes.egg-info/entry_points.txt +0 -0
  146. {comtypes-1.4.9 → comtypes-1.4.11}/comtypes.egg-info/top_level.txt +0 -0
  147. {comtypes-1.4.9 → comtypes-1.4.11}/setup.cfg +0 -0
  148. {comtypes-1.4.9 → comtypes-1.4.11}/setup.py +0 -0
@@ -1,31 +1,29 @@
1
1
  # Code generator to generate code for everything contained in COM type
2
2
  # libraries.
3
+ import contextlib
4
+ import io
3
5
  import keyword
4
6
  import logging
5
7
  import os
6
8
  import textwrap
7
- from typing import Any
8
- from typing import Dict, List, Tuple
9
- from typing import Sequence
10
- from typing import Optional, Union as _UnionT
11
- import io
9
+ import warnings
10
+ from typing import Any, Dict, Iterator, List, Literal, Optional, Sequence, Tuple
11
+ from typing import Union as _UnionT
12
12
 
13
13
  import comtypes
14
14
  from comtypes import typeinfo
15
15
  from comtypes.tools import tlbparser, typedesc
16
- from comtypes.tools.codegenerator import namespaces
17
- from comtypes.tools.codegenerator import packing
18
- from comtypes.tools.codegenerator.modulenamer import name_wrapper_module
16
+ from comtypes.tools.codegenerator import heads, namespaces, packing
17
+ from comtypes.tools.codegenerator.comments import ComInterfaceBodyImplCommentWriter
19
18
  from comtypes.tools.codegenerator.helpers import (
20
- get_real_type,
21
19
  ASSUME_STRINGS,
22
20
  ComMethodGenerator,
23
21
  DispMethodGenerator,
24
22
  DispPropertyGenerator,
25
23
  TypeNamer,
24
+ get_real_type,
26
25
  )
27
- from comtypes.tools.codegenerator import typeannotator
28
-
26
+ from comtypes.tools.codegenerator.modulenamer import name_wrapper_module
29
27
 
30
28
  version = comtypes.__version__
31
29
 
@@ -59,7 +57,29 @@ class CodeGenerator(object):
59
57
  self.names = set() # names that have been generated
60
58
  self.externals = [] # typelibs imported to generated module
61
59
  self.enum_aliases: Dict[str, str] = {}
62
- self.last_item_class = False
60
+ self.last_item = "attribute"
61
+
62
+ @contextlib.contextmanager
63
+ def adjust_blank(
64
+ self, item: Literal["assert", "attribute", "class", "comment", "variable"]
65
+ ) -> Iterator[io.StringIO]:
66
+ if self.last_item == "class":
67
+ print(file=self.stream)
68
+ print(file=self.stream)
69
+ elif self.last_item == "attribute":
70
+ print(file=self.stream)
71
+ if item == "class":
72
+ print(file=self.stream)
73
+ elif self.last_item in ("variable", "assert", "comment"):
74
+ if item == "class":
75
+ print(file=self.stream)
76
+ print(file=self.stream)
77
+ elif item == "attribute":
78
+ print(file=self.stream)
79
+ else:
80
+ raise TypeError
81
+ yield self.stream
82
+ self.last_item = item
63
83
 
64
84
  def generate(self, item):
65
85
  if item in self.done:
@@ -128,8 +148,8 @@ class CodeGenerator(object):
128
148
  path = self._make_relative_path(filename, comtypes.gen.__path__[0])
129
149
  self.imports.add("os")
130
150
  definition = (
131
- f"os.path.normpath(\n"
132
- f" os.path.abspath(os.path.join(os.path.dirname(__file__),\n"
151
+ "os.path.normpath(\n"
152
+ " os.path.abspath(os.path.join(os.path.dirname(__file__),\n"
133
153
  f" {path!r})))"
134
154
  )
135
155
  self.declarations.add("typelib_path", definition)
@@ -218,7 +238,7 @@ class CodeGenerator(object):
218
238
  print(self._make_dunder_all_part(), file=output)
219
239
  print(file=output)
220
240
  if tlib_mtime is not None:
221
- print("_check_version(%r, %f)" % (version, tlib_mtime), file=output)
241
+ print(f"_check_version({version!r}, {tlib_mtime:f})", file=output)
222
242
  return output.getvalue()
223
243
 
224
244
  def generate_friendly_code(self, modname: str) -> str:
@@ -288,19 +308,11 @@ class CodeGenerator(object):
288
308
  if "datetime.datetime(" in text:
289
309
  self.imports.add("datetime")
290
310
 
291
- def _to_docstring(self, orig: str, depth: int = 1) -> str:
292
- # increasing `depth` by one increases indentation by one
293
- indent = " " * depth
294
- # some chars are replaced to avoid causing a `SyntaxError`
295
- repled = orig.replace("\\", r"\\").replace('"', r"'")
296
- return f'{indent}"""{repled}"""'
297
-
298
311
  def ArrayType(self, tp: typedesc.ArrayType) -> None:
299
312
  self.generate(get_real_type(tp.typ))
300
313
  self.generate(tp.typ)
301
314
 
302
315
  def EnumValue(self, tp: typedesc.EnumValue) -> None:
303
- self.last_item_class = False
304
316
  value = int(tp.value)
305
317
  if keyword.iskeyword(tp.name):
306
318
  # XXX use logging!
@@ -314,7 +326,6 @@ class CodeGenerator(object):
314
326
  self.names.add(tp_name)
315
327
 
316
328
  def Enumeration(self, tp: typedesc.Enumeration) -> None:
317
- self.last_item_class = False
318
329
  for item in tp.values:
319
330
  self.generate(item)
320
331
  if tp.name:
@@ -334,8 +345,8 @@ class CodeGenerator(object):
334
345
  if isinstance(tp.typ, typedesc.Enumeration):
335
346
  self.enum_aliases[tp.name] = definition
336
347
  else:
337
- print(f"{tp.name} = {definition}", file=self.stream)
338
- self.last_item_class = False
348
+ with self.adjust_blank("variable") as ofi:
349
+ print(f"{tp.name} = {definition}", file=ofi)
339
350
  self.names.add(tp.name)
340
351
 
341
352
  def FundamentalType(self, item: typedesc.FundamentalType) -> None:
@@ -345,90 +356,12 @@ class CodeGenerator(object):
345
356
  for struct in head.struct.bases:
346
357
  self.generate(struct.get_head())
347
358
  self.more.add(struct)
348
- if head.struct.location:
349
- self.last_item_class = False
350
- print(f"# {head.struct.location}", file=self.stream)
351
359
  basenames = [self._to_type_name(b) for b in head.struct.bases]
352
360
  if basenames:
353
361
  self.imports.add("comtypes", "GUID")
354
362
 
355
- if not self.last_item_class:
356
- print(file=self.stream)
357
- print(file=self.stream)
358
-
359
- self.last_item_class = True
360
-
361
- method_names = [
362
- m.name for m in head.struct.members if type(m) is typedesc.Method
363
- ]
364
- print(
365
- f"class {head.struct.name}({', '.join(basenames)}):",
366
- file=self.stream,
367
- )
368
- print(
369
- " _iid_ = GUID('{}') # please look up iid and fill in!",
370
- file=self.stream,
371
- )
372
- if "Enum" in method_names:
373
- print(" def __iter__(self):", file=self.stream)
374
- print(" return self.Enum()", file=self.stream)
375
- elif method_names == "Next Skip Reset Clone".split():
376
- print(" def __iter__(self):", file=self.stream)
377
- print(" return self", file=self.stream)
378
- print(file=self.stream)
379
- print(" def next(self):", file=self.stream)
380
- print(" arr, fetched = self.Next(1)", file=self.stream)
381
- print(" if fetched == 0:", file=self.stream)
382
- print(" raise StopIteration", file=self.stream)
383
- print(" return arr[0]", file=self.stream)
384
-
385
- print(file=self.stream)
386
- print(file=self.stream)
387
-
388
- else:
389
- methods = [m for m in head.struct.members if type(m) is typedesc.Method]
390
-
391
- if methods:
392
- # Hm. We cannot generate code for IUnknown...
393
- if not self.last_item_class:
394
- print(file=self.stream)
395
-
396
- self.last_item_class = True
397
- print("assert 0, 'cannot generate code for IUnknown'", file=self.stream)
398
- print(file=self.stream)
399
- print(file=self.stream)
400
- print(f"class {head.struct.name}(_com_interface):", file=self.stream)
401
- print(" pass", file=self.stream)
402
- print(file=self.stream)
403
- print(file=self.stream)
404
- elif type(head.struct) == typedesc.Structure:
405
- if not self.last_item_class:
406
- print(file=self.stream)
407
- print(file=self.stream)
408
-
409
- self.last_item_class = True
410
-
411
- print(f"class {head.struct.name}(Structure):", file=self.stream)
412
- if hasattr(head.struct, "_recordinfo_"):
413
- print(
414
- f" _recordinfo_ = {head.struct._recordinfo_!r}",
415
- file=self.stream,
416
- )
417
- else:
418
- print(" pass", file=self.stream)
419
- print(file=self.stream)
420
- print(file=self.stream)
421
- elif type(head.struct) == typedesc.Union:
422
- if not self.last_item_class:
423
- print(file=self.stream)
424
- print(file=self.stream)
425
-
426
- self.last_item_class = True
427
-
428
- print(f"class {head.struct.name}(Union):", file=self.stream)
429
- print(" pass", file=self.stream)
430
- print(file=self.stream)
431
- print(file=self.stream)
363
+ with self.adjust_blank("class") as ofi:
364
+ heads.StructureHeadWriter(ofi).write(head, basenames)
432
365
  self.names.add(head.struct.name)
433
366
 
434
367
  def Structure(self, struct: typedesc.Structure) -> None:
@@ -461,104 +394,99 @@ class CodeGenerator(object):
461
394
  try:
462
395
  pack = packing.calc_packing(body.struct, fields)
463
396
  if pack is not None:
464
- self.last_item_class = False
465
- print(f"{body.struct.name}._pack_ = {pack}", file=self.stream)
397
+ with self.adjust_blank("attribute") as ofi:
398
+ print(f"{body.struct.name}._pack_ = {pack}", file=ofi)
466
399
  except packing.PackingError as details:
467
400
  # if packing fails, write a warning comment to the output.
468
- import warnings
469
-
470
- message = "Structure %s: %s" % (body.struct.name, details)
401
+ message = f"Structure {body.struct.name}: {details}"
471
402
  warnings.warn(message, UserWarning)
472
- print(f"# WARNING: {details}", file=self.stream)
473
- self.last_item_class = False
474
-
403
+ with self.adjust_blank("comment") as ofi:
404
+ print(f"# WARNING: {details}", file=ofi)
475
405
  if fields:
476
406
  if body.struct.bases:
477
407
  assert len(body.struct.bases) == 1
478
408
  self.generate(body.struct.bases[0].get_body())
479
-
480
- if not self.last_item_class:
481
- print(file=self.stream)
482
-
483
- self.last_item_class = False
484
-
485
- print(f"{body.struct.name}._fields_ = [", file=self.stream)
486
- if body.struct.location:
487
- print(f" # {body.struct.location}", file=self.stream)
488
- # unnamed fields will get autogenerated names "_", "_1". "_2", "_3", ...
489
- unnamed_index = 0
490
- for f in fields:
491
- if not f.name:
492
- if unnamed_index:
493
- fieldname = "_%d" % unnamed_index
494
- else:
495
- fieldname = "_"
496
- unnamed_index += 1
497
- print(
498
- f" # Unnamed field renamed to '{fieldname}'",
499
- file=self.stream,
500
- )
501
- else:
502
- fieldname = f.name
503
- if f.bits is None:
504
- print(
505
- f" ('{fieldname}', {self._to_type_name(f.typ)}),",
506
- file=self.stream,
507
- )
508
- else:
509
- print(
510
- f" ('{fieldname}', {self._to_type_name(f.typ)}, {f.bits}),",
511
- file=self.stream,
512
- )
513
- print("]", file=self.stream)
514
-
409
+ with self.adjust_blank("attribute") as ofi:
410
+ self._write_structbody_fields(body, fields, ofi)
515
411
  if body.struct.size is None:
516
- print(file=self.stream)
517
- msg = (
518
- "# The size provided by the typelib is incorrect.\n"
519
- "# The size and alignment check for %s is skipped."
520
- )
521
- print(msg % body.struct.name, file=self.stream)
412
+ with self.adjust_blank("comment") as ofi:
413
+ self._write_structbody_size_comments(body, ofi)
522
414
  elif body.struct.name not in packing.dont_assert_size:
523
- print(file=self.stream)
524
- size = body.struct.size // 8
525
- print(
526
- f"assert sizeof({body.struct.name}) == {size}, sizeof({body.struct.name})",
527
- file=self.stream,
528
- )
529
- align = body.struct.align // 8
530
- print(
531
- f"assert alignment({body.struct.name}) == {align}, alignment({body.struct.name})",
532
- file=self.stream,
533
- )
534
-
415
+ with self.adjust_blank("assert") as ofi:
416
+ self._write_structbody_size_assertion(body, ofi)
535
417
  if methods:
536
418
  self.imports.add("comtypes", "COMMETHOD")
537
-
538
- if not self.last_item_class:
539
- print(file=self.stream)
540
-
541
- self.last_item_class = False
542
- print(f"{body.struct.name}._methods_ = [", file=self.stream)
543
- if body.struct.location:
544
- print(f"# {body.struct.location}", file=self.stream)
545
-
546
- for m in methods:
547
- if m.location:
548
- print(f" # {m.location}", file=self.stream)
549
- print(
550
- (
551
- f" COMMETHOD(\n"
552
- f" [], \n"
553
- f" {self._to_type_name(m.returns)},\n"
554
- f" '{m.name}',\n"
555
- ),
556
- file=self.stream,
557
- )
558
- for a in m.iterArgTypes():
559
- print(f" ([], {self._to_type_name(a)}),\n", file=self.stream)
560
- print(" ),", file=self.stream)
561
- print("]", file=self.stream)
419
+ with self.adjust_blank("attribute") as ofi:
420
+ self._write_structbody_commethods(body, methods, ofi)
421
+
422
+ def _write_structbody_fields(
423
+ self,
424
+ body: typedesc.StructureBody,
425
+ fields: List[typedesc.Field],
426
+ ofi: io.StringIO,
427
+ ) -> None:
428
+ print(f"{body.struct.name}._fields_ = [", file=ofi)
429
+ if body.struct.location:
430
+ print(f" # {body.struct.location}", file=ofi)
431
+ # unnamed fields will get autogenerated names "_", "_1". "_2", "_3", ...
432
+ unnamed_index = 0
433
+ for f in fields:
434
+ if not f.name:
435
+ fieldname = "_" if not unnamed_index else f"_{unnamed_index:d}"
436
+ unnamed_index += 1
437
+ print(f" # Unnamed field renamed to '{fieldname}'", file=ofi)
438
+ else:
439
+ fieldname = f.name
440
+ typename = self._to_type_name(f.typ)
441
+ if f.bits is None:
442
+ print(f" ('{fieldname}', {typename}),", file=ofi)
443
+ else:
444
+ print(f" ('{fieldname}', {typename}, {f.bits}),", file=ofi)
445
+ print("]", file=ofi)
446
+
447
+ def _write_structbody_size_comments(
448
+ self, body: typedesc.StructureBody, ofi: io.StringIO
449
+ ) -> None:
450
+ msg1 = "# The size provided by the typelib is incorrect."
451
+ msg2 = f"# The size and alignment check for {body.struct.name} is skipped."
452
+ print(msg1, file=ofi)
453
+ print(msg2, file=ofi)
454
+
455
+ def _write_structbody_size_assertion(
456
+ self, body: typedesc.StructureBody, ofi: io.StringIO
457
+ ) -> None:
458
+ name = body.struct.name
459
+ assert body.struct.size is not None
460
+ size = body.struct.size // 8
461
+ print(f"assert sizeof({name}) == {size}, sizeof({name})", file=ofi)
462
+ align = body.struct.align // 8
463
+ print(f"assert alignment({name}) == {align}, alignment({name})", file=ofi)
464
+
465
+ def _write_structbody_commethods(
466
+ self,
467
+ body: typedesc.StructureBody,
468
+ methods: List[typedesc.Method],
469
+ ofi: io.StringIO,
470
+ ) -> None:
471
+ print(f"{body.struct.name}._methods_ = [", file=ofi)
472
+ if body.struct.location:
473
+ print(f"# {body.struct.location}", file=ofi)
474
+ for m in methods:
475
+ if m.location:
476
+ print(f" # {m.location}", file=ofi)
477
+ print(
478
+ (
479
+ " COMMETHOD(\n"
480
+ " [],\n"
481
+ f" {self._to_type_name(m.returns)},\n"
482
+ f" '{m.name}',\n"
483
+ ),
484
+ file=ofi,
485
+ )
486
+ for a in m.iterArgTypes():
487
+ print(f" ([], {self._to_type_name(a)}),\n", file=ofi)
488
+ print(" ),", file=ofi)
489
+ print("]", file=ofi)
562
490
 
563
491
  ################################################################
564
492
  # top-level typedesc generators
@@ -572,25 +500,9 @@ class CodeGenerator(object):
572
500
  # Should the '_reg_typelib_' attribute be at top-level in the
573
501
  # generated code, instead as being an attribute of the
574
502
  # 'Library' symbol?
575
- if not self.last_item_class:
576
- print(file=self.stream)
577
- print(file=self.stream)
578
-
579
- self.last_item_class = True
580
-
581
- print("class Library(object):", file=self.stream)
582
- if lib.doc:
583
- print(self._to_docstring(lib.doc), file=self.stream)
584
503
 
585
- if lib.name:
586
- print(f" name = {lib.name!r}", file=self.stream)
587
-
588
- print(
589
- f" _reg_typelib_ = ({lib.guid!r}, {lib.major!r}, {lib.minor!r})",
590
- file=self.stream,
591
- )
592
- print(file=self.stream)
593
- print(file=self.stream)
504
+ with self.adjust_blank("class") as ofi:
505
+ heads.LibraryHeadWriter(ofi).write(lib)
594
506
  self.names.add("Library")
595
507
 
596
508
  def External(self, ext: typedesc.External) -> None:
@@ -600,12 +512,10 @@ class CodeGenerator(object):
600
512
  self.imports.add(modname)
601
513
 
602
514
  def Constant(self, tp: typedesc.Constant) -> None:
603
- self.last_item_class = False
604
- print(
605
- f"{tp.name} = {tp.value!r} # Constant {self._to_type_name(tp.typ)}",
606
- file=self.stream,
607
- )
608
- self.names.add(tp.name)
515
+ with self.adjust_blank("variable") as ofi:
516
+ type_name = self._to_type_name(tp.typ)
517
+ print(f"{tp.name} = {tp.value!r} # Constant {type_name}", file=ofi)
518
+ self.names.add(tp.name)
609
519
 
610
520
  def SAFEARRAYType(self, sa: typedesc.SAFEARRAYType) -> None:
611
521
  self.generate(sa.typ)
@@ -638,30 +548,8 @@ class CodeGenerator(object):
638
548
  def CoClass(self, coclass: typedesc.CoClass) -> None:
639
549
  self.imports.add("comtypes", "GUID")
640
550
  self.imports.add("comtypes", "CoClass")
641
- if not self.last_item_class:
642
- print(file=self.stream)
643
- print(file=self.stream)
644
-
645
- self.last_item_class = True
646
-
647
- print(f"class {coclass.name}(CoClass):", file=self.stream)
648
- if coclass.doc:
649
- print(self._to_docstring(coclass.doc), file=self.stream)
650
- print(f" _reg_clsid_ = GUID({coclass.clsid!r})", file=self.stream)
651
- print(f" _idlflags_ = {coclass.idlflags}", file=self.stream)
652
- if self.filename is not None:
653
- print(" _typelib_path_ = typelib_path", file=self.stream)
654
- # X print
655
- # >> self.stream, "POINTER(%s).__ctypes_from_outparam__ = wrap" % coclass.name
656
-
657
- libid = coclass.tlibattr.guid
658
- wMajor, wMinor = coclass.tlibattr.wMajorVerNum, coclass.tlibattr.wMinorVerNum
659
- print(
660
- f" _reg_typelib_ = ({str(libid)!r}, {wMajor}, {wMinor})",
661
- file=self.stream,
662
- )
663
- print(file=self.stream)
664
- print(file=self.stream)
551
+ with self.adjust_blank("class") as ofi:
552
+ heads.CoClassHeadWriter(ofi, self.filename).write(coclass)
665
553
 
666
554
  for itf, _ in coclass.interfaces:
667
555
  self.generate(itf.get_head())
@@ -669,18 +557,13 @@ class CodeGenerator(object):
669
557
  implemented = [self._to_type_name(itf) for itf in impl]
670
558
  sources = [self._to_type_name(itf) for itf in src]
671
559
 
672
- if implemented:
673
- self.last_item_class = False
674
- print(
675
- f"{coclass.name}._com_interfaces_ = [{', '.join(implemented)}]",
676
- file=self.stream,
677
- )
678
- if sources:
679
- self.last_item_class = False
680
- print(
681
- f"{coclass.name}._outgoing_interfaces_ = [{', '.join(sources)}]",
682
- file=self.stream,
683
- )
560
+ with self.adjust_blank("attribute") as ofi:
561
+ if implemented:
562
+ itfs = ", ".join(implemented)
563
+ print(f"{coclass.name}._com_interfaces_ = [{itfs}]", file=ofi)
564
+ if sources:
565
+ itfs = ", ".join(sources)
566
+ print(f"{coclass.name}._outgoing_interfaces_ = [{itfs}]", file=ofi)
684
567
 
685
568
  self.names.add(coclass.name)
686
569
 
@@ -741,16 +624,6 @@ class CodeGenerator(object):
741
624
  return self.known_interfaces[item.name] == item.iid
742
625
  return False
743
626
 
744
- def _is_enuminterface(self, itf: typedesc.ComInterface) -> bool:
745
- # Check if this is an IEnumXXX interface
746
- if not itf.name.startswith("IEnum"):
747
- return False
748
- member_names = [mth.name for mth in itf.members]
749
- for name in ("Next", "Skip", "Reset", "Clone"):
750
- if name not in member_names:
751
- return False
752
- return True
753
-
754
627
  def ComInterfaceHead(self, head: typedesc.ComInterfaceHead) -> None:
755
628
  if head.itf.base is None:
756
629
  # we don't beed to generate IUnknown
@@ -761,49 +634,8 @@ class CodeGenerator(object):
761
634
 
762
635
  self.imports.add("comtypes", "GUID")
763
636
 
764
- if not self.last_item_class:
765
- print(file=self.stream)
766
- print(file=self.stream)
767
-
768
- self.last_item_class = True
769
-
770
- print(f"class {head.itf.name}({basename}):", file=self.stream)
771
- if head.itf.doc:
772
- print(self._to_docstring(head.itf.doc), file=self.stream)
773
-
774
- print(" _case_insensitive_ = True", file=self.stream)
775
- print(f" _iid_ = GUID({head.itf.iid!r})", file=self.stream)
776
- print(f" _idlflags_ = {head.itf.idlflags}", file=self.stream)
777
-
778
- if self._is_enuminterface(head.itf):
779
- print(file=self.stream)
780
- print(" def __iter__(self):", file=self.stream)
781
- print(" return self", file=self.stream)
782
- print(file=self.stream)
783
-
784
- print(" def __next__(self):", file=self.stream)
785
- print(" item, fetched = self.Next(1)", file=self.stream)
786
- print(" if fetched:", file=self.stream)
787
- print(" return item", file=self.stream)
788
- print(" raise StopIteration", file=self.stream)
789
- print(file=self.stream)
790
-
791
- print(" def __getitem__(self, index):", file=self.stream)
792
- print(" self.Reset()", file=self.stream)
793
- print(" self.Skip(index)", file=self.stream)
794
- print(" item, fetched = self.Next(1)", file=self.stream)
795
- print(" if fetched:", file=self.stream)
796
- print(" return item", file=self.stream)
797
- print(" raise IndexError(index)", file=self.stream)
798
-
799
- annotations = typeannotator.ComInterfaceMembersAnnotator(head.itf).generate()
800
- if annotations:
801
- print(file=self.stream)
802
- print(" if TYPE_CHECKING: # commembers", file=self.stream)
803
- print(annotations, file=self.stream)
804
-
805
- print(file=self.stream)
806
- print(file=self.stream)
637
+ with self.adjust_blank("class") as ofi:
638
+ heads.ComInterfaceHeadWriter(ofi).write(head, basename)
807
639
 
808
640
  def ComInterfaceBody(self, body: typedesc.ComInterfaceBody) -> None:
809
641
  # The base class must be fully generated, including the
@@ -816,88 +648,19 @@ class CodeGenerator(object):
816
648
  self.generate(a[0])
817
649
  self.generate(m.returns)
818
650
 
819
- if not self.last_item_class:
820
- print(file=self.stream)
821
-
822
- self.last_item_class = False
823
- print(f"{body.itf.name}._methods_ = [", file=self.stream)
824
- for m in body.itf.members:
825
- if isinstance(m, typedesc.ComMethod):
826
- self.make_ComMethod(m, "dual" in body.itf.idlflags)
827
- else:
828
- raise TypeError("what's this?")
829
-
830
- print("]", file=self.stream)
831
- print(file=self.stream)
832
- print(
833
- "################################################################",
834
- file=self.stream,
835
- )
836
- print(f"# code template for {body.itf.name} implementation", file=self.stream)
837
- print(f"# class {body.itf.name}_Impl(object):", file=self.stream)
838
-
839
- methods = {}
840
- for m in body.itf.members:
841
- if isinstance(m, typedesc.ComMethod):
842
- # m.arguments is a sequence of tuples:
843
- # (argtype, argname, idlflags, docstring)
844
- # Some typelibs have unnamed method parameters!
845
- inargs = [a[1] or "<unnamed>" for a in m.arguments if not "out" in a[2]]
846
- outargs = [a[1] or "<unnamed>" for a in m.arguments if "out" in a[2]]
847
- if "propget" in m.idlflags:
848
- methods.setdefault(m.name, [0, inargs, outargs, m.doc])[0] |= 1
849
- elif "propput" in m.idlflags:
850
- methods.setdefault(m.name, [0, inargs[:-1], inargs[-1:], m.doc])[
851
- 0
852
- ] |= 2
651
+ with self.adjust_blank("attribute") as ofi:
652
+ print(f"{body.itf.name}._methods_ = [", file=ofi)
653
+ for m in body.itf.members:
654
+ if isinstance(m, typedesc.ComMethod):
655
+ isdual = "dual" in body.itf.idlflags
656
+ print(ComMethodGenerator(m, isdual).generate(), file=ofi)
657
+ self.add_ComMth_requirements(m, isdual)
853
658
  else:
854
- methods[m.name] = [0, inargs, outargs, m.doc]
659
+ raise TypeError("what's this?")
855
660
 
856
- for name, (typ, inargs, outargs, doc) in methods.items():
857
- if typ == 0: # method
858
- print(
859
- f"# def {name}({', '.join(['self'] + inargs)}):",
860
- file=self.stream,
861
- )
862
- print(f"# {(doc or '-no docstring-')!r}", file=self.stream)
863
- print(f"# #return {', '.join(outargs)}", file=self.stream)
864
- elif typ == 1: # propget
865
- print("# @property", file=self.stream)
866
- print(
867
- f"# def {name}({', '.join(['self'] + inargs)}):",
868
- file=self.stream,
869
- )
870
- print(f"# {(doc or '-no docstring-')!r}", file=self.stream)
871
- print(f"# #return {', '.join(outargs)}", file=self.stream)
872
- elif typ == 2: # propput
873
- print(
874
- f"# def _set({', '.join(['self'] + inargs + outargs)}):",
875
- file=self.stream,
876
- )
877
- print(f"# {(doc or '-no docstring-')!r}", file=self.stream)
878
- print(
879
- f"# {name} = property(fset = _set, doc = _set.__doc__)",
880
- file=self.stream,
881
- )
882
- elif typ == 3: # propget + propput
883
- print(
884
- f"# def _get({', '.join(['self'] + inargs)}):",
885
- file=self.stream,
886
- )
887
- print(f"# {(doc or '-no docstring-')!r}", file=self.stream)
888
- print(f"# #return {', '.join(outargs)}", file=self.stream)
889
- print(
890
- f"# def _set({', '.join(['self'] + inargs + outargs)}):",
891
- file=self.stream,
892
- )
893
- print(f"# {(doc or '-no docstring-')!r}", file=self.stream)
894
- print(
895
- f"# {name} = property(_get, _set, doc = _set.__doc__)",
896
- file=self.stream,
897
- )
898
- else:
899
- raise RuntimeError("BUG")
900
- print("#", file=self.stream)
661
+ print("]", file=ofi)
662
+ print(file=self.stream)
663
+ ComInterfaceBodyImplCommentWriter(self.stream).write(body)
901
664
 
902
665
  def DispInterface(self, itf: typedesc.DispInterface) -> None:
903
666
  self.generate(itf.get_head())
@@ -909,28 +672,9 @@ class CodeGenerator(object):
909
672
  basename = self._to_type_name(head.itf.base)
910
673
 
911
674
  self.imports.add("comtypes", "GUID")
912
- if not self.last_item_class:
913
- print(file=self.stream)
914
- print(file=self.stream)
915
-
916
- self.last_item_class = True
917
675
 
918
- print(f"class {head.itf.name}({basename}):", file=self.stream)
919
- if head.itf.doc:
920
- print(self._to_docstring(head.itf.doc), file=self.stream)
921
- print(" _case_insensitive_ = True", file=self.stream)
922
- print(f" _iid_ = GUID({head.itf.iid!r})", file=self.stream)
923
- print(f" _idlflags_ = {head.itf.idlflags}", file=self.stream)
924
- print(" _methods_ = []", file=self.stream)
925
-
926
- annotations = typeannotator.DispInterfaceMembersAnnotator(head.itf).generate()
927
- if annotations:
928
- print(file=self.stream)
929
- print(" if TYPE_CHECKING: # dispmembers", file=self.stream)
930
- print(annotations, file=self.stream)
931
-
932
- print(file=self.stream)
933
- print(file=self.stream)
676
+ with self.adjust_blank("class") as ofi:
677
+ heads.DispInterfaceHeadWriter(ofi).write(head, basename)
934
678
 
935
679
  def DispInterfaceBody(self, body: typedesc.DispInterfaceBody) -> None:
936
680
  # make sure we can generate the body
@@ -943,34 +687,28 @@ class CodeGenerator(object):
943
687
  self.generate(m.typ)
944
688
  else:
945
689
  raise TypeError(m)
946
-
947
- if not self.last_item_class:
948
- print(file=self.stream)
949
-
950
- self.last_item_class = False
951
-
952
- print(f"{body.itf.name}._disp_methods_ = [", file=self.stream)
953
- for m in body.itf.members:
954
- if isinstance(m, typedesc.DispMethod):
955
- self.make_DispMethod(m)
956
- elif isinstance(m, typedesc.DispProperty):
957
- self.make_DispProperty(m)
958
- else:
959
- raise TypeError(m)
960
- print("]", file=self.stream)
690
+ with self.adjust_blank("attribute") as ofi:
691
+ print(f"{body.itf.name}._disp_methods_ = [", file=ofi)
692
+ for m in body.itf.members:
693
+ if isinstance(m, typedesc.DispMethod):
694
+ print(DispMethodGenerator(m).generate(), file=ofi)
695
+ self.add_DispMth_requirements(m)
696
+ elif isinstance(m, typedesc.DispProperty):
697
+ print(DispPropertyGenerator(m).generate(), file=ofi)
698
+ self.add_DispProp_requirements(m)
699
+ else:
700
+ raise TypeError(m)
701
+ print("]", file=ofi)
961
702
 
962
703
  ################################################################
963
- # non-toplevel method generators
704
+ # non-toplevel method requirements
964
705
  #
965
- def make_ComMethod(self, m: typedesc.ComMethod, isdual: bool) -> None:
706
+ def add_ComMth_requirements(self, m: typedesc.ComMethod, isdual: bool) -> None:
966
707
  self.imports.add("comtypes", "COMMETHOD")
967
708
  if isdual:
968
709
  self.imports.add("comtypes", "dispid")
969
710
  if __debug__ and m.doc:
970
711
  self.imports.add("comtypes", "helpstring")
971
- gen = ComMethodGenerator(m, isdual)
972
- print(gen.generate(), file=self.stream)
973
- self.last_item_class = False
974
712
  for typ, _, _, default in m.arguments:
975
713
  if isinstance(typ, typedesc.ComInterface):
976
714
  self.declarations.add(
@@ -981,23 +719,17 @@ class CodeGenerator(object):
981
719
  if default is not None:
982
720
  self.need_VARIANT_imports(default)
983
721
 
984
- def make_DispMethod(self, m: typedesc.DispMethod) -> None:
722
+ def add_DispMth_requirements(self, m: typedesc.DispMethod) -> None:
985
723
  self.imports.add("comtypes", "DISPMETHOD")
986
724
  self.imports.add("comtypes", "dispid")
987
725
  if __debug__ and m.doc:
988
726
  self.imports.add("comtypes", "helpstring")
989
- gen = DispMethodGenerator(m)
990
- print(gen.generate(), file=self.stream)
991
- self.last_item_class = False
992
727
  for _, _, _, default in m.arguments:
993
728
  if default is not None:
994
729
  self.need_VARIANT_imports(default)
995
730
 
996
- def make_DispProperty(self, prop: typedesc.DispProperty) -> None:
731
+ def add_DispProp_requirements(self, prop: typedesc.DispProperty) -> None:
997
732
  self.imports.add("comtypes", "DISPPROPERTY")
998
733
  self.imports.add("comtypes", "dispid")
999
734
  if __debug__ and prop.doc:
1000
735
  self.imports.add("comtypes", "helpstring")
1001
- gen = DispPropertyGenerator(prop)
1002
- print(gen.generate(), file=self.stream)
1003
- self.last_item_class = False