comtypes 1.4.8__zip → 1.4.10__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 (154) hide show
  1. {comtypes-1.4.8 → comtypes-1.4.10}/CHANGES.txt +40 -0
  2. {comtypes-1.4.8/comtypes.egg-info → comtypes-1.4.10}/PKG-INFO +4 -3
  3. {comtypes-1.4.8 → comtypes-1.4.10}/README.md +1 -1
  4. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/GUID.py +38 -16
  5. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/__init__.py +36 -16
  6. comtypes-1.4.10/comtypes/_comobject.py +562 -0
  7. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_memberspec.py +93 -13
  8. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_meta.py +1 -0
  9. comtypes-1.4.10/comtypes/_post_coinit/_cominterface_meta_patcher.py +152 -0
  10. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_post_coinit/bstr.py +12 -5
  11. comtypes-1.4.8/comtypes/_py_instance_method.py → comtypes-1.4.10/comtypes/_post_coinit/instancemethod.py +1 -2
  12. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_post_coinit/misc.py +60 -25
  13. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_post_coinit/unknwn.py +26 -176
  14. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_safearray.py +3 -4
  15. comtypes-1.4.10/comtypes/_vtbl.py +448 -0
  16. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/automation.py +46 -49
  17. comtypes-1.4.10/comtypes/client/__init__.py +42 -0
  18. comtypes-1.4.10/comtypes/client/_activeobj.py +46 -0
  19. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/_code_cache.py +10 -5
  20. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/_constants.py +1 -1
  21. comtypes-1.4.10/comtypes/client/_create.py +147 -0
  22. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/_events.py +58 -13
  23. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/_generate.py +7 -11
  24. comtypes-1.4.10/comtypes/client/_managing.py +114 -0
  25. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/dynamic.py +2 -3
  26. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/client/lazybind.py +12 -13
  27. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/connectionpoints.py +2 -1
  28. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/errorinfo.py +22 -9
  29. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/git.py +5 -5
  30. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/hints.pyi +7 -15
  31. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/logutil.py +15 -3
  32. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/messageloop.py +1 -1
  33. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/persist.py +3 -5
  34. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/safearray.py +17 -5
  35. comtypes-1.4.10/comtypes/server/__init__.py +104 -0
  36. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/server/automation.py +1 -2
  37. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/server/connectionpoints.py +5 -5
  38. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/server/inprocserver.py +25 -17
  39. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/server/localserver.py +49 -19
  40. comtypes-1.4.10/comtypes/server/register.py +478 -0
  41. comtypes-1.4.10/comtypes/server/w_getopt.py +48 -0
  42. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/shelllink.py +16 -33
  43. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/stream.py +7 -4
  44. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestComServer.py +6 -7
  45. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestDispServer.py +4 -2
  46. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/__init__.py +10 -12
  47. comtypes-1.4.10/comtypes/test/find_memleak.py +72 -0
  48. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/runtests.py +1 -0
  49. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/setup.py +2 -1
  50. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_BSTR.py +10 -23
  51. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_GUID.py +1 -0
  52. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_QueryService.py +1 -0
  53. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_agilent.py +4 -3
  54. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_avmc.py +1 -1
  55. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_basic.py +12 -6
  56. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_casesensitivity.py +3 -5
  57. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_clear_cache.py +1 -1
  58. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_client.py +2 -2
  59. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_client_dynamic.py +2 -2
  60. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_client_regenerate_modules.py +2 -2
  61. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_collections.py +4 -4
  62. comtypes-1.4.10/comtypes/test/test_comobject.py +146 -0
  63. comtypes-1.4.10/comtypes/test/test_comserver.py +349 -0
  64. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_createwrappers.py +2 -4
  65. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_dispifc_records.py +1 -1
  66. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_dispifc_safearrays.py +1 -1
  67. comtypes-1.4.10/comtypes/test/test_dispinterface.py +153 -0
  68. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_dyndispatch.py +1 -0
  69. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_excel.py +22 -12
  70. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_findgendir.py +1 -2
  71. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_getactiveobj.py +4 -4
  72. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_ie.py +19 -9
  73. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_ienum.py +2 -2
  74. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_imfattributes.py +13 -3
  75. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_inout_args.py +8 -5
  76. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_midl_safearray_create.py +14 -4
  77. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_monikers.py +23 -9
  78. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_msscript.py +2 -1
  79. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_npsupport.py +4 -4
  80. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_outparam.py +37 -14
  81. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_persist.py +2 -4
  82. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_recordinfo.py +1 -1
  83. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_safearray.py +1 -90
  84. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_sapi.py +4 -1
  85. comtypes-1.4.10/comtypes/test/test_server.py +350 -0
  86. comtypes-1.4.10/comtypes/test/test_server_register.py +524 -0
  87. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_shelllink.py +2 -3
  88. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_showevents.py +7 -17
  89. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_storage.py +12 -6
  90. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_stream.py +16 -5
  91. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_subinterface.py +4 -2
  92. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_typeannotator.py +1 -2
  93. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_typeinfo.py +19 -7
  94. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_urlhistory.py +7 -4
  95. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_variant.py +3 -19
  96. comtypes-1.4.10/comtypes/test/test_w_getopt.py +29 -0
  97. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_win32com_interop.py +80 -36
  98. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_wmi.py +0 -3
  99. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_word.py +1 -1
  100. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/codegenerator.py +166 -440
  101. comtypes-1.4.10/comtypes/tools/codegenerator/comments.py +79 -0
  102. comtypes-1.4.10/comtypes/tools/codegenerator/heads.py +192 -0
  103. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/helpers.py +11 -14
  104. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/namespaces.py +13 -5
  105. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/packing.py +4 -4
  106. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/typeannotator.py +19 -9
  107. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/tlbparser.py +22 -23
  108. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/typedesc.py +4 -8
  109. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/typedesc_base.py +2 -2
  110. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/typeinfo.py +159 -63
  111. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/viewobject.py +3 -9
  112. {comtypes-1.4.8 → comtypes-1.4.10/comtypes.egg-info}/PKG-INFO +4 -3
  113. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes.egg-info/SOURCES.txt +11 -3
  114. {comtypes-1.4.8 → comtypes-1.4.10}/pyproject.toml +12 -19
  115. comtypes-1.4.8/comtypes/_comobject.py +0 -833
  116. comtypes-1.4.8/comtypes/_idl_stuff.py +0 -67
  117. comtypes-1.4.8/comtypes/client/__init__.py +0 -323
  118. comtypes-1.4.8/comtypes/server/__init__.py +0 -70
  119. comtypes-1.4.8/comtypes/server/register.py +0 -431
  120. comtypes-1.4.8/comtypes/server/w_getopt.py +0 -75
  121. comtypes-1.4.8/comtypes/test/find_memleak.py +0 -76
  122. comtypes-1.4.8/comtypes/test/test_comserver.py +0 -239
  123. comtypes-1.4.8/comtypes/test/test_dispinterface.py +0 -137
  124. comtypes-1.4.8/comtypes/test/test_propputref.py +0 -40
  125. comtypes-1.4.8/comtypes/test/test_server.py +0 -354
  126. {comtypes-1.4.8 → comtypes-1.4.10}/LICENSE.txt +0 -0
  127. {comtypes-1.4.8 → comtypes-1.4.10}/MANIFEST.in +0 -0
  128. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_npsupport.py +0 -0
  129. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_post_coinit/__init__.py +0 -0
  130. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/_tlib_version_checker.py +0 -0
  131. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/clear_cache.py +0 -0
  132. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/hresult.py +0 -0
  133. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/patcher.py +0 -0
  134. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestComServer.idl +0 -0
  135. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestComServer.tlb +0 -0
  136. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestDispServer.idl +0 -0
  137. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/TestDispServer.tlb +0 -0
  138. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/mylib.idl +0 -0
  139. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/mylib.tlb +0 -0
  140. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/mytypelib.idl +0 -0
  141. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_DISPPARAMS.py +0 -0
  142. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_dict.py +0 -0
  143. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_jscript.js +0 -0
  144. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/test_pump_events.py +0 -0
  145. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/test/urlhist.tlb +0 -0
  146. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/__init__.py +0 -0
  147. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/__init__.py +0 -0
  148. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/tools/codegenerator/modulenamer.py +0 -0
  149. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes/util.py +0 -0
  150. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes.egg-info/dependency_links.txt +0 -0
  151. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes.egg-info/entry_points.txt +0 -0
  152. {comtypes-1.4.8 → comtypes-1.4.10}/comtypes.egg-info/top_level.txt +0 -0
  153. {comtypes-1.4.8 → comtypes-1.4.10}/setup.cfg +0 -0
  154. {comtypes-1.4.8 → comtypes-1.4.10}/setup.py +0 -0
@@ -1,10 +1,11 @@
1
1
  import sys
2
2
  from ctypes import *
3
- from comtypes import IUnknown, HRESULT, COMMETHOD, GUID, BSTR
3
+ from ctypes.wintypes import DWORD, ULONG
4
+
5
+ from comtypes import BSTR, COMMETHOD, GUID, HRESULT, IUnknown
4
6
  from comtypes.hresult import *
5
7
 
6
8
  LPCOLESTR = c_wchar_p
7
- DWORD = c_ulong
8
9
 
9
10
 
10
11
  class ICreateErrorInfo(IUnknown):
@@ -45,26 +46,38 @@ class ISupportErrorInfo(IUnknown):
45
46
 
46
47
 
47
48
  ################################################################
48
- _oleaut32 = oledll.oleaut32
49
+ _oleaut32 = OleDLL("oleaut32")
50
+
51
+ _CreateErrorInfo = _oleaut32.CreateErrorInfo
52
+ _CreateErrorInfo.argtypes = [POINTER(POINTER(ICreateErrorInfo))]
53
+ _CreateErrorInfo.restype = HRESULT
54
+
55
+ _GetErrorInfo = _oleaut32.GetErrorInfo
56
+ _GetErrorInfo.argtypes = [ULONG, POINTER(POINTER(IErrorInfo))]
57
+ _GetErrorInfo.restype = HRESULT
58
+
59
+ _SetErrorInfo = _oleaut32.SetErrorInfo
60
+ _SetErrorInfo.argtypes = [ULONG, POINTER(IErrorInfo)]
61
+ _SetErrorInfo.restype = HRESULT
49
62
 
50
63
 
51
64
  def CreateErrorInfo():
52
65
  cei = POINTER(ICreateErrorInfo)()
53
- _oleaut32.CreateErrorInfo(byref(cei))
66
+ _CreateErrorInfo(byref(cei))
54
67
  return cei
55
68
 
56
69
 
57
70
  def GetErrorInfo():
58
71
  """Get the error information for the current thread."""
59
72
  errinfo = POINTER(IErrorInfo)()
60
- if S_OK == _oleaut32.GetErrorInfo(0, byref(errinfo)):
73
+ if S_OK == _GetErrorInfo(0, byref(errinfo)):
61
74
  return errinfo
62
75
  return None
63
76
 
64
77
 
65
78
  def SetErrorInfo(errinfo):
66
79
  """Set error information for the current thread."""
67
- return _oleaut32.SetErrorInfo(0, errinfo)
80
+ return _SetErrorInfo(0, errinfo)
68
81
 
69
82
 
70
83
  def ReportError(
@@ -89,7 +102,7 @@ def ReportError(
89
102
  ei.SetSource(
90
103
  progid
91
104
  ) # progid for the class or application that created the error
92
- _oleaut32.SetErrorInfo(0, ei)
105
+ _SetErrorInfo(0, ei)
93
106
  return hresult
94
107
 
95
108
 
@@ -103,9 +116,9 @@ def ReportException(
103
116
  tb = tb.tb_next
104
117
  line = tb.tb_frame.f_lineno
105
118
  name = tb.tb_frame.f_globals["__name__"]
106
- text = "%s: %s (%s, line %d)" % (typ, value, name, line)
119
+ text = f"{typ}: {value} ({name}, line {line:d})"
107
120
  else:
108
- text = "%s: %s" % (typ, value)
121
+ text = f"{typ}: {value}"
109
122
  return ReportError(
110
123
  text,
111
124
  iid,
@@ -5,18 +5,18 @@ between different threading appartments.
5
5
  """
6
6
 
7
7
  from ctypes import *
8
+ from ctypes.wintypes import DWORD
9
+
8
10
  from comtypes import (
9
- IUnknown,
10
- STDMETHOD,
11
+ CLSCTX_INPROC_SERVER,
11
12
  COMMETHOD,
12
13
  GUID,
13
14
  HRESULT,
15
+ STDMETHOD,
14
16
  CoCreateInstance,
15
- CLSCTX_INPROC_SERVER,
17
+ IUnknown,
16
18
  )
17
19
 
18
- DWORD = c_ulong
19
-
20
20
 
21
21
  class IGlobalInterfaceTable(IUnknown):
22
22
  _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")
@@ -1,13 +1,25 @@
1
1
  # logutil.py
2
- import logging, ctypes
2
+ import logging
3
+ from ctypes import WinDLL
4
+ from ctypes.wintypes import LPCSTR, LPCWSTR
5
+
6
+ _kernel32 = WinDLL("kernel32")
7
+
8
+ _OutputDebugStringA = _kernel32.OutputDebugStringA
9
+ _OutputDebugStringA.argtypes = [LPCSTR]
10
+ _OutputDebugStringA.restype = None
11
+
12
+ _OutputDebugStringW = _kernel32.OutputDebugStringW
13
+ _OutputDebugStringW.argtypes = [LPCWSTR]
14
+ _OutputDebugStringW.restype = None
3
15
 
4
16
 
5
17
  class NTDebugHandler(logging.Handler):
6
18
  def emit(
7
19
  self,
8
20
  record,
9
- writeA=ctypes.windll.kernel32.OutputDebugStringA,
10
- writeW=ctypes.windll.kernel32.OutputDebugStringW,
21
+ writeA=_OutputDebugStringA,
22
+ writeW=_OutputDebugStringW,
11
23
  ):
12
24
  text = self.format(record)
13
25
  if isinstance(text, str):
@@ -1,5 +1,5 @@
1
1
  import ctypes
2
- from ctypes import WinDLL, byref, WinError
2
+ from ctypes import WinDLL, WinError, byref
3
3
  from ctypes.wintypes import MSG
4
4
 
5
5
  _user32 = WinDLL("user32")
@@ -10,13 +10,11 @@ The 'DictPropertyBag' class is a class implementing the IPropertyBag
10
10
  interface, useful in client code.
11
11
  """
12
12
 
13
- from ctypes import c_int, c_ulong, c_ushort, c_wchar_p
14
- from ctypes import POINTER, Structure
15
- from ctypes.wintypes import WORD, DWORD, BOOL
13
+ from ctypes import POINTER, Structure, c_int, c_ulong, c_ushort, c_wchar_p
14
+ from ctypes.wintypes import BOOL, DWORD, WORD
16
15
  from typing import TYPE_CHECKING
17
16
 
18
- from comtypes import GUID, IUnknown, COMMETHOD, HRESULT
19
- from comtypes import IPersist
17
+ from comtypes import COMMETHOD, GUID, HRESULT, IPersist, IUnknown
20
18
  from comtypes.automation import VARIANT, tagEXCEPINFO
21
19
 
22
20
  if TYPE_CHECKING:
@@ -1,13 +1,15 @@
1
- import threading
2
1
  import array
2
+ import threading
3
+ from ctypes import POINTER, Structure, byref, c_long, cast, memmove, pointer, sizeof
3
4
  from typing import TYPE_CHECKING
5
+
4
6
  import comtypes
5
- from ctypes import POINTER, Structure, byref, cast, c_long, memmove, pointer, sizeof
6
- from comtypes import _safearray, IUnknown, com_interface_registry
7
+ from comtypes import IUnknown, _safearray, com_interface_registry
7
8
  from comtypes.patcher import Patch
8
9
 
9
10
  if TYPE_CHECKING:
10
11
  from typing import Type, TypeVar
12
+
11
13
  from comtypes import hints # type: ignore
12
14
 
13
15
  _CT = TypeVar("_CT", bound=comtypes._CData)
@@ -73,11 +75,12 @@ def _midlSAFEARRAY(itemtype: "Type[_CT]") -> "Type[hints.LP_SAFEARRAY[_CT]]":
73
75
  def _make_safearray_type(itemtype):
74
76
  # Create and return a subclass of tagSAFEARRAY
75
77
  from comtypes.automation import (
76
- _ctype_to_vartype,
78
+ VT_DISPATCH,
79
+ VT_HRESULT,
77
80
  VT_RECORD,
78
81
  VT_UNKNOWN,
79
82
  IDispatch,
80
- VT_DISPATCH,
83
+ _ctype_to_vartype,
81
84
  )
82
85
 
83
86
  meta = type(_safearray.tagSAFEARRAY)
@@ -123,6 +126,15 @@ def _make_safearray_type(itemtype):
123
126
  one-dimensional arrays. To create multidimensional arrys,
124
127
  numpy arrays must be passed.
125
128
  """
129
+ if cls._vartype_ == VT_HRESULT:
130
+ raise TypeError(
131
+ # There are COM type libraries that define the
132
+ # `_midlSAFEARRAY(HRESULT)` type; however, creating `HRESULT`
133
+ # safearray pointer instance does not work.
134
+ # See also: https://github.com/enthought/comtypes/issues/668
135
+ "Cannot create SAFEARRAY type VT_HRESULT."
136
+ )
137
+
126
138
  if comtypes.npsupport.isndarray(value):
127
139
  return cls.create_from_ndarray(value, extra)
128
140
 
@@ -0,0 +1,104 @@
1
+ import ctypes
2
+ from ctypes import HRESULT, POINTER, OleDLL, byref, c_void_p
3
+ from ctypes.wintypes import DWORD, LPVOID
4
+ from typing import TYPE_CHECKING, Any, Optional, Type
5
+
6
+ import comtypes
7
+ import comtypes.client
8
+ import comtypes.client.dynamic
9
+ from comtypes import GUID, STDMETHOD, IUnknown
10
+ from comtypes.automation import IDispatch
11
+ from comtypes.GUID import REFCLSID
12
+
13
+ if TYPE_CHECKING:
14
+ from ctypes import _Pointer
15
+
16
+ from comtypes import hints # type: ignore
17
+
18
+
19
+ ################################################################
20
+ # Interfaces
21
+ class IClassFactory(IUnknown):
22
+ _iid_ = GUID("{00000001-0000-0000-C000-000000000046}")
23
+ _methods_ = [
24
+ STDMETHOD(
25
+ HRESULT,
26
+ "CreateInstance",
27
+ [POINTER(IUnknown), POINTER(GUID), POINTER(ctypes.c_void_p)],
28
+ ),
29
+ STDMETHOD(HRESULT, "LockServer", [ctypes.c_int]),
30
+ ]
31
+
32
+ def CreateInstance(
33
+ self,
34
+ punkouter: Optional[Type["_Pointer[IUnknown]"]] = None,
35
+ interface: Optional[Type[IUnknown]] = None,
36
+ dynamic: bool = False,
37
+ ) -> Any:
38
+ if dynamic:
39
+ if interface is not None:
40
+ raise ValueError("interface and dynamic are mutually exclusive")
41
+ itf = IDispatch
42
+ elif interface is None:
43
+ itf = IUnknown
44
+ else:
45
+ itf = interface
46
+ obj = POINTER(itf)()
47
+ self.__com_CreateInstance(punkouter, itf._iid_, byref(obj)) # type: ignore
48
+ if dynamic:
49
+ return comtypes.client.dynamic.Dispatch(obj)
50
+ elif interface is None:
51
+ # An interface was not specified, so return the best.
52
+ return comtypes.client.GetBestInterface(obj)
53
+ # An interface was specified and obj is already that interface.
54
+ return obj
55
+
56
+ if TYPE_CHECKING:
57
+
58
+ def LockServer(self, fLock: int) -> hints.Hresult: ...
59
+
60
+
61
+ # class IExternalConnection(IUnknown):
62
+ # _iid_ = GUID("{00000019-0000-0000-C000-000000000046}")
63
+ # _methods_ = [
64
+ # STDMETHOD(HRESULT, "AddConnection", [c_ulong, c_ulong]),
65
+ # STDMETHOD(HRESULT, "ReleaseConnection", [c_ulong, c_ulong, c_ulong])]
66
+
67
+ # The following code is untested:
68
+
69
+ ACTIVEOBJECT_STRONG = 0x0
70
+ ACTIVEOBJECT_WEAK = 0x1
71
+
72
+ _oleaut32 = OleDLL("oleaut32")
73
+
74
+ _RegisterActiveObject = _oleaut32.RegisterActiveObject
75
+ _RegisterActiveObject.argtypes = [
76
+ c_void_p,
77
+ REFCLSID,
78
+ DWORD,
79
+ POINTER(DWORD),
80
+ ]
81
+ _RegisterActiveObject.restype = HRESULT
82
+
83
+ _RevokeActiveObject = _oleaut32.RevokeActiveObject
84
+ _RevokeActiveObject.argtypes = [
85
+ DWORD,
86
+ LPVOID,
87
+ ]
88
+ _RevokeActiveObject.restype = HRESULT
89
+
90
+
91
+ def RegisterActiveObject(comobj: comtypes.COMObject, weak: bool = True) -> int:
92
+ punk = comobj._com_pointers_[IUnknown._iid_]
93
+ clsid = comobj._reg_clsid_
94
+ if weak:
95
+ flags = ACTIVEOBJECT_WEAK
96
+ else:
97
+ flags = ACTIVEOBJECT_STRONG
98
+ handle = ctypes.c_ulong()
99
+ _RegisterActiveObject(punk, byref(clsid), flags, byref(handle))
100
+ return handle.value
101
+
102
+
103
+ def RevokeActiveObject(handle: int) -> None:
104
+ _RevokeActiveObject(handle, None)
@@ -1,10 +1,9 @@
1
1
  import logging
2
-
3
2
  from ctypes import *
4
- from comtypes.hresult import *
5
3
 
6
4
  from comtypes import COMObject, IUnknown
7
5
  from comtypes.automation import IDispatch, IEnumVARIANT
6
+ from comtypes.hresult import *
8
7
 
9
8
  logger = logging.getLogger(__name__)
10
9
 
@@ -1,11 +1,11 @@
1
+ import logging
1
2
  from ctypes import *
2
- from comtypes import IUnknown, COMObject, COMError
3
+
4
+ from comtypes import COMError, COMObject, IUnknown
5
+ from comtypes.automation import IDispatch
6
+ from comtypes.connectionpoints import IConnectionPoint
3
7
  from comtypes.hresult import *
4
8
  from comtypes.typeinfo import LoadRegTypeLib
5
- from comtypes.connectionpoints import IConnectionPoint
6
- from comtypes.automation import IDispatch
7
-
8
- import logging
9
9
 
10
10
  logger = logging.getLogger(__name__)
11
11
 
@@ -1,12 +1,14 @@
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 TYPE_CHECKING, Any, Literal, Optional, Type
6
+
7
+ from comtypes import GUID, COMObject, IUnknown, hresult
8
+ from comtypes.server import IClassFactory
9
9
 
10
+ if TYPE_CHECKING:
11
+ from ctypes import _Pointer
10
12
 
11
13
  logger = logging.getLogger(__name__)
12
14
  _debug = logger.debug
@@ -18,33 +20,39 @@ _critical = logger.critical
18
20
  class ClassFactory(COMObject):
19
21
  _com_interfaces_ = [IClassFactory]
20
22
 
21
- def __init__(self, cls):
23
+ def __init__(self, cls: Type[COMObject]) -> None:
22
24
  super(ClassFactory, self).__init__()
23
25
  self._cls = cls
24
26
 
25
- def IClassFactory_CreateInstance(self, this, punkOuter, riid, ppv):
27
+ def IClassFactory_CreateInstance(
28
+ self,
29
+ this: Any,
30
+ punkOuter: Optional[Type["_Pointer[IUnknown]"]],
31
+ riid: "_Pointer[GUID]",
32
+ ppv: ctypes.c_void_p,
33
+ ) -> int:
26
34
  _debug("ClassFactory.CreateInstance(%s)", riid[0])
27
35
  result = self._cls().IUnknown_QueryInterface(None, riid, ppv)
28
36
  _debug("CreateInstance() -> %s", result)
29
37
  return result
30
38
 
31
- def IClassFactory_LockServer(self, this, fLock):
39
+ def IClassFactory_LockServer(self, this: Any, fLock: bool) -> Literal[0]:
32
40
  if fLock:
33
41
  COMObject.__server__.Lock()
34
42
  else:
35
43
  COMObject.__server__.Unlock()
36
- return S_OK
44
+ return hresult.S_OK
37
45
 
38
46
 
39
47
  # will be set by py2exe boot script 'from outside'
40
48
  _clsid_to_class = {}
41
49
 
42
50
 
43
- def inproc_find_class(clsid):
51
+ def inproc_find_class(clsid: GUID) -> Type[COMObject]:
44
52
  if _clsid_to_class:
45
53
  return _clsid_to_class[clsid]
46
54
 
47
- key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, "CLSID\\%s\\InprocServer32" % clsid)
55
+ key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, f"CLSID\\{clsid}\\InprocServer32")
48
56
  try:
49
57
  pathdir = winreg.QueryValueEx(key, "PythonPath")[0]
50
58
  except:
@@ -70,7 +78,7 @@ def inproc_find_class(clsid):
70
78
  _logging_configured = False
71
79
 
72
80
 
73
- def _setup_logging(clsid):
81
+ def _setup_logging(clsid: GUID) -> None:
74
82
  """Read from the registry, and configure the logging module.
75
83
 
76
84
  Currently, the handler (NTDebugHandler) is hardcoded.
@@ -109,7 +117,7 @@ def _setup_logging(clsid):
109
117
  logging.getLogger(name).setLevel(level)
110
118
 
111
119
 
112
- def DllGetClassObject(rclsid, riid, ppv):
120
+ def DllGetClassObject(rclsid: int, riid: int, ppv: int) -> int:
113
121
  COMObject.__run_inprocserver__()
114
122
 
115
123
  iid = GUID.from_address(riid)
@@ -127,7 +135,7 @@ def DllGetClassObject(rclsid, riid, ppv):
127
135
 
128
136
  cls = inproc_find_class(clsid)
129
137
  if not cls:
130
- return CLASS_E_CLASSNOTAVAILABLE
138
+ return hresult.CLASS_E_CLASSNOTAVAILABLE
131
139
 
132
140
  result = ClassFactory(cls).IUnknown_QueryInterface(
133
141
  None, ctypes.pointer(iid), ctypes.c_void_p(ppv)
@@ -136,12 +144,12 @@ def DllGetClassObject(rclsid, riid, ppv):
136
144
  return result
137
145
  except Exception:
138
146
  _critical("DllGetClassObject", exc_info=True)
139
- return E_FAIL
147
+ return hresult.E_FAIL
140
148
 
141
149
 
142
- def DllCanUnloadNow():
150
+ def DllCanUnloadNow() -> Literal[1]: # S_FALSE
143
151
  COMObject.__run_inprocserver__()
144
152
  result = COMObject.__server__.DllCanUnloadNow()
145
153
  # To avoid a memory leak when PyInitialize()/PyUninitialize() are
146
154
  # called several times, we refuse to unload the dll.
147
- return S_FALSE
155
+ return hresult.S_FALSE
@@ -1,10 +1,23 @@
1
- import sys
2
- from ctypes import *
3
- import comtypes
4
- from comtypes.hresult import *
5
- from comtypes.server import IClassFactory
6
1
  import logging
7
2
  import queue
3
+ from ctypes import (
4
+ HRESULT,
5
+ POINTER,
6
+ OleDLL,
7
+ byref,
8
+ c_ulong,
9
+ c_void_p,
10
+ )
11
+ from ctypes.wintypes import DWORD, LPDWORD
12
+ from typing import TYPE_CHECKING, Any, Literal, Optional, Sequence, Type
13
+
14
+ import comtypes
15
+ from comtypes import GUID, hresult
16
+ from comtypes.server import IClassFactory
17
+
18
+ if TYPE_CHECKING:
19
+ from ctypes import _Pointer
20
+
8
21
 
9
22
  logger = logging.getLogger(__name__)
10
23
  _debug = logger.debug
@@ -15,38 +28,49 @@ REGCLS_MULTI_SEPARATE = 2 # multiple use, but separate control over each
15
28
  REGCLS_SUSPENDED = 4 # register it as suspended, will be activated
16
29
  REGCLS_SURROGATE = 8 # must be used when a surrogate process
17
30
 
31
+ _ole32 = OleDLL("ole32")
32
+
33
+ REFCLSID = POINTER(GUID)
34
+ _CoRegisterClassObject = _ole32.CoRegisterClassObject
35
+ _CoRegisterClassObject.argtypes = [REFCLSID, c_void_p, DWORD, DWORD, LPDWORD]
36
+ _CoRegisterClassObject.restype = HRESULT
37
+
38
+ _CoRevokeClassObject = _ole32.CoRevokeClassObject
39
+ _CoRevokeClassObject.argtypes = [DWORD]
40
+ _CoRevokeClassObject.restype = HRESULT
41
+
18
42
 
19
- def run(classes):
43
+ def run(classes: Sequence[Type[comtypes.COMObject]]) -> None:
20
44
  classobjects = [ClassFactory(cls) for cls in classes]
21
45
  comtypes.COMObject.__run_localserver__(classobjects)
22
46
 
23
47
 
24
48
  class ClassFactory(comtypes.COMObject):
25
49
  _com_interfaces_ = [IClassFactory]
26
- _locks = 0
27
- _queue = None
28
- regcls = REGCLS_MULTIPLEUSE
50
+ _locks: int = 0
51
+ _queue: Optional[queue.Queue] = None
52
+ regcls: int = REGCLS_MULTIPLEUSE
29
53
 
30
- def __init__(self, cls, *args, **kw):
54
+ def __init__(self, cls: Type[comtypes.COMObject], *args, **kw) -> None:
31
55
  super(ClassFactory, self).__init__()
32
56
  self._cls = cls
33
57
  self._register_class()
34
58
  self._args = args
35
59
  self._kw = kw
36
60
 
37
- def IUnknown_AddRef(self, this):
61
+ def IUnknown_AddRef(self, this: Any) -> int:
38
62
  return 2
39
63
 
40
- def IUnknown_Release(self, this):
64
+ def IUnknown_Release(self, this: Any) -> int:
41
65
  return 1
42
66
 
43
- def _register_class(self):
67
+ def _register_class(self) -> None:
44
68
  regcls = getattr(self._cls, "_regcls_", self.regcls)
45
69
  cookie = c_ulong()
46
70
  ptr = self._com_pointers_[comtypes.IUnknown._iid_]
47
71
  clsctx = self._cls._reg_clsctx_
48
72
  clsctx &= ~comtypes.CLSCTX_INPROC # reset the inproc flags
49
- oledll.ole32.CoRegisterClassObject(
73
+ _CoRegisterClassObject(
50
74
  byref(comtypes.GUID(self._cls._reg_clsid_)),
51
75
  ptr,
52
76
  clsctx,
@@ -55,19 +79,25 @@ class ClassFactory(comtypes.COMObject):
55
79
  )
56
80
  self.cookie = cookie
57
81
 
58
- def _revoke_class(self):
59
- oledll.ole32.CoRevokeClassObject(self.cookie)
82
+ def _revoke_class(self) -> None:
83
+ _CoRevokeClassObject(self.cookie)
60
84
 
61
- def CreateInstance(self, this, punkOuter, riid, ppv):
85
+ def CreateInstance(
86
+ self,
87
+ this: Any,
88
+ punkOuter: Optional[Type["_Pointer[comtypes.IUnknown]"]],
89
+ riid: "_Pointer[comtypes.GUID]",
90
+ ppv: c_void_p,
91
+ ) -> int:
62
92
  _debug("ClassFactory.CreateInstance(%s)", riid[0])
63
93
  obj = self._cls(*self._args, **self._kw)
64
94
  result = obj.IUnknown_QueryInterface(None, riid, ppv)
65
95
  _debug("CreateInstance() -> %s", result)
66
96
  return result
67
97
 
68
- def LockServer(self, this, fLock):
98
+ def LockServer(self, this: Any, fLock: bool) -> Literal[0]:
69
99
  if fLock:
70
100
  comtypes.COMObject.__server__.Lock()
71
101
  else:
72
102
  comtypes.COMObject.__server__.Unlock()
73
- return S_OK
103
+ return hresult.S_OK