comtypes 1.4.10__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 (151) hide show
  1. {comtypes-1.4.10 → comtypes-1.4.12}/CHANGES.txt +48 -0
  2. {comtypes-1.4.10/comtypes.egg-info → comtypes-1.4.12}/PKG-INFO +4 -3
  3. {comtypes-1.4.10 → comtypes-1.4.12}/README.md +1 -1
  4. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/__init__.py +11 -5
  5. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_comobject.py +29 -31
  6. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_memberspec.py +107 -81
  7. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_meta.py +1 -1
  8. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_npsupport.py +12 -17
  9. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_post_coinit/_cominterface_meta_patcher.py +8 -10
  10. comtypes-1.4.12/comtypes/_post_coinit/activeobj.py +61 -0
  11. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_post_coinit/misc.py +1 -23
  12. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_post_coinit/unknwn.py +33 -26
  13. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_vtbl.py +55 -58
  14. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/automation.py +19 -23
  15. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/__init__.py +2 -1
  16. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/_activeobj.py +8 -0
  17. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/_code_cache.py +10 -24
  18. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/_constants.py +1 -1
  19. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/_events.py +92 -54
  20. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/_generate.py +1 -3
  21. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/dynamic.py +3 -3
  22. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/lazybind.py +3 -3
  23. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/connectionpoints.py +37 -3
  24. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/errorinfo.py +54 -16
  25. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/hints.pyi +15 -2
  26. comtypes-1.4.12/comtypes/hresult.py +159 -0
  27. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/messageloop.py +15 -13
  28. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/patcher.py +2 -2
  29. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/persist.py +9 -2
  30. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/safearray.py +10 -10
  31. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/server/__init__.py +5 -37
  32. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/server/automation.py +2 -2
  33. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/server/connectionpoints.py +71 -70
  34. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/server/inprocserver.py +10 -7
  35. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/server/localserver.py +16 -22
  36. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/server/register.py +7 -7
  37. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_GUID.py +6 -7
  38. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_agilent.py +1 -1
  39. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_basic.py +6 -3
  40. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_client_dynamic.py +1 -1
  41. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_collections.py +6 -3
  42. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_comobject.py +19 -6
  43. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_comserver.py +32 -4
  44. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_createwrappers.py +1 -1
  45. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_dict.py +2 -1
  46. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_dispifc_records.py +0 -2
  47. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_dispifc_safearrays.py +0 -2
  48. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_dispinterface.py +1 -1
  49. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_dyndispatch.py +4 -2
  50. comtypes-1.4.12/comtypes/test/test_errorinfo.py +115 -0
  51. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_excel.py +1 -3
  52. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_getactiveobj.py +19 -2
  53. comtypes-1.4.12/comtypes/test/test_hresult.py +87 -0
  54. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_inout_args.py +9 -2
  55. comtypes-1.4.12/comtypes/test/test_messageloop.py +117 -0
  56. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_midl_safearray_create.py +0 -2
  57. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_msscript.py +1 -1
  58. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_npsupport.py +22 -11
  59. comtypes-1.4.12/comtypes/test/test_persist.py +71 -0
  60. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_recordinfo.py +0 -2
  61. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_safearray.py +2 -1
  62. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_server.py +6 -6
  63. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_server_register.py +2 -1
  64. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_storage.py +1 -1
  65. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_stream.py +22 -2
  66. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_typeinfo.py +19 -2
  67. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_urlhistory.py +1 -1
  68. comtypes-1.4.12/comtypes/test/test_util.py +227 -0
  69. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_variant.py +43 -25
  70. comtypes-1.4.12/comtypes/test/test_viewobject.py +78 -0
  71. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_w_getopt.py +4 -4
  72. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_word.py +1 -1
  73. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/codegenerator.py +1 -1
  74. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/comments.py +1 -1
  75. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/heads.py +5 -5
  76. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/helpers.py +7 -7
  77. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/namespaces.py +3 -3
  78. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/typeannotator.py +2 -2
  79. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/tlbparser.py +8 -7
  80. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/typedesc.py +14 -14
  81. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/typedesc_base.py +19 -19
  82. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/typeinfo.py +14 -9
  83. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/util.py +38 -6
  84. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/viewobject.py +29 -5
  85. {comtypes-1.4.10 → comtypes-1.4.12/comtypes.egg-info}/PKG-INFO +4 -3
  86. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes.egg-info/SOURCES.txt +6 -0
  87. {comtypes-1.4.10 → comtypes-1.4.12}/pyproject.toml +13 -7
  88. comtypes-1.4.10/comtypes/hresult.py +0 -81
  89. comtypes-1.4.10/comtypes/test/test_persist.py +0 -38
  90. {comtypes-1.4.10 → comtypes-1.4.12}/LICENSE.txt +0 -0
  91. {comtypes-1.4.10 → comtypes-1.4.12}/MANIFEST.in +0 -0
  92. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/GUID.py +0 -0
  93. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_post_coinit/__init__.py +0 -0
  94. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_post_coinit/bstr.py +0 -0
  95. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_post_coinit/instancemethod.py +0 -0
  96. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_safearray.py +0 -0
  97. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/_tlib_version_checker.py +0 -0
  98. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/clear_cache.py +0 -0
  99. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/_create.py +0 -0
  100. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/client/_managing.py +0 -0
  101. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/git.py +0 -0
  102. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/logutil.py +0 -0
  103. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/server/w_getopt.py +0 -0
  104. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/shelllink.py +0 -0
  105. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/stream.py +0 -0
  106. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/TestComServer.idl +0 -0
  107. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/TestComServer.py +0 -0
  108. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/TestComServer.tlb +0 -0
  109. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/TestDispServer.idl +0 -0
  110. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/TestDispServer.py +0 -0
  111. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/TestDispServer.tlb +0 -0
  112. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/__init__.py +0 -0
  113. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/find_memleak.py +0 -0
  114. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/mylib.idl +0 -0
  115. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/mylib.tlb +0 -0
  116. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/mytypelib.idl +0 -0
  117. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/runtests.py +0 -0
  118. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/setup.py +0 -0
  119. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_BSTR.py +0 -0
  120. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_DISPPARAMS.py +0 -0
  121. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_QueryService.py +0 -0
  122. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_avmc.py +0 -0
  123. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_casesensitivity.py +0 -0
  124. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_clear_cache.py +0 -0
  125. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_client.py +0 -0
  126. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_client_regenerate_modules.py +0 -0
  127. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_findgendir.py +0 -0
  128. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_ie.py +0 -0
  129. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_ienum.py +0 -0
  130. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_imfattributes.py +0 -0
  131. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_jscript.js +0 -0
  132. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_monikers.py +0 -0
  133. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_outparam.py +0 -0
  134. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_pump_events.py +0 -0
  135. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_sapi.py +0 -0
  136. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_shelllink.py +0 -0
  137. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_showevents.py +0 -0
  138. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_subinterface.py +0 -0
  139. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_typeannotator.py +0 -0
  140. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_win32com_interop.py +0 -0
  141. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/test_wmi.py +0 -0
  142. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/test/urlhist.tlb +0 -0
  143. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/__init__.py +0 -0
  144. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/__init__.py +0 -0
  145. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/modulenamer.py +0 -0
  146. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes/tools/codegenerator/packing.py +0 -0
  147. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes.egg-info/dependency_links.txt +0 -0
  148. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes.egg-info/entry_points.txt +0 -0
  149. {comtypes-1.4.10 → comtypes-1.4.12}/comtypes.egg-info/top_level.txt +0 -0
  150. {comtypes-1.4.10 → comtypes-1.4.12}/setup.cfg +0 -0
  151. {comtypes-1.4.10 → comtypes-1.4.12}/setup.py +0 -0
@@ -1,5 +1,6 @@
1
1
  import ctypes
2
2
  from typing import (
3
+ TYPE_CHECKING,
3
4
  Any,
4
5
  Callable,
5
6
  Dict,
@@ -8,33 +9,51 @@ from typing import (
8
9
  Literal,
9
10
  NamedTuple,
10
11
  Optional,
12
+ Sequence,
11
13
  Tuple,
12
14
  Type,
13
15
  )
14
16
  from typing import Union as _UnionT
15
17
 
16
18
  import comtypes
17
- from comtypes import _CData
18
19
 
19
- _PositionalParamFlagType = Tuple[int, Optional[str]]
20
- _OptionalParamFlagType = Tuple[int, Optional[str], Any]
21
- _ParamFlagType = _UnionT[_PositionalParamFlagType, _OptionalParamFlagType]
22
- _PositionalArgSpecElmType = Tuple[List[str], Type[_CData], str]
23
- _OptionalArgSpecElmType = Tuple[List[str], Type[_CData], str, Any]
24
- _ArgSpecElmType = _UnionT[_PositionalArgSpecElmType, _OptionalArgSpecElmType]
20
+ if TYPE_CHECKING:
21
+ from _ctypes import _PyCSimpleType
22
+ from ctypes import _CArgObject, _CDataType
25
23
 
24
+ from comtypes import hints # type: ignore
25
+ else:
26
+ _PyCSimpleType = type(ctypes.c_int)
27
+ _CArgObject = type(ctypes.byref(ctypes.c_int()))
28
+
29
+
30
+ DISPATCH_METHOD = 1
31
+ DISPATCH_PROPERTYGET = 2
32
+ DISPATCH_PROPERTYPUT = 4
33
+ DISPATCH_PROPERTYPUTREF = 8
34
+
35
+ PARAMFLAG_NONE = 0
36
+ PARAMFLAG_FIN = 1
37
+ PARAMFLAG_FOUT = 2
38
+ PARAMFLAG_FLCID = 4
39
+ PARAMFLAG_FRETVAL = 8
40
+ PARAMFLAG_FOPT = 16
41
+ PARAMFLAG_FHASDEFAULT = 32
42
+ PARAMFLAG_FHASCUSTDATA = 64
26
43
 
27
44
  _PARAMFLAGS = {
28
- "in": 1,
29
- "out": 2,
30
- "lcid": 4,
31
- "retval": 8,
32
- "optional": 16,
45
+ "in": PARAMFLAG_FIN,
46
+ "out": PARAMFLAG_FOUT,
47
+ "lcid": PARAMFLAG_FLCID,
48
+ "retval": PARAMFLAG_FRETVAL,
49
+ "optional": PARAMFLAG_FOPT,
33
50
  }
34
51
 
35
52
 
36
- def _encode_idl(names):
37
- # sum up all values found in _PARAMFLAGS, ignoring all others.
53
+ def _encode_idl(names: Sequence[str]) -> int:
54
+ """Sums up 'in', 'out', 'lcid', 'retval' and 'optional' values
55
+ found in _PARAMFLAGS, ignoring all other PARAMFLAG_... stuff.
56
+ """
38
57
  return sum([_PARAMFLAGS.get(n, 0) for n in names])
39
58
 
40
59
 
@@ -43,20 +62,20 @@ _NOTHING = object()
43
62
 
44
63
  def _unpack_argspec(
45
64
  idl: List[str],
46
- typ: Type[_CData],
65
+ typ: Type["_CDataType"],
47
66
  name: Optional[str] = None,
48
67
  defval: Any = _NOTHING,
49
- ) -> Tuple[List[str], Type[_CData], Optional[str], Any]:
68
+ ) -> Tuple[List[str], Type["_CDataType"], Optional[str], Any]:
50
69
  return idl, typ, name, defval
51
70
 
52
71
 
53
72
  def _resolve_argspec(
54
- items: Tuple[_ArgSpecElmType, ...],
55
- ) -> Tuple[Tuple[_ParamFlagType, ...], Tuple[Type[_CData], ...]]:
73
+ items: Tuple["hints.ArgSpecElmType", ...],
74
+ ) -> Tuple[Tuple["hints.ParamFlagType", ...], Tuple[Type["_CDataType"], ...]]:
56
75
  """Unpacks and converts from argspec to paramflags and argtypes.
57
76
 
58
77
  - paramflags is a sequence of `(pflags: int, argname: str, | None[, defval: Any])`.
59
- - argtypes is a sequence of `type[_CData]`.
78
+ - argtypes is a sequence of `type[_CDataType]`.
60
79
  """
61
80
  from comtypes.automation import VARIANT
62
81
 
@@ -83,14 +102,23 @@ def _resolve_argspec(
83
102
  return tuple(paramflags), tuple(argtypes)
84
103
 
85
104
 
105
+ if TYPE_CHECKING:
106
+ _VarFlags = Tuple[str, ...]
107
+ _VarFlagsWithDispIdHelpstr = Tuple["dispid", "helpstring", hints.Unpack[_VarFlags]]
108
+ _VarFlagsWithDispId = Tuple["dispid", hints.Unpack[_VarFlags]]
109
+ _VarFlagsWithHelpstr = Tuple["helpstring", hints.Unpack[_VarFlags]]
110
+ _DispIdlFlags = _UnionT[_VarFlagsWithDispIdHelpstr, _VarFlagsWithDispId]
111
+ _ComIdlFlags = _UnionT[_VarFlags, _VarFlagsWithHelpstr]
112
+
113
+
86
114
  class _ComMemberSpec(NamedTuple):
87
115
  """Specifier for a slot of COM method or property."""
88
116
 
89
- restype: Optional[Type[_CData]]
117
+ restype: Optional[Type["_CDataType"]]
90
118
  name: str
91
- argtypes: Tuple[Type[_CData], ...]
92
- paramflags: Optional[Tuple[_ParamFlagType, ...]]
93
- idlflags: Tuple[_UnionT[str, int], ...]
119
+ argtypes: Tuple[Type["_CDataType"], ...]
120
+ paramflags: Optional[Tuple["hints.ParamFlagType", ...]]
121
+ idlflags: _UnionT["_ComIdlFlags", "_DispIdlFlags"]
94
122
  doc: Optional[str]
95
123
 
96
124
  def is_prop(self) -> bool:
@@ -102,9 +130,9 @@ class _DispMemberSpec(NamedTuple):
102
130
 
103
131
  what: Literal["DISPMETHOD", "DISPPROPERTY"]
104
132
  name: str
105
- idlflags: Tuple[_UnionT[str, int], ...]
106
- restype: Optional[Type[_CData]]
107
- argspec: Tuple[_ArgSpecElmType, ...]
133
+ idlflags: "_DispIdlFlags"
134
+ restype: Optional[Type["_CDataType"]]
135
+ argspec: Tuple["hints.ArgSpecElmType", ...]
108
136
 
109
137
  @property
110
138
  def memid(self) -> int:
@@ -134,7 +162,7 @@ class helpstring(str):
134
162
  "Specifies the helpstring for a COM method or property."
135
163
 
136
164
 
137
- class defaultvalue(object):
165
+ class defaultvalue:
138
166
  "Specifies the default value for parameters marked optional."
139
167
 
140
168
  def __init__(self, value):
@@ -197,15 +225,32 @@ def COMMETHOD(idlflags, restype, methodname, *argspec) -> _ComMemberSpec:
197
225
 
198
226
 
199
227
  ################################################################
200
-
201
- _PropFunc = Optional[Callable[..., Any]]
202
- _DocType = Optional[str]
228
+ # workarounds for ctypes functions and parameters
229
+
230
+
231
+ def _prepare_parameter(value: Any, atyp: Type["_CDataType"]) -> "_CDataType":
232
+ # parameter was passed, call `from_param()` to
233
+ # convert it to a `ctypes` type.
234
+ if getattr(value, "_type_", None) is atyp:
235
+ # Array of or pointer to type `atyp` was passed,
236
+ # pointer to `atyp` expected.
237
+ v = value
238
+ elif type(atyp) is _PyCSimpleType: # type: ignore
239
+ # The `from_param` method of simple types
240
+ # (`c_int`, `c_double`, ...) returns a `byref` object which
241
+ # we cannot use since later it will be wrapped in a pointer.
242
+ # Simply call the constructor with the argument in that case.
243
+ v = atyp(value)
244
+ else:
245
+ v = atyp.from_param(value)
246
+ assert not isinstance(v, _CArgObject) # type: ignore
247
+ return v
203
248
 
204
249
 
205
250
  def _fix_inout_args(
206
251
  func: Callable[..., Any],
207
- argtypes: Tuple[Type[_CData], ...],
208
- paramflags: Tuple[_ParamFlagType, ...],
252
+ argtypes: Tuple[Type["_CDataType"], ...],
253
+ paramflags: Tuple["hints.ParamFlagType", ...],
209
254
  ) -> Callable[..., Any]:
210
255
  """This function provides a workaround for a bug in `ctypes`.
211
256
 
@@ -217,13 +262,11 @@ def _fix_inout_args(
217
262
  #
218
263
  # TODO: The workaround should be disabled when a ctypes
219
264
  # version is used where the bug is fixed.
220
- SIMPLETYPE = type(ctypes.c_int)
221
- BYREFTYPE = type(ctypes.byref(ctypes.c_int()))
222
265
 
223
266
  def call_with_inout(self, *args, **kw):
224
267
  args = list(args)
225
268
  # Indexed by order in the output
226
- outargs: Dict[int, _UnionT[_CData, "ctypes._CArgObject"]] = {}
269
+ outargs: Dict[int, "_CDataType"] = {}
227
270
  outnum = 0
228
271
  param_index = 0
229
272
  # Go through all expected arguments and match them to the provided arguments.
@@ -231,8 +274,8 @@ def _fix_inout_args(
231
274
  # through the keyword arguments.
232
275
  for i, info in enumerate(paramflags):
233
276
  direction = info[0]
234
- dir_in = direction & 1 == 1
235
- dir_out = direction & 2 == 2
277
+ dir_in = bool(direction & PARAMFLAG_FIN)
278
+ dir_out = bool(direction & PARAMFLAG_FOUT)
236
279
  is_positional = param_index < len(args)
237
280
  if not (dir_in or dir_out):
238
281
  # The original code here did not check for this special case and
@@ -249,34 +292,16 @@ def _fix_inout_args(
249
292
  name = info[1]
250
293
  # [in, out] parameters are passed as pointers,
251
294
  # this is the pointed-to type:
252
- atyp: Type[_CData] = getattr(argtypes[i], "_type_")
295
+ atyp: Type["_CDataType"] = getattr(argtypes[i], "_type_")
253
296
 
254
297
  # Get the actual parameter, either as positional or
255
298
  # keyword arg.
256
299
 
257
- def prepare_parameter(v):
258
- # parameter was passed, call `from_param()` to
259
- # convert it to a `ctypes` type.
260
- if getattr(v, "_type_", None) is atyp:
261
- # Array of or pointer to type `atyp` was passed,
262
- # pointer to `atyp` expected.
263
- pass
264
- elif type(atyp) is SIMPLETYPE:
265
- # The `from_param` method of simple types
266
- # (`c_int`, `c_double`, ...) returns a `byref` object which
267
- # we cannot use since later it will be wrapped in a pointer.
268
- # Simply call the constructor with the argument in that case.
269
- v = atyp(v)
270
- else:
271
- v = atyp.from_param(v)
272
- assert not isinstance(v, BYREFTYPE)
273
- return v
274
-
275
300
  if is_positional:
276
- v = prepare_parameter(args[param_index])
301
+ v = _prepare_parameter(args[param_index], atyp)
277
302
  args[param_index] = v
278
303
  elif name in kw:
279
- v = prepare_parameter(kw[name])
304
+ v = _prepare_parameter(kw[name], atyp)
280
305
  kw[name] = v
281
306
  else:
282
307
  # no parameter was passed, make an empty one of the required type
@@ -321,7 +346,14 @@ def _fix_inout_args(
321
346
  return call_with_inout
322
347
 
323
348
 
324
- class PropertyMapping(object):
349
+ ################################################################
350
+
351
+
352
+ _PropFunc = Optional[Callable[..., Any]]
353
+ _DocType = Optional[str]
354
+
355
+
356
+ class PropertyMapping:
325
357
  def __init__(self):
326
358
  self._data: Dict[Tuple[str, _DocType, int], List[_PropFunc]] = {}
327
359
 
@@ -361,7 +393,7 @@ class PropertyMapping(object):
361
393
  yield (name, doc, nargs, fget, fset)
362
394
 
363
395
 
364
- class PropertyGenerator(object):
396
+ class PropertyGenerator:
365
397
  def __init__(self, cls_name: str) -> None:
366
398
  self._mapping = PropertyMapping()
367
399
  self._cls_name = cls_name
@@ -439,7 +471,7 @@ class DispPropertyGenerator(PropertyGenerator):
439
471
  return m.name, None, len(m.argspec) - 1
440
472
 
441
473
 
442
- class ComMemberGenerator(object):
474
+ class ComMemberGenerator:
443
475
  def __init__(self, cls_name: str, vtbl_offset: int, iid: "comtypes.GUID") -> None:
444
476
  self._vtbl_offset = vtbl_offset
445
477
  self._iid = iid
@@ -472,8 +504,8 @@ class ComMemberGenerator(object):
472
504
  ) -> Callable[..., Any]:
473
505
  """This is a workaround. See `_fix_inout_args` docstring and comments."""
474
506
  if m.paramflags:
475
- dirflags = [(p[0] & 3) for p in m.paramflags]
476
- if 3 in dirflags:
507
+ dirflags = [(p[0] & (PARAMFLAG_FIN | PARAMFLAG_FOUT)) for p in m.paramflags]
508
+ if (PARAMFLAG_FIN | PARAMFLAG_FOUT) in dirflags:
477
509
  return _fix_inout_args(func, m.argtypes, m.paramflags)
478
510
  return func
479
511
 
@@ -484,7 +516,7 @@ class ComMemberGenerator(object):
484
516
  return iter(self._props)
485
517
 
486
518
 
487
- class DispMemberGenerator(object):
519
+ class DispMemberGenerator:
488
520
  def __init__(self, cls_name: str) -> None:
489
521
  self._props = DispPropertyGenerator(cls_name)
490
522
  # sequence of (name: str, func_or_prop: Callable | property, is_prop: bool)
@@ -510,15 +542,15 @@ class DispMemberGenerator(object):
510
542
  memid = m.memid
511
543
 
512
544
  def fget(obj):
513
- return obj.Invoke(memid, _invkind=2) # DISPATCH_PROPERTYGET
545
+ return obj.Invoke(memid, _invkind=DISPATCH_PROPERTYGET)
514
546
 
515
547
  if "readonly" in m.idlflags:
516
548
  return property(fget)
517
549
 
518
550
  def fset(obj, value):
519
- # Detect whether to use DISPATCH_PROPERTYPUT or
520
- # DISPATCH_PROPERTYPUTREF
521
- invkind = 8 if comtypes._is_object(value) else 4
551
+ # Detect whether to use PUT or PUTREF
552
+ is_ref = comtypes._is_object(value)
553
+ invkind = DISPATCH_PROPERTYPUTREF if is_ref else DISPATCH_PROPERTYPUT
522
554
  return obj.Invoke(memid, value, _invkind=invkind)
523
555
 
524
556
  return property(fget, fset)
@@ -529,25 +561,19 @@ class DispMemberGenerator(object):
529
561
  if "propget" in m.idlflags:
530
562
 
531
563
  def getfunc(obj, *args, **kw):
532
- return obj.Invoke(
533
- memid, _invkind=2, *args, **kw
534
- ) # DISPATCH_PROPERTYGET
564
+ return obj.Invoke(memid, _invkind=DISPATCH_PROPERTYGET, *args, **kw)
535
565
 
536
566
  return getfunc
537
567
  elif "propput" in m.idlflags:
538
568
 
539
569
  def putfunc(obj, *args, **kw):
540
- return obj.Invoke(
541
- memid, _invkind=4, *args, **kw
542
- ) # DISPATCH_PROPERTYPUT
570
+ return obj.Invoke(memid, _invkind=DISPATCH_PROPERTYPUT, *args, **kw)
543
571
 
544
572
  return putfunc
545
573
  elif "propputref" in m.idlflags:
546
574
 
547
575
  def putreffunc(obj, *args, **kw):
548
- return obj.Invoke(
549
- memid, _invkind=8, *args, **kw
550
- ) # DISPATCH_PROPERTYPUTREF
576
+ return obj.Invoke(memid, _invkind=DISPATCH_PROPERTYPUTREF, *args, **kw)
551
577
 
552
578
  return putreffunc
553
579
  # a first attempt to make use of the restype. Still, support for
@@ -556,7 +582,7 @@ class DispMemberGenerator(object):
556
582
  interface = m.restype.__com_interface__ # type: ignore
557
583
 
558
584
  def comitffunc(obj, *args, **kw):
559
- result = obj.Invoke(memid, _invkind=1, *args, **kw)
585
+ result = obj.Invoke(memid, _invkind=DISPATCH_METHOD, *args, **kw)
560
586
  if result is None:
561
587
  return
562
588
  return result.QueryInterface(interface)
@@ -564,7 +590,7 @@ class DispMemberGenerator(object):
564
590
  return comitffunc
565
591
 
566
592
  def func(obj, *args, **kw):
567
- return obj.Invoke(memid, _invkind=1, *args, **kw) # DISPATCH_METHOD
593
+ return obj.Invoke(memid, _invkind=DISPATCH_METHOD, *args, **kw)
568
594
 
569
595
  return func
570
596
 
@@ -580,7 +606,7 @@ class DispMemberGenerator(object):
580
606
  # Should they be implemented in C for speed?
581
607
 
582
608
 
583
- class bound_named_property(object):
609
+ class bound_named_property:
584
610
  def __init__(self, name, fget, fset, instance):
585
611
  self.name = name
586
612
  self.instance = instance
@@ -621,7 +647,7 @@ class bound_named_property(object):
621
647
  raise TypeError(msg)
622
648
 
623
649
 
624
- class named_property(object):
650
+ class named_property:
625
651
  def __init__(self, name, fget=None, fset=None, doc=None):
626
652
  self.name = name
627
653
  self.fget = fget
@@ -61,7 +61,7 @@ class _coclass_meta(type):
61
61
  # XXX We should insist that a _reg_clsid_ is present.
62
62
  if "_reg_clsid_" in namespace:
63
63
  clsid = namespace["_reg_clsid_"]
64
- comtypes.com_coclass_registry[str(clsid)] = self
64
+ comtypes.com_coclass_registry[str(clsid)] = self # type: ignore
65
65
 
66
66
  # `_coclass_pointer_meta` is a subclass inherited from `_coclass_meta`.
67
67
  # In other words, when the `__new__` method of this metaclass is called, an
@@ -92,27 +92,21 @@ class Interop:
92
92
 
93
93
  return self.numpy.dtype(tagVARIANT_format)
94
94
 
95
- def _check_ctypeslib_typecodes(self):
95
+ def _build_typecodes(self):
96
96
  if not self.enabled:
97
97
  return {}
98
98
  import numpy as np
99
- from numpy import ctypeslib
99
+ from numpy.ctypeslib import as_ctypes_type
100
100
 
101
- try:
102
- from numpy.ctypeslib import _typecodes
103
- except ImportError:
104
- from numpy.ctypeslib import as_ctypes_type
101
+ dtypes_to_ctypes = {}
105
102
 
106
- dtypes_to_ctypes = {}
107
-
108
- for tp in set(np.sctypeDict.values()):
109
- try:
110
- ctype_for = as_ctypes_type(tp)
111
- dtypes_to_ctypes[np.dtype(tp).str] = ctype_for
112
- except NotImplementedError:
113
- continue
114
- ctypeslib._typecodes = dtypes_to_ctypes
115
- return ctypeslib._typecodes
103
+ for tp in set(np.sctypeDict.values()):
104
+ try:
105
+ ctype_for = as_ctypes_type(tp)
106
+ dtypes_to_ctypes[np.dtype(tp).str] = ctype_for
107
+ except NotImplementedError:
108
+ continue
109
+ return dtypes_to_ctypes
116
110
 
117
111
  def isndarray(self, value):
118
112
  """Check if a value is an ndarray.
@@ -168,7 +162,8 @@ class Interop:
168
162
  # if that succeeded we can be enabled
169
163
  self.enabled = True
170
164
  self.VARIANT_dtype = self._make_variant_dtype()
171
- self.typecodes = self._check_ctypeslib_typecodes()
165
+ self.typecodes = self._build_typecodes()
166
+ self.datetime64 = self.numpy.datetime64
172
167
  self.com_null_date64 = self.numpy.datetime64("1899-12-30T00:00:00", "ns")
173
168
 
174
169
 
@@ -2,14 +2,14 @@ import types
2
2
  from _ctypes import COMError
3
3
  from typing import Type
4
4
 
5
- from comtypes import patcher
5
+ from comtypes import hresult, patcher
6
6
 
7
7
  _all_slice = slice(None, None, None)
8
8
 
9
9
 
10
10
  def case_insensitive(p: Type) -> None:
11
11
  @patcher.Patch(p)
12
- class CaseInsensitive(object):
12
+ class CaseInsensitive:
13
13
  # case insensitive attributes for COM methods and properties
14
14
  def __getattr__(self, name):
15
15
  """Implement case insensitive access to methods and properties"""
@@ -34,7 +34,7 @@ def case_insensitive(p: Type) -> None:
34
34
 
35
35
  def reference_fix(pp: Type) -> None:
36
36
  @patcher.Patch(pp)
37
- class ReferenceFix(object):
37
+ class ReferenceFix:
38
38
  def __setitem__(self, index, value):
39
39
  # We override the __setitem__ method of the
40
40
  # POINTER(POINTER(interface)) type, so that the COM
@@ -64,7 +64,7 @@ def reference_fix(pp: Type) -> None:
64
64
 
65
65
  def sized(itf: Type) -> None:
66
66
  @patcher.Patch(itf)
67
- class _(object):
67
+ class _:
68
68
  def __len__(self):
69
69
  "Return the the 'self.Count' property."
70
70
  return self.Count
@@ -72,7 +72,7 @@ def sized(itf: Type) -> None:
72
72
 
73
73
  def callable_and_subscriptable(itf: Type) -> None:
74
74
  @patcher.Patch(itf)
75
- class _(object):
75
+ class _:
76
76
  # 'Item' is the 'default' value. Make it available by
77
77
  # calling the instance (Not sure this makes sense, but
78
78
  # win32com does this also).
@@ -96,8 +96,7 @@ def callable_and_subscriptable(itf: Type) -> None:
96
96
  try:
97
97
  result = self.Item(*args)
98
98
  except COMError as err:
99
- (hresult, text, details) = err.args
100
- if hresult == -2147352565: # DISP_E_BADINDEX
99
+ if err.hresult == hresult.DISP_E_BADINDEX:
101
100
  raise IndexError("invalid index")
102
101
  else:
103
102
  raise
@@ -115,8 +114,7 @@ def callable_and_subscriptable(itf: Type) -> None:
115
114
  try:
116
115
  self.Item[index] = value
117
116
  except COMError as err:
118
- (hresult, text, details) = err.args
119
- if hresult == -2147352565: # DISP_E_BADINDEX
117
+ if err.hresult == hresult.DISP_E_BADINDEX:
120
118
  raise IndexError("invalid index")
121
119
  else:
122
120
  raise
@@ -127,7 +125,7 @@ def callable_and_subscriptable(itf: Type) -> None:
127
125
 
128
126
  def iterator(itf: Type) -> None:
129
127
  @patcher.Patch(itf)
130
- class _(object):
128
+ class _:
131
129
  def __iter__(self):
132
130
  "Return an iterator over the _NewEnum collection."
133
131
  # This method returns a pointer to _some_ _NewEnum interface.
@@ -0,0 +1,61 @@
1
+ from ctypes import HRESULT, POINTER, OleDLL, byref, c_ulong, c_void_p
2
+ from ctypes.wintypes import DWORD, LPVOID
3
+ from typing import TYPE_CHECKING, Optional, Type, TypeVar, overload
4
+ from typing import Union as _UnionT
5
+
6
+ from comtypes import GUID
7
+ from comtypes._post_coinit.unknwn import IUnknown
8
+ from comtypes.GUID import REFCLSID
9
+
10
+ if TYPE_CHECKING:
11
+ from comtypes import hints # type: ignore
12
+
13
+
14
+ _T_IUnknown = TypeVar("_T_IUnknown", bound=IUnknown)
15
+
16
+ ACTIVEOBJECT_STRONG = 0x0
17
+ ACTIVEOBJECT_WEAK = 0x1
18
+
19
+
20
+ def RegisterActiveObject(
21
+ punk: "_UnionT[IUnknown, hints.LP_LP_Vtbl]", clsid: GUID, flags: int
22
+ ) -> int:
23
+ """Registers a pointer as the active object for its class and returns the handle."""
24
+ handle = c_ulong()
25
+ _RegisterActiveObject(punk, byref(clsid), flags, byref(handle))
26
+ return handle.value
27
+
28
+
29
+ def RevokeActiveObject(handle: int) -> None:
30
+ """Ends a pointer's status as active."""
31
+ _RevokeActiveObject(handle, None)
32
+
33
+
34
+ @overload
35
+ def GetActiveObject(clsid: GUID, interface: None = None) -> IUnknown: ...
36
+ @overload
37
+ def GetActiveObject(clsid: GUID, interface: Type[_T_IUnknown]) -> _T_IUnknown: ...
38
+ def GetActiveObject(
39
+ clsid: GUID, interface: Optional[Type[IUnknown]] = None
40
+ ) -> IUnknown:
41
+ """Retrieves a pointer to a running object"""
42
+ p = POINTER(IUnknown)()
43
+ _GetActiveObject(byref(clsid), None, byref(p))
44
+ if interface is not None:
45
+ p = p.QueryInterface(interface) # type: ignore
46
+ return p # type: ignore
47
+
48
+
49
+ _oleaut32 = OleDLL("oleaut32")
50
+
51
+ _RegisterActiveObject = _oleaut32.RegisterActiveObject
52
+ _RegisterActiveObject.argtypes = [c_void_p, REFCLSID, DWORD, POINTER(DWORD)]
53
+ _RegisterActiveObject.restype = HRESULT
54
+
55
+ _RevokeActiveObject = _oleaut32.RevokeActiveObject
56
+ _RevokeActiveObject.argtypes = [DWORD, LPVOID]
57
+ _RevokeActiveObject.restype = HRESULT
58
+
59
+ _GetActiveObject = _oleaut32.GetActiveObject
60
+ _GetActiveObject.argtypes = [REFCLSID, LPVOID, POINTER(POINTER(IUnknown))]
61
+ _GetActiveObject.restype = HRESULT
@@ -17,6 +17,7 @@ from typing import TYPE_CHECKING, Any, Callable, Optional, Type, TypeVar, overlo
17
17
  from comtypes import CLSCTX_LOCAL_SERVER, CLSCTX_REMOTE_SERVER, CLSCTX_SERVER, GUID
18
18
  from comtypes._memberspec import COMMETHOD
19
19
  from comtypes._post_coinit.unknwn import IUnknown
20
+ from comtypes.GUID import REFCLSID
20
21
 
21
22
  if TYPE_CHECKING:
22
23
  from ctypes import _Pointer
@@ -171,21 +172,6 @@ def CoGetClassObject(clsid, clsctx=None, pServerInfo=None, interface=None):
171
172
  return p # type: ignore
172
173
 
173
174
 
174
- @overload
175
- def GetActiveObject(clsid: GUID, interface: None = None) -> IUnknown: ...
176
- @overload
177
- def GetActiveObject(clsid: GUID, interface: Type[_T_IUnknown]) -> _T_IUnknown: ...
178
- def GetActiveObject(
179
- clsid: GUID, interface: Optional[Type[IUnknown]] = None
180
- ) -> IUnknown:
181
- """Retrieves a pointer to a running object"""
182
- p = POINTER(IUnknown)()
183
- _GetActiveObject(byref(clsid), None, byref(p))
184
- if interface is not None:
185
- p = p.QueryInterface(interface) # type: ignore
186
- return p # type: ignore
187
-
188
-
189
175
  class MULTI_QI(Structure):
190
176
  _fields_ = [("pIID", POINTER(GUID)), ("pItf", POINTER(c_void_p)), ("hr", HRESULT)]
191
177
  if TYPE_CHECKING:
@@ -238,14 +224,6 @@ class _COSERVERINFO(Structure):
238
224
  dwReserved2: int
239
225
 
240
226
 
241
- _oleaut32 = OleDLL("oleaut32")
242
-
243
- REFCLSID = POINTER(GUID)
244
- _GetActiveObject = _oleaut32.GetActiveObject
245
- _GetActiveObject.argtypes = [REFCLSID, LPVOID, POINTER(POINTER(IUnknown))]
246
- _GetActiveObject.restype = HRESULT
247
-
248
-
249
227
  _ole32 = OleDLL("ole32")
250
228
 
251
229
  COSERVERINFO = _COSERVERINFO