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
@@ -0,0 +1,131 @@
1
+ import unittest as ut
2
+
3
+ from ctypes import POINTER, byref, c_bool, c_ubyte, c_ulonglong, oledll, pointer
4
+ import comtypes
5
+ import comtypes.client
6
+
7
+ comtypes.client.GetModule("portabledeviceapi.dll")
8
+ from comtypes.gen.PortableDeviceApiLib import IStream
9
+
10
+
11
+ STGC_DEFAULT = 0
12
+ STREAM_SEEK_SET = 0
13
+ STREAM_SEEK_CUR = 1
14
+ STREAM_SEEK_END = 2
15
+
16
+
17
+ def _create_stream() -> IStream:
18
+ # Create an IStream
19
+ stream = POINTER(IStream)() # type: ignore
20
+ comtypes._ole32.CreateStreamOnHGlobal(None, c_bool(True), byref(stream))
21
+ return stream # type: ignore
22
+
23
+
24
+ class Test_RemoteWrite(ut.TestCase):
25
+ def test_RemoteWrite(self):
26
+ stream = _create_stream()
27
+ test_data = "Some data".encode("utf-8")
28
+ pv = (c_ubyte * len(test_data)).from_buffer(bytearray(test_data))
29
+
30
+ written = stream.RemoteWrite(pv, len(test_data))
31
+
32
+ # Verification
33
+ self.assertEqual(written, len(test_data))
34
+
35
+
36
+ class Test_RemoteRead(ut.TestCase):
37
+ def test_RemoteRead(self):
38
+ stream = _create_stream()
39
+ test_data = "Some data".encode("utf-8")
40
+ pv = (c_ubyte * len(test_data)).from_buffer(bytearray(test_data))
41
+ stream.RemoteWrite(pv, len(test_data))
42
+
43
+ # Make sure the data actually gets written before trying to read back
44
+ stream.Commit(STGC_DEFAULT)
45
+ # Move the stream back to the beginning
46
+ stream.RemoteSeek(0, STREAM_SEEK_SET)
47
+
48
+ buffer_size = 1024
49
+
50
+ read_buffer, data_read = stream.RemoteRead(buffer_size)
51
+
52
+ # Verification
53
+ self.assertEqual(data_read, len(test_data))
54
+ self.assertEqual(bytearray(read_buffer)[0:data_read], test_data)
55
+
56
+
57
+ class Test_RemoteSeek(ut.TestCase):
58
+ def _create_sample_stream(self) -> IStream:
59
+ stream = _create_stream()
60
+ test_data = b"spam egg bacon ham"
61
+ pv = (c_ubyte * len(test_data)).from_buffer(bytearray(test_data))
62
+ stream.RemoteWrite(pv, len(test_data))
63
+ stream.Commit(STGC_DEFAULT)
64
+ return stream
65
+
66
+ def test_takes_STREAM_SEEK_SET_as_origin(self):
67
+ stream = self._create_sample_stream()
68
+ newpos = stream.RemoteSeek(9, STREAM_SEEK_SET)
69
+ self.assertEqual(newpos, 9)
70
+ buf, read = stream.RemoteRead(1024)
71
+ self.assertEqual(bytearray(buf)[0:read], b"bacon ham")
72
+
73
+ def test_takes_STREAM_SEEK_CUR_as_origin(self):
74
+ stream = self._create_sample_stream()
75
+ stream.RemoteSeek(8, STREAM_SEEK_SET)
76
+ newpos = stream.RemoteSeek(7, STREAM_SEEK_CUR)
77
+ self.assertEqual(newpos, 15)
78
+ buf, read = stream.RemoteRead(1024)
79
+ self.assertEqual(bytearray(buf)[0:read], b"ham")
80
+
81
+ def test_takes_STREAM_SEEK_END_as_origin(self):
82
+ stream = self._create_sample_stream()
83
+ stream.RemoteSeek(8, STREAM_SEEK_SET)
84
+ newpos = stream.RemoteSeek(-13, STREAM_SEEK_END)
85
+ self.assertEqual(newpos, 5)
86
+ buf, read = stream.RemoteRead(1024)
87
+ self.assertEqual(bytearray(buf)[0:read], b"egg bacon ham")
88
+
89
+
90
+ class Test_SetSize(ut.TestCase):
91
+ def test_SetSize(self):
92
+ stream = _create_stream()
93
+ stream.SetSize(42)
94
+ pui = pointer(c_ulonglong())
95
+ oledll.shlwapi.IStream_Size(stream, pui)
96
+ self.assertEqual(pui.contents.value, 42)
97
+
98
+
99
+ class Test_RemoteCopyTo(ut.TestCase):
100
+ def test_RemoteCopyTo(self):
101
+ src = _create_stream()
102
+ dst = _create_stream()
103
+ test_data = b"parrot"
104
+ pv = (c_ubyte * len(test_data)).from_buffer(bytearray(test_data))
105
+ src_written = src.RemoteWrite(pv, len(test_data))
106
+ src.Commit(STGC_DEFAULT)
107
+ src.RemoteSeek(0, STREAM_SEEK_SET)
108
+ cpy_read, cpy_written = src.RemoteCopyTo(dst, src_written)
109
+ self.assertEqual(cpy_read, len(test_data))
110
+ self.assertEqual(cpy_written, len(test_data))
111
+ dst.Commit(STGC_DEFAULT)
112
+ dst.RemoteSeek(0, STREAM_SEEK_SET)
113
+ dst_buf, dst_read = dst.RemoteRead(1024)
114
+ self.assertEqual(bytearray(dst_buf)[0:dst_read], test_data)
115
+
116
+
117
+ class Test_Clone(ut.TestCase):
118
+ def test_Clone(self):
119
+ orig = _create_stream()
120
+ test_data = b"spam egg bacon ham"
121
+ pv = (c_ubyte * len(test_data)).from_buffer(bytearray(test_data))
122
+ orig.RemoteWrite(pv, len(test_data))
123
+ orig.Commit(STGC_DEFAULT)
124
+ orig.RemoteSeek(0, STREAM_SEEK_SET)
125
+ new_stm = orig.Clone()
126
+ buf, read = new_stm.RemoteRead(1024)
127
+ self.assertEqual(bytearray(buf)[0:read], test_data)
128
+
129
+
130
+ if __name__ == "__main__":
131
+ ut.main()
@@ -7,6 +7,7 @@ from comtypes.tools.tlbparser import (
7
7
  HRESULT_type,
8
8
  VARIANT_type,
9
9
  VARIANT_BOOL_type,
10
+ void_type,
10
11
  )
11
12
 
12
13
 
@@ -20,7 +21,6 @@ idispatch_type = typedesc.ComInterface(
20
21
  ["restricted"],
21
22
  None,
22
23
  )
23
- void_type = typedesc.FundamentalType("void", 0, 0)
24
24
 
25
25
 
26
26
  class Test_AvoidUsingKeywords(unittest.TestCase):
@@ -9,6 +9,7 @@ from comtypes.patcher import Patch
9
9
  GetModule(os.path.join(os.path.dirname(__file__), "urlhist.tlb"))
10
10
  from comtypes.gen import urlhistLib
11
11
 
12
+
12
13
  # The pwcsTitle and pwcsUrl fields of the _STATURL structure must be
13
14
  # freed by the caller. The only way to do this without patching the
14
15
  # generated code directly is to monkey-patch the
@@ -1,5 +1,3 @@
1
- from __future__ import print_function
2
-
3
1
  import datetime
4
2
  import decimal
5
3
  import sys
@@ -196,23 +194,6 @@ class VariantTestCase(unittest.TestCase):
196
194
  v.value = ""
197
195
  self.assertEqual(v.vt, VT_BSTR)
198
196
 
199
- @unittest.skip(
200
- "Fails on creating `TestComServerLib.TestComServer`. Library not registered."
201
- )
202
- def test_UDT(self):
203
- from comtypes.gen.TestComServerLib import MYCOLOR
204
-
205
- v = VARIANT(MYCOLOR(red=1.0, green=2.0, blue=3.0))
206
- value = v.value
207
- self.assertEqual((1.0, 2.0, 3.0), (value.red, value.green, value.blue))
208
-
209
- def func():
210
- v = VARIANT(MYCOLOR(red=1.0, green=2.0, blue=3.0))
211
- return v.value
212
-
213
- bytes = find_memleak(func)
214
- self.assertFalse(bytes, "Leaks %d bytes" % bytes)
215
-
216
197
  def test_ctypes_in_variant(self):
217
198
  v = VARIANT()
218
199
  objs = [
@@ -0,0 +1,29 @@
1
+ import unittest
2
+
3
+ from comtypes.server.w_getopt import GetoptError, w_getopt
4
+
5
+
6
+ class TestCase(unittest.TestCase):
7
+ def test_1(self):
8
+ args = "-embedding spam /RegServer foo /UnregSERVER blabla".split()
9
+ opts, args = w_getopt(args, "regserver unregserver embedding".split())
10
+ self.assertEqual(
11
+ opts, [("embedding", ""), ("regserver", ""), ("unregserver", "")]
12
+ )
13
+ self.assertEqual(args, ["spam", "foo", "blabla"])
14
+
15
+ def test_2(self):
16
+ args = "/TLB Hello.Tlb HELLO.idl".split()
17
+ opts, args = w_getopt(args, ["tlb:"])
18
+ self.assertEqual(opts, [("tlb", "Hello.Tlb")])
19
+ self.assertEqual(args, ["HELLO.idl"])
20
+
21
+ def test_3(self):
22
+ # Invalid option
23
+ self.assertRaises(
24
+ GetoptError, w_getopt, "/TLIB hello.tlb hello.idl".split(), ["tlb:"]
25
+ )
26
+
27
+ def test_4(self):
28
+ # Missing argument
29
+ self.assertRaises(GetoptError, w_getopt, "/TLB".split(), ["tlb:"])
@@ -1,19 +1,37 @@
1
1
  import unittest
2
-
3
- from ctypes import PyDLL, py_object, c_void_p, byref, POINTER
2
+ from ctypes import POINTER, PyDLL, byref, c_void_p, py_object
4
3
  from ctypes.wintypes import BOOL
5
4
 
6
- from comtypes import IUnknown
5
+ from comtypes import COMObject, IUnknown
6
+ from comtypes.automation import VARIANT, IDispatch
7
7
  from comtypes.client import CreateObject
8
- from comtypes.automation import IDispatch
9
- from comtypes.test import requires
10
8
 
11
- requires("pythoncom")
12
9
  try:
13
10
  import pythoncom
14
11
  import win32com.client
15
12
 
16
- skip = False
13
+ IMPORT_FAILED = False
14
+ # pywin32 is available. The pythoncom dll contains two handy
15
+ # exported functions that allow to create a VARIANT from a Python
16
+ # object, also a function that unpacks a VARIANT into a Python
17
+ # object.
18
+ #
19
+ # This allows us to create und unpack SAFEARRAY instances
20
+ # contained in VARIANTs, and check for consistency with the
21
+ # comtypes code.
22
+ _dll = PyDLL(pythoncom.__file__)
23
+
24
+ # c:/sf/pywin32/com/win32com/src/oleargs.cpp 213
25
+ # PyObject *PyCom_PyObjectFromVariant(const VARIANT *var)
26
+ unpack = _dll.PyCom_PyObjectFromVariant
27
+ unpack.restype = py_object
28
+ unpack.argtypes = (POINTER(VARIANT),)
29
+
30
+ # c:/sf/pywin32/com/win32com/src/oleargs.cpp 54
31
+ # BOOL PyCom_VariantFromPyObject(PyObject *obj, VARIANT *var)
32
+ _pack = _dll.PyCom_VariantFromPyObject
33
+ _pack.argtypes = py_object, POINTER(VARIANT)
34
+ _pack.restype = BOOL
17
35
  # We use the PyCom_PyObjectFromIUnknown function in pythoncom25.dll to
18
36
  # convert a comtypes COM pointer into a pythoncom COM pointer.
19
37
  # Fortunately this function is exported by the dll...
@@ -30,17 +48,58 @@ except ImportError:
30
48
  # if it is available since pythoncom is not a project dependency and adding tests depending
31
49
  # on the vagaries of various testing environments is not deterministic.
32
50
  # TODO: Evaluate if we should just remove this test or what.
33
- skip = True
51
+ IMPORT_FAILED = True
34
52
 
35
53
 
36
54
  def setUpModule():
37
- if skip:
55
+ if IMPORT_FAILED:
38
56
  raise unittest.SkipTest(
39
57
  "This test requires the pythoncom library installed. If this is "
40
58
  "important tests then we need to add dev dependencies to the project that include pythoncom."
41
59
  )
42
60
 
43
61
 
62
+ ################################################################
63
+
64
+
65
+ def pack(obj):
66
+ var = VARIANT()
67
+ _pack(obj, byref(var))
68
+ return var
69
+
70
+
71
+ class PyWinSafeArrayTest(unittest.TestCase):
72
+ def test_1dim(self):
73
+ data = (1, 2, 3)
74
+ variant = pack(data)
75
+ self.assertEqual(variant.value, data)
76
+ self.assertEqual(unpack(variant), data)
77
+
78
+ def test_2dim(self):
79
+ data = ((1, 2, 3), (4, 5, 6), (7, 8, 9))
80
+ variant = pack(data)
81
+ self.assertEqual(variant.value, data)
82
+ self.assertEqual(unpack(variant), data)
83
+
84
+ def test_3dim(self):
85
+ data = (((1, 2), (3, 4), (5, 6)), ((7, 8), (9, 10), (11, 12)))
86
+ variant = pack(data)
87
+ self.assertEqual(variant.value, data)
88
+ self.assertEqual(unpack(variant), data)
89
+
90
+ def test_4dim(self):
91
+ data = (
92
+ (((1, 2), (3, 4)), ((5, 6), (7, 8))),
93
+ (((9, 10), (11, 12)), ((13, 14), (15, 16))),
94
+ )
95
+ variant = pack(data)
96
+ self.assertEqual(variant.value, data)
97
+ self.assertEqual(unpack(variant), data)
98
+
99
+
100
+ ################################################################
101
+
102
+
44
103
  def comtypes2pywin(ptr, interface=None):
45
104
  """Convert a comtypes pointer 'ptr' into a pythoncom
46
105
  PyI<interface> object.
@@ -56,9 +115,6 @@ def comtypes2pywin(ptr, interface=None):
56
115
  return _PyCom_PyObjectFromIUnknown(ptr, byref(interface._iid_), True)
57
116
 
58
117
 
59
- ################################################################
60
-
61
-
62
118
  def comtypes_get_refcount(ptr):
63
119
  """Helper function for testing: return the COM reference count of
64
120
  a comtypes COM object"""
@@ -66,9 +122,6 @@ def comtypes_get_refcount(ptr):
66
122
  return ptr.Release()
67
123
 
68
124
 
69
- from comtypes import COMObject
70
-
71
-
72
125
  class MyComObject(COMObject):
73
126
  """A completely trivial COM object implementing IDispatch. Calling
74
127
  any methods will return the error code E_NOTIMPL (except the
@@ -77,42 +130,33 @@ class MyComObject(COMObject):
77
130
  _com_interfaces_ = [IDispatch]
78
131
 
79
132
 
80
- ################################################################
81
-
82
-
83
- class Test(unittest.TestCase):
84
- def tearDown(self):
85
- if hasattr(self, "ie"):
86
- self.ie.Quit()
87
- del self.ie
88
-
133
+ class ConvertComtypesPtrToPythonComObjTest(unittest.TestCase):
89
134
  def test_mycomobject(self):
90
135
  o = MyComObject()
91
136
  p = comtypes2pywin(o, IDispatch)
92
137
  disp = win32com.client.Dispatch(p)
93
138
  self.assertEqual(repr(disp), "<COMObject <unknown>>")
94
139
 
95
- def test_ie(self):
96
- # Convert a comtypes COM interface pointer into a win32com COM
97
- # pointer.
98
- ie = self.ie = CreateObject("InternetExplorer.Application")
140
+ def test_refcount(self):
141
+ # Convert a comtypes COM interface pointer into a win32com COM pointer.
142
+ dic = CreateObject("Scripting.Dictionary")
99
143
  # The COM refcount of the created object is 1:
100
- self.assertEqual(comtypes_get_refcount(ie), 1)
101
- # IE starts invisible:
102
- self.assertEqual(ie.Visible, False)
144
+ self.assertEqual(comtypes_get_refcount(dic), 1)
145
+ dic["foo"] = "bar"
146
+ self.assertEqual(dic.Item("foo"), "bar")
103
147
 
104
148
  # Create a pythoncom PyIDispatch object from it:
105
- p = comtypes2pywin(ie, interface=IDispatch)
106
- self.assertEqual(comtypes_get_refcount(ie), 2)
149
+ p = comtypes2pywin(dic, interface=IDispatch)
150
+ self.assertEqual(comtypes_get_refcount(dic), 2)
107
151
 
108
152
  # Make it usable...
109
153
  disp = win32com.client.Dispatch(p)
110
- self.assertEqual(comtypes_get_refcount(ie), 2)
111
- self.assertEqual(disp.Visible, False)
154
+ self.assertEqual(comtypes_get_refcount(dic), 2)
155
+ self.assertEqual(disp.Item("foo"), "bar")
112
156
 
113
157
  # Cleanup and make sure that the COM refcounts are correct
114
158
  del p, disp
115
- self.assertEqual(comtypes_get_refcount(ie), 1)
159
+ self.assertEqual(comtypes_get_refcount(dic), 1)
116
160
 
117
161
 
118
162
  if __name__ == "__main__":
@@ -1,9 +1,6 @@
1
1
  import unittest as ut
2
2
 
3
3
  from comtypes.client import CoGetObject
4
- from comtypes.test import requires
5
-
6
- requires("time")
7
4
 
8
5
 
9
6
  # WMI has dual interfaces.