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
@@ -139,20 +139,16 @@ def _load_tlib(obj: Any) -> typeinfo.ITypeLib:
139
139
  elif isinstance(obj, GUID):
140
140
  clsid = str(obj)
141
141
  # lookup associated typelib in registry
142
- with winreg.OpenKey(
143
- winreg.HKEY_CLASSES_ROOT, r"CLSID\%s\TypeLib" % clsid
144
- ) as key:
142
+ with winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, rf"CLSID\{clsid}\TypeLib") as key:
145
143
  libid = winreg.EnumValue(key, 0)[1]
146
- with winreg.OpenKey(
147
- winreg.HKEY_CLASSES_ROOT, r"CLSID\%s\Version" % clsid
148
- ) as key:
144
+ with winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, rf"CLSID\{clsid}\Version") as key:
149
145
  ver = winreg.EnumValue(key, 0)[1].split(".")
150
146
  return typeinfo.LoadRegTypeLib(GUID(libid), int(ver[0]), int(ver[1]), 0)
151
147
  # obj is a sequence containing libid
152
148
  elif isinstance(obj, (tuple, list)):
153
149
  libid, ver = obj[0], obj[1:]
154
150
  if not ver: # case of version numbers are not containing
155
- with winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, r"TypeLib\%s" % libid) as key:
151
+ with winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, rf"TypeLib\{libid}") as key:
156
152
  ver = [int(v, base=16) for v in winreg.EnumKey(key, 0).split(".")]
157
153
  return typeinfo.LoadRegTypeLib(GUID(libid), *ver)
158
154
  # obj is a COMObject implementation
@@ -161,7 +157,7 @@ def _load_tlib(obj: Any) -> typeinfo.ITypeLib:
161
157
  # obj is a pointer of ITypeLib
162
158
  elif isinstance(obj, ctypes.POINTER(typeinfo.ITypeLib)):
163
159
  return obj # type: ignore
164
- raise TypeError("'%r' is not supported type for loading typelib" % obj)
160
+ raise TypeError(f"'{obj!r}' is not supported type for loading typelib")
165
161
 
166
162
 
167
163
  def _get_existing_module(tlib: typeinfo.ITypeLib) -> Optional[types.ModuleType]:
@@ -67,7 +67,7 @@ class NamedProperty(object):
67
67
 
68
68
  def __iter__(self):
69
69
  """Explicitly disallow iteration."""
70
- msg = "%r is not iterable" % self.disp
70
+ msg = f"{self.disp!r} is not iterable"
71
71
  raise TypeError(msg)
72
72
 
73
73
 
@@ -151,7 +151,7 @@ class Dispatch(object):
151
151
  if descr.cParams == 1:
152
152
  return self._comobj._invoke(descr.memid, descr.invkind, 0)
153
153
  else:
154
- raise RuntimeError("funckind %d not yet implemented" % descr.funckind)
154
+ raise RuntimeError(f"funckind {descr.funckind:d} not yet implemented")
155
155
  put = self.__bind(name, DISPATCH_PROPERTYPUT)
156
156
  putref = self.__bind(name, DISPATCH_PROPERTYPUTREF)
157
157
  return NamedProperty(self, descr, put, putref)
@@ -1,10 +1,10 @@
1
1
  import sys
2
2
  from ctypes import *
3
+ from ctypes.wintypes import DWORD
3
4
  from comtypes import IUnknown, HRESULT, COMMETHOD, GUID, BSTR
4
5
  from comtypes.hresult import *
5
6
 
6
7
  LPCOLESTR = c_wchar_p
7
- DWORD = c_ulong
8
8
 
9
9
 
10
10
  class ICreateErrorInfo(IUnknown):
@@ -103,9 +103,9 @@ def ReportException(
103
103
  tb = tb.tb_next
104
104
  line = tb.tb_frame.f_lineno
105
105
  name = tb.tb_frame.f_globals["__name__"]
106
- text = "%s: %s (%s, line %d)" % (typ, value, name, line)
106
+ text = f"{typ}: {value} ({name}, line {line:d})"
107
107
  else:
108
- text = "%s: %s" % (typ, value)
108
+ text = f"{typ}: {value}"
109
109
  return ReportError(
110
110
  text,
111
111
  iid,
@@ -5,6 +5,7 @@ between different threading appartments.
5
5
  """
6
6
 
7
7
  from ctypes import *
8
+ from ctypes.wintypes import DWORD
8
9
  from comtypes import (
9
10
  IUnknown,
10
11
  STDMETHOD,
@@ -15,8 +16,6 @@ from comtypes import (
15
16
  CLSCTX_INPROC_SERVER,
16
17
  )
17
18
 
18
- DWORD = c_ulong
19
-
20
19
 
21
20
  class IGlobalInterfaceTable(IUnknown):
22
21
  _iid_ = GUID("{00000146-0000-0000-C000-000000000046}")
@@ -3,17 +3,11 @@
3
3
  # - utilities for type hints.
4
4
  import ctypes
5
5
  import sys
6
- from typing import Any as Any, ClassVar, Generic, NoReturn, TypeVar, overload
6
+ from typing import Any as Any, ClassVar, Generic, NoReturn, Protocol, TypeVar, overload
7
7
  from typing import Optional, Union as _UnionT
8
- from typing import List, Tuple as Tuple, Type
8
+ from typing import Tuple as Tuple, Type
9
9
  from typing import Callable, Iterator, Sequence
10
10
 
11
- if sys.version_info >= (3, 8):
12
- from typing import Protocol
13
- from typing import Literal as Literal
14
- else:
15
- from typing_extensions import Protocol
16
- from typing_extensions import Literal as Literal
17
11
  if sys.version_info >= (3, 9):
18
12
  from typing import Annotated as Annotated
19
13
  else:
@@ -30,10 +24,11 @@ else:
30
24
  from typing_extensions import Self as Self
31
25
 
32
26
  import comtypes
33
- from comtypes import IUnknown as IUnknown, GUID as GUID
27
+ from comtypes import IUnknown as IUnknown, COMObject as COMObject, GUID as GUID
34
28
  from comtypes.automation import IDispatch as IDispatch, VARIANT as VARIANT
35
29
  from comtypes.server import IClassFactory as IClassFactory
36
- from comtypes.typeinfo import ITypeInfo as ITypeInfo
30
+ from comtypes.server import localserver as localserver
31
+ from comtypes.typeinfo import ITypeInfo as ITypeInfo, ITypeLib as ITypeLib
37
32
  from comtypes._safearray import tagSAFEARRAY as tagSAFEARRAY
38
33
 
39
34
  Incomplete: TypeAlias = Any
@@ -74,6 +69,8 @@ class LP_SAFEARRAY(ctypes._Pointer[tagSAFEARRAY], Generic[_CT]):
74
69
  def unpack(self: LP_SAFEARRAY[_T_Struct]) -> Sequence[_T_Struct]: ...
75
70
  @overload
76
71
  def unpack(self) -> Sequence[Any]: ...
72
+ @classmethod
73
+ def from_param(cls, value: Any, /) -> Self: ...
77
74
 
78
75
  _T_coclass = TypeVar("_T_coclass", bound=comtypes.CoClass)
79
76
 
@@ -85,11 +82,6 @@ class FirstComItfOf(Generic[_T_coclass]):
85
82
  as an argument.
86
83
  """
87
84
 
88
- class _MethodTypeDesc(Protocol):
89
- arguments: List[Tuple[Any, str, List[str], Optional[Any]]]
90
- idlflags: List[str]
91
- name: str
92
-
93
85
  _P_Put = ParamSpec("_P_Put")
94
86
  _R_Put = TypeVar("_R_Put")
95
87
  _P_PutRef = ParamSpec("_P_PutRef")
@@ -78,6 +78,7 @@ def _make_safearray_type(itemtype):
78
78
  VT_UNKNOWN,
79
79
  IDispatch,
80
80
  VT_DISPATCH,
81
+ VT_HRESULT,
81
82
  )
82
83
 
83
84
  meta = type(_safearray.tagSAFEARRAY)
@@ -123,6 +124,15 @@ def _make_safearray_type(itemtype):
123
124
  one-dimensional arrays. To create multidimensional arrys,
124
125
  numpy arrays must be passed.
125
126
  """
127
+ if cls._vartype_ == VT_HRESULT:
128
+ raise TypeError(
129
+ # There are COM type libraries that define the
130
+ # `_midlSAFEARRAY(HRESULT)` type; however, creating `HRESULT`
131
+ # safearray pointer instance does not work.
132
+ # See also: https://github.com/enthought/comtypes/issues/668
133
+ "Cannot create SAFEARRAY type VT_HRESULT."
134
+ )
135
+
126
136
  if comtypes.npsupport.isndarray(value):
127
137
  return cls.create_from_ndarray(value, extra)
128
138
 
@@ -0,0 +1,86 @@
1
+ import ctypes
2
+ from ctypes import HRESULT, POINTER, byref
3
+ from typing import TYPE_CHECKING, Any, Optional, Type
4
+
5
+ import comtypes
6
+ import comtypes.client
7
+ import comtypes.client.dynamic
8
+ from comtypes import GUID, STDMETHOD, IUnknown
9
+ from comtypes.automation import IDispatch
10
+
11
+ if TYPE_CHECKING:
12
+ from ctypes import _Pointer
13
+
14
+ from comtypes import hints # type: ignore
15
+
16
+
17
+ ################################################################
18
+ # Interfaces
19
+ class IClassFactory(IUnknown):
20
+ _iid_ = GUID("{00000001-0000-0000-C000-000000000046}")
21
+ _methods_ = [
22
+ STDMETHOD(
23
+ HRESULT,
24
+ "CreateInstance",
25
+ [POINTER(IUnknown), POINTER(GUID), POINTER(ctypes.c_void_p)],
26
+ ),
27
+ STDMETHOD(HRESULT, "LockServer", [ctypes.c_int]),
28
+ ]
29
+
30
+ def CreateInstance(
31
+ self,
32
+ punkouter: Optional[Type["_Pointer[IUnknown]"]] = None,
33
+ interface: Optional[Type[IUnknown]] = None,
34
+ dynamic: bool = False,
35
+ ) -> Any:
36
+ if dynamic:
37
+ if interface is not None:
38
+ raise ValueError("interface and dynamic are mutually exclusive")
39
+ itf = IDispatch
40
+ elif interface is None:
41
+ itf = IUnknown
42
+ else:
43
+ itf = interface
44
+ obj = POINTER(itf)()
45
+ self.__com_CreateInstance(punkouter, itf._iid_, byref(obj)) # type: ignore
46
+ if dynamic:
47
+ return comtypes.client.dynamic.Dispatch(obj)
48
+ elif interface is None:
49
+ # An interface was not specified, so return the best.
50
+ return comtypes.client.GetBestInterface(obj)
51
+ # An interface was specified and obj is already that interface.
52
+ return obj
53
+
54
+ if TYPE_CHECKING:
55
+
56
+ def LockServer(self, fLock: int) -> hints.Hresult: ...
57
+
58
+
59
+ # class IExternalConnection(IUnknown):
60
+ # _iid_ = GUID("{00000019-0000-0000-C000-000000000046}")
61
+ # _methods_ = [
62
+ # STDMETHOD(HRESULT, "AddConnection", [c_ulong, c_ulong]),
63
+ # STDMETHOD(HRESULT, "ReleaseConnection", [c_ulong, c_ulong, c_ulong])]
64
+
65
+ # The following code is untested:
66
+
67
+ ACTIVEOBJECT_STRONG = 0x0
68
+ ACTIVEOBJECT_WEAK = 0x1
69
+
70
+ oleaut32 = ctypes.oledll.oleaut32
71
+
72
+
73
+ def RegisterActiveObject(comobj: comtypes.COMObject, weak: bool = True) -> int:
74
+ punk = comobj._com_pointers_[IUnknown._iid_]
75
+ clsid = comobj._reg_clsid_
76
+ if weak:
77
+ flags = ACTIVEOBJECT_WEAK
78
+ else:
79
+ flags = ACTIVEOBJECT_STRONG
80
+ handle = ctypes.c_ulong()
81
+ oleaut32.RegisterActiveObject(punk, byref(clsid), flags, byref(handle))
82
+ return handle.value
83
+
84
+
85
+ def RevokeActiveObject(handle: int) -> None:
86
+ oleaut32.RevokeActiveObject(handle, None)
@@ -1,12 +1,11 @@
1
1
  import ctypes
2
- from comtypes import COMObject, GUID
3
- from comtypes.server import IClassFactory
4
- from comtypes.hresult import *
5
-
6
- import sys
7
2
  import logging
3
+ import sys
8
4
  import winreg
5
+ from typing import Any, Literal, Optional, Type
9
6
 
7
+ from comtypes import GUID, COMObject, IUnknown, hresult
8
+ from comtypes.server import IClassFactory
10
9
 
11
10
  logger = logging.getLogger(__name__)
12
11
  _debug = logger.debug
@@ -18,33 +17,39 @@ _critical = logger.critical
18
17
  class ClassFactory(COMObject):
19
18
  _com_interfaces_ = [IClassFactory]
20
19
 
21
- def __init__(self, cls):
20
+ def __init__(self, cls: Type[COMObject]) -> None:
22
21
  super(ClassFactory, self).__init__()
23
22
  self._cls = cls
24
23
 
25
- def IClassFactory_CreateInstance(self, this, punkOuter, riid, ppv):
24
+ def IClassFactory_CreateInstance(
25
+ self,
26
+ this: Any,
27
+ punkOuter: Optional[Type["ctypes._Pointer[IUnknown]"]],
28
+ riid: "ctypes._Pointer[GUID]",
29
+ ppv: ctypes.c_void_p,
30
+ ) -> int:
26
31
  _debug("ClassFactory.CreateInstance(%s)", riid[0])
27
32
  result = self._cls().IUnknown_QueryInterface(None, riid, ppv)
28
33
  _debug("CreateInstance() -> %s", result)
29
34
  return result
30
35
 
31
- def IClassFactory_LockServer(self, this, fLock):
36
+ def IClassFactory_LockServer(self, this: Any, fLock: bool) -> Literal[0]:
32
37
  if fLock:
33
38
  COMObject.__server__.Lock()
34
39
  else:
35
40
  COMObject.__server__.Unlock()
36
- return S_OK
41
+ return hresult.S_OK
37
42
 
38
43
 
39
44
  # will be set by py2exe boot script 'from outside'
40
45
  _clsid_to_class = {}
41
46
 
42
47
 
43
- def inproc_find_class(clsid):
48
+ def inproc_find_class(clsid: GUID) -> Type[COMObject]:
44
49
  if _clsid_to_class:
45
50
  return _clsid_to_class[clsid]
46
51
 
47
- key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, "CLSID\\%s\\InprocServer32" % clsid)
52
+ key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, f"CLSID\\{clsid}\\InprocServer32")
48
53
  try:
49
54
  pathdir = winreg.QueryValueEx(key, "PythonPath")[0]
50
55
  except:
@@ -70,7 +75,7 @@ def inproc_find_class(clsid):
70
75
  _logging_configured = False
71
76
 
72
77
 
73
- def _setup_logging(clsid):
78
+ def _setup_logging(clsid: GUID) -> None:
74
79
  """Read from the registry, and configure the logging module.
75
80
 
76
81
  Currently, the handler (NTDebugHandler) is hardcoded.
@@ -109,7 +114,7 @@ def _setup_logging(clsid):
109
114
  logging.getLogger(name).setLevel(level)
110
115
 
111
116
 
112
- def DllGetClassObject(rclsid, riid, ppv):
117
+ def DllGetClassObject(rclsid: int, riid: int, ppv: int) -> int:
113
118
  COMObject.__run_inprocserver__()
114
119
 
115
120
  iid = GUID.from_address(riid)
@@ -127,7 +132,7 @@ def DllGetClassObject(rclsid, riid, ppv):
127
132
 
128
133
  cls = inproc_find_class(clsid)
129
134
  if not cls:
130
- return CLASS_E_CLASSNOTAVAILABLE
135
+ return hresult.CLASS_E_CLASSNOTAVAILABLE
131
136
 
132
137
  result = ClassFactory(cls).IUnknown_QueryInterface(
133
138
  None, ctypes.pointer(iid), ctypes.c_void_p(ppv)
@@ -136,12 +141,12 @@ def DllGetClassObject(rclsid, riid, ppv):
136
141
  return result
137
142
  except Exception:
138
143
  _critical("DllGetClassObject", exc_info=True)
139
- return E_FAIL
144
+ return hresult.E_FAIL
140
145
 
141
146
 
142
- def DllCanUnloadNow():
147
+ def DllCanUnloadNow() -> Literal[1]: # S_FALSE
143
148
  COMObject.__run_inprocserver__()
144
149
  result = COMObject.__server__.DllCanUnloadNow()
145
150
  # To avoid a memory leak when PyInitialize()/PyUninitialize() are
146
151
  # called several times, we refuse to unload the dll.
147
- return S_FALSE
152
+ return hresult.S_FALSE
@@ -1,10 +1,16 @@
1
+ import logging
2
+ import queue
1
3
  import sys
2
- from ctypes import *
4
+ from ctypes import byref, c_ulong, c_void_p, oledll
5
+ from typing import TYPE_CHECKING, Any, Literal, Optional, Sequence, Type
6
+
3
7
  import comtypes
4
- from comtypes.hresult import *
8
+ from comtypes import hresult
5
9
  from comtypes.server import IClassFactory
6
- import logging
7
- import queue
10
+
11
+ if TYPE_CHECKING:
12
+ from ctypes import _Pointer
13
+
8
14
 
9
15
  logger = logging.getLogger(__name__)
10
16
  _debug = logger.debug
@@ -16,31 +22,31 @@ REGCLS_SUSPENDED = 4 # register it as suspended, will be activated
16
22
  REGCLS_SURROGATE = 8 # must be used when a surrogate process
17
23
 
18
24
 
19
- def run(classes):
25
+ def run(classes: Sequence[Type[comtypes.COMObject]]) -> None:
20
26
  classobjects = [ClassFactory(cls) for cls in classes]
21
27
  comtypes.COMObject.__run_localserver__(classobjects)
22
28
 
23
29
 
24
30
  class ClassFactory(comtypes.COMObject):
25
31
  _com_interfaces_ = [IClassFactory]
26
- _locks = 0
27
- _queue = None
28
- regcls = REGCLS_MULTIPLEUSE
32
+ _locks: int = 0
33
+ _queue: Optional[queue.Queue] = None
34
+ regcls: int = REGCLS_MULTIPLEUSE
29
35
 
30
- def __init__(self, cls, *args, **kw):
36
+ def __init__(self, cls: Type[comtypes.COMObject], *args, **kw) -> None:
31
37
  super(ClassFactory, self).__init__()
32
38
  self._cls = cls
33
39
  self._register_class()
34
40
  self._args = args
35
41
  self._kw = kw
36
42
 
37
- def IUnknown_AddRef(self, this):
43
+ def IUnknown_AddRef(self, this: Any) -> int:
38
44
  return 2
39
45
 
40
- def IUnknown_Release(self, this):
46
+ def IUnknown_Release(self, this: Any) -> int:
41
47
  return 1
42
48
 
43
- def _register_class(self):
49
+ def _register_class(self) -> None:
44
50
  regcls = getattr(self._cls, "_regcls_", self.regcls)
45
51
  cookie = c_ulong()
46
52
  ptr = self._com_pointers_[comtypes.IUnknown._iid_]
@@ -55,19 +61,25 @@ class ClassFactory(comtypes.COMObject):
55
61
  )
56
62
  self.cookie = cookie
57
63
 
58
- def _revoke_class(self):
64
+ def _revoke_class(self) -> None:
59
65
  oledll.ole32.CoRevokeClassObject(self.cookie)
60
66
 
61
- def CreateInstance(self, this, punkOuter, riid, ppv):
67
+ def CreateInstance(
68
+ self,
69
+ this: Any,
70
+ punkOuter: Optional[Type["_Pointer[comtypes.IUnknown]"]],
71
+ riid: "_Pointer[comtypes.GUID]",
72
+ ppv: c_void_p,
73
+ ) -> int:
62
74
  _debug("ClassFactory.CreateInstance(%s)", riid[0])
63
75
  obj = self._cls(*self._args, **self._kw)
64
76
  result = obj.IUnknown_QueryInterface(None, riid, ppv)
65
77
  _debug("CreateInstance() -> %s", result)
66
78
  return result
67
79
 
68
- def LockServer(self, this, fLock):
80
+ def LockServer(self, this: Any, fLock: bool) -> Literal[0]:
69
81
  if fLock:
70
82
  comtypes.COMObject.__server__.Lock()
71
83
  else:
72
84
  comtypes.COMObject.__server__.Unlock()
73
- return S_OK
85
+ return hresult.S_OK