comtypes 1.4.11__zip → 1.4.12__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 (150) hide show
  1. {comtypes-1.4.11 → comtypes-1.4.12}/CHANGES.txt +26 -0
  2. {comtypes-1.4.11/comtypes.egg-info → comtypes-1.4.12}/PKG-INFO +2 -2
  3. {comtypes-1.4.11 → comtypes-1.4.12}/README.md +1 -1
  4. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/__init__.py +8 -2
  5. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/_comobject.py +6 -6
  6. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/_memberspec.py +7 -7
  7. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/_npsupport.py +12 -17
  8. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/_post_coinit/_cominterface_meta_patcher.py +5 -5
  9. comtypes-1.4.12/comtypes/_post_coinit/activeobj.py +61 -0
  10. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/_post_coinit/misc.py +1 -23
  11. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/_post_coinit/unknwn.py +4 -6
  12. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/_vtbl.py +3 -3
  13. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/automation.py +10 -13
  14. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/client/__init__.py +2 -1
  15. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/client/_activeobj.py +8 -0
  16. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/client/_code_cache.py +1 -1
  17. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/client/_constants.py +1 -1
  18. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/client/_events.py +6 -6
  19. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/client/_generate.py +1 -1
  20. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/client/dynamic.py +3 -3
  21. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/client/lazybind.py +3 -3
  22. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/errorinfo.py +1 -1
  23. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/hresult.py +68 -0
  24. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/messageloop.py +1 -1
  25. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/patcher.py +2 -2
  26. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/persist.py +9 -2
  27. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/safearray.py +10 -10
  28. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/server/__init__.py +5 -37
  29. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/server/automation.py +2 -2
  30. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/server/connectionpoints.py +3 -3
  31. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/server/inprocserver.py +2 -2
  32. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/server/localserver.py +3 -3
  33. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/server/register.py +5 -5
  34. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_agilent.py +1 -1
  35. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_client_dynamic.py +1 -1
  36. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_comserver.py +7 -2
  37. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_createwrappers.py +1 -1
  38. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_dispifc_records.py +0 -2
  39. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_dispifc_safearrays.py +0 -2
  40. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_dispinterface.py +1 -1
  41. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_excel.py +1 -3
  42. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_getactiveobj.py +19 -2
  43. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_hresult.py +39 -0
  44. comtypes-1.4.12/comtypes/test/test_messageloop.py +117 -0
  45. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_midl_safearray_create.py +0 -2
  46. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_msscript.py +1 -1
  47. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_npsupport.py +22 -11
  48. comtypes-1.4.12/comtypes/test/test_persist.py +71 -0
  49. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_recordinfo.py +0 -2
  50. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_server.py +6 -6
  51. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_storage.py +1 -1
  52. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_stream.py +22 -2
  53. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_urlhistory.py +1 -1
  54. comtypes-1.4.12/comtypes/test/test_util.py +227 -0
  55. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_variant.py +41 -24
  56. comtypes-1.4.12/comtypes/test/test_viewobject.py +78 -0
  57. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_word.py +1 -1
  58. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/tools/codegenerator/codegenerator.py +1 -1
  59. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/tools/codegenerator/comments.py +1 -1
  60. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/tools/codegenerator/heads.py +5 -5
  61. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/tools/codegenerator/helpers.py +7 -7
  62. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/tools/codegenerator/namespaces.py +3 -3
  63. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/tools/codegenerator/typeannotator.py +2 -2
  64. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/tools/tlbparser.py +1 -1
  65. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/tools/typedesc.py +14 -14
  66. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/tools/typedesc_base.py +19 -19
  67. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/util.py +38 -6
  68. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/viewobject.py +29 -5
  69. {comtypes-1.4.11 → comtypes-1.4.12/comtypes.egg-info}/PKG-INFO +2 -2
  70. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes.egg-info/SOURCES.txt +4 -0
  71. {comtypes-1.4.11 → comtypes-1.4.12}/pyproject.toml +12 -1
  72. comtypes-1.4.11/comtypes/test/test_persist.py +0 -38
  73. {comtypes-1.4.11 → comtypes-1.4.12}/LICENSE.txt +0 -0
  74. {comtypes-1.4.11 → comtypes-1.4.12}/MANIFEST.in +0 -0
  75. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/GUID.py +0 -0
  76. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/_meta.py +0 -0
  77. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/_post_coinit/__init__.py +0 -0
  78. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/_post_coinit/bstr.py +0 -0
  79. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/_post_coinit/instancemethod.py +0 -0
  80. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/_safearray.py +0 -0
  81. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/_tlib_version_checker.py +0 -0
  82. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/clear_cache.py +0 -0
  83. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/client/_create.py +0 -0
  84. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/client/_managing.py +0 -0
  85. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/connectionpoints.py +0 -0
  86. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/git.py +0 -0
  87. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/hints.pyi +0 -0
  88. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/logutil.py +0 -0
  89. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/server/w_getopt.py +0 -0
  90. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/shelllink.py +0 -0
  91. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/stream.py +0 -0
  92. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/TestComServer.idl +0 -0
  93. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/TestComServer.py +0 -0
  94. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/TestComServer.tlb +0 -0
  95. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/TestDispServer.idl +0 -0
  96. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/TestDispServer.py +0 -0
  97. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/TestDispServer.tlb +0 -0
  98. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/__init__.py +0 -0
  99. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/find_memleak.py +0 -0
  100. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/mylib.idl +0 -0
  101. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/mylib.tlb +0 -0
  102. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/mytypelib.idl +0 -0
  103. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/runtests.py +0 -0
  104. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/setup.py +0 -0
  105. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_BSTR.py +0 -0
  106. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_DISPPARAMS.py +0 -0
  107. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_GUID.py +0 -0
  108. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_QueryService.py +0 -0
  109. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_avmc.py +0 -0
  110. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_basic.py +0 -0
  111. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_casesensitivity.py +0 -0
  112. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_clear_cache.py +0 -0
  113. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_client.py +0 -0
  114. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_client_regenerate_modules.py +0 -0
  115. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_collections.py +0 -0
  116. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_comobject.py +0 -0
  117. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_dict.py +0 -0
  118. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_dyndispatch.py +0 -0
  119. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_errorinfo.py +0 -0
  120. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_findgendir.py +0 -0
  121. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_ie.py +0 -0
  122. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_ienum.py +0 -0
  123. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_imfattributes.py +0 -0
  124. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_inout_args.py +0 -0
  125. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_jscript.js +0 -0
  126. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_monikers.py +0 -0
  127. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_outparam.py +0 -0
  128. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_pump_events.py +0 -0
  129. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_safearray.py +0 -0
  130. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_sapi.py +0 -0
  131. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_server_register.py +0 -0
  132. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_shelllink.py +0 -0
  133. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_showevents.py +0 -0
  134. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_subinterface.py +0 -0
  135. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_typeannotator.py +0 -0
  136. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_typeinfo.py +0 -0
  137. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_w_getopt.py +0 -0
  138. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_win32com_interop.py +0 -0
  139. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/test_wmi.py +0 -0
  140. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/test/urlhist.tlb +0 -0
  141. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/tools/__init__.py +0 -0
  142. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/tools/codegenerator/__init__.py +0 -0
  143. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/tools/codegenerator/modulenamer.py +0 -0
  144. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/tools/codegenerator/packing.py +0 -0
  145. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes/typeinfo.py +0 -0
  146. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes.egg-info/dependency_links.txt +0 -0
  147. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes.egg-info/entry_points.txt +0 -0
  148. {comtypes-1.4.11 → comtypes-1.4.12}/comtypes.egg-info/top_level.txt +0 -0
  149. {comtypes-1.4.11 → comtypes-1.4.12}/setup.cfg +0 -0
  150. {comtypes-1.4.11 → comtypes-1.4.12}/setup.py +0 -0
@@ -12,7 +12,7 @@ from comtypes.automation import (
12
12
  from comtypes.typeinfo import FUNC_DISPATCH, FUNC_PUREVIRTUAL
13
13
 
14
14
 
15
- class FuncDesc(object):
15
+ class FuncDesc:
16
16
  """Stores important FUNCDESC properties by copying them from a
17
17
  real FUNCDESC instance.
18
18
  """
@@ -28,7 +28,7 @@ class FuncDesc(object):
28
28
  _all_slice = slice(None, None, None)
29
29
 
30
30
 
31
- class NamedProperty(object):
31
+ class NamedProperty:
32
32
  def __init__(self, disp, get, put, putref):
33
33
  self.get = get
34
34
  self.put = put
@@ -83,7 +83,7 @@ class NamedProperty(object):
83
83
  # objects do not (could be added, would probably be expensive)
84
84
 
85
85
 
86
- class Dispatch(object):
86
+ class Dispatch:
87
87
  """Dynamic dispatch for an object the exposes type information.
88
88
  Binding at runtime is done via ITypeComp::Bind calls.
89
89
  """
@@ -126,7 +126,7 @@ def ReportError(
126
126
  clsid = GUID(clsid)
127
127
  try:
128
128
  progid = clsid.as_progid()
129
- except WindowsError:
129
+ except OSError:
130
130
  pass
131
131
  else:
132
132
  # progid for the class or application that created the error
@@ -89,3 +89,71 @@ def HRESULT_FROM_WIN32(x: int) -> int:
89
89
  # them into HRESULT values by setting the high bit, ensuring a consistent way
90
90
  # to indicate failure across these APIs.
91
91
  RPC_S_SERVER_UNAVAILABLE = -2147023174 # 0x800706BA (WIN32: 1722 0x6BA)
92
+
93
+
94
+ ################################################################
95
+ # signed32bithex
96
+ #
97
+ # When using this package, error codes for exceptions like
98
+ # `COMError` or `WindowsError` are base10 integers.
99
+ #
100
+ # However, as shown below, many technical references represent
101
+ # HRESULT values using signed 32-bit hexadecimal notation:
102
+ # https://learn.microsoft.com/en-us/windows/win32/seccrypto/common-hresult-values
103
+ # https://learn.microsoft.com/en-us/windows/win32/learnwin32/error-codes-in-com
104
+ #
105
+ # If you search for the error code using the proper notation,
106
+ # you might be able to find the reference.
107
+ #
108
+ # Don't be overly afraid of `COMError` or `WindowsError`!
109
+
110
+
111
+ def signed32bithex_to_int(value: str, /) -> int:
112
+ """Converts a string in signed 32-bit hexadecimal notation to an integer.
113
+
114
+ Examples:
115
+
116
+ >>> signed32bithex_to_int('0x00000000') == 0 # S_OK
117
+ True
118
+ >>> signed32bithex_to_int('0x00000001') == 1 # S_FALSE
119
+ True
120
+ >>> signed32bithex_to_int('0x8000FFFF') == -2147418113 # E_UNEXPECTED
121
+ True
122
+ """
123
+ val = int(value, 16)
124
+ if val < 0x80000000:
125
+ return val
126
+ return val - 0x100000000
127
+
128
+
129
+ def int_to_signed32bithex(value: int, /) -> str:
130
+ """Converts an integer to a string in signed 32-bit hexadecimal notation.
131
+
132
+ Examples:
133
+
134
+ >>> import comtypes.hresult as hr
135
+ >>> int_to_signed32bithex(hr.S_OK)
136
+ '0x00000000'
137
+ >>> int_to_signed32bithex(hr.S_FALSE)
138
+ '0x00000001'
139
+ >>> int_to_signed32bithex(hr.E_UNEXPECTED)
140
+ '0x8000FFFF'
141
+
142
+ >>> from comtypes import CoCreateInstance
143
+ >>> from comtypes import shelllink, automation
144
+ >>> CLSID_ShellLink = shelllink.ShellLink().IPersist_GetClassID()
145
+ >>> p = CoCreateInstance(CLSID_ShellLink)
146
+ >>> p.QueryInterface(shelllink.IShellLinkA) # doctest: +ELLIPSIS
147
+ <POINTER(IShellLinkA) ptr=0x... at ...>
148
+ >>> p.QueryInterface(automation.IDispatch) # doctest: +ELLIPSIS
149
+ Traceback (most recent call last):
150
+ ...
151
+ _ctypes.COMError: (-2147467262, ..., (None, None, None, 0, None))
152
+ >>> int_to_signed32bithex(-2147467262) # E_NOINTERFACE
153
+ '0x80004002'
154
+ """
155
+ # it is simpler than using `hex(value & 0xFFFFFFFF)`
156
+ return f"0x{value & 0xFFFFFFFF:08X}"
157
+
158
+
159
+ ################################################################
@@ -17,7 +17,7 @@ TranslateMessage = _user32.TranslateMessage
17
17
  DispatchMessage = _user32.DispatchMessageA
18
18
 
19
19
 
20
- class _MessageLoop(object):
20
+ class _MessageLoop:
21
21
  def __init__(self) -> None:
22
22
  self._filters: List["_FilterCallable"] = []
23
23
 
@@ -1,4 +1,4 @@
1
- class Patch(object):
1
+ class Patch:
2
2
  """
3
3
  Implements a class decorator suitable for patching an existing class with
4
4
  a new namespace.
@@ -69,7 +69,7 @@ def no_replace(f):
69
69
  return f
70
70
 
71
71
 
72
- class ReferenceEmptyClass(object):
72
+ class ReferenceEmptyClass:
73
73
  """
74
74
  This empty class will serve as a reference for attributes present on
75
75
  any class.
@@ -12,7 +12,7 @@ interface, useful in client code.
12
12
 
13
13
  from ctypes import POINTER, Structure, c_int, c_ulong, c_ushort, c_wchar_p
14
14
  from ctypes.wintypes import BOOL, DWORD, WORD
15
- from typing import TYPE_CHECKING
15
+ from typing import TYPE_CHECKING, Any, Optional
16
16
 
17
17
  from comtypes import COMMETHOD, GUID, HRESULT, IPersist, IUnknown
18
18
  from comtypes.automation import VARIANT, tagEXCEPINFO
@@ -65,6 +65,13 @@ class IPropertyBag(IUnknown):
65
65
  ),
66
66
  ]
67
67
 
68
+ if TYPE_CHECKING:
69
+
70
+ def Read(
71
+ self, pszPropName: str, pVar: VARIANT, pErrorLog: Optional[IErrorLog]
72
+ ) -> Any: ...
73
+ def Write(self, pszPropName: str, pVar: Any) -> hints.Hresult: ...
74
+
68
75
 
69
76
  class IPersistPropertyBag(IPersist):
70
77
  _iid_ = GUID("{37D84F60-42CB-11CE-8135-00AA004BB851}")
@@ -266,7 +273,7 @@ class DictPropertyBag(COMObject):
266
273
  _com_interfaces_ = [IPropertyBag]
267
274
 
268
275
  def __init__(self, **kw):
269
- super(DictPropertyBag, self).__init__()
276
+ super().__init__()
270
277
  self.values = kw
271
278
 
272
279
  def Read(self, this, name, pVar, errorlog):
@@ -17,7 +17,7 @@ if TYPE_CHECKING:
17
17
  _safearray_type_cache = {}
18
18
 
19
19
 
20
- class _SafeArrayAsNdArrayContextManager(object):
20
+ class _SafeArrayAsNdArrayContextManager:
21
21
  """Context manager allowing safe arrays to be extracted as ndarrays.
22
22
 
23
23
  This is thread-safe.
@@ -110,7 +110,7 @@ def _make_safearray_type(itemtype):
110
110
  raise TypeError(itemtype)
111
111
 
112
112
  @Patch(POINTER(sa_type))
113
- class _(object):
113
+ class _:
114
114
  # Should explain the ideas how SAFEARRAY is used in comtypes
115
115
  _itemtype_ = itemtype # a ctypes type
116
116
  _vartype_ = vartype # a VARTYPE value: VT_...
@@ -378,7 +378,7 @@ def _make_safearray_type(itemtype):
378
378
  return tuple(result) # for compatibility with pywin32.
379
379
 
380
380
  @Patch(POINTER(POINTER(sa_type)))
381
- class __(object):
381
+ class __:
382
382
  @classmethod
383
383
  def from_param(cls, value):
384
384
  if isinstance(value, cls._type_):
@@ -398,19 +398,19 @@ def _make_safearray_type(itemtype):
398
398
  def _ndarray_to_variant_array(value):
399
399
  """Convert an ndarray to VARIANT_dtype array"""
400
400
  # Check that variant arrays are supported
401
- if comtypes.npsupport.interop.VARIANT_dtype is None:
401
+ if comtypes.npsupport.VARIANT_dtype is None:
402
402
  msg = "VARIANT ndarrays require NumPy 1.7 or newer."
403
403
  raise RuntimeError(msg)
404
- numpy = comtypes.npsupport.interop.numpy
404
+ numpy = comtypes.npsupport.numpy
405
405
 
406
406
  # special cases
407
- if numpy.issubdtype(value.dtype, comtypes.npsupport.interop.datetime64):
407
+ if numpy.issubdtype(value.dtype, comtypes.npsupport.datetime64):
408
408
  return _datetime64_ndarray_to_variant_array(value)
409
409
 
410
410
  from comtypes.automation import VARIANT
411
411
 
412
412
  # Empty array
413
- varr = numpy.zeros(value.shape, comtypes.npsupport.interop.VARIANT_dtype, order="F")
413
+ varr = numpy.zeros(value.shape, comtypes.npsupport.VARIANT_dtype, order="F")
414
414
  # Convert each value to a variant and put it in the array.
415
415
  varr.flat = [VARIANT(v) for v in value.flat]
416
416
  return varr
@@ -423,12 +423,12 @@ def _datetime64_ndarray_to_variant_array(value):
423
423
  # fractional days.
424
424
  from comtypes.automation import VT_DATE
425
425
 
426
- numpy = comtypes.npsupport.interop.numpy
426
+ numpy = comtypes.npsupport.numpy
427
427
  value = numpy.array(value, "datetime64[ns]")
428
- value = value - comtypes.npsupport.interop.com_null_date64
428
+ value = value - comtypes.npsupport.com_null_date64
429
429
  # Convert to days
430
430
  value = value / numpy.timedelta64(1, "D")
431
- varr = numpy.zeros(value.shape, comtypes.npsupport.interop.VARIANT_dtype, order="F")
431
+ varr = numpy.zeros(value.shape, comtypes.npsupport.VARIANT_dtype, order="F")
432
432
  varr["vt"] = VT_DATE
433
433
  varr["_"]["VT_R8"].flat = value.flat
434
434
  return varr
@@ -1,14 +1,13 @@
1
1
  import ctypes
2
- from ctypes import HRESULT, POINTER, OleDLL, byref, c_void_p
3
- from ctypes.wintypes import DWORD, LPVOID
2
+ from ctypes import HRESULT, POINTER, byref
4
3
  from typing import TYPE_CHECKING, Any, Optional, Type
5
4
 
6
5
  import comtypes
7
6
  import comtypes.client
8
7
  import comtypes.client.dynamic
9
8
  from comtypes import GUID, STDMETHOD, IUnknown
9
+ from comtypes import RevokeActiveObject as RevokeActiveObject
10
10
  from comtypes.automation import IDispatch
11
- from comtypes.GUID import REFCLSID
12
11
 
13
12
  if TYPE_CHECKING:
14
13
  from ctypes import _Pointer
@@ -64,41 +63,10 @@ class IClassFactory(IUnknown):
64
63
  # STDMETHOD(HRESULT, "AddConnection", [c_ulong, c_ulong]),
65
64
  # STDMETHOD(HRESULT, "ReleaseConnection", [c_ulong, c_ulong, c_ulong])]
66
65
 
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
66
 
91
67
  def RegisterActiveObject(comobj: comtypes.COMObject, weak: bool = True) -> int:
68
+ """Registers a pointer as the active object for its class and returns the handle."""
92
69
  punk = comobj._com_pointers_[IUnknown._iid_]
93
70
  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)
71
+ flags = comtypes.ACTIVEOBJECT_WEAK if weak else comtypes.ACTIVEOBJECT_STRONG
72
+ return comtypes.RegisterActiveObject(punk, clsid, flags)
@@ -22,7 +22,7 @@ class VARIANTEnumerator(COMObject):
22
22
  items # keep, so that we can restore our iterator (in Reset, and Clone).
23
23
  )
24
24
  self.seq = iter(self.items)
25
- super(VARIANTEnumerator, self).__init__()
25
+ super().__init__()
26
26
 
27
27
  def Next(self, this, celt, rgVar, pCeltFetched):
28
28
  if not rgVar:
@@ -75,7 +75,7 @@ class COMCollection(COMObject):
75
75
  def __init__(self, itemtype, collection):
76
76
  self.collection = collection
77
77
  self.itemtype = itemtype
78
- super(COMCollection, self).__init__()
78
+ super().__init__()
79
79
 
80
80
  def _get_Item(self, this, pathname, pitem):
81
81
  if not pitem:
@@ -31,7 +31,7 @@ class ConnectionPointImpl(COMObject):
31
31
  def __init__(
32
32
  self, sink_interface: Type[IUnknown], sink_typeinfo: ITypeInfo
33
33
  ) -> None:
34
- super(ConnectionPointImpl, self).__init__()
34
+ super().__init__()
35
35
  self._connections: Dict[int, IUnknown] = {}
36
36
  self._cookie = 0
37
37
  self._sink_interface = sink_interface
@@ -109,7 +109,7 @@ class ConnectionPointImpl(COMObject):
109
109
  yield result
110
110
 
111
111
 
112
- class ConnectableObjectMixin(object):
112
+ class ConnectableObjectMixin:
113
113
  """Mixin which implements IConnectionPointContainer.
114
114
 
115
115
  Call Fire_Event(interface, methodname, *args, **kw) to fire an
@@ -122,7 +122,7 @@ class ConnectableObjectMixin(object):
122
122
  _reg_typelib_: ClassVar[Tuple[str, int, int]]
123
123
 
124
124
  def __init__(self) -> None:
125
- super(ConnectableObjectMixin, self).__init__()
125
+ super().__init__()
126
126
  self.__connections: Dict[Type[IDispatch], ConnectionPointImpl] = {}
127
127
 
128
128
  tlib = LoadRegTypeLib(*self._reg_typelib_)
@@ -22,7 +22,7 @@ class ClassFactory(COMObject):
22
22
  _com_interfaces_ = [IClassFactory]
23
23
 
24
24
  def __init__(self, cls: Type[COMObject]) -> None:
25
- super(ClassFactory, self).__init__()
25
+ super().__init__()
26
26
  self._cls = cls
27
27
 
28
28
  def IClassFactory_CreateInstance(
@@ -92,7 +92,7 @@ def _setup_logging(clsid: GUID) -> None:
92
92
 
93
93
  try:
94
94
  hkey = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, r"CLSID\%s\Logging" % clsid)
95
- except WindowsError:
95
+ except OSError:
96
96
  return
97
97
  from comtypes.logutil import NTDebugHandler
98
98
 
@@ -1,11 +1,12 @@
1
1
  import logging
2
2
  import queue
3
- from ctypes import HRESULT, POINTER, OleDLL, byref, c_ulong, c_void_p
3
+ from ctypes import HRESULT, OleDLL, byref, c_ulong, c_void_p
4
4
  from ctypes.wintypes import DWORD, LPDWORD
5
5
  from typing import TYPE_CHECKING, Any, Literal, Optional, Sequence, Type
6
6
 
7
7
  import comtypes
8
8
  from comtypes import GUID, COMObject, IUnknown, hresult
9
+ from comtypes.GUID import REFCLSID
9
10
  from comtypes.server import IClassFactory
10
11
 
11
12
  if TYPE_CHECKING:
@@ -23,7 +24,6 @@ REGCLS_SURROGATE = 8 # must be used when a surrogate process
23
24
 
24
25
  _ole32 = OleDLL("ole32")
25
26
 
26
- REFCLSID = POINTER(GUID)
27
27
  _CoRegisterClassObject = _ole32.CoRegisterClassObject
28
28
  _CoRegisterClassObject.argtypes = [REFCLSID, c_void_p, DWORD, DWORD, LPDWORD]
29
29
  _CoRegisterClassObject.restype = HRESULT
@@ -45,7 +45,7 @@ class ClassFactory(COMObject):
45
45
  regcls: int = REGCLS_MULTIPLEUSE
46
46
 
47
47
  def __init__(self, cls: Type[COMObject], *args, **kw) -> None:
48
- super(ClassFactory, self).__init__()
48
+ super().__init__()
49
49
  self._cls = cls
50
50
  self._register_class()
51
51
  self._args = args
@@ -105,7 +105,7 @@ def _delete_key(hkey: int, subkey: str, *, force: bool) -> None:
105
105
  else:
106
106
  _debug("DeleteKey %s\\%s", _explain(hkey), subkey)
107
107
  winreg.DeleteKey(hkey, subkey)
108
- except WindowsError as detail:
108
+ except OSError as detail:
109
109
  if get_winerror(detail) != 2:
110
110
  raise
111
111
 
@@ -113,7 +113,7 @@ def _delete_key(hkey: int, subkey: str, *, force: bool) -> None:
113
113
  _Entry = Tuple[int, str, str, str]
114
114
 
115
115
 
116
- class Registrar(object):
116
+ class Registrar:
117
117
  """COM class registration.
118
118
 
119
119
  The COM class can override what this does by implementing
@@ -142,7 +142,7 @@ class Registrar(object):
142
142
  _debug('DeleteKey( %s\\CLSID\\%s\\Logging"' % (_explain(HKCR), clsid))
143
143
  hkey = winreg.OpenKey(HKCR, rf"CLSID\{clsid}")
144
144
  winreg.DeleteKey(hkey, "Logging")
145
- except WindowsError as detail:
145
+ except OSError as detail:
146
146
  if get_winerror(detail) != 2:
147
147
  raise
148
148
 
@@ -166,7 +166,7 @@ class Registrar(object):
166
166
  _debug("DeleteValue(format)")
167
167
  try:
168
168
  winreg.DeleteValue(hkey, "format")
169
- except WindowsError as detail:
169
+ except OSError as detail:
170
170
  if get_winerror(detail) != 2:
171
171
  raise
172
172
 
@@ -231,7 +231,7 @@ class Registrar(object):
231
231
  try:
232
232
  _debug("UnRegisterTypeLib(%s, %s, %s)", *tlib)
233
233
  UnRegisterTypeLib(*tlib)
234
- except WindowsError as detail:
234
+ except OSError as detail:
235
235
  if not get_winerror(detail) in (
236
236
  TYPE_E_REGISTRYACCESS,
237
237
  TYPE_E_CANTLOADLIBRARY,
@@ -12,7 +12,7 @@ from comtypes.test import ResourceDenied
12
12
 
13
13
  try:
14
14
  GUID.from_progid("Agilent546XX.Agilent546XX")
15
- except WindowsError:
15
+ except OSError:
16
16
  pass
17
17
 
18
18
  else:
@@ -26,7 +26,7 @@ class Test_Dispatch_Function(ut.TestCase):
26
26
 
27
27
  def test_returns_dynamic_Dispatch_if_takes_ptrIDispatch_and_raised_winerr(self):
28
28
  obj = mock.MagicMock(spec=ctypes.POINTER(automation.IDispatch))
29
- obj.GetTypeInfo.side_effect = WindowsError()
29
+ obj.GetTypeInfo.side_effect = OSError()
30
30
  self.assertIsInstance(dynamic.Dispatch(obj), dynamic._Dispatch)
31
31
 
32
32
  def test_returns_what_is_took_if_takes_other(self):
@@ -22,7 +22,7 @@ except ImportError:
22
22
  def setUpModule():
23
23
  try:
24
24
  register(comtypes.test.TestComServer.TestComServer)
25
- except WindowsError as e:
25
+ except OSError as e:
26
26
  if e.winerror != 5: # [Error 5] Access is denied
27
27
  raise e
28
28
  raise unittest.SkipTest(
@@ -35,7 +35,7 @@ def tearDownModule():
35
35
  unregister(comtypes.test.TestComServer.TestComServer)
36
36
 
37
37
 
38
- class BaseServerTest(object):
38
+ class BaseServerTest:
39
39
  def create_object(self) -> Any: ...
40
40
 
41
41
  def _find_memleak(self, func):
@@ -116,6 +116,11 @@ class TestInproc(BaseServerTest, unittest.TestCase):
116
116
  "TestComServerLib.TestComServer", clsctx=comtypes.CLSCTX_INPROC_SERVER
117
117
  )
118
118
 
119
+ @unittest.skip("Fails occasionally with a memory leak on INPROC.")
120
+ def test_eval(self):
121
+ # This test sometimes leaks memory when run as an in-process server.
122
+ pass
123
+
119
124
 
120
125
  class TestLocalServer(BaseServerTest, unittest.TestCase):
121
126
  def create_object(self):
@@ -51,7 +51,7 @@ def add_test(fname):
51
51
  def test(self):
52
52
  try:
53
53
  comtypes.typeinfo.LoadTypeLibEx(fname)
54
- except WindowsError:
54
+ except OSError:
55
55
  return
56
56
  comtypes.client.GetModule(fname)
57
57
 
@@ -1,5 +1,3 @@
1
- # coding: utf-8
2
-
3
1
  import unittest
4
2
  from ctypes import byref, pointer
5
3
 
@@ -1,5 +1,3 @@
1
- # coding: utf-8
2
-
3
1
  import unittest
4
2
  from ctypes import byref, c_double, pointer
5
3
 
@@ -16,7 +16,7 @@ except ImportError:
16
16
  def setUpModule():
17
17
  try:
18
18
  register(comtypes.test.TestDispServer.TestDispServer)
19
- except WindowsError as e:
19
+ except OSError as e:
20
20
  if e.winerror != 5: # [Error 5] Access is denied
21
21
  raise e
22
22
  raise unittest.SkipTest(
@@ -1,5 +1,3 @@
1
- # -*- coding: latin-1 -*-
2
-
3
1
  import datetime
4
2
  import sys
5
3
  import unittest
@@ -26,7 +24,7 @@ except (ImportError, OSError):
26
24
  IMPORT_FAILED = True
27
25
 
28
26
 
29
- class BaseBindTest(object):
27
+ class BaseBindTest:
30
28
  # `dynamic = True/False` must be defined in subclasses!
31
29
  dynamic: ClassVar[bool]
32
30
 
@@ -1,9 +1,13 @@
1
+ import contextlib
1
2
  import time
2
3
  import unittest
3
4
 
4
5
  import comtypes
5
6
  import comtypes.client
6
- import comtypes.test
7
+
8
+ with contextlib.redirect_stdout(None): # supress warnings
9
+ comtypes.client.GetModule("msvidctl.dll")
10
+ from comtypes.gen import MSVidCtlLib as msvidctl
7
11
 
8
12
  try:
9
13
  # pass Word libUUID
@@ -29,7 +33,7 @@ class Test_Word(unittest.TestCase):
29
33
  def setUp(self):
30
34
  try:
31
35
  comtypes.client.GetActiveObject("Word.Application")
32
- except WindowsError:
36
+ except OSError:
33
37
  pass
34
38
  else:
35
39
  # seems word is running, we cannot test this.
@@ -67,5 +71,18 @@ class Test_Word(unittest.TestCase):
67
71
  comtypes.client.GetActiveObject("Word.Application")
68
72
 
69
73
 
74
+ class Test_MSVidCtlLib(unittest.TestCase):
75
+ def test_register_and_revoke(self):
76
+ vidctl = comtypes.client.CreateObject(msvidctl.MSVidCtl)
77
+ with self.assertRaises(WindowsError):
78
+ comtypes.client.GetActiveObject(msvidctl.MSVidCtl)
79
+ handle = comtypes.client.RegisterActiveObject(vidctl, msvidctl.MSVidCtl)
80
+ activeobj = comtypes.client.GetActiveObject(msvidctl.MSVidCtl)
81
+ self.assertEqual(vidctl, activeobj)
82
+ comtypes.client.RevokeActiveObject(handle)
83
+ with self.assertRaises(WindowsError):
84
+ comtypes.client.GetActiveObject(msvidctl.MSVidCtl)
85
+
86
+
70
87
  if __name__ == "__main__":
71
88
  unittest.main()
@@ -1,3 +1,4 @@
1
+ import doctest
1
2
  import unittest as ut
2
3
 
3
4
  import comtypes.hresult
@@ -46,3 +47,41 @@ class Test_HRESULT_FROM_WIN32(ut.TestCase):
46
47
  ]:
47
48
  with self.subTest(w32=w32, hr=hr):
48
49
  self.assertEqual(comtypes.hresult.HRESULT_FROM_WIN32(w32), hr)
50
+
51
+
52
+ class Test_signed32bithex_to_int(ut.TestCase):
53
+ def test(self):
54
+ for val, expected in [
55
+ ("0x00000000", comtypes.hresult.S_OK),
56
+ ("0x00000001", comtypes.hresult.S_FALSE),
57
+ ("0x8000FFFF", comtypes.hresult.E_UNEXPECTED),
58
+ ("0x80004002", comtypes.hresult.E_NOINTERFACE),
59
+ # boundary values
60
+ ("0x7FFFFFFF", 2147483647),
61
+ ("0x80000000", -2147483648),
62
+ ("0xFFFFFFFF", -1),
63
+ ]:
64
+ with self.subTest(val=val, expected=expected):
65
+ self.assertEqual(comtypes.hresult.signed32bithex_to_int(val), expected)
66
+
67
+
68
+ class Test_int_to_signed32bithex(ut.TestCase):
69
+ def test(self):
70
+ for val, expected in [
71
+ (comtypes.hresult.S_OK, "0x00000000"),
72
+ (comtypes.hresult.S_FALSE, "0x00000001"),
73
+ (comtypes.hresult.E_UNEXPECTED, "0x8000FFFF"),
74
+ (comtypes.hresult.E_NOINTERFACE, "0x80004002"),
75
+ ]:
76
+ with self.subTest(val=val, expected=expected):
77
+ self.assertEqual(comtypes.hresult.int_to_signed32bithex(val), expected)
78
+
79
+
80
+ class DocTest(ut.TestCase):
81
+ def test(self):
82
+ doctest.testmod(
83
+ comtypes.hresult,
84
+ verbose=False,
85
+ optionflags=doctest.ELLIPSIS,
86
+ raise_on_error=True,
87
+ )