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
@@ -64,7 +64,7 @@ def requires(resource, msg=None):
64
64
  return
65
65
  if not is_resource_enabled(resource):
66
66
  if msg is None:
67
- msg = "Use of the `%s' resource not enabled" % resource
67
+ msg = f"Use of the `{resource}` resource not enabled"
68
68
  raise ResourceDenied(msg)
69
69
 
70
70
 
@@ -94,12 +94,10 @@ def get_tests(package, mask, verbosity):
94
94
  except ResourceDenied as detail:
95
95
  skipped.append(modname)
96
96
  if verbosity > 1:
97
- print("Skipped %s: %s" % (modname, detail), file=sys.stderr)
97
+ print(f"Skipped {modname}: {detail}", file=sys.stderr)
98
98
  continue
99
99
  except Exception as detail:
100
- print(
101
- "Warning: could not import %s: %s" % (modname, detail), file=sys.stderr
102
- )
100
+ print(f"Warning: could not import {modname}: {detail}", file=sys.stderr)
103
101
  continue
104
102
  for name in dir(mod):
105
103
  if name.startswith("_"):
@@ -121,8 +119,8 @@ def usage():
121
119
 
122
120
  def test_with_refcounts(runner, verbosity, testcase):
123
121
  """Run testcase several times, tracking reference counts."""
124
- import gc
125
122
  import ctypes
123
+ import gc
126
124
 
127
125
  ptc = ctypes._pointer_type_cache.copy()
128
126
  cfc = ctypes._c_functype_cache.copy()
@@ -149,9 +147,9 @@ def test_with_refcounts(runner, verbosity, testcase):
149
147
  cleanup()
150
148
  refcounts[i] = sys.gettotalrefcount() - rc
151
149
  if [_f for _f in refcounts if _f]:
152
- print("%s leaks:\n\t" % testcase, refcounts)
150
+ print(f"{testcase} leaks:\n\t", refcounts)
153
151
  elif verbosity:
154
- print("%s: ok." % testcase)
152
+ print(f"{testcase}: ok.")
155
153
 
156
154
 
157
155
  class TestRunner(unittest.TextTestRunner):
@@ -180,21 +178,21 @@ class TestRunner(unittest.TextTestRunner):
180
178
  len(skipped) != 1 and "s" or "",
181
179
  )
182
180
  )
183
- self.stream.writeln("Unavailable resources: %s" % ", ".join(requested))
181
+ self.stream.writeln(f"Unavailable resources: {', '.join(requested)}")
184
182
  else:
185
183
  self.stream.writeln(
186
- "Ran %d test%s in %.3fs" % (run, run != 1 and "s" or "", timeTaken)
184
+ f"Ran {run} test{'s' if run != 1 else ''} in {timeTaken:.3f}s"
187
185
  )
188
186
  self.stream.writeln()
189
187
  if not result.wasSuccessful():
190
188
  self.stream.write("FAILED (")
191
189
  failed, errored = list(map(len, (result.failures, result.errors)))
192
190
  if failed:
193
- self.stream.write("failures=%d" % failed)
191
+ self.stream.write(f"failures={failed}")
194
192
  if errored:
195
193
  if failed:
196
194
  self.stream.write(", ")
197
- self.stream.write("errors=%d" % errored)
195
+ self.stream.write(f"errors={errored}")
198
196
  self.stream.writeln(")")
199
197
  else:
200
198
  self.stream.writeln("OK")
@@ -0,0 +1,72 @@
1
+ import gc
2
+ from ctypes import POINTER, Structure, WinDLL, WinError, byref, c_size_t, sizeof
3
+ from ctypes.wintypes import BOOL, DWORD, HANDLE
4
+
5
+ ################################################################
6
+
7
+
8
+ class PROCESS_MEMORY_COUNTERS(Structure):
9
+ _fields_ = [
10
+ ("cb", DWORD),
11
+ ("PageFaultCount", DWORD),
12
+ ("PeakWorkingSetSize", c_size_t),
13
+ ("WorkingSetSize", c_size_t),
14
+ ("QuotaPeakPagedPoolUsage", c_size_t),
15
+ ("QuotaPagedPoolUsage", c_size_t),
16
+ ("QuotaPeakNonPagedPoolUsage", c_size_t),
17
+ ("QuotaNonPagedPoolUsage", c_size_t),
18
+ ("PagefileUsage", c_size_t),
19
+ ("PeakPagefileUsage", c_size_t),
20
+ ]
21
+
22
+ def __init__(self):
23
+ self.cb = sizeof(self)
24
+
25
+ def dump(self):
26
+ for n, _ in self._fields_[2:]:
27
+ print(n, getattr(self, n) / 1e6)
28
+
29
+
30
+ _psapi = WinDLL("psapi")
31
+
32
+ _GetProcessMemoryInfo = _psapi.GetProcessMemoryInfo
33
+ _GetProcessMemoryInfo.argtypes = [HANDLE, POINTER(PROCESS_MEMORY_COUNTERS), DWORD]
34
+ _GetProcessMemoryInfo.restype = BOOL
35
+
36
+
37
+ def wss():
38
+ # Return the working set size (memory used by process)
39
+ pmi = PROCESS_MEMORY_COUNTERS()
40
+ if not _GetProcessMemoryInfo(-1, byref(pmi), sizeof(pmi)):
41
+ raise WinError()
42
+ return pmi.WorkingSetSize
43
+
44
+
45
+ LOOPS = 10, 1000
46
+
47
+
48
+ def find_memleak(func, loops=LOOPS):
49
+ # call 'func' several times, so that memory consumption
50
+ # stabilizes:
51
+ for j in range(loops[0]):
52
+ for k in range(loops[1]):
53
+ func()
54
+ gc.collect()
55
+ gc.collect()
56
+ gc.collect()
57
+ bytes = wss()
58
+ # call 'func' several times, recording the difference in
59
+ # memory consumption before and after the call. Repeat this a
60
+ # few times, and return a list containing the memory
61
+ # consumption differences.
62
+ for j in range(loops[0]):
63
+ for k in range(loops[1]):
64
+ func()
65
+ gc.collect()
66
+ gc.collect()
67
+ gc.collect()
68
+ # return the increased in process size
69
+ result = wss() - bytes
70
+ # Sometimes the process size did decrease, we do not report leaks
71
+ # in this case:
72
+ return max(result, 0)
@@ -1,4 +1,5 @@
1
1
  import sys
2
+
2
3
  import comtypes.test
3
4
 
4
5
 
@@ -1,6 +1,7 @@
1
1
  # all the unittests can be converted to exe-files.
2
- from distutils.core import setup
3
2
  import glob
3
+ from distutils.core import setup
4
+
4
5
  import py2exe
5
6
 
6
7
  setup(name="test_*", console=glob.glob("test_*.py"))
@@ -1,17 +1,15 @@
1
- import unittest, os
2
- from ctypes import *
3
- from comtypes import BSTR
4
- from comtypes.test import requires
5
-
6
- ##requires("memleaks")
1
+ import unittest
2
+ from ctypes import WinDLL
3
+ from ctypes.wintypes import UINT
7
4
 
5
+ from comtypes import BSTR
8
6
  from comtypes.test.find_memleak import find_memleak
9
7
 
10
8
 
11
9
  class Test(unittest.TestCase):
12
10
  def check_leaks(self, func, limit=0):
13
11
  bytes = find_memleak(func)
14
- self.assertFalse(bytes > limit, "Leaks %d bytes" % bytes)
12
+ self.assertFalse(bytes > limit, f"Leaks {bytes} bytes")
15
13
 
16
14
  def test_creation(self):
17
15
  def doit():
@@ -27,23 +25,12 @@ class Test(unittest.TestCase):
27
25
 
28
26
  self.check_leaks(doit)
29
27
 
30
- def test_paramflags(self):
31
- prototype = WINFUNCTYPE(c_void_p, BSTR)
32
- func = prototype(("SysStringLen", oledll.oleaut32))
33
- func.restype = c_void_p
34
- func.argtypes = (BSTR,)
35
-
36
- def doit():
37
- func("abcdef")
38
- func("abc xyz")
39
- func(BSTR("abc def"))
40
-
41
- self.check_leaks(doit)
42
-
43
28
  def test_inargs(self):
44
- SysStringLen = windll.oleaut32.SysStringLen
45
- SysStringLen.argtypes = (BSTR,)
46
- SysStringLen.restype = c_uint
29
+ oleaut32 = WinDLL("oleaut32")
30
+
31
+ SysStringLen = oleaut32.SysStringLen
32
+ SysStringLen.argtypes = [BSTR]
33
+ SysStringLen.restype = UINT
47
34
 
48
35
  self.assertEqual(SysStringLen("abc xyz"), 7)
49
36
 
@@ -1,4 +1,5 @@
1
1
  import unittest
2
+
2
3
  from comtypes import GUID
3
4
 
4
5
 
@@ -1,5 +1,6 @@
1
1
  import unittest
2
2
  from ctypes import POINTER
3
+
3
4
  import comtypes
4
5
  from comtypes.client import CreateObject, GetModule
5
6
 
@@ -3,11 +3,12 @@
3
3
  # connected, the driver is used in simulation mode.
4
4
 
5
5
  import unittest
6
- from comtypes.test import ResourceDenied
7
- from comtypes.client import CreateObject
6
+ from ctypes import POINTER, c_double
7
+
8
8
  from comtypes import GUID
9
+ from comtypes.client import CreateObject
9
10
  from comtypes.safearray import _midlSAFEARRAY
10
- from ctypes import c_double, POINTER
11
+ from comtypes.test import ResourceDenied
11
12
 
12
13
  try:
13
14
  GUID.from_progid("Agilent546XX.Agilent546XX")
@@ -37,7 +37,7 @@ class Test(unittest.TestCase):
37
37
 
38
38
  def check_leaks(self, func, limit=0):
39
39
  bytes = find_memleak(func)
40
- self.assertFalse(bytes > limit, "Leaks %d bytes" % bytes)
40
+ self.assertFalse(bytes > limit, f"Leaks {bytes} bytes")
41
41
 
42
42
 
43
43
  if __name__ == "__main__":
@@ -1,7 +1,9 @@
1
1
  ##import ut
2
2
  import unittest as ut
3
- from ctypes import windll, POINTER, byref, HRESULT
4
- from comtypes import IUnknown, STDMETHOD, GUID
3
+ from ctypes import HRESULT, POINTER, byref
4
+
5
+ from comtypes import GUID, STDMETHOD, IUnknown
6
+ from comtypes.typeinfo import ICreateTypeLib2, _CreateTypeLib2
5
7
 
6
8
  # XXX leaks references!
7
9
 
@@ -20,8 +22,10 @@ class BasicTest(ut.TestCase):
20
22
  POINTER(IUnknown)()
21
23
 
22
24
  def test_refcounts(self):
23
- p = POINTER(IUnknown)()
24
- windll.oleaut32.CreateTypeLib2(1, "blabla", byref(p))
25
+ # Since all COM interfaces derive from IUnknown and have the same reference counting behavior, any interface
26
+ # — whether ICreateTypeLib2 or otherwise — could be used for this test.
27
+ p = POINTER(ICreateTypeLib2)()
28
+ _CreateTypeLib2(1, "blabla", byref(p))
25
29
  # initial refcount is 2
26
30
  for i in range(2, 10):
27
31
  self.assertEqual(p.AddRef(), i)
@@ -29,8 +33,10 @@ class BasicTest(ut.TestCase):
29
33
  self.assertEqual(p.Release(), i)
30
34
 
31
35
  def test_qi(self):
32
- p = POINTER(IUnknown)()
33
- windll.oleaut32.CreateTypeLib2(1, "blabla", byref(p))
36
+ # Since all COM interfaces derive from IUnknown and have the same QueryInterface behavior, any interface
37
+ # — whether ICreateTypeLib2 or otherwise — could be used for this test.
38
+ p = POINTER(ICreateTypeLib2)()
39
+ _CreateTypeLib2(1, "blabla", byref(p))
34
40
  self.assertEqual(p.AddRef(), 2)
35
41
  self.assertEqual(p.Release(), 1)
36
42
 
@@ -31,13 +31,11 @@ class TestCase(unittest.TestCase):
31
31
  # names in the base class __map_case__ must also appear in the
32
32
  # subclass.
33
33
  for name in iem.IWebBrowser.__map_case__:
34
- self.assertTrue(
35
- name in iem.IWebBrowserApp.__map_case__, "%s missing" % name
36
- )
37
- self.assertTrue(name in iem.IWebBrowser2.__map_case__, "%s missing" % name)
34
+ self.assertTrue(name in iem.IWebBrowserApp.__map_case__, f"{name} missing")
35
+ self.assertTrue(name in iem.IWebBrowser2.__map_case__, f"{name} missing")
38
36
 
39
37
  for name in iem.IWebBrowserApp.__map_case__:
40
- self.assertTrue(name in iem.IWebBrowser2.__map_case__, "%s missing" % name)
38
+ self.assertTrue(name in iem.IWebBrowser2.__map_case__, f"{name} missing")
41
39
 
42
40
 
43
41
  if __name__ == "__main__":
@@ -4,8 +4,8 @@ Test for the ``comtypes.clear_cache`` module.
4
4
 
5
5
  import contextlib
6
6
  import runpy
7
- from unittest.mock import patch, call
8
7
  from unittest import TestCase
8
+ from unittest.mock import call, patch
9
9
 
10
10
  from comtypes.client import _find_gen_dir
11
11
 
@@ -1,11 +1,11 @@
1
1
  import contextlib
2
- from ctypes import POINTER, byref
3
2
  import os
4
3
  import sys
5
4
  import unittest as ut
5
+ from ctypes import POINTER, byref
6
6
 
7
7
  import comtypes.client
8
- from comtypes import COSERVERINFO, CLSCTX_INPROC_SERVER
8
+ from comtypes import CLSCTX_INPROC_SERVER, COSERVERINFO
9
9
 
10
10
  # create the typelib wrapper and import it
11
11
  comtypes.client.GetModule("scrrun.dll")
@@ -2,8 +2,8 @@ import ctypes
2
2
  import unittest as ut
3
3
  from unittest import mock
4
4
 
5
- from comtypes import automation, COMError, IUnknown
6
- from comtypes.client import CreateObject, dynamic, GetModule, lazybind
5
+ from comtypes import COMError, IUnknown, automation
6
+ from comtypes.client import CreateObject, GetModule, dynamic, lazybind
7
7
 
8
8
 
9
9
  class Test_Dispatch_Function(ut.TestCase):
@@ -1,12 +1,12 @@
1
1
  import contextlib
2
2
  import importlib
3
- from pathlib import Path
4
3
  import shutil
5
4
  import sys
6
5
  import tempfile
7
6
  import types
8
- from typing import Iterator
9
7
  import unittest as ut
8
+ from pathlib import Path
9
+ from typing import Iterator
10
10
  from unittest import mock
11
11
 
12
12
  import comtypes
@@ -1,7 +1,7 @@
1
1
  import unittest
2
- from comtypes.client import CreateObject
3
2
  from ctypes import ArgumentError
4
3
 
4
+ from comtypes.client import CreateObject
5
5
  from comtypes.test.find_memleak import find_memleak
6
6
 
7
7
 
@@ -74,7 +74,7 @@ class Test(unittest.TestCase):
74
74
  item.ProcessImageFileName
75
75
 
76
76
  bytes = find_memleak(doit, (20, 20))
77
- self.assertFalse(bytes, "Leaks %d bytes" % bytes)
77
+ self.assertFalse(bytes, f"Leaks {bytes} bytes")
78
78
 
79
79
  @unittest.skip("This test takes a long time. Do we need it? Can it be rewritten?")
80
80
  def test_leaks_2(self):
@@ -87,7 +87,7 @@ class Test(unittest.TestCase):
87
87
  iter(apps).Next(99)
88
88
 
89
89
  bytes = find_memleak(doit, (20, 20))
90
- self.assertFalse(bytes, "Leaks %d bytes" % bytes)
90
+ self.assertFalse(bytes, f"Leaks {bytes} bytes")
91
91
 
92
92
  @unittest.skip("This test takes a long time. Do we need it? Can it be rewritten?")
93
93
  def test_leaks_3(self):
@@ -102,7 +102,7 @@ class Test(unittest.TestCase):
102
102
  pass
103
103
 
104
104
  bytes = find_memleak(doit, (20, 20))
105
- self.assertFalse(bytes, "Leaks %d bytes" % bytes)
105
+ self.assertFalse(bytes, f"Leaks {bytes} bytes")
106
106
 
107
107
 
108
108
  class TestCollectionInterface(unittest.TestCase):
@@ -0,0 +1,146 @@
1
+ import ctypes
2
+ import unittest as ut
3
+ from ctypes import POINTER, byref, pointer
4
+ from unittest import mock
5
+
6
+ import comtypes.client
7
+ from comtypes import CLSCTX_SERVER, COMObject, IUnknown, hresult
8
+ from comtypes._post_coinit.misc import _CoCreateInstance
9
+ from comtypes.automation import IDispatch
10
+
11
+ comtypes.client.GetModule("UIAutomationCore.dll")
12
+ comtypes.client.GetModule("scrrun.dll")
13
+ from comtypes.gen import Scripting as scrrun
14
+ from comtypes.gen import UIAutomationClient as uiac
15
+ from comtypes.gen import stdole
16
+
17
+
18
+ class Test_QueryInterface(ut.TestCase):
19
+ def test_custom_interface(self):
20
+ iuia = uiac.CUIAutomation().QueryInterface(uiac.IUIAutomation)
21
+ self.assertTrue(bool(iuia))
22
+ self.assertEqual(iuia.AddRef(), 2)
23
+ punk = iuia.QueryInterface(IUnknown)
24
+ self.assertEqual(iuia.AddRef(), 4)
25
+ self.assertEqual(punk.AddRef(), 5)
26
+ self.assertEqual(iuia.Release(), 4)
27
+ del iuia
28
+ self.assertEqual(punk.Release(), 2)
29
+ self.assertEqual(punk.Release(), 1)
30
+
31
+ def test_dispatch_interface(self):
32
+ dic = scrrun.Dictionary().QueryInterface(scrrun.IDictionary)
33
+ self.assertTrue(bool(dic))
34
+ self.assertEqual(dic.GetTypeInfoCount(), 1)
35
+ self.assertEqual(
36
+ dic.GetTypeInfo(0).GetTypeAttr().guid,
37
+ scrrun.IDictionary._iid_,
38
+ )
39
+ self.assertEqual(dic.GetIDsOfNames("Add"), [1])
40
+
41
+
42
+ class Test_IUnknown_QueryInterface(ut.TestCase):
43
+ def test_e_pointer(self):
44
+ hr = scrrun.Dictionary().IUnknown_QueryInterface(
45
+ None, pointer(scrrun.IDictionary._iid_), ctypes.c_void_p()
46
+ )
47
+ self.assertEqual(hr, hresult.E_POINTER)
48
+
49
+ def test_e_no_interface(self):
50
+ hr = scrrun.Dictionary().IUnknown_QueryInterface(
51
+ None, pointer(uiac.IUIAutomation._iid_), ctypes.c_void_p()
52
+ )
53
+ self.assertEqual(hr, hresult.E_NOINTERFACE)
54
+
55
+ def test_valid_pointer(self):
56
+ ptr = ctypes.c_void_p()
57
+ _CoCreateInstance(
58
+ byref(scrrun.Dictionary._reg_clsid_),
59
+ None,
60
+ CLSCTX_SERVER,
61
+ byref(scrrun.IDictionary._iid_),
62
+ byref(ptr),
63
+ )
64
+ before_val = ptr.value
65
+ hr = scrrun.Dictionary().IUnknown_QueryInterface(
66
+ None, pointer(scrrun.IDictionary._iid_), ptr
67
+ )
68
+ self.assertEqual(hr, hresult.S_OK)
69
+ self.assertEqual(ptr.value, before_val)
70
+
71
+ def test_valid_interface(self):
72
+ dic = POINTER(IDispatch)()
73
+ hr = scrrun.Dictionary().IUnknown_QueryInterface(
74
+ None, pointer(scrrun.IDictionary._iid_), byref(dic)
75
+ )
76
+ self.assertEqual(hr, hresult.S_OK)
77
+ self.assertEqual(dic.AddRef(), 2) # type: ignore
78
+ self.assertEqual(dic.Release(), 1) # type: ignore
79
+ self.assertEqual(dic.GetTypeInfoCount(), 1) # type: ignore
80
+
81
+
82
+ class Test_IUnknown_AddRef_IUnknown_Release(ut.TestCase):
83
+ def test(self):
84
+ cuia = uiac.CUIAutomation()
85
+ self.assertEqual(cuia.IUnknown_AddRef(None), 1)
86
+ self.assertEqual(cuia.IUnknown_AddRef(None), 2)
87
+ with mock.patch.object(COMObject, "_final_release_") as release:
88
+ self.assertEqual(cuia.IUnknown_Release(None), 1)
89
+ release.assert_not_called()
90
+ self.assertEqual(cuia.IUnknown_Release(None), 0)
91
+ release.assert_called_once_with()
92
+
93
+
94
+ class Test_ISupportErrorInfo_InterfaceSupportsErrorInfo(ut.TestCase):
95
+ def test_s_ok(self):
96
+ cuia = uiac.CUIAutomation()
97
+ self.assertEqual(
98
+ cuia.ISupportErrorInfo_InterfaceSupportsErrorInfo(
99
+ None, pointer(IUnknown._iid_)
100
+ ),
101
+ hresult.S_OK,
102
+ )
103
+ self.assertEqual(
104
+ cuia.ISupportErrorInfo_InterfaceSupportsErrorInfo(
105
+ None, pointer(uiac.IUIAutomation._iid_)
106
+ ),
107
+ hresult.S_OK,
108
+ )
109
+
110
+ def test_s_false(self):
111
+ cuia = uiac.CUIAutomation()
112
+ self.assertEqual(
113
+ cuia.ISupportErrorInfo_InterfaceSupportsErrorInfo(
114
+ None, pointer(IDispatch._iid_)
115
+ ),
116
+ hresult.S_FALSE,
117
+ )
118
+ self.assertEqual(
119
+ cuia.ISupportErrorInfo_InterfaceSupportsErrorInfo(
120
+ None, pointer(scrrun.IDictionary._iid_)
121
+ ),
122
+ hresult.S_FALSE,
123
+ )
124
+
125
+
126
+ class Test_IProvideClassInfo_GetClassInfo(ut.TestCase):
127
+ def test(self):
128
+ tinfo = uiac.CUIAutomation().IProvideClassInfo_GetClassInfo()
129
+ self.assertEqual(tinfo.GetTypeAttr().guid, uiac.CUIAutomation._reg_clsid_)
130
+
131
+
132
+ class Test_IProvideClassInfo2_GetGUID(ut.TestCase):
133
+ def test(self):
134
+ # GUIDKIND_DEFAULT_SOURCE_DISP_IID = 1
135
+ self.assertEqual(
136
+ stdole.StdFont().IProvideClassInfo2_GetGUID(1),
137
+ stdole.FontEvents._iid_,
138
+ )
139
+
140
+
141
+ class Test_IPersist_GetClassID(ut.TestCase):
142
+ def test(self):
143
+ self.assertEqual(
144
+ uiac.CUIAutomation().IPersist_GetClassID(),
145
+ uiac.CUIAutomation._reg_clsid_,
146
+ )