comtypes 1.4.7__zip → 1.4.9__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 (149) hide show
  1. {comtypes-1.4.7 → comtypes-1.4.9}/CHANGES.txt +39 -0
  2. {comtypes-1.4.7/comtypes.egg-info → comtypes-1.4.9}/PKG-INFO +6 -4
  3. {comtypes-1.4.7 → comtypes-1.4.9}/README.md +5 -3
  4. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/GUID.py +6 -5
  5. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/__init__.py +16 -5
  6. comtypes-1.4.9/comtypes/_comobject.py +507 -0
  7. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/_memberspec.py +81 -9
  8. comtypes-1.4.9/comtypes/_meta.py +95 -0
  9. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/_npsupport.py +2 -1
  10. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/_post_coinit/__init__.py +1 -0
  11. comtypes-1.4.9/comtypes/_post_coinit/_cominterface_meta_patcher.py +153 -0
  12. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/_post_coinit/misc.py +21 -40
  13. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/_post_coinit/unknwn.py +88 -209
  14. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/_safearray.py +1 -2
  15. comtypes-1.4.9/comtypes/_vtbl.py +448 -0
  16. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/automation.py +36 -45
  17. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/client/__init__.py +21 -31
  18. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/client/_code_cache.py +5 -4
  19. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/client/_constants.py +1 -1
  20. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/client/_events.py +1 -2
  21. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/client/_generate.py +9 -13
  22. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/client/lazybind.py +2 -7
  23. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/errorinfo.py +3 -3
  24. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/git.py +2 -2
  25. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/hints.pyi +11 -19
  26. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/persist.py +7 -7
  27. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/safearray.py +12 -6
  28. comtypes-1.4.9/comtypes/server/__init__.py +86 -0
  29. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/server/inprocserver.py +22 -17
  30. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/server/localserver.py +28 -16
  31. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/server/register.py +62 -73
  32. comtypes-1.4.9/comtypes/server/w_getopt.py +48 -0
  33. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/shelllink.py +49 -67
  34. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/TestComServer.py +1 -1
  35. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/TestDispServer.py +1 -1
  36. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/__init__.py +9 -12
  37. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/find_memleak.py +0 -1
  38. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_BSTR.py +4 -7
  39. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_agilent.py +0 -1
  40. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_avmc.py +1 -1
  41. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_casesensitivity.py +3 -5
  42. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_clear_cache.py +1 -0
  43. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_collections.py +3 -3
  44. comtypes-1.4.9/comtypes/test/test_comobject.py +146 -0
  45. comtypes-1.4.9/comtypes/test/test_comserver.py +319 -0
  46. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_createwrappers.py +2 -6
  47. comtypes-1.4.9/comtypes/test/test_dispinterface.py +153 -0
  48. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_excel.py +22 -13
  49. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_ie.py +2 -5
  50. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_inout_args.py +8 -5
  51. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_midl_safearray_create.py +9 -1
  52. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_outparam.py +17 -10
  53. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_safearray.py +1 -90
  54. comtypes-1.4.9/comtypes/test/test_server.py +350 -0
  55. comtypes-1.4.9/comtypes/test/test_server_register.py +536 -0
  56. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_shelllink.py +10 -14
  57. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_showevents.py +7 -17
  58. comtypes-1.4.9/comtypes/test/test_stream.py +131 -0
  59. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_typeannotator.py +1 -1
  60. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_urlhistory.py +1 -0
  61. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_variant.py +0 -19
  62. comtypes-1.4.9/comtypes/test/test_w_getopt.py +29 -0
  63. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_win32com_interop.py +80 -36
  64. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_wmi.py +0 -3
  65. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/tools/codegenerator/codegenerator.py +62 -68
  66. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/tools/codegenerator/helpers.py +8 -8
  67. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/tools/codegenerator/namespaces.py +97 -27
  68. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/tools/codegenerator/packing.py +4 -4
  69. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/tools/codegenerator/typeannotator.py +9 -11
  70. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/tools/tlbparser.py +33 -32
  71. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/tools/typedesc.py +3 -8
  72. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/typeinfo.py +32 -47
  73. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/util.py +1 -0
  74. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/viewobject.py +1 -5
  75. {comtypes-1.4.7 → comtypes-1.4.9/comtypes.egg-info}/PKG-INFO +6 -4
  76. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes.egg-info/SOURCES.txt +6 -3
  77. comtypes-1.4.9/pyproject.toml +55 -0
  78. comtypes-1.4.7/comtypes/_comobject.py +0 -834
  79. comtypes-1.4.7/comtypes/_idl_stuff.py +0 -67
  80. comtypes-1.4.7/comtypes/_meta.py +0 -70
  81. comtypes-1.4.7/comtypes/server/__init__.py +0 -69
  82. comtypes-1.4.7/comtypes/server/w_getopt.py +0 -75
  83. comtypes-1.4.7/comtypes/test/test_comserver.py +0 -239
  84. comtypes-1.4.7/comtypes/test/test_dispinterface.py +0 -138
  85. comtypes-1.4.7/comtypes/test/test_propputref.py +0 -40
  86. comtypes-1.4.7/comtypes/test/test_server.py +0 -348
  87. comtypes-1.4.7/comtypes/test/test_stream.py +0 -53
  88. comtypes-1.4.7/pyproject.toml +0 -3
  89. {comtypes-1.4.7 → comtypes-1.4.9}/LICENSE.txt +0 -0
  90. {comtypes-1.4.7 → comtypes-1.4.9}/MANIFEST.in +0 -0
  91. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/_post_coinit/bstr.py +0 -0
  92. /comtypes-1.4.7/comtypes/_py_instance_method.py → /comtypes-1.4.9/comtypes/_post_coinit/instancemethod.py +0 -0
  93. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/_tlib_version_checker.py +0 -0
  94. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/clear_cache.py +0 -0
  95. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/client/dynamic.py +0 -0
  96. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/connectionpoints.py +0 -0
  97. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/hresult.py +0 -0
  98. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/logutil.py +0 -0
  99. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/messageloop.py +0 -0
  100. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/patcher.py +0 -0
  101. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/server/automation.py +0 -0
  102. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/server/connectionpoints.py +0 -0
  103. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/stream.py +0 -0
  104. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/TestComServer.idl +0 -0
  105. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/TestComServer.tlb +0 -0
  106. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/TestDispServer.idl +0 -0
  107. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/TestDispServer.tlb +0 -0
  108. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/mylib.idl +0 -0
  109. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/mylib.tlb +0 -0
  110. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/mytypelib.idl +0 -0
  111. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/runtests.py +0 -0
  112. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/setup.py +0 -0
  113. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_DISPPARAMS.py +0 -0
  114. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_GUID.py +0 -0
  115. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_QueryService.py +0 -0
  116. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_basic.py +0 -0
  117. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_client.py +0 -0
  118. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_client_dynamic.py +0 -0
  119. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_client_regenerate_modules.py +0 -0
  120. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_dict.py +0 -0
  121. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_dispifc_records.py +0 -0
  122. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_dispifc_safearrays.py +0 -0
  123. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_dyndispatch.py +0 -0
  124. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_findgendir.py +0 -0
  125. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_getactiveobj.py +0 -0
  126. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_ienum.py +0 -0
  127. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_imfattributes.py +0 -0
  128. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_jscript.js +0 -0
  129. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_monikers.py +0 -0
  130. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_msscript.py +0 -0
  131. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_npsupport.py +0 -0
  132. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_persist.py +0 -0
  133. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_pump_events.py +0 -0
  134. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_recordinfo.py +0 -0
  135. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_sapi.py +0 -0
  136. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_storage.py +0 -0
  137. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_subinterface.py +0 -0
  138. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_typeinfo.py +0 -0
  139. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/test_word.py +0 -0
  140. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/test/urlhist.tlb +0 -0
  141. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/tools/__init__.py +0 -0
  142. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/tools/codegenerator/__init__.py +0 -0
  143. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/tools/codegenerator/modulenamer.py +0 -0
  144. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes/tools/typedesc_base.py +0 -0
  145. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes.egg-info/dependency_links.txt +0 -0
  146. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes.egg-info/entry_points.txt +0 -0
  147. {comtypes-1.4.7 → comtypes-1.4.9}/comtypes.egg-info/top_level.txt +0 -0
  148. {comtypes-1.4.7 → comtypes-1.4.9}/setup.cfg +0 -0
  149. {comtypes-1.4.7 → comtypes-1.4.9}/setup.py +0 -0
@@ -1,4 +1,3 @@
1
- from __future__ import print_function
2
1
  import unittest, gc
3
2
  from ctypes import *
4
3
  from ctypes.wintypes import *
@@ -1,17 +1,14 @@
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 WINFUNCTYPE, c_uint, c_void_p, oledll, windll
7
3
 
4
+ from comtypes import BSTR
8
5
  from comtypes.test.find_memleak import find_memleak
9
6
 
10
7
 
11
8
  class Test(unittest.TestCase):
12
9
  def check_leaks(self, func, limit=0):
13
10
  bytes = find_memleak(func)
14
- self.assertFalse(bytes > limit, "Leaks %d bytes" % bytes)
11
+ self.assertFalse(bytes > limit, f"Leaks {bytes} bytes")
15
12
 
16
13
  def test_creation(self):
17
14
  def doit():
@@ -2,7 +2,6 @@
2
2
  # is installed. It is not requires to have a physical instrument
3
3
  # connected, the driver is used in simulation mode.
4
4
 
5
- from __future__ import print_function
6
5
  import unittest
7
6
  from comtypes.test import ResourceDenied
8
7
  from comtypes.client import CreateObject
@@ -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__":
@@ -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__":
@@ -1,6 +1,7 @@
1
1
  """
2
2
  Test for the ``comtypes.clear_cache`` module.
3
3
  """
4
+
4
5
  import contextlib
5
6
  import runpy
6
7
  from unittest.mock import patch, call
@@ -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
7
+ import comtypes.client
8
+ from comtypes import COMObject, IUnknown, hresult
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
+ ctypes.oledll.ole32.CoCreateInstance(
58
+ byref(scrrun.Dictionary._reg_clsid_),
59
+ None,
60
+ comtypes.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
+ )
@@ -0,0 +1,319 @@
1
+ import doctest
2
+ import unittest
3
+ from ctypes import pointer
4
+ from typing import Any
5
+
6
+ import comtypes.test.TestComServer
7
+ from comtypes import BSTR
8
+ from comtypes.automation import VARIANT, _midlSAFEARRAY
9
+ from comtypes.client import CreateObject
10
+ from comtypes.server.register import register, unregister
11
+ from comtypes.test.find_memleak import find_memleak
12
+
13
+ try:
14
+ from win32com.client import Dispatch
15
+
16
+ IMPORT_PYWIN32_FAILED = False
17
+ except ImportError:
18
+ IMPORT_PYWIN32_FAILED = True
19
+
20
+
21
+ def setUpModule():
22
+ try:
23
+ register(comtypes.test.TestComServer.TestComServer)
24
+ except WindowsError as e:
25
+ if e.winerror != 5: # [Error 5] Access is denied
26
+ raise e
27
+ raise unittest.SkipTest(
28
+ "This test requires the tests to be run as admin since it tries to "
29
+ "register the test COM server."
30
+ )
31
+
32
+
33
+ def tearDownModule():
34
+ unregister(comtypes.test.TestComServer.TestComServer)
35
+
36
+
37
+ class BaseServerTest(object):
38
+ def create_object(self) -> Any: ...
39
+
40
+ def _find_memleak(self, func):
41
+ bytes = find_memleak(func)
42
+ self.assertFalse(bytes, f"Leaks {bytes} bytes") # type: ignore
43
+
44
+ def test_mixedinout(self):
45
+ o = self.create_object()
46
+ self.assertEqual(o.MixedInOut(2, 4), (3, 5)) # type: ignore
47
+
48
+ def test_getname(self):
49
+ # This tests a tricky bug, introduced with this patch:
50
+ # http://www.python.org/sf/1643874
51
+ #
52
+ # Returning a BSTR as an [out] parameter from a server
53
+ # implementation must transfer the ownership to the caller.
54
+ # When this is not done, the BSTR instance is SysFreeString'd
55
+ # too early, and the memory is reused.
56
+ obj = self.create_object()
57
+ pb = pointer(BSTR())
58
+ # Get the BSTR from the server:
59
+ obj._ITestComServer__com__get_name(pb)
60
+ # Retrieve the value, but keep the pointer to the BSTR alive:
61
+ name = pb[0]
62
+ # Create sme BSTR's to reuse the memory in case it has been freed:
63
+ for i in range(10):
64
+ BSTR("f" * len(name))
65
+ # Make sure the pointer is still valid:
66
+ self.assertEqual(pb[0], name) # type: ignore
67
+
68
+ def test_get_id(self):
69
+ obj = self.create_object()
70
+ self._find_memleak(lambda: obj.id)
71
+
72
+ def test_get_name(self):
73
+ obj = self.create_object()
74
+ self._find_memleak(lambda: obj.name)
75
+
76
+ def test_set_name(self):
77
+ obj = self.create_object()
78
+
79
+ def func():
80
+ obj.name = "abcde"
81
+
82
+ self._find_memleak(func)
83
+
84
+ def test_SetName(self):
85
+ obj = self.create_object()
86
+
87
+ def func():
88
+ obj.SetName("abcde")
89
+
90
+ self._find_memleak(func)
91
+
92
+ def test_eval(self):
93
+ obj = self.create_object()
94
+
95
+ def func():
96
+ return obj.eval("(1, 2, 3)")
97
+
98
+ self.assertEqual(func(), (1, 2, 3)) # type: ignore
99
+ self._find_memleak(func)
100
+
101
+ def test_get_typeinfo(self):
102
+ obj = self.create_object()
103
+
104
+ def func():
105
+ obj.GetTypeInfo(0)
106
+ obj.GetTypeInfoCount()
107
+ obj.QueryInterface(comtypes.IUnknown)
108
+
109
+ self._find_memleak(func)
110
+
111
+
112
+ class TestInproc(BaseServerTest, unittest.TestCase):
113
+ def create_object(self):
114
+ return CreateObject(
115
+ "TestComServerLib.TestComServer", clsctx=comtypes.CLSCTX_INPROC_SERVER
116
+ )
117
+
118
+
119
+ class TestLocalServer(BaseServerTest, unittest.TestCase):
120
+ def create_object(self):
121
+ return CreateObject(
122
+ "TestComServerLib.TestComServer", clsctx=comtypes.CLSCTX_LOCAL_SERVER
123
+ )
124
+
125
+ @unittest.skip("This fails. Why?")
126
+ def test_get_typeinfo(self):
127
+ # Calling `GetTypeInfo` occurs;
128
+ # OSError: exception: access violation reading 0x0000000000000000
129
+ pass
130
+
131
+
132
+ @unittest.skipIf(IMPORT_PYWIN32_FAILED, "This depends on 'pywin32'.")
133
+ class TestInproc_win32com(BaseServerTest, unittest.TestCase):
134
+ def create_object(self):
135
+ return Dispatch("TestComServerLib.TestComServer")
136
+
137
+ # These tests make no sense with win32com, override to disable them:
138
+ @unittest.skip("This test make no sense with win32com.")
139
+ def test_get_typeinfo(self):
140
+ pass
141
+
142
+ @unittest.skip("This test make no sense with win32com.")
143
+ def test_getname(self):
144
+ pass
145
+
146
+ @unittest.skip("This test make no sense with win32com.")
147
+ def test_mixedinout(self):
148
+ # Not sure about this; it raise 'Invalid Number of parameters'
149
+ # Is mixed [in], [out] args not compatible with IDispatch???
150
+ pass
151
+
152
+
153
+ @unittest.skipIf(IMPORT_PYWIN32_FAILED, "This depends on 'pywin32'.")
154
+ class TestLocalServer_win32com(BaseServerTest, unittest.TestCase):
155
+ def create_object(self):
156
+ return Dispatch(
157
+ "TestComServerLib.TestComServer", clsctx=comtypes.CLSCTX_LOCAL_SERVER
158
+ )
159
+
160
+ # These tests are skipped for the same reason as `TestInproc_win32com`.
161
+ @unittest.skip("This test make no sense with win32com.")
162
+ def test_get_typeinfo(self):
163
+ pass
164
+
165
+ @unittest.skip("This test make no sense with win32com.")
166
+ def test_getname(self):
167
+ pass
168
+
169
+ @unittest.skip("This test make no sense with win32com.")
170
+ def test_mixedinout(self):
171
+ pass
172
+
173
+
174
+ class VariantTest(unittest.TestCase):
175
+ def test_UDT(self):
176
+ from comtypes.gen.TestComServerLib import MYCOLOR
177
+
178
+ v = VARIANT(MYCOLOR(red=1.0, green=2.0, blue=3.0))
179
+ value = v.value
180
+ self.assertEqual(1.0, value.red) # type: ignore
181
+ self.assertEqual(2.0, value.green) # type: ignore
182
+ self.assertEqual(3.0, value.blue) # type: ignore
183
+
184
+ def func():
185
+ v = VARIANT(MYCOLOR(red=1.0, green=2.0, blue=3.0))
186
+ return v.value
187
+
188
+ bytes = find_memleak(func)
189
+ self.assertFalse(bytes, f"Leaks {bytes} bytes") # type: ignore
190
+
191
+
192
+ class SafeArrayTest(unittest.TestCase):
193
+ def test_UDT(self):
194
+ from comtypes.gen.TestComServerLib import MYCOLOR
195
+
196
+ t = _midlSAFEARRAY(MYCOLOR)
197
+ self.assertTrue(t is _midlSAFEARRAY(MYCOLOR))
198
+
199
+ sa = t.from_param([MYCOLOR(0, 0, 0), MYCOLOR(1, 2, 3)])
200
+
201
+ self.assertEqual(
202
+ [(x.red, x.green, x.blue) for x in sa[0]],
203
+ [(0.0, 0.0, 0.0), (1.0, 2.0, 3.0)],
204
+ )
205
+
206
+ def doit():
207
+ t.from_param([MYCOLOR(0, 0, 0), MYCOLOR(1, 2, 3)])
208
+
209
+ bytes = find_memleak(doit)
210
+ self.assertFalse(bytes, f"Leaks {bytes} bytes") # type: ignore
211
+
212
+
213
+ class PropPutRefTest(unittest.TestCase):
214
+ def doit(self, dynamic: bool):
215
+ d = CreateObject("Scripting.Dictionary", dynamic=dynamic)
216
+ s = CreateObject("TestComServerLib.TestComServer", dynamic=dynamic)
217
+ s.name = "the value"
218
+
219
+ # This calls propputref, since we assign an Object
220
+ d.Item["object"] = s
221
+ # This calls propput, since we assing a Value
222
+ d.Item["value"] = s.name
223
+
224
+ self.assertEqual(d.Item["object"], s)
225
+ self.assertEqual(d.Item["object"].name, "the value")
226
+ self.assertEqual(d.Item["value"], "the value")
227
+
228
+ # Changing the default property of the object
229
+ s.name = "foo bar"
230
+ self.assertEqual(d.Item["object"], s)
231
+ self.assertEqual(d.Item["object"].name, "foo bar")
232
+ self.assertEqual(d.Item["value"], "the value")
233
+
234
+ # This also calls propputref since we assign an Object
235
+ d.Item["var"] = VARIANT(s)
236
+ self.assertEqual(d.Item["var"], s)
237
+
238
+ def test_earlybind(self):
239
+ self.doit(dynamic=False)
240
+
241
+ def test_latebind(self):
242
+ self.doit(dynamic=True)
243
+
244
+
245
+ class TestEvents(unittest.TestCase):
246
+ def test(self):
247
+ import comtypes.test.test_comserver
248
+
249
+ doctest.testmod(
250
+ comtypes.test.test_comserver, verbose=False, optionflags=doctest.ELLIPSIS
251
+ )
252
+
253
+
254
+ class ShowEventsExamples:
255
+ # The following functions are never called, they only contain doctests:
256
+
257
+ def ShowEventsFloat(self):
258
+ """
259
+ >>> from comtypes.client import CreateObject, ShowEvents
260
+ >>>
261
+ >>> o = CreateObject("TestComServerLib.TestComServer")
262
+ >>> con = ShowEvents(o)
263
+ # event found: ITestComServerEvents_EvalStarted
264
+ # event found: ITestComServerEvents_EvalCompleted
265
+ >>> result = o.eval("10. / 4")
266
+ Event ITestComServerEvents_EvalStarted(None, '10. / 4')
267
+ Event ITestComServerEvents_EvalCompleted(None, '10. / 4', VARIANT(vt=0x5, 2.5))
268
+ >>> result
269
+ 2.5
270
+ >>>
271
+ """
272
+
273
+ # # The following test, if enabled, works but the testsuit
274
+ # # crashes elsewhere. Is there s problem with SAFEARRAYs?
275
+
276
+ # def Fails(self):
277
+ # """
278
+ # >>> from comtypes.client import CreateObject, ShowEvents
279
+ # >>>
280
+ # >>> o = CreateObject("TestComServerLib.TestComServer")
281
+ # >>> con = ShowEvents(o)
282
+ # # event found: ITestComServerEvents_EvalStarted
283
+ # # event found: ITestComServerEvents_EvalCompleted
284
+ # >>> result = o.eval("['32'] * 2")
285
+ # Event ITestComServerEvents_EvalStarted(None, u"['32'] * 2")
286
+ # Event ITestComServerEvents_EvalCompleted(None, u"['32'] * 2", VARIANT(vt=0x200c, (u'32', u'32')))
287
+ # >>> result
288
+ # (u'32', u'32')
289
+ # >>>
290
+ # """
291
+
292
+ def GetEvents(self):
293
+ """
294
+ >>> from comtypes.client import CreateObject, GetEvents
295
+ >>>
296
+ >>> o = CreateObject("TestComServerLib.TestComServer")
297
+ >>> class EventHandler(object):
298
+ ... def EvalStarted(self, this, what):
299
+ ... print("EvalStarted: %s" % what)
300
+ ... return 0
301
+ ... def EvalCompleted(self, this, what, result):
302
+ ... print("EvalCompleted: %s = %s" % (what, result.value))
303
+ ... return 0
304
+ ...
305
+ >>>
306
+ >>> con = GetEvents(o, EventHandler())
307
+ >>> o.eval("2 + 3")
308
+ EvalStarted: 2 + 3
309
+ EvalCompleted: 2 + 3 = 5
310
+ 5
311
+ >>> del con
312
+ >>> o.eval("3 + 2")
313
+ 5
314
+ >>>
315
+ """
316
+
317
+
318
+ if __name__ == "__main__":
319
+ unittest.main()
@@ -1,5 +1,3 @@
1
- from __future__ import print_function
2
-
3
1
  import glob
4
2
  import os
5
3
  import unittest
@@ -17,8 +15,6 @@ def setUpModule():
17
15
  )
18
16
 
19
17
 
20
- # requires("typelibs")
21
-
22
18
  # filter warnings about interfaces without a base interface; they will
23
19
  # be skipped in the code generation.
24
20
  warnings.filterwarnings(
@@ -59,8 +55,8 @@ def add_test(fname):
59
55
  return
60
56
  comtypes.client.GetModule(fname)
61
57
 
62
- test.__doc__ = "test GetModule(%r)" % fname
63
- setattr(Test, "test_%d" % number, test)
58
+ test.__doc__ = f"test GetModule({fname!r})"
59
+ setattr(Test, f"test_{number}", test)
64
60
  number += 1
65
61
 
66
62