comtypes 1.4.4__zip → 1.4.5__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 (130) hide show
  1. {comtypes-1.4.4 → comtypes-1.4.5}/CHANGES.txt +12 -0
  2. {comtypes-1.4.4/comtypes.egg-info → comtypes-1.4.5}/PKG-INFO +1 -1
  3. comtypes-1.4.5/comtypes/__init__.py +268 -0
  4. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/_comobject.py +2 -1
  5. comtypes-1.4.5/comtypes/_idl_stuff.py +67 -0
  6. comtypes-1.4.5/comtypes/_post_coinit/__init__.py +15 -0
  7. comtypes-1.4.5/comtypes/_post_coinit/bstr.py +30 -0
  8. comtypes-1.4.5/comtypes/_post_coinit/misc.py +385 -0
  9. comtypes-1.4.5/comtypes/_post_coinit/unknwn.py +537 -0
  10. comtypes-1.4.5/comtypes/_py_instance_method.py +13 -0
  11. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/_safearray.py +3 -2
  12. comtypes-1.4.5/comtypes/_tlib_version_checker.py +18 -0
  13. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/automation.py +22 -6
  14. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/client/_generate.py +2 -1
  15. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/hints.pyi +34 -0
  16. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/safearray.py +11 -4
  17. comtypes-1.4.5/comtypes/stream.py +65 -0
  18. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_client.py +11 -0
  19. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_dispifc_records.py +1 -1
  20. comtypes-1.4.5/comtypes/test/test_dispifc_safearrays.py +89 -0
  21. comtypes-1.4.5/comtypes/test/test_istream.py +53 -0
  22. comtypes-1.4.5/comtypes/test/test_midl_safearray_create.py +100 -0
  23. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_wmi.py +11 -18
  24. {comtypes-1.4.4 → comtypes-1.4.5/comtypes.egg-info}/PKG-INFO +1 -1
  25. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes.egg-info/SOURCES.txt +11 -0
  26. {comtypes-1.4.4 → comtypes-1.4.5}/setup.cfg +1 -0
  27. comtypes-1.4.4/comtypes/__init__.py +0 -1229
  28. {comtypes-1.4.4 → comtypes-1.4.5}/LICENSE.txt +0 -0
  29. {comtypes-1.4.4 → comtypes-1.4.5}/MANIFEST.in +0 -0
  30. {comtypes-1.4.4 → comtypes-1.4.5}/README.md +0 -0
  31. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/GUID.py +0 -0
  32. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/_memberspec.py +0 -0
  33. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/_meta.py +0 -0
  34. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/_npsupport.py +0 -0
  35. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/clear_cache.py +0 -0
  36. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/client/__init__.py +0 -0
  37. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/client/_code_cache.py +0 -0
  38. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/client/_constants.py +0 -0
  39. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/client/_events.py +0 -0
  40. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/client/dynamic.py +0 -0
  41. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/client/lazybind.py +0 -0
  42. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/connectionpoints.py +0 -0
  43. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/errorinfo.py +0 -0
  44. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/git.py +0 -0
  45. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/hresult.py +0 -0
  46. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/logutil.py +0 -0
  47. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/messageloop.py +0 -0
  48. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/patcher.py +0 -0
  49. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/persist.py +0 -0
  50. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/server/__init__.py +0 -0
  51. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/server/automation.py +0 -0
  52. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/server/connectionpoints.py +0 -0
  53. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/server/inprocserver.py +0 -0
  54. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/server/localserver.py +0 -0
  55. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/server/register.py +0 -0
  56. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/server/w_getopt.py +0 -0
  57. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/shelllink.py +0 -0
  58. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/TestComServer.idl +0 -0
  59. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/TestComServer.py +0 -0
  60. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/TestComServer.tlb +0 -0
  61. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/TestDispServer.idl +0 -0
  62. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/TestDispServer.py +0 -0
  63. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/TestDispServer.tlb +0 -0
  64. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/__init__.py +0 -0
  65. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/find_memleak.py +0 -0
  66. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/mylib.idl +0 -0
  67. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/mylib.tlb +0 -0
  68. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/mytypelib.idl +0 -0
  69. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/runtests.py +0 -0
  70. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/setup.py +0 -0
  71. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_BSTR.py +0 -0
  72. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_DISPPARAMS.py +0 -0
  73. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_GUID.py +0 -0
  74. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_QueryService.py +0 -0
  75. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_agilent.py +0 -0
  76. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_avmc.py +0 -0
  77. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_basic.py +0 -0
  78. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_casesensitivity.py +0 -0
  79. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_clear_cache.py +0 -0
  80. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_client_dynamic.py +0 -0
  81. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_client_regenerate_modules.py +0 -0
  82. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_collections.py +0 -0
  83. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_comserver.py +0 -0
  84. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_createwrappers.py +0 -0
  85. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_dict.py +0 -0
  86. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_dispinterface.py +0 -0
  87. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_dyndispatch.py +0 -0
  88. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_excel.py +0 -0
  89. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_findgendir.py +0 -0
  90. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_getactiveobj.py +0 -0
  91. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_ie.py +0 -0
  92. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_ienum.py +0 -0
  93. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_imfattributes.py +0 -0
  94. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_inout_args.py +0 -0
  95. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_jscript.js +0 -0
  96. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_msscript.py +0 -0
  97. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_npsupport.py +0 -0
  98. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_outparam.py +0 -0
  99. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_propputref.py +0 -0
  100. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_pump_events.py +0 -0
  101. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_safearray.py +0 -0
  102. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_sapi.py +0 -0
  103. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_server.py +0 -0
  104. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_showevents.py +0 -0
  105. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_subinterface.py +0 -0
  106. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_typeinfo.py +0 -0
  107. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_urlhistory.py +0 -0
  108. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_variant.py +0 -0
  109. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_win32com_interop.py +0 -0
  110. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/test_word.py +0 -0
  111. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/test/urlhist.tlb +0 -0
  112. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/__init__.py +0 -0
  113. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/codegenerator/__init__.py +0 -0
  114. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/codegenerator/codegenerator.py +0 -0
  115. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/codegenerator/helpers.py +0 -0
  116. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/codegenerator/modulenamer.py +0 -0
  117. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/codegenerator/namespaces.py +0 -0
  118. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/codegenerator/packing.py +0 -0
  119. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/codegenerator/typeannotator.py +0 -0
  120. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/tlbparser.py +0 -0
  121. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/typedesc.py +0 -0
  122. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/tools/typedesc_base.py +0 -0
  123. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/typeinfo.py +0 -0
  124. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/util.py +0 -0
  125. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes/viewobject.py +0 -0
  126. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes.egg-info/dependency_links.txt +0 -0
  127. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes.egg-info/entry_points.txt +0 -0
  128. {comtypes-1.4.4 → comtypes-1.4.5}/comtypes.egg-info/top_level.txt +0 -0
  129. {comtypes-1.4.4 → comtypes-1.4.5}/pyproject.toml +0 -0
  130. {comtypes-1.4.4 → comtypes-1.4.5}/setup.py +0 -0
@@ -1,14 +1,17 @@
1
1
  # This stub contains...
2
2
  # - symbols those what might occur recursive imports in runtime.
3
3
  # - utilities for type hints.
4
+ import ctypes
4
5
  import sys
5
6
  from typing import (
6
7
  Any,
7
8
  Callable,
9
+ ClassVar,
8
10
  Generic,
9
11
  Iterator,
10
12
  List,
11
13
  NoReturn,
14
+ Sequence,
12
15
  Tuple,
13
16
  Type,
14
17
  TypeVar,
@@ -37,9 +40,11 @@ else:
37
40
  from typing_extensions import Self
38
41
 
39
42
  import comtypes
43
+ from comtypes import IUnknown as IUnknown, GUID as GUID
40
44
  from comtypes.automation import IDispatch as IDispatch, VARIANT as VARIANT
41
45
  from comtypes.server import IClassFactory as IClassFactory
42
46
  from comtypes.typeinfo import ITypeInfo as ITypeInfo
47
+ from comtypes._safearray import tagSAFEARRAY as tagSAFEARRAY
43
48
 
44
49
  Incomplete: TypeAlias = Any
45
50
  """The type symbol is used temporarily until the COM library parsers or
@@ -51,6 +56,35 @@ Hresult: TypeAlias = int
51
56
  arguments and with `HRESULT` as its return type in its COM method definition.
52
57
  """
53
58
 
59
+ _CT = TypeVar("_CT", bound=ctypes._CData)
60
+ _T_IUnknown = TypeVar("_T_IUnknown", bound=IUnknown)
61
+ _T_Struct = TypeVar("_T_Struct", bound=ctypes.Structure)
62
+
63
+ class LP_SAFEARRAY(ctypes._Pointer[tagSAFEARRAY], Generic[_CT]):
64
+ contents: tagSAFEARRAY
65
+ _itemtype_: ClassVar[_CT] # type: ignore
66
+ _vartype_: ClassVar[int]
67
+ _needsfree: ClassVar[bool]
68
+
69
+ @overload
70
+ @classmethod
71
+ def create(
72
+ cls: Type[LP_SAFEARRAY[ctypes._Pointer[_T_IUnknown]]],
73
+ value: Sequence[_T_IUnknown],
74
+ extra: ctypes._Pointer[GUID] = ...,
75
+ ) -> LP_SAFEARRAY[ctypes._Pointer[_T_IUnknown]]: ...
76
+ @overload
77
+ @classmethod
78
+ def create(cls, value: Sequence[_CT], extra: Any = ...) -> LP_SAFEARRAY[_CT]: ...
79
+ @overload
80
+ def unpack(
81
+ self: LP_SAFEARRAY[ctypes._Pointer[_T_IUnknown]],
82
+ ) -> Sequence[_T_IUnknown]: ...
83
+ @overload
84
+ def unpack(self: LP_SAFEARRAY[_T_Struct]) -> Sequence[_T_Struct]: ...
85
+ @overload
86
+ def unpack(self) -> Sequence[Any]: ...
87
+
54
88
  _T_coclass = TypeVar("_T_coclass", bound=comtypes.CoClass)
55
89
 
56
90
  class FirstComItfOf(Generic[_T_coclass]):
@@ -1,10 +1,17 @@
1
1
  import threading
2
2
  import array
3
+ from typing import TYPE_CHECKING
3
4
  import comtypes
4
5
  from ctypes import POINTER, Structure, byref, cast, c_long, memmove, pointer, sizeof
5
6
  from comtypes import _safearray, IUnknown, com_interface_registry
6
7
  from comtypes.patcher import Patch
7
8
 
9
+ if TYPE_CHECKING:
10
+ from typing import Type, TypeVar
11
+ from comtypes import hints # type: ignore
12
+
13
+ _CT = TypeVar("_CT", bound=comtypes._CData)
14
+
8
15
  _safearray_type_cache = {}
9
16
 
10
17
 
@@ -49,18 +56,18 @@ safearray_as_ndarray = _SafeArrayAsNdArrayContextManager()
49
56
 
50
57
  ################################################################
51
58
  # This is THE PUBLIC function: the gateway to the SAFEARRAY functionality.
52
- def _midlSAFEARRAY(itemtype):
59
+ def _midlSAFEARRAY(itemtype: "Type[_CT]") -> "Type[hints.LP_SAFEARRAY[_CT]]":
53
60
  """This function mimics the 'SAFEARRAY(aType)' IDL idiom. It
54
61
  returns a subtype of SAFEARRAY, instances will be built with a
55
62
  typecode VT_... corresponding to the aType, which must be one of
56
63
  the supported ctypes.
57
64
  """
58
65
  try:
59
- return POINTER(_safearray_type_cache[itemtype])
66
+ return POINTER(_safearray_type_cache[itemtype]) # type: ignore
60
67
  except KeyError:
61
68
  sa_type = _make_safearray_type(itemtype)
62
69
  _safearray_type_cache[itemtype] = sa_type
63
- return POINTER(sa_type)
70
+ return POINTER(sa_type) # type: ignore
64
71
 
65
72
 
66
73
  def _make_safearray_type(itemtype):
@@ -109,7 +116,7 @@ def _make_safearray_type(itemtype):
109
116
  _needsfree = False
110
117
 
111
118
  @classmethod
112
- def create(cls, value, extra=None):
119
+ def create(cls, value, extra=extra):
113
120
  """Create a POINTER(SAFEARRAY_...) instance of the correct
114
121
  type; value is an object containing the items to store.
115
122
 
@@ -0,0 +1,65 @@
1
+ from ctypes import Array, c_ubyte, c_ulong, HRESULT, POINTER, pointer
2
+ from typing import Tuple, TYPE_CHECKING
3
+
4
+ from comtypes import COMMETHOD, GUID, IUnknown
5
+
6
+
7
+ class ISequentialStream(IUnknown):
8
+ """Defines methods for the stream objects in sequence."""
9
+
10
+ _iid_ = GUID("{0C733A30-2A1C-11CE-ADE5-00AA0044773D}")
11
+ _idlflags_ = []
12
+
13
+ _methods_ = [
14
+ # Note that these functions are called `Read` and `Write` in Microsoft's documentation,
15
+ # see https://learn.microsoft.com/en-us/windows/win32/api/objidl/nn-objidl-isequentialstream.
16
+ # However, the comtypes code generation detects these as `RemoteRead` and `RemoteWrite`
17
+ # for very subtle reasons, see e.g. https://stackoverflow.com/q/19820999/. We will not
18
+ # rename these in this manual import for the sake of consistency.
19
+ COMMETHOD(
20
+ [],
21
+ HRESULT,
22
+ "RemoteRead",
23
+ # This call only works if `pv` is pre-allocated with `cb` bytes,
24
+ # which cannot be done by the high level function generated by metaclasses.
25
+ # Therefore, we override the high level function to implement this behaviour
26
+ # and then delegate the call the raw COM method.
27
+ (["out"], POINTER(c_ubyte), "pv"),
28
+ (["in"], c_ulong, "cb"),
29
+ (["out"], POINTER(c_ulong), "pcbRead"),
30
+ ),
31
+ COMMETHOD(
32
+ [],
33
+ HRESULT,
34
+ "RemoteWrite",
35
+ (["in"], POINTER(c_ubyte), "pv"),
36
+ (["in"], c_ulong, "cb"),
37
+ (["out"], POINTER(c_ulong), "pcbWritten"),
38
+ ),
39
+ ]
40
+
41
+ def RemoteRead(self, cb: int) -> Tuple["Array[c_ubyte]", int]:
42
+ """Reads a specified number of bytes from the stream object into memory
43
+ starting at the current seek pointer.
44
+ """
45
+ # Behaves as if `pv` is pre-allocated with `cb` bytes by the high level func.
46
+ pv = (c_ubyte * cb)()
47
+ pcb_read = pointer(c_ulong(0))
48
+ self.__com_RemoteRead(pv, c_ulong(cb), pcb_read) # type: ignore
49
+ # return both `out` parameters
50
+ return pv, pcb_read.contents.value
51
+
52
+ if TYPE_CHECKING:
53
+
54
+ def RemoteWrite(self, pv: "Array[c_ubyte]", cb: int) -> int:
55
+ """Writes a specified number of bytes into the stream object starting at
56
+ the current seek pointer.
57
+ """
58
+ ...
59
+
60
+
61
+ # fmt: off
62
+ __known_symbols__ = [
63
+ 'ISequentialStream',
64
+ ]
65
+ # fmt: on
@@ -71,6 +71,12 @@ class Test_GetModule(ut.TestCase):
71
71
  # the `_Pointer` interface, rather than importing `_Pointer` from `ctypes`.
72
72
  self.assertTrue(issubclass(mod._Pointer, comtypes.IUnknown))
73
73
 
74
+ def test_portabledeviceapi(self):
75
+ mod = comtypes.client.GetModule("portabledeviceapi.dll")
76
+ from comtypes.stream import ISequentialStream
77
+
78
+ self.assertTrue(issubclass(mod.IStream, ISequentialStream))
79
+
74
80
  def test_no_replacing_Patch_namespace(self):
75
81
  # NOTE: An object named `Patch` is defined in some dll.
76
82
  # Depending on how the namespace is defined in the static module,
@@ -117,6 +123,11 @@ class Test_KnownSymbols(ut.TestCase):
117
123
 
118
124
  self._doit(comtypes)
119
125
 
126
+ def test_symbols_in_comtypes_stream(self):
127
+ import comtypes.stream
128
+
129
+ self._doit(comtypes.stream)
130
+
120
131
  def test_symbols_in_comtypes_automation(self):
121
132
  import comtypes.automation
122
133
 
@@ -26,7 +26,7 @@ class Test_DispMethods(unittest.TestCase):
26
26
  def _create_dispifc(self) -> "ComtypesCppTestSrvLib.IDispRecordParamTest":
27
27
  # Explicitely ask for the dispinterface of the component.
28
28
  return CreateObject(
29
- "Comtypes.DispIfcParamTests",
29
+ "Comtypes.DispRecordParamTest",
30
30
  clsctx=CLSCTX_LOCAL_SERVER,
31
31
  interface=ComtypesCppTestSrvLib.IDispRecordParamTest,
32
32
  )
@@ -0,0 +1,89 @@
1
+ # coding: utf-8
2
+
3
+ from ctypes import byref, c_double, pointer
4
+ import unittest
5
+
6
+ import comtypes
7
+ import comtypes.safearray
8
+ from comtypes import CLSCTX_LOCAL_SERVER
9
+ from comtypes.client import CreateObject, GetModule
10
+
11
+ ComtypesCppTestSrvLib_GUID = "{07D2AEE5-1DF8-4D2C-953A-554ADFD25F99}"
12
+
13
+ try:
14
+ GetModule((ComtypesCppTestSrvLib_GUID, 1, 0, 0))
15
+ import comtypes.gen.ComtypesCppTestSrvLib as ComtypesCppTestSrvLib
16
+
17
+ IMPORT_FAILED = False
18
+ except (ImportError, OSError):
19
+ IMPORT_FAILED = True
20
+
21
+
22
+ @unittest.skipIf(IMPORT_FAILED, "This depends on the out of process COM-server.")
23
+ class Test_DispMethods(unittest.TestCase):
24
+ """Test dispmethods with safearray and safearray pointer parameters."""
25
+
26
+ UNPACKED_ZERO_VALS = tuple(0.0 for _ in range(10))
27
+ UNPACKED_CONSECUTIVE_VALS = tuple(float(i) for i in range(10))
28
+
29
+ def _create_dispifc(self) -> "ComtypesCppTestSrvLib.IDispSafearrayParamTest":
30
+ # Explicitely ask for the dispinterface of the component.
31
+ return CreateObject(
32
+ "Comtypes.DispSafearrayParamTest",
33
+ clsctx=CLSCTX_LOCAL_SERVER,
34
+ interface=ComtypesCppTestSrvLib.IDispSafearrayParamTest,
35
+ )
36
+
37
+ def _create_zero_array(self):
38
+ return comtypes.safearray._midlSAFEARRAY(c_double).create(
39
+ [c_double() for _ in range(10)]
40
+ )
41
+
42
+ def _create_consecutive_array(self):
43
+ return comtypes.safearray._midlSAFEARRAY(c_double).create(
44
+ [c_double(i) for i in range(10)]
45
+ )
46
+
47
+ def test_inout_byref(self):
48
+ dispifc = self._create_dispifc()
49
+ # Passing a safearray by reference to a method that has declared the parameter
50
+ # as [in, out] we expect modifications of the safearray on the server side to
51
+ # also change the safearray on the client side.
52
+ test_array = self._create_zero_array()
53
+ self.assertEqual(test_array.unpack(), self.UNPACKED_ZERO_VALS)
54
+ dispifc.InitArray(byref(test_array))
55
+ self.assertEqual(test_array.unpack(), self.UNPACKED_CONSECUTIVE_VALS)
56
+
57
+ def test_inout_pointer(self):
58
+ dispifc = self._create_dispifc()
59
+ # Passing a safearray pointer to a method that has declared the parameter
60
+ # as [in, out] we expect modifications of the safearray on the server side to
61
+ # also change the safearray on the client side.
62
+ test_array = self._create_zero_array()
63
+ self.assertEqual(test_array.unpack(), self.UNPACKED_ZERO_VALS)
64
+ dispifc.InitArray(pointer(test_array))
65
+ self.assertEqual(test_array.unpack(), self.UNPACKED_CONSECUTIVE_VALS)
66
+
67
+ def test_in_safearray(self):
68
+ # Passing a safearray to a method that has declared the parameter just as [in]
69
+ # we expect modifications of the safearray on the server side NOT to change
70
+ # the safearray on the client side.
71
+ # We also need to test if the safearray gets properly passed to the method on
72
+ # the server side. For this, the 'VerifyArray' method returns 'True' if
73
+ # the safearray items have values equal to the initialization values
74
+ # provided by 'InitArray'.
75
+ for sa, expected, unpacked_content in [
76
+ (self._create_consecutive_array(), True, self.UNPACKED_CONSECUTIVE_VALS),
77
+ # Also perform the inverted test. For this, create a safearray with zeros.
78
+ (self._create_zero_array(), False, self.UNPACKED_ZERO_VALS),
79
+ ]:
80
+ with self.subTest(expected=expected, unpacked_content=unpacked_content):
81
+ # Perform the check on initialization values.
82
+ self.assertEqual(self._create_dispifc().VerifyArray(sa), expected)
83
+ # Check if the safearray is unchanged although the method
84
+ # modifies the safearray on the server side.
85
+ self.assertEqual(sa.unpack(), unpacked_content)
86
+
87
+
88
+ if __name__ == "__main__":
89
+ unittest.main()
@@ -0,0 +1,53 @@
1
+ import unittest as ut
2
+
3
+ from ctypes import POINTER, byref, c_bool, c_ubyte
4
+ import comtypes
5
+ import comtypes.client
6
+
7
+ comtypes.client.GetModule("portabledeviceapi.dll")
8
+ from comtypes.gen.PortableDeviceApiLib import IStream
9
+
10
+
11
+ def _create_stream() -> IStream:
12
+ # Create an IStream
13
+ stream = POINTER(IStream)() # type: ignore
14
+ comtypes._ole32.CreateStreamOnHGlobal(None, c_bool(True), byref(stream))
15
+ return stream # type: ignore
16
+
17
+
18
+ class Test_RemoteWrite(ut.TestCase):
19
+ def test_RemoteWrite(self):
20
+ stream = _create_stream()
21
+ test_data = "Some data".encode("utf-8")
22
+ pv = (c_ubyte * len(test_data)).from_buffer(bytearray(test_data))
23
+
24
+ written = stream.RemoteWrite(pv, len(test_data))
25
+
26
+ # Verification
27
+ self.assertEqual(written, len(test_data))
28
+
29
+
30
+ class Test_RemoteRead(ut.TestCase):
31
+ def test_RemoteRead(self):
32
+ stream = _create_stream()
33
+ test_data = "Some data".encode("utf-8")
34
+ pv = (c_ubyte * len(test_data)).from_buffer(bytearray(test_data))
35
+ stream.RemoteWrite(pv, len(test_data))
36
+
37
+ # Make sure the data actually gets written before trying to read back
38
+ stream.Commit(0)
39
+ # Move the stream back to the beginning
40
+ STREAM_SEEK_SET = 0
41
+ stream.RemoteSeek(0, STREAM_SEEK_SET)
42
+
43
+ buffer_size = 1024
44
+
45
+ read_buffer, data_read = stream.RemoteRead(buffer_size)
46
+
47
+ # Verification
48
+ self.assertEqual(data_read, len(test_data))
49
+ self.assertEqual(bytearray(read_buffer)[0:data_read], test_data)
50
+
51
+
52
+ if __name__ == "__main__":
53
+ ut.main()
@@ -0,0 +1,100 @@
1
+ # coding: utf-8
2
+
3
+ from ctypes import c_int, pointer, POINTER
4
+ import unittest
5
+
6
+ import comtypes
7
+ import comtypes.safearray
8
+ from comtypes import CLSCTX_INPROC_SERVER, CLSCTX_LOCAL_SERVER
9
+ from comtypes.client import CreateObject, GetModule
10
+ import comtypes.typeinfo
11
+
12
+ GetModule("UIAutomationCore.dll")
13
+ from comtypes.gen.UIAutomationClient import CUIAutomation, IUIAutomation
14
+
15
+ ComtypesCppTestSrvLib_GUID = "{07D2AEE5-1DF8-4D2C-953A-554ADFD25F99}"
16
+
17
+ try:
18
+ GetModule((ComtypesCppTestSrvLib_GUID, 1, 0, 0))
19
+ from comtypes.gen.ComtypesCppTestSrvLib import StructRecordParamTest
20
+ from comtypes.gen.ComtypesCppTestSrvLib import IDispSafearrayParamTest
21
+
22
+ IMPORT_FAILED = False
23
+ except (ImportError, OSError):
24
+ IMPORT_FAILED = True
25
+
26
+
27
+ class Test_midlSAFEARRAY_create(unittest.TestCase):
28
+ def test_iunk(self):
29
+ extra = pointer(IUIAutomation._iid_)
30
+ iuia = CreateObject(
31
+ CUIAutomation().IPersist_GetClassID(),
32
+ interface=IUIAutomation,
33
+ clsctx=CLSCTX_INPROC_SERVER,
34
+ )
35
+ sa_type = comtypes.safearray._midlSAFEARRAY(POINTER(IUIAutomation))
36
+ for ptn, sa in [
37
+ ("with extra", sa_type.create([iuia], extra=extra)),
38
+ ("without extra", sa_type.create([iuia])),
39
+ ]:
40
+ with self.subTest(ptn=ptn):
41
+ (unpacked,) = sa.unpack()
42
+ self.assertIsInstance(unpacked, POINTER(IUIAutomation))
43
+
44
+ @unittest.skipIf(IMPORT_FAILED, "This depends on the out of process COM-server.")
45
+ def test_idisp(self):
46
+ extra = pointer(IDispSafearrayParamTest._iid_)
47
+ idisp = CreateObject(
48
+ "Comtypes.DispSafearrayParamTest",
49
+ clsctx=CLSCTX_LOCAL_SERVER,
50
+ interface=IDispSafearrayParamTest,
51
+ )
52
+ sa_type = comtypes.safearray._midlSAFEARRAY(POINTER(IDispSafearrayParamTest))
53
+ for ptn, sa in [
54
+ ("with extra", sa_type.create([idisp], extra=extra)),
55
+ ("without extra", sa_type.create([idisp])),
56
+ ]:
57
+ with self.subTest(ptn=ptn):
58
+ (unpacked,) = sa.unpack()
59
+ self.assertIsInstance(unpacked, POINTER(IDispSafearrayParamTest))
60
+
61
+ @unittest.skipIf(IMPORT_FAILED, "This depends on the out of process COM-server.")
62
+ def test_record(self):
63
+ extra = comtypes.typeinfo.GetRecordInfoFromGuids(
64
+ *StructRecordParamTest._recordinfo_
65
+ )
66
+ record = StructRecordParamTest()
67
+ record.question = "The meaning of life, the universe and everything?"
68
+ record.answer = 42
69
+ record.needs_clarification = True
70
+ sa_type = comtypes.safearray._midlSAFEARRAY(StructRecordParamTest)
71
+ for ptn, sa in [
72
+ ("with extra", sa_type.create([record], extra=extra)),
73
+ ("without extra", sa_type.create([record])),
74
+ ]:
75
+ with self.subTest(ptn=ptn):
76
+ (unpacked,) = sa.unpack()
77
+ self.assertIsInstance(unpacked, StructRecordParamTest)
78
+ self.assertEqual(
79
+ unpacked.question,
80
+ "The meaning of life, the universe and everything?",
81
+ )
82
+ self.assertEqual(unpacked.answer, 42)
83
+ self.assertEqual(unpacked.needs_clarification, True)
84
+
85
+ def test_ctype(self):
86
+ extra = None
87
+ cdata = c_int(1)
88
+ sa_type = comtypes.safearray._midlSAFEARRAY(c_int)
89
+ for ptn, sa in [
90
+ ("with extra", sa_type.create([cdata], extra=extra)),
91
+ ("without extra", sa_type.create([cdata])),
92
+ ]:
93
+ with self.subTest(ptn=ptn):
94
+ (unpacked,) = sa.unpack()
95
+ self.assertIsInstance(unpacked, int)
96
+ self.assertEqual(unpacked, 1)
97
+
98
+
99
+ if __name__ == "__main__":
100
+ unittest.main()
@@ -1,17 +1,10 @@
1
- import sys
2
1
  import unittest as ut
3
- from ctypes import POINTER
2
+
4
3
  from comtypes.client import CoGetObject
5
4
  from comtypes.test import requires
6
5
 
7
6
  requires("time")
8
7
 
9
- if sys.version_info >= (3, 0):
10
- base_text_type = str
11
- text_type = str
12
- else:
13
- base_text_type = basestring
14
- text_type = unicode
15
8
 
16
9
  # WMI has dual interfaces.
17
10
  # Some methods/properties have "[out] POINTER(VARIANT)" parameters.
@@ -19,7 +12,7 @@ else:
19
12
  # that's what VARIANT.__ctypes_from_outparam__ does.
20
13
  class Test(ut.TestCase):
21
14
  def test_wmi(self):
22
- wmi = CoGetObject("winmgmts:")
15
+ wmi: "WbemScripting.ISWbemServices" = CoGetObject("winmgmts:")
23
16
  disks = wmi.InstancesOf("Win32_LogicalDisk")
24
17
 
25
18
  # There are different typelibs installed for WMI on win2k and winXP.
@@ -28,8 +21,8 @@ class Test(ut.TestCase):
28
21
  # import comtypes.gen._565783C6_CB41_11D1_8B02_00600806D9B6_0_1_1 as mod
29
22
  # WinXP:
30
23
  # import comtypes.gen._565783C6_CB41_11D1_8B02_00600806D9B6_0_1_2 as mod
31
- # So, the one that's referenced onm WbemScripting will be used, whether the actual
32
- # typelib is available or not. XXX
24
+ # So, the one that's referenced onm WbemScripting will be used, whether the
25
+ # actual typelib is available or not. XXX
33
26
  from comtypes.gen import WbemScripting
34
27
 
35
28
  WbemScripting.wbemPrivilegeCreateToken
@@ -37,25 +30,25 @@ class Test(ut.TestCase):
37
30
  for item in disks:
38
31
  # obj[index] is forwarded to obj.Item(index)
39
32
  # .Value is a property with "[out] POINTER(VARIANT)" parameter.
33
+ item: "WbemScripting.ISWbemObject"
40
34
  a = item.Properties_["Caption"].Value
41
35
  b = item.Properties_.Item("Caption").Value
42
36
  c = item.Properties_("Caption").Value
43
37
  self.assertEqual(a, b)
44
38
  self.assertEqual(a, c)
45
- self.assertTrue(isinstance(a, base_text_type))
46
- self.assertTrue(isinstance(b, base_text_type))
47
- self.assertTrue(isinstance(c, base_text_type))
39
+ self.assertTrue(isinstance(a, str))
40
+ self.assertTrue(isinstance(b, str))
41
+ self.assertTrue(isinstance(c, str))
48
42
  result = {}
49
43
  for prop in item.Properties_:
50
- self.assertTrue(isinstance(prop.Name, base_text_type))
44
+ prop: "WbemScripting.ISWbemProperty"
45
+ self.assertTrue(isinstance(prop.Name, str))
51
46
  prop.Value
52
47
  result[prop.Name] = prop.Value
53
48
  # print "\t", (prop.Name, prop.Value)
54
49
  self.assertEqual(len(item.Properties_), item.Properties_.Count)
55
50
  self.assertEqual(len(item.Properties_), len(result))
56
- self.assertTrue(
57
- isinstance(item.Properties_["Description"].Value, text_type)
58
- )
51
+ self.assertTrue(isinstance(item.Properties_["Description"].Value, str))
59
52
  # len(obj) is forwared to obj.Count
60
53
  self.assertEqual(len(disks), disks.Count)
61
54
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: comtypes
3
- Version: 1.4.4
3
+ Version: 1.4.5
4
4
  Summary: Pure Python COM package
5
5
  Home-page: https://github.com/enthought/comtypes
6
6
  Download-URL: https://github.com/enthought/comtypes/releases
@@ -8,10 +8,13 @@ setup.py
8
8
  comtypes/GUID.py
9
9
  comtypes/__init__.py
10
10
  comtypes/_comobject.py
11
+ comtypes/_idl_stuff.py
11
12
  comtypes/_memberspec.py
12
13
  comtypes/_meta.py
13
14
  comtypes/_npsupport.py
15
+ comtypes/_py_instance_method.py
14
16
  comtypes/_safearray.py
17
+ comtypes/_tlib_version_checker.py
15
18
  comtypes/automation.py
16
19
  comtypes/clear_cache.py
17
20
  comtypes/connectionpoints.py
@@ -25,6 +28,7 @@ comtypes/patcher.py
25
28
  comtypes/persist.py
26
29
  comtypes/safearray.py
27
30
  comtypes/shelllink.py
31
+ comtypes/stream.py
28
32
  comtypes/typeinfo.py
29
33
  comtypes/util.py
30
34
  comtypes/viewobject.py
@@ -33,6 +37,10 @@ comtypes.egg-info/SOURCES.txt
33
37
  comtypes.egg-info/dependency_links.txt
34
38
  comtypes.egg-info/entry_points.txt
35
39
  comtypes.egg-info/top_level.txt
40
+ comtypes/_post_coinit/__init__.py
41
+ comtypes/_post_coinit/bstr.py
42
+ comtypes/_post_coinit/misc.py
43
+ comtypes/_post_coinit/unknwn.py
36
44
  comtypes/client/__init__.py
37
45
  comtypes/client/_code_cache.py
38
46
  comtypes/client/_constants.py
@@ -77,6 +85,7 @@ comtypes/test/test_comserver.py
77
85
  comtypes/test/test_createwrappers.py
78
86
  comtypes/test/test_dict.py
79
87
  comtypes/test/test_dispifc_records.py
88
+ comtypes/test/test_dispifc_safearrays.py
80
89
  comtypes/test/test_dispinterface.py
81
90
  comtypes/test/test_dyndispatch.py
82
91
  comtypes/test/test_excel.py
@@ -86,7 +95,9 @@ comtypes/test/test_ie.py
86
95
  comtypes/test/test_ienum.py
87
96
  comtypes/test/test_imfattributes.py
88
97
  comtypes/test/test_inout_args.py
98
+ comtypes/test/test_istream.py
89
99
  comtypes/test/test_jscript.js
100
+ comtypes/test/test_midl_safearray_create.py
90
101
  comtypes/test/test_msscript.py
91
102
  comtypes/test/test_npsupport.py
92
103
  comtypes/test/test_outparam.py
@@ -21,6 +21,7 @@ classifiers =
21
21
  python_requires = >=3.7
22
22
  packages =
23
23
  comtypes
24
+ comtypes._post_coinit
24
25
  comtypes.client
25
26
  comtypes.server
26
27
  comtypes.tools