comtypes 1.4.5__zip → 1.4.7__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 (136) hide show
  1. {comtypes-1.4.5 → comtypes-1.4.7}/CHANGES.txt +30 -0
  2. {comtypes-1.4.5/comtypes.egg-info → comtypes-1.4.7}/PKG-INFO +28 -36
  3. {comtypes-1.4.5 → comtypes-1.4.7}/README.md +26 -34
  4. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/GUID.py +24 -24
  5. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/__init__.py +1 -1
  6. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/_memberspec.py +4 -12
  7. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/_post_coinit/bstr.py +13 -6
  8. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/automation.py +21 -54
  9. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/client/__init__.py +2 -9
  10. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/client/_code_cache.py +2 -2
  11. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/hints.pyi +8 -18
  12. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/persist.py +19 -3
  13. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/shelllink.py +72 -21
  14. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_client.py +9 -0
  15. comtypes-1.4.7/comtypes/test/test_monikers.py +70 -0
  16. comtypes-1.4.7/comtypes/test/test_persist.py +40 -0
  17. comtypes-1.4.7/comtypes/test/test_recordinfo.py +79 -0
  18. comtypes-1.4.7/comtypes/test/test_shelllink.py +133 -0
  19. comtypes-1.4.7/comtypes/test/test_storage.py +127 -0
  20. comtypes-1.4.7/comtypes/test/test_typeannotator.py +127 -0
  21. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/tools/codegenerator/codegenerator.py +0 -1
  22. comtypes-1.4.7/comtypes/tools/codegenerator/modulenamer.py +23 -0
  23. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/tools/codegenerator/typeannotator.py +27 -22
  24. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/tools/tlbparser.py +22 -24
  25. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/tools/typedesc_base.py +2 -8
  26. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/typeinfo.py +57 -56
  27. {comtypes-1.4.5 → comtypes-1.4.7/comtypes.egg-info}/PKG-INFO +28 -36
  28. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes.egg-info/SOURCES.txt +7 -1
  29. {comtypes-1.4.5 → comtypes-1.4.7}/setup.cfg +1 -1
  30. comtypes-1.4.5/comtypes/tools/codegenerator/modulenamer.py +0 -24
  31. {comtypes-1.4.5 → comtypes-1.4.7}/LICENSE.txt +0 -0
  32. {comtypes-1.4.5 → comtypes-1.4.7}/MANIFEST.in +0 -0
  33. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/_comobject.py +0 -0
  34. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/_idl_stuff.py +0 -0
  35. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/_meta.py +0 -0
  36. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/_npsupport.py +0 -0
  37. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/_post_coinit/__init__.py +0 -0
  38. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/_post_coinit/misc.py +0 -0
  39. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/_post_coinit/unknwn.py +0 -0
  40. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/_py_instance_method.py +0 -0
  41. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/_safearray.py +0 -0
  42. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/_tlib_version_checker.py +0 -0
  43. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/clear_cache.py +0 -0
  44. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/client/_constants.py +0 -0
  45. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/client/_events.py +0 -0
  46. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/client/_generate.py +0 -0
  47. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/client/dynamic.py +0 -0
  48. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/client/lazybind.py +0 -0
  49. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/connectionpoints.py +0 -0
  50. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/errorinfo.py +0 -0
  51. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/git.py +0 -0
  52. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/hresult.py +0 -0
  53. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/logutil.py +0 -0
  54. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/messageloop.py +0 -0
  55. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/patcher.py +0 -0
  56. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/safearray.py +0 -0
  57. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/server/__init__.py +0 -0
  58. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/server/automation.py +0 -0
  59. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/server/connectionpoints.py +0 -0
  60. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/server/inprocserver.py +0 -0
  61. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/server/localserver.py +0 -0
  62. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/server/register.py +0 -0
  63. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/server/w_getopt.py +0 -0
  64. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/stream.py +0 -0
  65. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/TestComServer.idl +0 -0
  66. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/TestComServer.py +0 -0
  67. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/TestComServer.tlb +0 -0
  68. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/TestDispServer.idl +0 -0
  69. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/TestDispServer.py +0 -0
  70. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/TestDispServer.tlb +0 -0
  71. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/__init__.py +0 -0
  72. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/find_memleak.py +0 -0
  73. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/mylib.idl +0 -0
  74. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/mylib.tlb +0 -0
  75. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/mytypelib.idl +0 -0
  76. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/runtests.py +0 -0
  77. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/setup.py +0 -0
  78. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_BSTR.py +0 -0
  79. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_DISPPARAMS.py +0 -0
  80. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_GUID.py +0 -0
  81. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_QueryService.py +0 -0
  82. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_agilent.py +0 -0
  83. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_avmc.py +0 -0
  84. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_basic.py +0 -0
  85. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_casesensitivity.py +0 -0
  86. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_clear_cache.py +0 -0
  87. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_client_dynamic.py +0 -0
  88. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_client_regenerate_modules.py +0 -0
  89. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_collections.py +0 -0
  90. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_comserver.py +0 -0
  91. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_createwrappers.py +0 -0
  92. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_dict.py +0 -0
  93. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_dispifc_records.py +0 -0
  94. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_dispifc_safearrays.py +0 -0
  95. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_dispinterface.py +0 -0
  96. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_dyndispatch.py +0 -0
  97. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_excel.py +0 -0
  98. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_findgendir.py +0 -0
  99. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_getactiveobj.py +0 -0
  100. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_ie.py +0 -0
  101. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_ienum.py +0 -0
  102. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_imfattributes.py +0 -0
  103. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_inout_args.py +0 -0
  104. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_jscript.js +0 -0
  105. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_midl_safearray_create.py +0 -0
  106. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_msscript.py +0 -0
  107. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_npsupport.py +0 -0
  108. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_outparam.py +0 -0
  109. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_propputref.py +0 -0
  110. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_pump_events.py +0 -0
  111. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_safearray.py +0 -0
  112. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_sapi.py +0 -0
  113. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_server.py +0 -0
  114. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_showevents.py +0 -0
  115. /comtypes-1.4.5/comtypes/test/test_istream.py → /comtypes-1.4.7/comtypes/test/test_stream.py +0 -0
  116. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_subinterface.py +0 -0
  117. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_typeinfo.py +0 -0
  118. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_urlhistory.py +0 -0
  119. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_variant.py +0 -0
  120. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_win32com_interop.py +0 -0
  121. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_wmi.py +0 -0
  122. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/test_word.py +0 -0
  123. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/test/urlhist.tlb +0 -0
  124. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/tools/__init__.py +0 -0
  125. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/tools/codegenerator/__init__.py +0 -0
  126. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/tools/codegenerator/helpers.py +0 -0
  127. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/tools/codegenerator/namespaces.py +0 -0
  128. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/tools/codegenerator/packing.py +0 -0
  129. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/tools/typedesc.py +0 -0
  130. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/util.py +0 -0
  131. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes/viewobject.py +0 -0
  132. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes.egg-info/dependency_links.txt +0 -0
  133. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes.egg-info/entry_points.txt +0 -0
  134. {comtypes-1.4.5 → comtypes-1.4.7}/comtypes.egg-info/top_level.txt +0 -0
  135. {comtypes-1.4.5 → comtypes-1.4.7}/pyproject.toml +0 -0
  136. {comtypes-1.4.5 → comtypes-1.4.7}/setup.py +0 -0
@@ -0,0 +1,127 @@
1
+ from _ctypes import COMError
2
+ from ctypes import byref, c_ubyte, POINTER
3
+ import contextlib
4
+ from pathlib import Path
5
+ import unittest
6
+
7
+ import comtypes
8
+ import comtypes.client
9
+
10
+
11
+ with contextlib.redirect_stdout(None): # supress warnings
12
+ mod = comtypes.client.GetModule("msvidctl.dll")
13
+
14
+ from comtypes.gen.MSVidCtlLib import IStorage
15
+
16
+
17
+ STATFLAG_DEFAULT = 0
18
+ STGC_DEFAULT = 0
19
+ STGM_CREATE = 0x00001000
20
+ STGM_DIRECT = 0x00000000
21
+ STGM_DELETEONRELEASE = 0x04000000
22
+ STGM_READ = 0x00000000
23
+ STGM_READWRITE = 0x00000002
24
+ STGM_SHARE_EXCLUSIVE = 0x00000010
25
+ STGM_TRANSACTED = 0x00010000
26
+ STGMOVE_MOVE = 0
27
+ STREAM_SEEK_SET = 0
28
+
29
+ STG_E_PATHNOTFOUND = -2147287038
30
+
31
+
32
+ class Test_IStorage(unittest.TestCase):
33
+ CREATE_DOC_FLAG = (
34
+ STGM_DIRECT
35
+ | STGM_READWRITE
36
+ | STGM_CREATE
37
+ | STGM_SHARE_EXCLUSIVE
38
+ | STGM_DELETEONRELEASE
39
+ )
40
+ CREATE_STM_FLAG = STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE
41
+ OPEN_STM_FLAG = STGM_READ | STGM_SHARE_EXCLUSIVE
42
+ CREATE_STG_FLAG = STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE
43
+ OPEN_STG_FLAG = STGM_TRANSACTED | STGM_READWRITE | STGM_SHARE_EXCLUSIVE
44
+
45
+ def _create_docfile(self) -> IStorage:
46
+ stg = POINTER(IStorage)()
47
+ comtypes._ole32.StgCreateDocfile(None, self.CREATE_DOC_FLAG, 0, byref(stg))
48
+ return stg # type: ignore
49
+
50
+ def test_CreateStream(self):
51
+ storage = self._create_docfile()
52
+ filepath = Path(storage.Stat(STATFLAG_DEFAULT).pwcsName)
53
+ self.assertTrue(filepath.exists())
54
+ stream = storage.CreateStream("example", self.CREATE_STM_FLAG, 0, 0)
55
+ test_data = "Some data".encode("utf-8")
56
+ pv = (c_ubyte * len(test_data)).from_buffer(bytearray(test_data))
57
+ stream.RemoteWrite(pv, len(test_data))
58
+ stream.Commit(STGC_DEFAULT)
59
+ stream.RemoteSeek(0, STREAM_SEEK_SET)
60
+ read_buffer, data_read = stream.RemoteRead(1024)
61
+ self.assertEqual(bytearray(read_buffer)[0:data_read], test_data)
62
+ storage.Commit(STGC_DEFAULT)
63
+ self.assertTrue(filepath.exists())
64
+ del storage
65
+ self.assertFalse(filepath.exists())
66
+
67
+ def test_CreateStorage(self):
68
+ parent = self._create_docfile()
69
+ child = parent.CreateStorage("child", self.CREATE_STG_FLAG, 0, 0)
70
+ self.assertEqual("child", child.Stat(STATFLAG_DEFAULT).pwcsName)
71
+
72
+ def test_OpenStorage(self):
73
+ parent = self._create_docfile()
74
+ created_child = parent.CreateStorage("child", self.CREATE_STG_FLAG, 0, 0)
75
+ del created_child
76
+ opened_child = parent.OpenStorage("child", None, self.OPEN_STG_FLAG, None, 0)
77
+ self.assertEqual("child", opened_child.Stat(STATFLAG_DEFAULT).pwcsName)
78
+
79
+ def test_RemoteCopyTo(self):
80
+ src_stg = self._create_docfile()
81
+ src_stg.CreateStorage("child", self.CREATE_STG_FLAG, 0, 0)
82
+ dst_stg = self._create_docfile()
83
+ src_stg.RemoteCopyTo(0, None, None, dst_stg)
84
+ src_stg.Commit(STGC_DEFAULT)
85
+ del src_stg
86
+ opened_stg = dst_stg.OpenStorage("child", None, self.OPEN_STG_FLAG, None, 0)
87
+ self.assertEqual("child", opened_stg.Stat(STATFLAG_DEFAULT).pwcsName)
88
+
89
+ def test_MoveElementTo(self):
90
+ src_stg = self._create_docfile()
91
+ src_stg.CreateStorage("foo", self.CREATE_STG_FLAG, 0, 0)
92
+ dst_stg = self._create_docfile()
93
+ src_stg.MoveElementTo("foo", dst_stg, "bar", STGMOVE_MOVE)
94
+ opened_stg = dst_stg.OpenStorage("bar", None, self.OPEN_STG_FLAG, None, 0)
95
+ self.assertEqual("bar", opened_stg.Stat(STATFLAG_DEFAULT).pwcsName)
96
+ with self.assertRaises(COMError) as ctx:
97
+ src_stg.OpenStorage("foo", None, self.OPEN_STG_FLAG, None, 0)
98
+ self.assertEqual(ctx.exception.hresult, STG_E_PATHNOTFOUND)
99
+
100
+ def test_Revert(self):
101
+ storage = self._create_docfile()
102
+ foo = storage.CreateStorage("foo", self.CREATE_STG_FLAG, 0, 0)
103
+ foo.CreateStorage("bar", self.CREATE_STG_FLAG, 0, 0)
104
+ bar = foo.OpenStorage("bar", None, self.OPEN_STG_FLAG, None, 0)
105
+ self.assertEqual("bar", bar.Stat(STATFLAG_DEFAULT).pwcsName)
106
+ foo.Revert()
107
+ with self.assertRaises(COMError) as ctx:
108
+ foo.OpenStorage("bar", None, self.OPEN_STG_FLAG, None, 0)
109
+ self.assertEqual(ctx.exception.hresult, STG_E_PATHNOTFOUND)
110
+
111
+ def test_DestroyElement(self):
112
+ storage = self._create_docfile()
113
+ storage.CreateStorage("example", self.CREATE_STG_FLAG, 0, 0)
114
+ storage.DestroyElement("example")
115
+ with self.assertRaises(COMError) as ctx:
116
+ storage.OpenStorage("example", None, self.OPEN_STG_FLAG, None, 0)
117
+ self.assertEqual(ctx.exception.hresult, STG_E_PATHNOTFOUND)
118
+
119
+ def test_RenameElement(self):
120
+ storage = self._create_docfile()
121
+ storage.CreateStorage("example", self.CREATE_STG_FLAG, 0, 0)
122
+ storage.RenameElement("example", "sample")
123
+ sample = storage.OpenStorage("sample", None, self.OPEN_STG_FLAG, None, 0)
124
+ self.assertEqual("sample", sample.Stat(STATFLAG_DEFAULT).pwcsName)
125
+ with self.assertRaises(COMError) as ctx:
126
+ storage.OpenStorage("example", None, self.OPEN_STG_FLAG, None, 0)
127
+ self.assertEqual(ctx.exception.hresult, STG_E_PATHNOTFOUND)
@@ -0,0 +1,127 @@
1
+ import unittest
2
+
3
+ from comtypes.tools import typedesc
4
+ from comtypes.tools.codegenerator import typeannotator
5
+ from comtypes.tools.tlbparser import (
6
+ BSTR_type,
7
+ HRESULT_type,
8
+ VARIANT_type,
9
+ VARIANT_BOOL_type,
10
+ )
11
+
12
+
13
+ iunknown_type = typedesc.ComInterface(
14
+ "IUnknown", None, "{00000000-0000-0000-C000-000000000046}", ["hidden"], None
15
+ )
16
+ idispatch_type = typedesc.ComInterface(
17
+ "IDispatch",
18
+ iunknown_type,
19
+ "{00020400-0000-0000-C000-000000000046}",
20
+ ["restricted"],
21
+ None,
22
+ )
23
+ void_type = typedesc.FundamentalType("void", 0, 0)
24
+
25
+
26
+ class Test_AvoidUsingKeywords(unittest.TestCase):
27
+ def _create_typedesc_disp_interface(self) -> typedesc.DispInterface:
28
+ guid = "{00000000-0000-0000-0000-000000000000}"
29
+ itf = typedesc.DispInterface("IDispDerived", idispatch_type, guid, [], None)
30
+ ham = typedesc.DispProperty(0, "ham", BSTR_type, ["readonly"], None)
31
+ bacon = typedesc.DispMethod(
32
+ 472, 1, "bacon", VARIANT_BOOL_type, ["hidden"], None
33
+ )
34
+ bacon.add_argument(VARIANT_type, "and", ["in"], None)
35
+ bacon.add_argument(VARIANT_type, "foo", ["in"], None)
36
+ get_spam = typedesc.DispMethod(6, 2, "spam", VARIANT_type, ["propget"], None)
37
+ get_spam.add_argument(VARIANT_type, "arg1", ["in", "optional"], None)
38
+ put_spam = typedesc.DispMethod(6, 4, "spam", void_type, ["propput"], None)
39
+ put_spam.add_argument(VARIANT_type, "arg1", ["in", "optional"], None)
40
+ put_spam.add_argument(VARIANT_type, "arg2", ["in"], None)
41
+ except_ = typedesc.DispProperty(1, "except", BSTR_type, ["readonly"], None)
42
+ raise_ = typedesc.DispMethod(
43
+ 474, 1, "raise", VARIANT_BOOL_type, ["hidden"], None
44
+ )
45
+ raise_.add_argument(VARIANT_type, "foo", ["in"], None)
46
+ raise_.add_argument(VARIANT_type, "bar", ["in", "optional"], None)
47
+ get_def = typedesc.DispMethod(8, 2, "def", VARIANT_type, ["propget"], None)
48
+ get_def.add_argument(VARIANT_type, "arg1", ["in", "optional"], None)
49
+ put_def = typedesc.DispMethod(8, 4, "def", void_type, ["propput"], None)
50
+ put_def.add_argument(VARIANT_type, "arg1", ["in", "optional"], None)
51
+ put_def.add_argument(VARIANT_type, "arg2", ["in"], None)
52
+ for m in [ham, bacon, get_spam, put_spam, except_, raise_, get_def, put_def]:
53
+ itf.add_member(m)
54
+ return itf
55
+
56
+ def test_disp_interface(self):
57
+ itf = self._create_typedesc_disp_interface()
58
+ expected = (
59
+ " @property # dispprop\n"
60
+ " def ham(self) -> hints.Incomplete: ...\n"
61
+ " pass # @property # dispprop\n"
62
+ " pass # avoid using a keyword for def except(self) -> hints.Incomplete: ...\n" # noqa
63
+ " def bacon(self, *args: hints.Any, **kwargs: hints.Any) -> hints.Incomplete: ...\n" # noqa
64
+ " def _get_spam(self, arg1: hints.Incomplete = ...) -> hints.Incomplete: ...\n" # noqa
65
+ " def _set_spam(self, arg1: hints.Incomplete = ..., **kwargs: hints.Any) -> hints.Incomplete: ...\n" # noqa
66
+ " spam = hints.named_property('spam', _get_spam, _set_spam)\n"
67
+ " pass # avoid using a keyword for def raise(self, foo: hints.Incomplete, bar: hints.Incomplete = ...) -> hints.Incomplete: ...\n" # noqa
68
+ " def _get_def(self, arg1: hints.Incomplete = ...) -> hints.Incomplete: ...\n" # noqa
69
+ " def _set_def(self, arg1: hints.Incomplete = ..., **kwargs: hints.Any) -> hints.Incomplete: ...\n" # noqa
70
+ " pass # avoid using a keyword for def = hints.named_property('def', _get_def, _set_def)" # noqa
71
+ )
72
+ self.assertEqual(
73
+ expected, typeannotator.DispInterfaceMembersAnnotator(itf).generate()
74
+ )
75
+
76
+ def _create_typedesc_com_interface(self) -> typedesc.ComInterface:
77
+ guid = "{00000000-0000-0000-0000-000000000000}"
78
+ itf = typedesc.ComInterface(
79
+ "IUnkDerived", iunknown_type, guid, ["hidden"], None
80
+ )
81
+ spam = typedesc.ComMethod(
82
+ 2, 1610678269, "spam", HRESULT_type, ["propget"], None
83
+ )
84
+ get_ham = typedesc.ComMethod(
85
+ 2, 1610678270, "ham", HRESULT_type, ["propget"], None
86
+ )
87
+ put_ham = typedesc.ComMethod(
88
+ 4, 1610678270, "ham", HRESULT_type, ["propput"], None
89
+ )
90
+ bacon = typedesc.ComMethod(1, 1610678271, "bacon", HRESULT_type, [], None)
91
+ bacon.add_argument(VARIANT_type, "foo", ["in"], None)
92
+ bacon.add_argument(VARIANT_type, "or", ["in"], None)
93
+ global_ = typedesc.ComMethod(
94
+ 2, 1610678272, "global", HRESULT_type, ["propget"], None
95
+ )
96
+ get_class = typedesc.ComMethod(
97
+ 2, 1610678273, "class", HRESULT_type, ["propget"], None
98
+ )
99
+ put_class = typedesc.ComMethod(
100
+ 4, 1610678273, "class", HRESULT_type, ["propput"], None
101
+ )
102
+ pass_ = typedesc.ComMethod(1, 1610678274, "pass", HRESULT_type, [], None)
103
+ pass_.add_argument(VARIANT_type, "foo", ["in"], None)
104
+ pass_.add_argument(VARIANT_type, "bar", ["in", "optional"], None)
105
+ members = [spam, get_ham, put_ham, bacon, global_, get_class, put_class, pass_]
106
+ itf.extend_members(members)
107
+ return itf
108
+
109
+ def test_com_interface(self):
110
+ itf = self._create_typedesc_com_interface()
111
+ expected = (
112
+ " def _get_spam(self) -> hints.Hresult: ...\n"
113
+ " spam = hints.normal_property(_get_spam)\n"
114
+ " def _get_ham(self) -> hints.Hresult: ...\n"
115
+ " def _set_ham(self) -> hints.Hresult: ...\n"
116
+ " ham = hints.normal_property(_get_ham, _set_ham)\n"
117
+ " def bacon(self, *args: hints.Any, **kwargs: hints.Any) -> hints.Hresult: ...\n" # noqa
118
+ " def _get_global(self) -> hints.Hresult: ...\n"
119
+ " pass # avoid using a keyword for global = hints.normal_property(_get_global)\n" # noqa
120
+ " def _get_class(self) -> hints.Hresult: ...\n"
121
+ " def _set_class(self) -> hints.Hresult: ...\n"
122
+ " pass # avoid using a keyword for class = hints.normal_property(_get_class, _set_class)\n" # noqa
123
+ " pass # avoid using a keyword for def pass(self, foo: hints.Incomplete, bar: hints.Incomplete = ...) -> hints.Hresult: ..." # noqa
124
+ )
125
+ self.assertEqual(
126
+ expected, typeannotator.ComInterfaceMembersAnnotator(itf).generate()
127
+ )
@@ -196,7 +196,6 @@ class CodeGenerator(object):
196
196
  print("from typing import TYPE_CHECKING", file=output)
197
197
  print(file=output)
198
198
  print("if TYPE_CHECKING:", file=output)
199
- print(" from typing import Any, Tuple", file=output)
200
199
  print(" from comtypes import hints", file=output)
201
200
  print(file=output)
202
201
  print(file=output)
@@ -0,0 +1,23 @@
1
+ from typing import Optional
2
+
3
+ import comtypes
4
+ from comtypes import typeinfo
5
+
6
+
7
+ def name_wrapper_module(tlib: typeinfo.ITypeLib) -> str:
8
+ """Determine the name of a typelib wrapper module"""
9
+ libattr = tlib.GetLibAttr()
10
+ guid = str(libattr.guid)[1:-1].replace("-", "_")
11
+ modname = f"_{guid}_{libattr.lcid}_{libattr.wMajorVerNum}_{libattr.wMinorVerNum}"
12
+ return f"comtypes.gen.{modname}"
13
+
14
+
15
+ def name_friendly_module(tlib: typeinfo.ITypeLib) -> Optional[str]:
16
+ """Determine the friendly-name of a typelib module.
17
+ If cannot get friendly-name from typelib, returns `None`.
18
+ """
19
+ try:
20
+ modulename = tlib.GetDocumentation(-1)[0]
21
+ except comtypes.COMError:
22
+ return
23
+ return f"comtypes.gen.{modulename}"
@@ -1,18 +1,8 @@
1
1
  import abc
2
2
  import keyword
3
- from typing import (
4
- Any,
5
- Dict,
6
- Generic,
7
- Iterable,
8
- Iterator,
9
- List,
10
- Optional,
11
- Sequence,
12
- Tuple,
13
- TYPE_CHECKING,
14
- TypeVar,
15
- )
3
+ from typing import Any, Generic, TypeVar, TYPE_CHECKING
4
+ from typing import Dict, List, Optional, Sequence, Tuple
5
+ from typing import Iterable, Iterator
16
6
 
17
7
  from comtypes.tools import typedesc
18
8
 
@@ -124,6 +114,8 @@ class _MethodsAnnotator(abc.ABC, Generic[_T_MTD]):
124
114
  content = f"{mem_name} = hints.named_property('{mem_name}', fset={setter})"
125
115
  else:
126
116
  return
117
+ if keyword.iskeyword(mem_name):
118
+ content = f"pass # avoid using a keyword for {content}"
127
119
  self._define_member(content)
128
120
 
129
121
  def _define_normal_prop(
@@ -137,6 +129,8 @@ class _MethodsAnnotator(abc.ABC, Generic[_T_MTD]):
137
129
  content = f"{mem_name} = hints.normal_property(fset={setter})"
138
130
  else:
139
131
  return
132
+ if keyword.iskeyword(mem_name):
133
+ content = f"pass # avoid using a keyword for {content}"
140
134
  self._define_member(content)
141
135
 
142
136
  def _define_member(self, content: str) -> None:
@@ -242,14 +236,14 @@ class ComMethodAnnotator(_MethodAnnotator[typedesc.ComMethod]):
242
236
  has_optional = False
243
237
  for _, argname, default in self.inarg_specs:
244
238
  if keyword.iskeyword(argname):
245
- inargs = ["*args: Any", "**kwargs: Any"]
239
+ inargs = ["*args: hints.Any", "**kwargs: hints.Any"]
246
240
  break
247
241
  if default is None:
248
242
  if has_optional:
249
243
  # probably propput or propputref
250
244
  # HACK: Something that goes into this conditional branch
251
245
  # should be a special callback.
252
- inargs.append("**kwargs: Any")
246
+ inargs.append("**kwargs: hints.Any")
253
247
  break
254
248
  inargs.append(f"{argname}: hints.Incomplete")
255
249
  else:
@@ -261,9 +255,12 @@ class ComMethodAnnotator(_MethodAnnotator[typedesc.ComMethod]):
261
255
  elif len(outargs) == 1:
262
256
  out = outargs[0]
263
257
  else:
264
- out = "Tuple[" + ", ".join(outargs) + "]"
258
+ out = "hints.Tuple[" + ", ".join(outargs) + "]"
265
259
  in_ = ("self, " + ", ".join(inargs)) if inargs else "self"
266
- return f"def {name}({in_}) -> {out}: ..."
260
+ content = f"def {name}({in_}) -> {out}: ..."
261
+ if keyword.iskeyword(name):
262
+ content = f"pass # avoid using a keyword for {content}"
263
+ return content
267
264
 
268
265
 
269
266
  class ComMethodsAnnotator(_MethodsAnnotator[typedesc.ComMethod]):
@@ -285,14 +282,14 @@ class DispMethodAnnotator(_MethodAnnotator[typedesc.DispMethod]):
285
282
  has_optional = False
286
283
  for _, argname, default in self.inarg_specs:
287
284
  if keyword.iskeyword(argname):
288
- inargs = ["*args: Any", "**kwargs: Any"]
285
+ inargs = ["*args: hints.Any", "**kwargs: hints.Any"]
289
286
  break
290
287
  if default is None:
291
288
  if has_optional:
292
289
  # probably propput or propputref
293
290
  # HACK: Something that goes into this conditional branch
294
291
  # should be a special callback.
295
- inargs.append("**kwargs: Any")
292
+ inargs.append("**kwargs: hints.Any")
296
293
  break
297
294
  inargs.append(f"{argname}: hints.Incomplete")
298
295
  else:
@@ -300,7 +297,10 @@ class DispMethodAnnotator(_MethodAnnotator[typedesc.DispMethod]):
300
297
  has_optional = True
301
298
  out = _to_outtype(self.method.returns)
302
299
  in_ = ("self, " + ", ".join(inargs)) if inargs else "self"
303
- return f"def {name}({in_}) -> {out}: ..."
300
+ content = f"def {name}({in_}) -> {out}: ..."
301
+ if keyword.iskeyword(name):
302
+ content = f"pass # avoid using a keyword for {content}"
303
+ return content
304
304
 
305
305
 
306
306
  class DispMethodsAnnotator(_MethodsAnnotator[typedesc.DispMethod]):
@@ -328,9 +328,14 @@ class DispInterfaceMembersAnnotator(object):
328
328
  props, methods = self._categorize_members()
329
329
  property_lines: List[str] = []
330
330
  for mem in props:
331
- property_lines.append("@property # dispprop")
332
331
  out = _to_outtype(mem.typ)
333
- property_lines.append(f"def {mem.name}(self) -> {out}: ...")
332
+ decorator = "@property # dispprop"
333
+ content = f"def {mem.name}(self) -> {out}: ..."
334
+ if keyword.iskeyword(mem.name):
335
+ decorator = f"pass # {decorator}"
336
+ content = f"pass # avoid using a keyword for {content}"
337
+ property_lines.append(decorator)
338
+ property_lines.append(content)
334
339
  dispprops = "\n".join(f" {p}" for p in property_lines)
335
340
  dispmethods = DispMethodsAnnotator().generate(methods)
336
341
  return "\n".join(d for d in (dispprops, dispmethods) if d)
@@ -298,27 +298,25 @@ class Parser(object):
298
298
  names = tinfo.GetNames(fd.memid, fd.cParams + 1)
299
299
  names.append("rhs")
300
300
  names = names[: fd.cParams + 1]
301
+ # function name first, then parameter names
301
302
  assert len(names) == fd.cParams + 1
302
303
  flags = self.func_flags(fd.wFuncFlags)
303
304
  flags += self.inv_kind(fd.invkind)
304
305
  mth = typedesc.ComMethod(
305
306
  fd.invkind, fd.memid, func_name, returns, flags, func_doc
306
307
  )
307
- for p in range(fd.cParams):
308
- typ = self.make_type(fd.lprgelemdescParam[p].tdesc, tinfo)
309
- name = names[p + 1]
310
- flags = fd.lprgelemdescParam[p]._.paramdesc.wParamFlags
311
- if flags & typeinfo.PARAMFLAG_FHASDEFAULT:
308
+ for j in range(fd.cParams):
309
+ elemdesc = fd.lprgelemdescParam[j]
310
+ typ = self.make_type(elemdesc.tdesc, tinfo)
311
+ name = names[j + 1]
312
+ paramdesc = elemdesc._.paramdesc
313
+ if paramdesc.wParamFlags & typeinfo.PARAMFLAG_FHASDEFAULT:
312
314
  # XXX should be handled by VARIANT itself
313
- var = (
314
- fd.lprgelemdescParam[p]
315
- ._.paramdesc.pparamdescex[0]
316
- .varDefaultValue
317
- )
318
- default: Any = var.value
315
+ default: Any = paramdesc.pparamdescex[0].varDefaultValue.value
319
316
  else:
320
317
  default = None
321
- mth.add_argument(typ, name, self.param_flags(flags), default)
318
+ param_flags = self.param_flags(paramdesc.wParamFlags)
319
+ mth.add_argument(typ, name, param_flags, default)
322
320
  members.append((fd.oVft, mth))
323
321
  # Sort the methods by oVft (VTable offset): Some typeinfo
324
322
  # don't list methods in VTable order.
@@ -386,25 +384,25 @@ class Parser(object):
386
384
  names = tinfo.GetNames(fd.memid, fd.cParams + 1)
387
385
  names.append("rhs")
388
386
  names = names[: fd.cParams + 1]
389
- assert (
390
- len(names) == fd.cParams + 1
391
- ) # function name first, then parameter names
387
+ # function name first, then parameter names
388
+ assert len(names) == fd.cParams + 1
392
389
  flags = self.func_flags(fd.wFuncFlags)
393
390
  flags += self.inv_kind(fd.invkind)
394
391
  mth = typedesc.DispMethod(
395
392
  fd.memid, fd.invkind, func_name, returns, flags, func_doc
396
393
  )
397
- for p in range(fd.cParams):
398
- descparam = fd.lprgelemdescParam[p]
399
- typ = self.make_type(descparam.tdesc, tinfo)
400
- name = names[p + 1]
401
- flags = descparam._.paramdesc.wParamFlags
402
- if flags & typeinfo.PARAMFLAG_FHASDEFAULT:
403
- var = descparam._.paramdesc.pparamdescex[0].varDefaultValue # type: ignore
404
- default: Any = var.value
394
+ for j in range(fd.cParams):
395
+ elemdesc = fd.lprgelemdescParam[j]
396
+ typ = self.make_type(elemdesc.tdesc, tinfo)
397
+ name = names[j + 1]
398
+ paramdesc = elemdesc._.paramdesc
399
+ if paramdesc.wParamFlags & typeinfo.PARAMFLAG_FHASDEFAULT:
400
+ # XXX should be handled by VARIANT itself
401
+ default: Any = paramdesc.pparamdescex[0].varDefaultValue.value
405
402
  else:
406
403
  default = None
407
- mth.add_argument(typ, name, self.param_flags(flags), default)
404
+ param_flags = self.param_flags(paramdesc.wParamFlags)
405
+ mth.add_argument(typ, name, param_flags, default)
408
406
  itf.add_member(mth)
409
407
  return itf
410
408
 
@@ -1,12 +1,6 @@
1
1
  # typedesc.py - classes representing C type descriptions
2
- from typing import (
3
- Any,
4
- List,
5
- Optional,
6
- Tuple,
7
- Union as _UnionT,
8
- SupportsInt,
9
- )
2
+ from typing import Any, SupportsInt
3
+ from typing import List, Optional, Tuple, Union as _UnionT
10
4
 
11
5
  import comtypes
12
6