comtypes 1.4.8__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 (146) hide show
  1. {comtypes-1.4.8 → comtypes-1.4.9}/CHANGES.txt +21 -0
  2. {comtypes-1.4.8/comtypes.egg-info → comtypes-1.4.9}/PKG-INFO +2 -2
  3. {comtypes-1.4.8 → comtypes-1.4.9}/README.md +1 -1
  4. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/GUID.py +6 -5
  5. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/__init__.py +16 -5
  6. comtypes-1.4.9/comtypes/_comobject.py +507 -0
  7. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_memberspec.py +80 -8
  8. comtypes-1.4.9/comtypes/_post_coinit/_cominterface_meta_patcher.py +153 -0
  9. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_post_coinit/misc.py +1 -1
  10. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_post_coinit/unknwn.py +25 -171
  11. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_safearray.py +1 -2
  12. comtypes-1.4.9/comtypes/_vtbl.py +448 -0
  13. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/automation.py +36 -45
  14. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/_code_cache.py +4 -4
  15. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/_constants.py +1 -1
  16. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/_events.py +1 -1
  17. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/_generate.py +4 -8
  18. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/lazybind.py +2 -2
  19. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/errorinfo.py +3 -3
  20. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/git.py +1 -2
  21. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/hints.pyi +7 -15
  22. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/safearray.py +10 -0
  23. comtypes-1.4.9/comtypes/server/__init__.py +86 -0
  24. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/inprocserver.py +22 -17
  25. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/localserver.py +28 -16
  26. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/register.py +61 -73
  27. comtypes-1.4.9/comtypes/server/w_getopt.py +48 -0
  28. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/shelllink.py +3 -26
  29. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/__init__.py +9 -11
  30. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_BSTR.py +4 -7
  31. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_avmc.py +1 -1
  32. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_casesensitivity.py +3 -5
  33. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_collections.py +3 -3
  34. comtypes-1.4.9/comtypes/test/test_comobject.py +146 -0
  35. comtypes-1.4.9/comtypes/test/test_comserver.py +319 -0
  36. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_createwrappers.py +2 -4
  37. comtypes-1.4.9/comtypes/test/test_dispinterface.py +153 -0
  38. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_excel.py +22 -12
  39. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_ie.py +2 -5
  40. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_inout_args.py +7 -4
  41. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_midl_safearray_create.py +9 -1
  42. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_outparam.py +17 -10
  43. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_safearray.py +1 -90
  44. comtypes-1.4.9/comtypes/test/test_server.py +350 -0
  45. comtypes-1.4.9/comtypes/test/test_server_register.py +536 -0
  46. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_showevents.py +7 -17
  47. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_variant.py +0 -17
  48. comtypes-1.4.9/comtypes/test/test_w_getopt.py +29 -0
  49. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_win32com_interop.py +80 -36
  50. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_wmi.py +0 -3
  51. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/codegenerator.py +62 -68
  52. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/helpers.py +8 -8
  53. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/packing.py +4 -4
  54. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/typeannotator.py +7 -7
  55. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/typedesc.py +1 -6
  56. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/typeinfo.py +11 -22
  57. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/viewobject.py +1 -5
  58. {comtypes-1.4.8 → comtypes-1.4.9/comtypes.egg-info}/PKG-INFO +2 -2
  59. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes.egg-info/SOURCES.txt +6 -3
  60. {comtypes-1.4.8 → comtypes-1.4.9}/pyproject.toml +1 -0
  61. comtypes-1.4.8/comtypes/_comobject.py +0 -833
  62. comtypes-1.4.8/comtypes/_idl_stuff.py +0 -67
  63. comtypes-1.4.8/comtypes/server/__init__.py +0 -70
  64. comtypes-1.4.8/comtypes/server/w_getopt.py +0 -75
  65. comtypes-1.4.8/comtypes/test/test_comserver.py +0 -239
  66. comtypes-1.4.8/comtypes/test/test_dispinterface.py +0 -137
  67. comtypes-1.4.8/comtypes/test/test_propputref.py +0 -40
  68. comtypes-1.4.8/comtypes/test/test_server.py +0 -354
  69. {comtypes-1.4.8 → comtypes-1.4.9}/LICENSE.txt +0 -0
  70. {comtypes-1.4.8 → comtypes-1.4.9}/MANIFEST.in +0 -0
  71. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_meta.py +0 -0
  72. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_npsupport.py +0 -0
  73. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_post_coinit/__init__.py +0 -0
  74. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_post_coinit/bstr.py +0 -0
  75. /comtypes-1.4.8/comtypes/_py_instance_method.py → /comtypes-1.4.9/comtypes/_post_coinit/instancemethod.py +0 -0
  76. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/_tlib_version_checker.py +0 -0
  77. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/clear_cache.py +0 -0
  78. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/__init__.py +0 -0
  79. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/client/dynamic.py +0 -0
  80. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/connectionpoints.py +0 -0
  81. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/hresult.py +0 -0
  82. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/logutil.py +0 -0
  83. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/messageloop.py +0 -0
  84. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/patcher.py +0 -0
  85. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/persist.py +0 -0
  86. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/automation.py +0 -0
  87. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/server/connectionpoints.py +0 -0
  88. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/stream.py +0 -0
  89. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestComServer.idl +0 -0
  90. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestComServer.py +0 -0
  91. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestComServer.tlb +0 -0
  92. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestDispServer.idl +0 -0
  93. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestDispServer.py +0 -0
  94. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/TestDispServer.tlb +0 -0
  95. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/find_memleak.py +0 -0
  96. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/mylib.idl +0 -0
  97. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/mylib.tlb +0 -0
  98. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/mytypelib.idl +0 -0
  99. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/runtests.py +0 -0
  100. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/setup.py +0 -0
  101. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_DISPPARAMS.py +0 -0
  102. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_GUID.py +0 -0
  103. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_QueryService.py +0 -0
  104. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_agilent.py +0 -0
  105. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_basic.py +0 -0
  106. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_clear_cache.py +0 -0
  107. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_client.py +0 -0
  108. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_client_dynamic.py +0 -0
  109. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_client_regenerate_modules.py +0 -0
  110. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_dict.py +0 -0
  111. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_dispifc_records.py +0 -0
  112. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_dispifc_safearrays.py +0 -0
  113. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_dyndispatch.py +0 -0
  114. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_findgendir.py +0 -0
  115. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_getactiveobj.py +0 -0
  116. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_ienum.py +0 -0
  117. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_imfattributes.py +0 -0
  118. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_jscript.js +0 -0
  119. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_monikers.py +0 -0
  120. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_msscript.py +0 -0
  121. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_npsupport.py +0 -0
  122. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_persist.py +0 -0
  123. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_pump_events.py +0 -0
  124. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_recordinfo.py +0 -0
  125. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_sapi.py +0 -0
  126. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_shelllink.py +0 -0
  127. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_storage.py +0 -0
  128. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_stream.py +0 -0
  129. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_subinterface.py +0 -0
  130. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_typeannotator.py +0 -0
  131. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_typeinfo.py +0 -0
  132. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_urlhistory.py +0 -0
  133. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/test_word.py +0 -0
  134. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/test/urlhist.tlb +0 -0
  135. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/__init__.py +0 -0
  136. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/__init__.py +0 -0
  137. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/modulenamer.py +0 -0
  138. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/codegenerator/namespaces.py +0 -0
  139. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/tlbparser.py +0 -0
  140. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/tools/typedesc_base.py +0 -0
  141. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes/util.py +0 -0
  142. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes.egg-info/dependency_links.txt +0 -0
  143. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes.egg-info/entry_points.txt +0 -0
  144. {comtypes-1.4.8 → comtypes-1.4.9}/comtypes.egg-info/top_level.txt +0 -0
  145. {comtypes-1.4.8 → comtypes-1.4.9}/setup.cfg +0 -0
  146. {comtypes-1.4.8 → comtypes-1.4.9}/setup.py +0 -0
@@ -1,8 +1,7 @@
1
1
  import array
2
2
  import datetime
3
3
  import unittest
4
- from ctypes import POINTER, PyDLL, byref, c_long, py_object
5
- from ctypes.wintypes import BOOL
4
+ from ctypes import POINTER, c_long
6
5
  from decimal import Decimal
7
6
 
8
7
  from comtypes import BSTR, IUnknown
@@ -19,7 +18,6 @@ from comtypes.automation import (
19
18
  _midlSAFEARRAY,
20
19
  )
21
20
  from comtypes.safearray import safearray_as_ndarray
22
- from comtypes.test import is_resource_enabled
23
21
  from comtypes.test.find_memleak import find_memleak
24
22
 
25
23
 
@@ -223,93 +221,6 @@ class SafeArrayTestCase(unittest.TestCase):
223
221
  del sa
224
222
  self.assertEqual((a, b), (com_refcnt(plib), com_refcnt(punk)))
225
223
 
226
- @unittest.skip(
227
- "This fails with a 'library not registered' error. Need to figure out how to "
228
- "register TestComServerLib (without admin if possible)."
229
- )
230
- def test_UDT(self):
231
- from comtypes.gen.TestComServerLib import MYCOLOR
232
-
233
- t = _midlSAFEARRAY(MYCOLOR)
234
- self.assertTrue(t is _midlSAFEARRAY(MYCOLOR))
235
-
236
- sa = t.from_param([MYCOLOR(0, 0, 0), MYCOLOR(1, 2, 3)])
237
-
238
- self.assertEqual(
239
- [(x.red, x.green, x.blue) for x in sa[0]],
240
- [(0.0, 0.0, 0.0), (1.0, 2.0, 3.0)],
241
- )
242
-
243
- def doit():
244
- t.from_param([MYCOLOR(0, 0, 0), MYCOLOR(1, 2, 3)])
245
-
246
- bytes = find_memleak(doit)
247
- self.assertFalse(bytes, "Leaks %d bytes" % bytes)
248
-
249
-
250
- if is_resource_enabled("pythoncom"):
251
- try:
252
- import pythoncom
253
- except ImportError:
254
- # pywin32 not installed...
255
- pass
256
- else:
257
- # pywin32 is available. The pythoncom dll contains two handy
258
- # exported functions that allow to create a VARIANT from a Python
259
- # object, also a function that unpacks a VARIANT into a Python
260
- # object.
261
- #
262
- # This allows us to create und unpack SAFEARRAY instances
263
- # contained in VARIANTs, and check for consistency with the
264
- # comtypes code.
265
-
266
- _dll = PyDLL(pythoncom.__file__)
267
-
268
- # c:/sf/pywin32/com/win32com/src/oleargs.cpp 213
269
- # PyObject *PyCom_PyObjectFromVariant(const VARIANT *var)
270
- unpack = _dll.PyCom_PyObjectFromVariant
271
- unpack.restype = py_object
272
- unpack.argtypes = (POINTER(VARIANT),)
273
-
274
- # c:/sf/pywin32/com/win32com/src/oleargs.cpp 54
275
- # BOOL PyCom_VariantFromPyObject(PyObject *obj, VARIANT *var)
276
- _pack = _dll.PyCom_VariantFromPyObject
277
- _pack.argtypes = py_object, POINTER(VARIANT)
278
- _pack.restype = BOOL
279
-
280
- def pack(obj):
281
- var = VARIANT()
282
- _pack(obj, byref(var))
283
- return var
284
-
285
- class PyWinTest(unittest.TestCase):
286
- def test_1dim(self):
287
- data = (1, 2, 3)
288
- variant = pack(data)
289
- self.assertEqual(variant.value, data)
290
- self.assertEqual(unpack(variant), data)
291
-
292
- def test_2dim(self):
293
- data = ((1, 2, 3), (4, 5, 6), (7, 8, 9))
294
- variant = pack(data)
295
- self.assertEqual(variant.value, data)
296
- self.assertEqual(unpack(variant), data)
297
-
298
- def test_3dim(self):
299
- data = (((1, 2), (3, 4), (5, 6)), ((7, 8), (9, 10), (11, 12)))
300
- variant = pack(data)
301
- self.assertEqual(variant.value, data)
302
- self.assertEqual(unpack(variant), data)
303
-
304
- def test_4dim(self):
305
- data = (
306
- (((1, 2), (3, 4)), ((5, 6), (7, 8))),
307
- (((9, 10), (11, 12)), ((13, 14), (15, 16))),
308
- )
309
- variant = pack(data)
310
- self.assertEqual(variant.value, data)
311
- self.assertEqual(unpack(variant), data)
312
-
313
224
 
314
225
  if __name__ == "__main__":
315
226
  unittest.main()
@@ -0,0 +1,350 @@
1
+ import os
2
+ import unittest
3
+
4
+ import comtypes.client
5
+ import comtypes.typeinfo
6
+
7
+ # Force module to raise.
8
+ raise unittest.SkipTest("This test module cannot run as-is. Investigate why")
9
+
10
+
11
+ class TypeLib(object):
12
+ """This class collects IDL code fragments and eventually writes
13
+ them into a .IDL file. The compile() method compiles the IDL file
14
+ into a typelibrary and registers it. A function is also
15
+ registered with atexit that will unregister the typelib at program
16
+ exit.
17
+ """
18
+
19
+ def __init__(self, lib):
20
+ self.lib = lib
21
+ self.interfaces = []
22
+ self.coclasses = []
23
+
24
+ def interface(self, header):
25
+ itf = Interface(header)
26
+ self.interfaces.append(itf)
27
+ return itf
28
+
29
+ def coclass(self, definition):
30
+ self.coclasses.append(definition)
31
+
32
+ def __str__(self):
33
+ header = (
34
+ """import "oaidl.idl";
35
+ import "ocidl.idl";
36
+ %s {"""
37
+ % self.lib
38
+ )
39
+ body = "\n".join([str(itf) for itf in self.interfaces])
40
+ footer = "\n".join(self.coclasses) + "}"
41
+ return "\n".join((header, body, footer))
42
+
43
+ def compile(self):
44
+ """Compile and register the typelib"""
45
+ code = str(self)
46
+ curdir = os.path.dirname(__file__)
47
+ idl_path = os.path.join(curdir, "mylib.idl")
48
+ tlb_path = os.path.join(curdir, "mylib.tlb")
49
+ if not os.path.isfile(idl_path) or open(idl_path, "r").read() != code:
50
+ open(idl_path, "w").write(code)
51
+ os.system(
52
+ r'call "%%VS71COMNTOOLS%%vsvars32.bat" && '
53
+ r"midl /nologo %s /tlb %s" % (idl_path, tlb_path)
54
+ )
55
+ # Register the typelib...
56
+ tlib = comtypes.typeinfo.LoadTypeLib(tlb_path)
57
+ # create the wrapper module...
58
+ comtypes.client.GetModule(tlb_path)
59
+ # Unregister the typelib at interpreter exit...
60
+ attr = tlib.GetLibAttr()
61
+ guid, major, minor = attr.guid, attr.wMajorVerNum, attr.wMinorVerNum
62
+ ## atexit.register(comtypes.typeinfo.UnRegisterTypeLib,
63
+ ## guid, major, minor)
64
+ return tlb_path
65
+
66
+
67
+ class Interface(object):
68
+ def __init__(self, header):
69
+ self.header = header
70
+ self.code = ""
71
+
72
+ def add(self, text):
73
+ self.code += text + "\n"
74
+ return self
75
+
76
+ def __str__(self):
77
+ return self.header + " {\n" + self.code + "}\n"
78
+
79
+
80
+ ################################################################
81
+ import comtypes
82
+ from comtypes.client import wrap
83
+
84
+ tlb = TypeLib("[uuid(f4f74946-4546-44bd-a073-9ea6f9fe78cb)] library TestLib")
85
+
86
+ itf = tlb.interface(
87
+ """[object,
88
+ oleautomation,
89
+ dual,
90
+ uuid(ed978f5f-cc45-4fcc-a7a6-751ffa8dfedd)]
91
+ interface IMyInterface : IDispatch"""
92
+ )
93
+
94
+ outgoing = tlb.interface(
95
+ """[object,
96
+ oleautomation,
97
+ dual,
98
+ uuid(f7c48a90-64ea-4bb8-abf1-b3a3aa996848)]
99
+ interface IMyEventInterface : IDispatch"""
100
+ )
101
+
102
+ tlb.coclass(
103
+ """
104
+ [uuid(fa9de8f4-20de-45fc-b079-648572428817)]
105
+ coclass MyServer {
106
+ [default] interface IMyInterface;
107
+ [default, source] interface IMyEventInterface;
108
+ };
109
+ """
110
+ )
111
+
112
+ # The purpose of the MyServer class is to locate three separate code
113
+ # section snippets closely together:
114
+ #
115
+ # 1. The IDL method definition for a COM interface method
116
+ # 2. The Python implementation of the COM method
117
+ # 3. The unittest(s) for the COM method.
118
+ #
119
+ from comtypes.server.connectionpoints import ConnectableObjectMixin
120
+
121
+
122
+ class MyServer(comtypes.CoClass, ConnectableObjectMixin):
123
+ _reg_typelib_ = ("{f4f74946-4546-44bd-a073-9ea6f9fe78cb}", 0, 0)
124
+ _reg_clsid_ = comtypes.GUID("{fa9de8f4-20de-45fc-b079-648572428817}")
125
+
126
+ ################
127
+ # definition
128
+ itf.add(
129
+ """[id(100), propget] HRESULT Name([out, retval] BSTR *pname);
130
+ [id(100), propput] HRESULT Name([in] BSTR name);"""
131
+ )
132
+ # implementation
133
+ Name = "foo"
134
+
135
+ # test
136
+ def test_Name(self):
137
+ p = wrap(self.create())
138
+ self.assertEqual((p.Name, p.name, p.nAME), ("foo",) * 3)
139
+ p.NAME = "spam"
140
+ self.assertEqual((p.Name, p.name, p.nAME), ("spam",) * 3)
141
+
142
+ ################
143
+ # definition
144
+ itf.add(
145
+ "[id(101)] HRESULT MixedInOut([in] int a, [out] int *b, [in] int c, [out] int *d);"
146
+ )
147
+
148
+ # implementation
149
+ def MixedInOut(self, a, c):
150
+ return a + 1, c + 1
151
+
152
+ # test
153
+ def test_MixedInOut(self):
154
+ p = wrap(self.create())
155
+ self.assertEqual(p.MixedInOut(1, 2), (2, 3))
156
+
157
+ ################
158
+ # definition
159
+ itf.add("[id(102)] HRESULT MultiInOutArgs([in, out] int *pa, [in, out] int *pb);")
160
+
161
+ # implementation
162
+ def MultiInOutArgs(self, pa, pb):
163
+ return pa[0] * 3, pb[0] * 4
164
+
165
+ # test
166
+ def test_MultiInOutArgs(self):
167
+ p = wrap(self.create())
168
+ self.assertEqual(p.MultiInOutArgs(1, 2), (3, 8))
169
+
170
+ ################
171
+ # definition
172
+ itf.add("HRESULT MultiInOutArgs2([in, out] int *pa, [out] int *pb);")
173
+ ## # implementation
174
+ ## def MultiInOutArgs2(self, pa):
175
+ ## return pa[0] * 3, pa[0] * 4
176
+ ## # test
177
+ ## def test_MultiInOutArgs2(self):
178
+ ## p = wrap(self.create())
179
+ ## self.assertEqual(p.MultiInOutArgs2(42), (126, 168))
180
+
181
+ ################
182
+ # definition
183
+ itf.add("HRESULT MultiInOutArgs3([out] int *pa, [out] int *pb);")
184
+
185
+ # implementation
186
+ def MultiInOutArgs3(self):
187
+ return 42, 43
188
+
189
+ # test
190
+ def test_MultiInOutArgs3(self):
191
+ p = wrap(self.create())
192
+ self.assertEqual(p.MultiInOutArgs3(), (42, 43))
193
+
194
+ ################
195
+ # definition
196
+ itf.add("HRESULT MultiInOutArgs4([out] int *pa, [in, out] int *pb);")
197
+
198
+ # implementation
199
+ def MultiInOutArgs4(self, pb):
200
+ return pb[0] + 3, pb[0] + 4
201
+
202
+ # test
203
+ def test_MultiInOutArgs4(self):
204
+ p = wrap(self.create())
205
+ res = p.MultiInOutArgs4(pb=32)
206
+
207
+ ## print "MultiInOutArgs4", res
208
+
209
+ itf.add(
210
+ """HRESULT GetStackTrace([in] ULONG FrameOffset,
211
+ [in, out] INT *Frames,
212
+ [in] ULONG FramesSize,
213
+ [out, optional] ULONG *FramesFilled);"""
214
+ )
215
+
216
+ def GetStackTrace(self, this, *args):
217
+ ## print "GetStackTrace", args
218
+ return 0
219
+
220
+ def test_GetStackTrace(self):
221
+ p = wrap(self.create())
222
+ from ctypes import POINTER, c_int, pointer
223
+
224
+ frames = (c_int * 5)()
225
+ res = p.GetStackTrace(42, frames, 5)
226
+ ## print "RES_1", res
227
+
228
+ frames = pointer(c_int(5))
229
+ res = p.GetStackTrace(42, frames, 0)
230
+
231
+ ## print "RES_2", res
232
+
233
+ # It is unlear to me if this is allowed or not. Apparently there
234
+ # are typelibs that define such an argument type, but it may be
235
+ # that these are buggy.
236
+ #
237
+ # Point is that SafeArrayCreateEx(VT_VARIANT|VT_BYREF, ..) fails.
238
+ # The MSDN docs for SafeArrayCreate() have a notice that neither
239
+ # VT_ARRAY not VT_BYREF may be set, this notice is missing however
240
+ # for SafeArrayCreateEx().
241
+ #
242
+ # We have this code here to make sure that comtypes can import
243
+ # such a typelib, although calling ths method will fail because
244
+ # such an array cannot be created.
245
+ itf.add("""HRESULT dummy([in] SAFEARRAY(VARIANT *) foo);""")
246
+
247
+ # Test events.
248
+ itf.add("""HRESULT DoSomething();""")
249
+ outgoing.add("""[id(103)] HRESULT OnSomething();""")
250
+
251
+ # implementation
252
+ def DoSomething(self):
253
+ "Implement the DoSomething method"
254
+ self.Fire_Event(0, "OnSomething")
255
+
256
+ # test
257
+ def test_events(self):
258
+ p = wrap(self.create())
259
+
260
+ class Handler(object):
261
+ called = 0
262
+
263
+ def OnSomething(self, this):
264
+ "Handles the OnSomething event"
265
+ self.called += 1
266
+
267
+ handler = Handler()
268
+ ev = comtypes.client.GetEvents(p, handler)
269
+ p.DoSomething()
270
+ self.assertEqual(handler.called, 1)
271
+
272
+ class Handler(object):
273
+ called = 0
274
+
275
+ def IMyEventInterface_OnSomething(self):
276
+ "Handles the OnSomething event"
277
+ self.called += 1
278
+
279
+ handler = Handler()
280
+ ev = comtypes.client.GetEvents(p, handler)
281
+ p.DoSomething()
282
+ self.assertEqual(handler.called, 1)
283
+
284
+ # events with out-parameters (these are probably very unlikely...)
285
+ itf.add("""HRESULT DoSomethingElse();""")
286
+ outgoing.add("""[id(104)] HRESULT OnSomethingElse([out, retval] int *px);""")
287
+
288
+ def DoSomethingElse(self):
289
+ "Implement the DoSomething method"
290
+ self.Fire_Event(0, "OnSomethingElse")
291
+
292
+ def test_DoSomethingElse(self):
293
+ p = wrap(self.create())
294
+
295
+ class Handler(object):
296
+ called = 0
297
+
298
+ def OnSomethingElse(self):
299
+ "Handles the OnSomething event"
300
+ self.called += 1
301
+ return 42
302
+
303
+ handler = Handler()
304
+ ev = comtypes.client.GetEvents(p, handler)
305
+ p.DoSomethingElse()
306
+ self.assertEqual(handler.called, 1)
307
+
308
+ class Handler(object):
309
+ called = 0
310
+
311
+ def OnSomethingElse(self, this, presult):
312
+ "Handles the OnSomething event"
313
+ self.called += 1
314
+ presult[0] = 42
315
+
316
+ handler = Handler()
317
+ ev = comtypes.client.GetEvents(p, handler)
318
+ p.DoSomethingElse()
319
+ self.assertEqual(handler.called, 1)
320
+
321
+
322
+ ################################################################
323
+
324
+ path = tlb.compile()
325
+ from comtypes.connectionpoints import IConnectionPointContainer
326
+ from comtypes.gen import TestLib
327
+ from comtypes.typeinfo import IProvideClassInfo, IProvideClassInfo2
328
+
329
+ MyServer._com_interfaces_ = [
330
+ TestLib.IMyInterface,
331
+ IProvideClassInfo2,
332
+ IConnectionPointContainer,
333
+ ]
334
+ MyServer._outgoing_interfaces_ = [TestLib.IMyEventInterface]
335
+
336
+ ################################################################
337
+
338
+
339
+ class Test(unittest.TestCase, MyServer):
340
+ def __init__(self, *args):
341
+ unittest.TestCase.__init__(self, *args)
342
+ MyServer.__init__(self)
343
+
344
+ def create(self):
345
+ obj = MyServer()
346
+ return obj.QueryInterface(comtypes.IUnknown)
347
+
348
+
349
+ if __name__ == "__main__":
350
+ unittest.main()