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
@@ -3,27 +3,17 @@
3
3
  # - utilities for type hints.
4
4
  import ctypes
5
5
  import sys
6
- from typing import (
7
- Any,
8
- Callable,
9
- ClassVar,
10
- Generic,
11
- Iterator,
12
- List,
13
- NoReturn,
14
- Sequence,
15
- Tuple,
16
- Type,
17
- TypeVar,
18
- Optional,
19
- overload,
20
- Union as _UnionT,
21
- )
6
+ from typing import Any as Any, ClassVar, Generic, NoReturn, TypeVar, overload
7
+ from typing import Optional, Union as _UnionT
8
+ from typing import List, Tuple as Tuple, Type
9
+ from typing import Callable, Iterator, Sequence
22
10
 
23
11
  if sys.version_info >= (3, 8):
24
12
  from typing import Protocol
13
+ from typing import Literal as Literal
25
14
  else:
26
15
  from typing_extensions import Protocol
16
+ from typing_extensions import Literal as Literal
27
17
  if sys.version_info >= (3, 9):
28
18
  from typing import Annotated as Annotated
29
19
  else:
@@ -35,9 +25,9 @@ else:
35
25
  from typing_extensions import Concatenate, ParamSpec, TypeAlias
36
26
  from typing_extensions import TypeGuard as TypeGuard
37
27
  if sys.version_info >= (3, 11):
38
- from typing import Self
28
+ from typing import Self as Self
39
29
  else:
40
- from typing_extensions import Self
30
+ from typing_extensions import Self as Self
41
31
 
42
32
  import comtypes
43
33
  from comtypes import IUnknown as IUnknown, GUID as GUID
@@ -9,12 +9,19 @@
9
9
  The 'DictPropertyBag' class is a class implementing the IPropertyBag
10
10
  interface, useful in client code.
11
11
  """
12
- from ctypes import *
12
+ from ctypes import c_int, c_ulong, c_ushort, c_wchar_p
13
+ from ctypes import POINTER, Structure
13
14
  from ctypes.wintypes import WORD, DWORD, BOOL
14
- from comtypes import GUID, IUnknown, COMMETHOD, HRESULT, dispid
15
+ from typing import TYPE_CHECKING
16
+
17
+ from comtypes import GUID, IUnknown, COMMETHOD, HRESULT
15
18
  from comtypes import IPersist
16
19
  from comtypes.automation import VARIANT, tagEXCEPINFO
17
20
 
21
+ if TYPE_CHECKING:
22
+ from comtypes import hints # type: ignore
23
+
24
+
18
25
  # XXX Replace by canonical solution!!!
19
26
  WSTRING = c_wchar_p
20
27
 
@@ -236,9 +243,18 @@ class IPersistFile(IPersist):
236
243
  ),
237
244
  ]
238
245
 
246
+ if TYPE_CHECKING:
247
+ # fmt: off
248
+ def IsDirty(self) -> hints.Hresult: ... # noqa
249
+ def Load(self, pszFileName: str, dwMode: int) -> hints.Hresult: ... # noqa
250
+ def Save(self, pszFileName: str, fRemember: bool) -> hints.Hresult: ... # noqa
251
+ def SaveCompleted(self, pszFileName: str) -> hints.Hresult: ... # noqa
252
+ def GetCurFile(self) -> str: ... # noqa
253
+ # fmt: on
254
+
239
255
 
240
256
  from comtypes import COMObject
241
- from comtypes.hresult import *
257
+ from comtypes.hresult import E_INVALIDARG, S_OK
242
258
 
243
259
 
244
260
  class DictPropertyBag(COMObject):
@@ -1,8 +1,17 @@
1
1
  from __future__ import print_function
2
- from ctypes import *
2
+ from ctypes import c_char_p, c_int, c_short, c_wchar_p
3
+ from ctypes import POINTER
4
+ from ctypes import byref, create_string_buffer, create_unicode_buffer
3
5
  from ctypes.wintypes import DWORD, WIN32_FIND_DATAA, WIN32_FIND_DATAW, MAX_PATH
6
+ from typing import Tuple, TYPE_CHECKING
7
+
4
8
  from comtypes import IUnknown, GUID, COMMETHOD, HRESULT, CoClass
5
9
 
10
+
11
+ if TYPE_CHECKING:
12
+ from comtypes import hints # type: ignore
13
+
14
+
6
15
  # for GetPath
7
16
  SLGP_SHORTPATH = 0x1
8
17
  SLGP_UNCPRIORITY = 0x2
@@ -113,31 +122,52 @@ class IShellLinkA(IUnknown):
113
122
  COMMETHOD([], HRESULT, "SetPath", (["in"], c_char_p, "pszFile")),
114
123
  ]
115
124
 
116
- def GetPath(self, flags=SLGP_SHORTPATH):
125
+ if TYPE_CHECKING:
126
+ # fmt: off
127
+ def GetIDList(self) -> hints.Incomplete: ... # noqa
128
+ def SetIDList(self, pidl: hints.Incomplete) -> hints.Incomplete: ... # noqa
129
+ def SetDescription(self, pszName: bytes) -> hints.Incomplete: ... # noqa
130
+ def SetWorkingDirectory(self, pszDir: bytes) -> hints.Hresult: ... # noqa
131
+ def SetArguments(self, pszArgs: bytes) -> hints.Hresult: ... # noqa
132
+ @property
133
+ def Hotkey(self) -> int: ... # noqa
134
+ @Hotkey.setter
135
+ def Hotkey(self, pwHotkey: int) -> None: ... # noqa
136
+ @property
137
+ def ShowCmd(self) -> int: ... # noqa
138
+ @ShowCmd.setter
139
+ def ShowCmd(self, piShowCmd: int) -> None: ... # noqa
140
+ def SetIconLocation(self, pszIconPath: bytes, iIcon: int) -> hints.Hresult: ... # noqa
141
+ def SetRelativePath(self, pszPathRel: bytes, dwReserved: hints.Literal[0]) -> hints.Hresult: ... # noqa
142
+ def Resolve(self, hwnd: int, fFlags: int) -> hints.Hresult: ... # noqa
143
+ def SetPath(self, pszFile: bytes) -> hints.Hresult: ... # noqa
144
+ # fmt: on
145
+
146
+ def GetPath(self, flags: int = SLGP_SHORTPATH) -> bytes:
117
147
  buf = create_string_buffer(MAX_PATH)
118
148
  # We're not interested in WIN32_FIND_DATA
119
- self.__com_GetPath(buf, MAX_PATH, None, flags)
149
+ self.__com_GetPath(buf, MAX_PATH, None, flags) # type: ignore
120
150
  return buf.value
121
151
 
122
- def GetDescription(self):
152
+ def GetDescription(self) -> bytes:
123
153
  buf = create_string_buffer(1024)
124
- self.__com_GetDescription(buf, 1024)
154
+ self.__com_GetDescription(buf, 1024) # type: ignore
125
155
  return buf.value
126
156
 
127
- def GetWorkingDirectory(self):
157
+ def GetWorkingDirectory(self) -> bytes:
128
158
  buf = create_string_buffer(MAX_PATH)
129
- self.__com_GetWorkingDirectory(buf, MAX_PATH)
159
+ self.__com_GetWorkingDirectory(buf, MAX_PATH) # type: ignore
130
160
  return buf.value
131
161
 
132
- def GetArguments(self):
162
+ def GetArguments(self) -> bytes:
133
163
  buf = create_string_buffer(1024)
134
- self.__com_GetArguments(buf, 1024)
164
+ self.__com_GetArguments(buf, 1024) # type: ignore
135
165
  return buf.value
136
166
 
137
- def GetIconLocation(self):
167
+ def GetIconLocation(self) -> Tuple[bytes, int]:
138
168
  iIcon = c_int()
139
169
  buf = create_string_buffer(MAX_PATH)
140
- self.__com_GetIconLocation(buf, MAX_PATH, byref(iIcon))
170
+ self.__com_GetIconLocation(buf, MAX_PATH, byref(iIcon)) # type: ignore
141
171
  return buf.value, iIcon.value
142
172
 
143
173
 
@@ -226,31 +256,52 @@ class IShellLinkW(IUnknown):
226
256
  COMMETHOD([], HRESULT, "SetPath", (["in"], c_wchar_p, "pszFile")),
227
257
  ]
228
258
 
229
- def GetPath(self, flags=SLGP_SHORTPATH):
259
+ if TYPE_CHECKING:
260
+ # fmt: off
261
+ def GetIDList(self) -> hints.Incomplete: ... # noqa
262
+ def SetIDList(self, pidl: hints.Incomplete) -> hints.Incomplete: ... # noqa
263
+ def SetDescription(self, pszName: str) -> hints.Incomplete: ... # noqa
264
+ def SetWorkingDirectory(self, pszDir: str) -> hints.Hresult: ... # noqa
265
+ def SetArguments(self, pszArgs: str) -> hints.Hresult: ... # noqa
266
+ @property
267
+ def Hotkey(self) -> int: ... # noqa
268
+ @Hotkey.setter
269
+ def Hotkey(self, pwHotkey: int) -> None: ... # noqa
270
+ @property
271
+ def ShowCmd(self) -> int: ... # noqa
272
+ @ShowCmd.setter
273
+ def ShowCmd(self, piShowCmd: int) -> None: ... # noqa
274
+ def SetIconLocation(self, pszIconPath: str, iIcon: int) -> hints.Hresult: ... # noqa
275
+ def SetRelativePath(self, pszPathRel: str, dwReserved: hints.Literal[0]) -> hints.Hresult: ... # noqa
276
+ def Resolve(self, hwnd: int, fFlags: int) -> hints.Hresult: ... # noqa
277
+ def SetPath(self, pszFile: str) -> hints.Hresult: ... # noqa
278
+ # fmt: on
279
+
280
+ def GetPath(self, flags: int = SLGP_SHORTPATH) -> str:
230
281
  buf = create_unicode_buffer(MAX_PATH)
231
282
  # We're not interested in WIN32_FIND_DATA
232
- self.__com_GetPath(buf, MAX_PATH, None, flags)
283
+ self.__com_GetPath(buf, MAX_PATH, None, flags) # type: ignore
233
284
  return buf.value
234
285
 
235
- def GetDescription(self):
286
+ def GetDescription(self) -> str:
236
287
  buf = create_unicode_buffer(1024)
237
- self.__com_GetDescription(buf, 1024)
288
+ self.__com_GetDescription(buf, 1024) # type: ignore
238
289
  return buf.value
239
290
 
240
- def GetWorkingDirectory(self):
291
+ def GetWorkingDirectory(self) -> str:
241
292
  buf = create_unicode_buffer(MAX_PATH)
242
- self.__com_GetWorkingDirectory(buf, MAX_PATH)
293
+ self.__com_GetWorkingDirectory(buf, MAX_PATH) # type: ignore
243
294
  return buf.value
244
295
 
245
- def GetArguments(self):
296
+ def GetArguments(self) -> str:
246
297
  buf = create_unicode_buffer(1024)
247
- self.__com_GetArguments(buf, 1024)
298
+ self.__com_GetArguments(buf, 1024) # type: ignore
248
299
  return buf.value
249
300
 
250
- def GetIconLocation(self):
301
+ def GetIconLocation(self) -> Tuple[str, int]:
251
302
  iIcon = c_int()
252
303
  buf = create_unicode_buffer(MAX_PATH)
253
- self.__com_GetIconLocation(buf, MAX_PATH, byref(iIcon))
304
+ self.__com_GetIconLocation(buf, MAX_PATH, byref(iIcon)) # type: ignore
254
305
  return buf.value, iIcon.value
255
306
 
256
307
 
@@ -77,6 +77,15 @@ class Test_GetModule(ut.TestCase):
77
77
 
78
78
  self.assertTrue(issubclass(mod.IStream, ISequentialStream))
79
79
 
80
+ def test_msvidctl(self):
81
+ with contextlib.redirect_stdout(None): # supress warnings
82
+ mod = comtypes.client.GetModule("msvidctl.dll")
83
+ from comtypes.persist import IPersist
84
+ from comtypes.typeinfo import IRecordInfo
85
+
86
+ self.assertIs(mod.IPersist, IPersist)
87
+ self.assertIs(mod.IRecordInfo, IRecordInfo)
88
+
80
89
  def test_no_replacing_Patch_namespace(self):
81
90
  # NOTE: An object named `Patch` is defined in some dll.
82
91
  # Depending on how the namespace is defined in the static module,
@@ -0,0 +1,70 @@
1
+ from _ctypes import COMError
2
+ from ctypes import byref, POINTER
3
+ import contextlib
4
+ import unittest
5
+
6
+ import comtypes
7
+ from comtypes.client import GetModule, CreateObject
8
+ from comtypes import hresult, GUID
9
+
10
+ with contextlib.redirect_stdout(None): # supress warnings
11
+ GetModule("msvidctl.dll")
12
+ from comtypes.gen import MSVidCtlLib as msvidctl
13
+ from comtypes.gen.MSVidCtlLib import IBindCtx, IMoniker, IRunningObjectTable
14
+
15
+
16
+ MKSYS_ITEMMONIKER = 4
17
+ ROTFLAGS_ALLOWANYCLIENT = 1
18
+
19
+
20
+ def _create_item_moniker(delim: str, item: str) -> IMoniker:
21
+ mon = POINTER(IMoniker)()
22
+ comtypes._ole32.CreateItemMoniker(delim, item, byref(mon))
23
+ return mon # type: ignore
24
+
25
+
26
+ def _create_bctx() -> IBindCtx:
27
+ bctx = POINTER(IBindCtx)()
28
+ # The first parameter is reserved and must be 0.
29
+ comtypes._ole32.CreateBindCtx(0, byref(bctx))
30
+ return bctx # type: ignore
31
+
32
+
33
+ def _create_rot() -> IRunningObjectTable:
34
+ rot = POINTER(IRunningObjectTable)()
35
+ # The first parameter is reserved and must be 0.
36
+ comtypes._ole32.GetRunningObjectTable(0, byref(rot))
37
+ return rot # type: ignore
38
+
39
+
40
+ class Test_IMoniker(unittest.TestCase):
41
+ def test_IsSystemMoniker(self):
42
+ item_id = str(GUID.create_new())
43
+ mon = _create_item_moniker("!", item_id)
44
+ self.assertEqual(mon.IsSystemMoniker(), MKSYS_ITEMMONIKER)
45
+
46
+
47
+ class Test_IBindCtx(unittest.TestCase):
48
+ def test_EnumObjectParam(self):
49
+ bctx = _create_bctx()
50
+ with self.assertRaises(COMError) as err_ctx:
51
+ # calling `EnumObjectParam` results in a return value of E_NOTIMPL.
52
+ # https://learn.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-ibindctx-enumobjectparam#notes-to-callers
53
+ bctx.EnumObjectParam()
54
+ self.assertEqual(err_ctx.exception.hresult, hresult.E_NOTIMPL)
55
+
56
+
57
+ class Test_IRunningObjectTable(unittest.TestCase):
58
+ def test_register_and_revoke_item_moniker(self):
59
+ vidctl = CreateObject(msvidctl.MSVidCtl, interface=msvidctl.IMSVidCtl)
60
+ item_id = str(GUID.create_new())
61
+ mon = _create_item_moniker("!", item_id)
62
+ rot = _create_rot()
63
+ bctx = _create_bctx()
64
+ self.assertEqual(mon.IsRunning(bctx, None, None), hresult.S_FALSE)
65
+ dw_reg = rot.Register(ROTFLAGS_ALLOWANYCLIENT, vidctl, mon)
66
+ self.assertEqual(mon.IsRunning(bctx, None, None), hresult.S_OK)
67
+ self.assertEqual(f"!{item_id}", mon.GetDisplayName(bctx, None))
68
+ self.assertEqual(rot.GetObject(mon).QueryInterface(msvidctl.IMSVidCtl), vidctl)
69
+ rot.Revoke(dw_reg)
70
+ self.assertEqual(mon.IsRunning(bctx, None, None), hresult.S_FALSE)
@@ -0,0 +1,40 @@
1
+ from pathlib import Path
2
+ import tempfile
3
+ import unittest as ut
4
+
5
+ from comtypes import CoCreateInstance, GUID, IPersist
6
+ from comtypes import persist
7
+
8
+
9
+ CLSID_ShellLink = GUID("{00021401-0000-0000-C000-000000000046}")
10
+
11
+
12
+ class Test_IPersist(ut.TestCase):
13
+ def test_GetClassID(self):
14
+ p = CoCreateInstance(CLSID_ShellLink).QueryInterface(IPersist)
15
+ self.assertEqual(p.GetClassID(), CLSID_ShellLink)
16
+
17
+
18
+ class Test_IPersistFile(ut.TestCase):
19
+ def setUp(self):
20
+ td = tempfile.TemporaryDirectory()
21
+ self.addCleanup(td.cleanup)
22
+ self.tmp_dir = Path(td.name)
23
+
24
+ def _create_pf(self) -> persist.IPersistFile:
25
+ return CoCreateInstance(CLSID_ShellLink).QueryInterface(persist.IPersistFile)
26
+
27
+ def test_load(self):
28
+ pf = self._create_pf()
29
+ tgt_file = (self.tmp_dir / "tgt.txt").resolve()
30
+ tgt_file.touch()
31
+ pf.Load(str(tgt_file), persist.STGM_DIRECT)
32
+ self.assertEqual(pf.GetCurFile(), str(tgt_file))
33
+
34
+ def test_save(self):
35
+ pf = self._create_pf()
36
+ tgt_file = self.tmp_dir / "tgt.txt"
37
+ self.assertFalse(tgt_file.exists())
38
+ pf.Save(str(tgt_file), True)
39
+ self.assertEqual(pf.GetCurFile(), str(tgt_file))
40
+ self.assertTrue(tgt_file.exists())
@@ -0,0 +1,79 @@
1
+ # coding: utf-8
2
+
3
+ import unittest
4
+
5
+ from comtypes import typeinfo
6
+ from comtypes.client import GetModule
7
+ from ctypes import byref, pointer, sizeof
8
+
9
+ ComtypesCppTestSrvLib_GUID = "{07D2AEE5-1DF8-4D2C-953A-554ADFD25F99}"
10
+
11
+ try:
12
+ GetModule((ComtypesCppTestSrvLib_GUID, 1, 0, 0))
13
+ from comtypes.gen.ComtypesCppTestSrvLib import StructRecordParamTest
14
+
15
+ IMPORT_FAILED = False
16
+ except (ImportError, OSError):
17
+ IMPORT_FAILED = True
18
+
19
+
20
+ def _create_recordinfo() -> typeinfo.IRecordInfo:
21
+ return typeinfo.GetRecordInfoFromGuids(*StructRecordParamTest._recordinfo_)
22
+
23
+
24
+ def _create_record(
25
+ question: str, answer: int, needs_clarification: bool
26
+ ) -> "StructRecordParamTest":
27
+ record = StructRecordParamTest()
28
+ record.question = question
29
+ record.answer = answer
30
+ record.needs_clarification = needs_clarification
31
+ return record
32
+
33
+
34
+ @unittest.skipIf(IMPORT_FAILED, "This depends on the out of process COM-server.")
35
+ class Test_IRecordInfo(unittest.TestCase):
36
+ def test_RecordCopy(self):
37
+ dst_rec = StructRecordParamTest()
38
+ ri = _create_recordinfo()
39
+ ri.RecordCopy(pointer(_create_record("foo", 3, True)), byref(dst_rec))
40
+ self.assertEqual(dst_rec.question, "foo")
41
+ self.assertEqual(dst_rec.answer, 3)
42
+ self.assertEqual(dst_rec.needs_clarification, True)
43
+
44
+ def test_GetGuid(self):
45
+ *_, expected_guid = StructRecordParamTest._recordinfo_
46
+ self.assertEqual(str(_create_recordinfo().GetGuid()), expected_guid)
47
+
48
+ def test_GetName(self):
49
+ self.assertEqual(
50
+ _create_recordinfo().GetName(),
51
+ StructRecordParamTest.__qualname__,
52
+ )
53
+
54
+ def test_GetSize(self):
55
+ self.assertEqual(
56
+ _create_recordinfo().GetSize(),
57
+ sizeof(StructRecordParamTest),
58
+ )
59
+
60
+ def test_GetTypeInfo(self):
61
+ ta = _create_recordinfo().GetTypeInfo().GetTypeAttr()
62
+ *_, expected_guid = StructRecordParamTest._recordinfo_
63
+ self.assertEqual(str(ta.guid), expected_guid)
64
+
65
+ def test_IsMatchingType(self):
66
+ ri = _create_recordinfo()
67
+ ti = ri.GetTypeInfo()
68
+ self.assertTrue(typeinfo.GetRecordInfoFromTypeInfo(ti).IsMatchingType(ri))
69
+
70
+ def test_RecordCreateCopy(self):
71
+ ri = _create_recordinfo()
72
+ actual = ri.RecordCreateCopy(byref(_create_record("foo", 3, True)))
73
+ self.assertIsInstance(actual, int)
74
+ dst_rec = StructRecordParamTest()
75
+ ri.RecordCopy(actual, byref(dst_rec))
76
+ ri.RecordDestroy(actual)
77
+ self.assertEqual(dst_rec.question, "foo")
78
+ self.assertEqual(dst_rec.answer, 3)
79
+ self.assertEqual(dst_rec.needs_clarification, True)
@@ -0,0 +1,133 @@
1
+ from pathlib import Path
2
+ import tempfile
3
+ import unittest as ut
4
+
5
+ from comtypes import CoCreateInstance, GUID, shelllink
6
+ import comtypes.hresult
7
+ from comtypes.persist import IPersistFile
8
+
9
+
10
+ CLSID_ShellLink = GUID("{00021401-0000-0000-C000-000000000046}")
11
+
12
+
13
+ class Test_IShellLinkA(ut.TestCase):
14
+ def setUp(self):
15
+ td = tempfile.TemporaryDirectory()
16
+ self.addCleanup(td.cleanup)
17
+ self.tmp_dir = Path(td.name)
18
+ self.src_file = (self.tmp_dir / "src.txt").resolve()
19
+ self.src_file.touch()
20
+
21
+ def _create_shortcut(self) -> shelllink.IShellLinkA:
22
+ return CoCreateInstance(CLSID_ShellLink, interface=shelllink.IShellLinkA)
23
+
24
+ def test_set_and_get_path(self):
25
+ shortcut = self._create_shortcut()
26
+ pf = shortcut.QueryInterface(IPersistFile)
27
+ self.assertEqual(pf.IsDirty(), comtypes.hresult.S_FALSE)
28
+ shortcut.SetPath(str(self.src_file).encode("utf-8"))
29
+ self.assertEqual(pf.IsDirty(), comtypes.hresult.S_OK)
30
+ self.assertEqual(
31
+ shortcut.GetPath(shelllink.SLGP_UNCPRIORITY),
32
+ str(self.src_file).encode("utf-8"),
33
+ )
34
+ lnk_file = (self.tmp_dir / "new.lnk").resolve()
35
+ self.assertFalse(lnk_file.exists())
36
+ pf.Save(str(lnk_file), True)
37
+ self.assertTrue(lnk_file.exists())
38
+ self.assertEqual(pf.GetCurFile(), str(lnk_file))
39
+
40
+ def test_set_and_get_working_directory(self):
41
+ shortcut = self._create_shortcut()
42
+ shortcut.SetWorkingDirectory(str(self.tmp_dir).encode("utf-8"))
43
+ self.assertEqual(
44
+ shortcut.GetWorkingDirectory(), str(self.tmp_dir).encode("utf-8")
45
+ )
46
+
47
+ def test_set_and_get_arguments(self):
48
+ shortcut = self._create_shortcut()
49
+ shortcut.SetArguments(b"-f")
50
+ self.assertEqual(shortcut.GetArguments(), b"-f")
51
+
52
+ def test_set_and_get_hotkey(self):
53
+ HOTKEYF_ALT = 0x04
54
+ HOTKEYF_CONTROL = 0x02
55
+ shortcut = self._create_shortcut()
56
+ shortcut.Hotkey = HOTKEYF_ALT | HOTKEYF_CONTROL
57
+ self.assertEqual(shortcut.Hotkey, HOTKEYF_ALT | HOTKEYF_CONTROL)
58
+
59
+ def test_set_and_get_showcmd(self):
60
+ SW_SHOWMAXIMIZED = 0x03
61
+ shortcut = self._create_shortcut()
62
+ shortcut.ShowCmd = SW_SHOWMAXIMIZED
63
+ self.assertEqual(shortcut.ShowCmd, SW_SHOWMAXIMIZED)
64
+
65
+ def test_set_and_get_icon_location(self):
66
+ shortcut = self._create_shortcut()
67
+ shortcut.SetIconLocation(str(self.src_file).encode("utf-8"), 1)
68
+ icon_path, index = shortcut.GetIconLocation()
69
+ self.assertEqual(icon_path, str(self.src_file).encode("utf-8"))
70
+ self.assertEqual(index, 1)
71
+
72
+
73
+ class Test_IShellLinkW(ut.TestCase):
74
+ def setUp(self):
75
+ td = tempfile.TemporaryDirectory()
76
+ self.addCleanup(td.cleanup)
77
+ self.tmp_dir = Path(td.name)
78
+ self.src_file = (self.tmp_dir / "src.txt").resolve()
79
+ self.src_file.touch()
80
+
81
+ def _create_shortcut(self) -> shelllink.IShellLinkW:
82
+ return CoCreateInstance(CLSID_ShellLink, interface=shelllink.IShellLinkW)
83
+
84
+ def test_set_and_get_path(self):
85
+ shortcut = self._create_shortcut()
86
+ pf = shortcut.QueryInterface(IPersistFile)
87
+ self.assertEqual(pf.IsDirty(), comtypes.hresult.S_FALSE)
88
+ shortcut.SetPath(str(self.src_file))
89
+ self.assertEqual(pf.IsDirty(), comtypes.hresult.S_OK)
90
+ self.assertEqual(
91
+ shortcut.GetPath(shelllink.SLGP_UNCPRIORITY),
92
+ str(self.src_file),
93
+ )
94
+ lnk_file = (self.tmp_dir / "new.lnk").resolve()
95
+ self.assertFalse(lnk_file.exists())
96
+ pf.Save(str(lnk_file), True)
97
+ self.assertTrue(lnk_file.exists())
98
+ self.assertEqual(pf.GetCurFile(), str(lnk_file))
99
+
100
+ def test_set_and_get_description(self):
101
+ shortcut = self._create_shortcut()
102
+ shortcut.SetDescription("sample")
103
+ self.assertEqual(shortcut.GetDescription(), "sample")
104
+
105
+ def test_set_and_get_working_directory(self):
106
+ shortcut = self._create_shortcut()
107
+ shortcut.SetWorkingDirectory(str(self.tmp_dir))
108
+ self.assertEqual(shortcut.GetWorkingDirectory(), str(self.tmp_dir))
109
+
110
+ def test_set_and_get_arguments(self):
111
+ shortcut = self._create_shortcut()
112
+ shortcut.SetArguments("-f")
113
+ self.assertEqual(shortcut.GetArguments(), "-f")
114
+
115
+ def test_set_and_get_hotkey(self):
116
+ HOTKEYF_ALT = 0x04
117
+ HOTKEYF_CONTROL = 0x02
118
+ shortcut = self._create_shortcut()
119
+ shortcut.Hotkey = HOTKEYF_ALT | HOTKEYF_CONTROL
120
+ self.assertEqual(shortcut.Hotkey, HOTKEYF_ALT | HOTKEYF_CONTROL)
121
+
122
+ def test_set_and_get_showcmd(self):
123
+ SW_SHOWMAXIMIZED = 0x03
124
+ shortcut = self._create_shortcut()
125
+ shortcut.ShowCmd = SW_SHOWMAXIMIZED
126
+ self.assertEqual(shortcut.ShowCmd, SW_SHOWMAXIMIZED)
127
+
128
+ def test_set_and_get_icon_location(self):
129
+ shortcut = self._create_shortcut()
130
+ shortcut.SetIconLocation(str(self.src_file), 1)
131
+ icon_path, index = shortcut.GetIconLocation()
132
+ self.assertEqual(icon_path, str(self.src_file))
133
+ self.assertEqual(index, 1)