comtypes 1.1.14__zip → 1.2.1__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 (106) hide show
  1. {comtypes-1.1.14 → comtypes-1.2.1}/CHANGES.txt +37 -0
  2. comtypes-1.2.1/PKG-INFO +79 -0
  3. comtypes-1.2.1/README.md +59 -0
  4. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/__init__.py +302 -555
  5. comtypes-1.2.1/comtypes/_memberspec.py +520 -0
  6. comtypes-1.2.1/comtypes/_npsupport.py +143 -0
  7. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/automation.py +99 -11
  8. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/__init__.py +80 -26
  9. comtypes-1.2.1/comtypes/client/_generate.py +274 -0
  10. comtypes-1.2.1/comtypes/hints.pyi +26 -0
  11. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/persist.py +14 -0
  12. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/safearray.py +22 -21
  13. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/__init__.py +0 -7
  14. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_client.py +35 -0
  15. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_dict.py +0 -4
  16. comtypes-1.2.1/comtypes/test/test_npsupport.py +343 -0
  17. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_safearray.py +2 -235
  18. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_variant.py +6 -59
  19. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/tools/codegenerator.py +454 -337
  20. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/tools/tlbparser.py +56 -75
  21. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/tools/typedesc.py +31 -3
  22. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/tools/typedesc_base.py +28 -1
  23. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/typeinfo.py +291 -121
  24. comtypes-1.2.1/comtypes.egg-info/PKG-INFO +79 -0
  25. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes.egg-info/SOURCES.txt +4 -1
  26. {comtypes-1.1.14 → comtypes-1.2.1}/setup.cfg +0 -1
  27. {comtypes-1.1.14 → comtypes-1.2.1}/setup.py +15 -8
  28. comtypes-1.1.14/PKG-INFO +0 -50
  29. comtypes-1.1.14/README.md +0 -31
  30. comtypes-1.1.14/comtypes/client/_generate.py +0 -257
  31. comtypes-1.1.14/comtypes/npsupport.py +0 -125
  32. comtypes-1.1.14/comtypes.egg-info/PKG-INFO +0 -50
  33. {comtypes-1.1.14 → comtypes-1.2.1}/LICENSE.txt +0 -0
  34. {comtypes-1.1.14 → comtypes-1.2.1}/MANIFEST.in +0 -0
  35. {comtypes-1.1.14 → comtypes-1.2.1}/clear_comtypes_cache.py +0 -0
  36. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/GUID.py +0 -0
  37. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/_comobject.py +0 -0
  38. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/_meta.py +0 -0
  39. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/_safearray.py +0 -0
  40. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/_code_cache.py +0 -0
  41. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/_constants.py +0 -0
  42. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/_events.py +0 -0
  43. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/dynamic.py +0 -0
  44. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/lazybind.py +0 -0
  45. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/connectionpoints.py +0 -0
  46. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/errorinfo.py +0 -0
  47. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/git.py +0 -0
  48. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/hresult.py +0 -0
  49. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/logutil.py +0 -0
  50. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/messageloop.py +0 -0
  51. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/patcher.py +0 -0
  52. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/__init__.py +0 -0
  53. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/automation.py +0 -0
  54. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/connectionpoints.py +0 -0
  55. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/inprocserver.py +0 -0
  56. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/localserver.py +0 -0
  57. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/register.py +0 -0
  58. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/w_getopt.py +0 -0
  59. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/shelllink.py +0 -0
  60. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestComServer.idl +0 -0
  61. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestComServer.py +0 -0
  62. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestComServer.tlb +0 -0
  63. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestDispServer.idl +0 -0
  64. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestDispServer.py +0 -0
  65. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestDispServer.tlb +0 -0
  66. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/find_memleak.py +0 -0
  67. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/mylib.idl +0 -0
  68. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/mytypelib.idl +0 -0
  69. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/runtests.py +0 -0
  70. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/setup.py +0 -0
  71. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_BSTR.py +0 -0
  72. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_DISPPARAMS.py +0 -0
  73. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_GUID.py +0 -0
  74. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_QueryService.py +0 -0
  75. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_agilent.py +0 -0
  76. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_avmc.py +0 -0
  77. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_basic.py +0 -0
  78. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_casesensitivity.py +0 -0
  79. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_collections.py +0 -0
  80. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_comserver.py +0 -0
  81. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_createwrappers.py +0 -0
  82. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_dispinterface.py +0 -0
  83. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_dyndispatch.py +0 -0
  84. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_excel.py +0 -0
  85. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_findgendir.py +0 -0
  86. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_getactiveobj.py +0 -0
  87. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_ie.py +0 -0
  88. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_jscript.js +0 -0
  89. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_msscript.py +0 -0
  90. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_outparam.py +0 -0
  91. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_propputref.py +0 -0
  92. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_pump_events.py +0 -0
  93. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_sapi.py +0 -0
  94. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_server.py +0 -0
  95. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_showevents.py +0 -0
  96. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_subinterface.py +0 -0
  97. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_typeinfo.py +0 -0
  98. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_urlhistory.py +0 -0
  99. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_win32com_interop.py +0 -0
  100. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_wmi.py +0 -0
  101. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_word.py +0 -0
  102. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/tools/__init__.py +0 -0
  103. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/util.py +0 -0
  104. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/viewobject.py +0 -0
  105. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes.egg-info/dependency_links.txt +0 -0
  106. {comtypes-1.1.14 → comtypes-1.2.1}/comtypes.egg-info/top_level.txt +0 -0
@@ -0,0 +1,343 @@
1
+ import datetime
2
+ import functools
3
+ import importlib
4
+ import inspect
5
+ import unittest
6
+ from ctypes import c_long, c_double, pointer, POINTER
7
+ from decimal import Decimal
8
+
9
+ import comtypes._npsupport
10
+ from comtypes import IUnknown
11
+ from comtypes._safearray import SafeArrayGetVartype
12
+ from comtypes.automation import (
13
+ BSTR,
14
+ VT_BSTR,
15
+ VT_DATE,
16
+ VT_I4,
17
+ _midlSAFEARRAY,
18
+ VARIANT,
19
+ VT_VARIANT,
20
+ VARIANT_BOOL
21
+ )
22
+ from comtypes.safearray import safearray_as_ndarray
23
+
24
+ try:
25
+ import numpy
26
+ except ImportError:
27
+ numpy = None
28
+
29
+
30
+ def setUpModule():
31
+ """Only run the module if we can import numpy."""
32
+ if numpy is None:
33
+ raise unittest.SkipTest("Skipping test_npsupport as numpy not installed.")
34
+
35
+
36
+ def get_ndarray(sa):
37
+ """Get an array from a safe array type"""
38
+ with safearray_as_ndarray:
39
+ return sa[0]
40
+
41
+
42
+ def com_refcnt(o):
43
+ """Return the COM refcount of an interface pointer"""
44
+ import gc
45
+ gc.collect()
46
+ gc.collect()
47
+ o.AddRef()
48
+ return o.Release()
49
+
50
+
51
+ def enabled_disabled(disabled_error):
52
+ """Decorator for testing which will replace the original test method with
53
+ two new methods in the same local frame, one will be called where npsupport
54
+ is enabled, the other where it is disabled. For the disabled version, it is
55
+ expected that disabled_error will be raised by the function.
56
+ """
57
+ frame_locals = inspect.currentframe().f_back.f_locals
58
+
59
+ def decorator_enabled_disabled(func):
60
+ @functools.wraps(func)
61
+ def call_enabled(self):
62
+ from comtypes import npsupport
63
+ npsupport.enable()
64
+ func(self)
65
+
66
+ @functools.wraps(func)
67
+ def call_disabled(self):
68
+ from comtypes import npsupport
69
+ if npsupport.enabled:
70
+ raise EnvironmentError(
71
+ "Expected numpy interop not to be enabled but it is."
72
+ )
73
+ with self.assertRaises(disabled_error):
74
+ func(self)
75
+
76
+ frame_locals[func.__name__ + "_enabled"] = call_enabled
77
+ frame_locals[func.__name__ + "_disabled"] = call_disabled
78
+
79
+ return decorator_enabled_disabled
80
+
81
+
82
+ class NumpySupportTestCase(unittest.TestCase):
83
+ def setUp(self):
84
+ # we reload the module in between tests to disable the previously
85
+ # enabled interop functionality
86
+ importlib.reload(comtypes._npsupport)
87
+ comtypes.npsupport = comtypes._npsupport.interop
88
+
89
+ @enabled_disabled(disabled_error=ImportError)
90
+ def test_not_imported_imported(self):
91
+ np = comtypes.npsupport.numpy
92
+ self.assertEqual(np, numpy)
93
+
94
+ def test_nested_contexts(self):
95
+ t = _midlSAFEARRAY(BSTR)
96
+ sa = t.from_param(["a", "b", "c"])
97
+
98
+ first = sa[0]
99
+ with safearray_as_ndarray:
100
+ second = sa[0]
101
+ with safearray_as_ndarray:
102
+ third = sa[0]
103
+ fourth = sa[0]
104
+ fifth = sa[0]
105
+
106
+ self.assertTrue(isinstance(first, tuple))
107
+ self.assertTrue(isinstance(second, numpy.ndarray))
108
+ self.assertTrue(isinstance(third, numpy.ndarray))
109
+ self.assertTrue(isinstance(fourth, numpy.ndarray))
110
+ self.assertTrue(isinstance(fifth, tuple))
111
+
112
+ @unittest.skip(
113
+ "Skipping because numpy cannot currently create an array of variants "
114
+ "because it doesn't recognise the VARIANT_BOOL typecode 'v'."
115
+ )
116
+ def test_datetime64_ndarray(self):
117
+ comtypes.npsupport.enable()
118
+ dates = numpy.array([
119
+ numpy.datetime64("2000-01-01T05:30:00", "s"),
120
+ numpy.datetime64("1800-01-01T05:30:00", "ms"),
121
+ numpy.datetime64("2014-03-07T00:12:56", "us"),
122
+ numpy.datetime64("2000-01-01T12:34:56", "ns"),
123
+ ])
124
+
125
+ t = _midlSAFEARRAY(VARIANT)
126
+ sa = t.from_param(dates)
127
+ arr = get_ndarray(sa).astype(dates.dtype)
128
+ self.assertTrue((dates == arr).all())
129
+
130
+ @unittest.skip(
131
+ "This fails with a 'library not registered' error. Need to figure "
132
+ "out how to register TestComServerLib (without admin if possible)."
133
+ )
134
+ def test_UDT_ndarray(self):
135
+ from comtypes.gen.TestComServerLib import MYCOLOR
136
+
137
+ t = _midlSAFEARRAY(MYCOLOR)
138
+ self.assertTrue(t is _midlSAFEARRAY(MYCOLOR))
139
+
140
+ sa = t.from_param([MYCOLOR(0, 0, 0), MYCOLOR(1, 2, 3)])
141
+ arr = get_ndarray(sa)
142
+
143
+ self.assertTrue(isinstance(arr, numpy.ndarray))
144
+ # The conversion code allows numpy to choose the dtype of
145
+ # structured data. This dtype is structured under numpy 1.5, 1.7 and
146
+ # 1.8, and object in 1.6. Instead of assuming either of these, check
147
+ # the array contents based on the chosen type.
148
+ if arr.dtype is numpy.dtype(object):
149
+ data = [(x.red, x.green, x.blue) for x in arr]
150
+ else:
151
+ float_dtype = numpy.dtype('float64')
152
+ self.assertIs(arr.dtype[0], float_dtype)
153
+ self.assertIs(arr.dtype[1], float_dtype)
154
+ self.assertIs(arr.dtype[2], float_dtype)
155
+ data = [tuple(x) for x in arr]
156
+ self.assertEqual(data, [(0.0, 0.0, 0.0), (1.0, 2.0, 3.0)])
157
+
158
+ def test_VT_BOOL_ndarray(self):
159
+ t = _midlSAFEARRAY(VARIANT_BOOL)
160
+
161
+ sa = t.from_param([True, False, True, False])
162
+ arr = get_ndarray(sa)
163
+ self.assertEqual(numpy.dtype(numpy.bool_), arr.dtype)
164
+ self.assertTrue(isinstance(arr, numpy.ndarray))
165
+ self.assertTrue((arr == (True, False, True, False)).all())
166
+
167
+ def test_VT_BSTR_ndarray(self):
168
+ t = _midlSAFEARRAY(BSTR)
169
+
170
+ sa = t.from_param(["a", "b", "c"])
171
+ arr = get_ndarray(sa)
172
+
173
+ self.assertTrue(isinstance(arr, numpy.ndarray))
174
+ self.assertEqual(numpy.dtype("<U1"), arr.dtype)
175
+ self.assertTrue((arr == ("a", "b", "c")).all())
176
+ self.assertEqual(SafeArrayGetVartype(sa), VT_BSTR)
177
+
178
+ @enabled_disabled(disabled_error=ValueError)
179
+ def test_VT_I4_ndarray(self):
180
+ t = _midlSAFEARRAY(c_long)
181
+
182
+ in_arr = numpy.array([11, 22, 33])
183
+ sa = t.from_param(in_arr)
184
+
185
+ arr = get_ndarray(sa)
186
+
187
+ self.assertTrue(isinstance(arr, numpy.ndarray))
188
+ self.assertEqual(numpy.dtype(int), arr.dtype)
189
+ self.assertTrue((arr == in_arr).all())
190
+ self.assertEqual(SafeArrayGetVartype(sa), VT_I4)
191
+
192
+ @enabled_disabled(disabled_error=ValueError)
193
+ def test_array(self):
194
+ t = _midlSAFEARRAY(c_double)
195
+ pat = pointer(t())
196
+
197
+ pat[0] = numpy.zeros(32, dtype=float)
198
+ arr = get_ndarray(pat[0])
199
+ self.assertTrue(isinstance(arr, numpy.ndarray))
200
+ self.assertEqual(numpy.dtype(float), arr.dtype)
201
+ self.assertTrue((arr == (0.0,) * 32).all())
202
+
203
+ data = ((1.0, 2.0, 3.0), (4.0, 5.0, 6.0), (7.0, 8.0, 9.0))
204
+ a = numpy.array(data, dtype=float)
205
+ pat[0] = a
206
+ arr = get_ndarray(pat[0])
207
+ self.assertTrue(isinstance(arr, numpy.ndarray))
208
+ self.assertEqual(numpy.dtype(float), arr.dtype)
209
+ self.assertTrue((arr == data).all())
210
+
211
+ data = ((1.0, 2.0), (3.0, 4.0), (5.0, 6.0))
212
+ a = numpy.array(data, dtype=float, order="F")
213
+ pat[0] = a
214
+ arr = get_ndarray(pat[0])
215
+ self.assertTrue(isinstance(arr, numpy.ndarray))
216
+ self.assertEqual(numpy.dtype(float), arr.dtype)
217
+ self.assertEqual(pat[0][0], data)
218
+
219
+ @unittest.skip(
220
+ "Skipping because creating an ndarray from ctypes pointer to c_void_p "
221
+ "is not currently supported."
222
+ )
223
+ def test_VT_UNKNOWN_multi_ndarray(self):
224
+ a = _midlSAFEARRAY(POINTER(IUnknown))
225
+ t = _midlSAFEARRAY(POINTER(IUnknown))
226
+ self.assertTrue(a is t)
227
+
228
+ from comtypes.typeinfo import CreateTypeLib
229
+ # will never be saved to disk
230
+ punk = CreateTypeLib("spam").QueryInterface(IUnknown)
231
+
232
+ # initial refcount
233
+ initial = com_refcnt(punk)
234
+
235
+ # This should increase the refcount by 4
236
+ sa = t.from_param((punk,) * 4)
237
+ self.assertEqual(initial + 4, com_refcnt(punk))
238
+
239
+ # Unpacking the array must not change the refcount, and must
240
+ # return an equal object. Creating an ndarray may change the
241
+ # refcount.
242
+ arr = get_ndarray(sa)
243
+ self.assertTrue(isinstance(arr, numpy.ndarray))
244
+ self.assertEqual(numpy.dtype(object), arr.dtype)
245
+ self.assertTrue((arr == (punk,)*4).all())
246
+ self.assertEqual(initial + 8, com_refcnt(punk))
247
+
248
+ del arr
249
+ self.assertEqual(initial + 4, com_refcnt(punk))
250
+
251
+ del sa
252
+ self.assertEqual(initial, com_refcnt(punk))
253
+
254
+ # This should increase the refcount by 2
255
+ sa = t.from_param((punk, None, punk, None))
256
+ self.assertEqual(initial + 2, com_refcnt(punk))
257
+
258
+ null = POINTER(IUnknown)()
259
+ arr = get_ndarray(sa)
260
+ self.assertTrue(isinstance(arr, numpy.ndarray))
261
+ self.assertEqual(numpy.dtype(object), arr.dtype)
262
+ self.assertTrue((arr == (punk, null, punk, null)).all())
263
+
264
+ del sa
265
+ del arr
266
+ self.assertEqual(initial, com_refcnt(punk))
267
+
268
+ @unittest.skip(
269
+ "Skipping because numpy cannot currently create an array of variants "
270
+ "because it doesn't recognise the VARIANT_BOOL typecode 'v'."
271
+ )
272
+ def test_VT_VARIANT_ndarray(self):
273
+ comtypes.npsupport.enable()
274
+ t = _midlSAFEARRAY(VARIANT)
275
+
276
+ now = datetime.datetime.now()
277
+ inarr = numpy.array(
278
+ [11, "22", "33", 44.0, None, True, now, Decimal("3.14")]
279
+ ).reshape(2, 4)
280
+ sa = t.from_param(inarr)
281
+ arr = get_ndarray(sa)
282
+ self.assertEqual(numpy.dtype(object), arr.dtype)
283
+ self.assertTrue(isinstance(arr, numpy.ndarray))
284
+ self.assertTrue((arr == inarr).all())
285
+ self.assertEqual(SafeArrayGetVartype(sa), VT_VARIANT)
286
+
287
+
288
+ class NumpyVariantTest(unittest.TestCase):
289
+ def setUp(self):
290
+ # we reload the module in between tests to disable the previously
291
+ # enabled interop functionality
292
+ importlib.reload(comtypes._npsupport)
293
+ comtypes.npsupport = comtypes._npsupport.interop
294
+
295
+ @enabled_disabled(disabled_error=ValueError)
296
+ def test_double(self):
297
+ for dtype in ('float32', 'float64'):
298
+ # because of FLOAT rounding errors, whi will only work for
299
+ # certain values!
300
+ a = numpy.array([1.0, 2.0, 3.0, 4.5], dtype=dtype)
301
+ v = VARIANT()
302
+ v.value = a
303
+ self.assertTrue((v.value == a).all())
304
+
305
+ @enabled_disabled(disabled_error=ValueError)
306
+ def test_int(self):
307
+ for dtype in ('int8', 'int16', 'int32', 'int64', 'uint8',
308
+ 'uint16', 'uint32', 'uint64'):
309
+ a = numpy.array((1, 1, 1, 1), dtype=dtype)
310
+ v = VARIANT()
311
+ v.value = a
312
+ self.assertTrue((v.value == a).all())
313
+
314
+ @enabled_disabled(disabled_error=ValueError)
315
+ def test_datetime64(self):
316
+ dates = [
317
+ numpy.datetime64("2000-01-01T05:30:00", "s"),
318
+ numpy.datetime64("1800-01-01T05:30:00", "ms"),
319
+ numpy.datetime64("2000-01-01T12:34:56", "us")
320
+ ]
321
+
322
+ for date in dates:
323
+ v = VARIANT()
324
+ v.value = date
325
+ self.assertEqual(v.vt, VT_DATE)
326
+ self.assertEqual(v.value, date.astype(datetime.datetime))
327
+
328
+ @unittest.skip(
329
+ "Skipping because numpy cannot currently create an array of variants "
330
+ "because it doesn't recognise the VARIANT_BOOL typecode 'v'."
331
+ )
332
+ def test_mixed(self):
333
+ comtypes.npsupport.enable()
334
+ now = datetime.datetime.now()
335
+ a = numpy.array(
336
+ [11, "22", None, True, now, Decimal("3.14")]).reshape(2, 3)
337
+ v = VARIANT()
338
+ v.value = a
339
+ self.assertTrue((v.value == a).all())
340
+
341
+
342
+ if __name__ == "__main__":
343
+ unittest.main()
@@ -1,7 +1,7 @@
1
1
  import array
2
2
  import datetime
3
3
  import unittest
4
- from ctypes import POINTER, PyDLL, byref, c_double, c_long, pointer, py_object
4
+ from ctypes import POINTER, PyDLL, byref, c_long, py_object
5
5
  from ctypes.wintypes import BOOL
6
6
  from decimal import Decimal
7
7
 
@@ -9,7 +9,7 @@ from comtypes import BSTR, IUnknown
9
9
  from comtypes._safearray import SafeArrayGetVartype
10
10
  from comtypes.automation import VARIANT, VARIANT_BOOL, VT_ARRAY, VT_BSTR, VT_I4, VT_R4, VT_R8, VT_VARIANT, _midlSAFEARRAY
11
11
  from comtypes.safearray import safearray_as_ndarray
12
- from comtypes.test import get_numpy, is_resource_enabled
12
+ from comtypes.test import is_resource_enabled
13
13
  from comtypes.test.find_memleak import find_memleak
14
14
 
15
15
 
@@ -55,16 +55,12 @@ class VariantTestCase(unittest.TestCase):
55
55
  bytes = find_memleak(func)
56
56
  self.assertFalse(bytes, "Leaks %d bytes" % bytes)
57
57
 
58
- @unittest.skip("This depends on comtypes.safearray which depends on numpy, which is not in "
59
- "the project dependencies.")
60
58
  def test_float_array(self):
61
59
  a = array.array("f", (3.14, 2.78))
62
60
  v = VARIANT(a)
63
61
  self.assertEqual(v.vt, VT_ARRAY | VT_R4)
64
62
  self.assertEqual(tuple(a.tolist()), v.value)
65
63
 
66
- @unittest.skip("This depends on comtypes.safearray which depends on numpy, which is not in "
67
- "the project dependencies.")
68
64
  def test_2dim_array(self):
69
65
  data = ((1, 2, 3, 4),
70
66
  (5, 6, 7, 8),
@@ -92,30 +88,6 @@ class SafeArrayTestCase(unittest.TestCase):
92
88
  self.assertEqual((c._itemtype_, c._vartype_),
93
89
  (BSTR, VT_BSTR))
94
90
 
95
- def test_nested_contexts(self):
96
- np = get_numpy()
97
- if np is None:
98
- return
99
-
100
- t = _midlSAFEARRAY(BSTR)
101
- sa = t.from_param(["a", "b", "c"])
102
-
103
- first = sa[0]
104
- with safearray_as_ndarray:
105
- second = sa[0]
106
- with safearray_as_ndarray:
107
- third = sa[0]
108
- fourth = sa[0]
109
- fifth = sa[0]
110
-
111
- self.assertTrue(isinstance(first, tuple))
112
- self.assertTrue(isinstance(second, np.ndarray))
113
- self.assertTrue(isinstance(third, np.ndarray))
114
- self.assertTrue(isinstance(fourth, np.ndarray))
115
- self.assertTrue(isinstance(fifth, tuple))
116
-
117
- @unittest.skip("This depends on comtypes.safearray which depends on numpy, which is not in "
118
- "the project dependencies.")
119
91
  def test_VT_BSTR(self):
120
92
  t = _midlSAFEARRAY(BSTR)
121
93
 
@@ -123,21 +95,6 @@ class SafeArrayTestCase(unittest.TestCase):
123
95
  self.assertEqual(sa[0], ("a", "b", "c"))
124
96
  self.assertEqual(SafeArrayGetVartype(sa), VT_BSTR)
125
97
 
126
- def test_VT_BSTR_ndarray(self):
127
- np = get_numpy()
128
- if np is None:
129
- return
130
-
131
- t = _midlSAFEARRAY(BSTR)
132
-
133
- sa = t.from_param(["a", "b", "c"])
134
- arr = get_array(sa)
135
-
136
- self.assertTrue(isinstance(arr, np.ndarray))
137
- self.assertEqual(np.dtype('<U1'), arr.dtype)
138
- self.assertTrue((arr == ("a", "b", "c")).all())
139
- self.assertEqual(SafeArrayGetVartype(sa), VT_BSTR)
140
-
141
98
  @unittest.skip("This fails with a memory leak. Figure out if false positive.")
142
99
  def test_VT_BSTR_leaks(self):
143
100
  sb = _midlSAFEARRAY(BSTR)
@@ -158,8 +115,6 @@ class SafeArrayTestCase(unittest.TestCase):
158
115
  bytes = find_memleak(doit)
159
116
  self.assertFalse(bytes, "Leaks %d bytes" % bytes)
160
117
 
161
- @unittest.skip("This depends on comtypes.safearray which depends on numpy, which is not in "
162
- "the project dependencies.")
163
118
  def test_VT_I4(self):
164
119
  t = _midlSAFEARRAY(c_long)
165
120
 
@@ -172,59 +127,6 @@ class SafeArrayTestCase(unittest.TestCase):
172
127
  # TypeError: len() of unsized object
173
128
  self.assertRaises(TypeError, lambda: t.from_param(object()))
174
129
 
175
- def test_VT_I4_ndarray(self):
176
- np = get_numpy()
177
- if np is None:
178
- return
179
-
180
- t = _midlSAFEARRAY(c_long)
181
-
182
- inarr = np.array([11, 22, 33])
183
- sa = t.from_param(inarr)
184
-
185
- arr = get_array(sa)
186
-
187
- self.assertTrue(isinstance(arr, np.ndarray))
188
- self.assertEqual(np.dtype(np.int), arr.dtype)
189
- self.assertTrue((arr == inarr).all())
190
- self.assertEqual(SafeArrayGetVartype(sa), VT_I4)
191
-
192
- def test_array(self):
193
- np = get_numpy()
194
- if np is None:
195
- return
196
-
197
- t = _midlSAFEARRAY(c_double)
198
- pat = pointer(t())
199
-
200
- pat[0] = np.zeros(32, dtype=np.float)
201
- arr = get_array(pat[0])
202
- self.assertTrue(isinstance(arr, np.ndarray))
203
- self.assertEqual(np.dtype(np.double), arr.dtype)
204
- self.assertTrue((arr == (0.0,) * 32).all())
205
-
206
- data = ((1.0, 2.0, 3.0),
207
- (4.0, 5.0, 6.0),
208
- (7.0, 8.0, 9.0))
209
- a = np.array(data, dtype=np.double)
210
- pat[0] = a
211
- arr = get_array(pat[0])
212
- self.assertTrue(isinstance(arr, np.ndarray))
213
- self.assertEqual(np.dtype(np.double), arr.dtype)
214
- self.assertTrue((arr == data).all())
215
-
216
- data = ((1.0, 2.0), (3.0, 4.0), (5.0, 6.0))
217
- a = np.array(data,
218
- dtype=np.double,
219
- order="F")
220
- pat[0] = a
221
- arr = get_array(pat[0])
222
- self.assertTrue(isinstance(arr, np.ndarray))
223
- self.assertEqual(np.dtype(np.double), arr.dtype)
224
- self.assertEqual(pat[0][0], data)
225
-
226
- @unittest.skip("This depends on comtypes.safearray which depends on numpy, which is not in "
227
- "the project dependencies.")
228
130
  def test_VT_VARIANT(self):
229
131
  t = _midlSAFEARRAY(VARIANT)
230
132
 
@@ -234,47 +136,12 @@ class SafeArrayTestCase(unittest.TestCase):
234
136
 
235
137
  self.assertEqual(SafeArrayGetVartype(sa), VT_VARIANT)
236
138
 
237
- def test_VT_VARIANT_ndarray(self):
238
- np = get_numpy()
239
- if np is None:
240
- return
241
-
242
- t = _midlSAFEARRAY(VARIANT)
243
-
244
- now = datetime.datetime.now()
245
- inarr = np.array(
246
- [11, "22", "33", 44.0, None, True, now, Decimal("3.14")]
247
- ).reshape(2, 4)
248
- sa = t.from_param(inarr)
249
- arr = get_array(sa)
250
- self.assertEqual(np.dtype(object), arr.dtype)
251
- self.assertTrue(isinstance(arr, np.ndarray))
252
- self.assertTrue((arr == inarr).all())
253
- self.assertEqual(SafeArrayGetVartype(sa), VT_VARIANT)
254
-
255
- @unittest.skip("This depends on comtypes.safearray which depends on numpy, which is not in "
256
- "the project dependencies.")
257
139
  def test_VT_BOOL(self):
258
140
  t = _midlSAFEARRAY(VARIANT_BOOL)
259
141
 
260
142
  sa = t.from_param([True, False, True, False])
261
143
  self.assertEqual(sa[0], (True, False, True, False))
262
144
 
263
- def test_VT_BOOL_ndarray(self):
264
- np = get_numpy()
265
- if np is None:
266
- return
267
-
268
- t = _midlSAFEARRAY(VARIANT_BOOL)
269
-
270
- sa = t.from_param([True, False, True, False])
271
- arr = get_array(sa)
272
- self.assertEqual(np.dtype(np.bool_), arr.dtype)
273
- self.assertTrue(isinstance(arr, np.ndarray))
274
- self.assertTrue((arr == (True, False, True, False)).all())
275
-
276
- @unittest.skip("This depends on comtypes.safearray which depends on numpy, which is not in "
277
- "the project dependencies.")
278
145
  def test_VT_UNKNOWN_1(self):
279
146
  a = _midlSAFEARRAY(POINTER(IUnknown))
280
147
  t = _midlSAFEARRAY(POINTER(IUnknown))
@@ -302,8 +169,6 @@ class SafeArrayTestCase(unittest.TestCase):
302
169
  sa = t.from_param([None])
303
170
  self.assertEqual((POINTER(IUnknown)(),), sa[0])
304
171
 
305
- @unittest.skip("This depends on comtypes.safearray which depends on numpy, which is not in "
306
- "the project dependencies.")
307
172
  def test_VT_UNKNOWN_multi(self):
308
173
  a = _midlSAFEARRAY(POINTER(IUnknown))
309
174
  t = _midlSAFEARRAY(POINTER(IUnknown))
@@ -350,55 +215,6 @@ class SafeArrayTestCase(unittest.TestCase):
350
215
  del sa
351
216
  self.assertEqual((a, b), (com_refcnt(plib), com_refcnt(punk)))
352
217
 
353
- def test_VT_UNKNOWN_multi_ndarray(self):
354
- np = get_numpy()
355
- if np is None:
356
- return
357
-
358
- a = _midlSAFEARRAY(POINTER(IUnknown))
359
- t = _midlSAFEARRAY(POINTER(IUnknown))
360
- self.assertTrue(a is t)
361
-
362
- from comtypes.typeinfo import CreateTypeLib
363
- # will never be saved to disk
364
- punk = CreateTypeLib("spam").QueryInterface(IUnknown)
365
-
366
- # initial refcount
367
- initial = com_refcnt(punk)
368
-
369
- # This should increase the refcount by 4
370
- sa = t.from_param((punk,) * 4)
371
- self.assertEqual(initial + 4, com_refcnt(punk))
372
-
373
- # Unpacking the array must not change the refcount, and must
374
- # return an equal object. Creating an ndarray may change the
375
- # refcount.
376
- arr = get_array(sa)
377
- self.assertTrue(isinstance(arr, np.ndarray))
378
- self.assertEqual(np.dtype(object), arr.dtype)
379
- self.assertTrue((arr == (punk,)*4).all())
380
- self.assertEqual(initial + 8, com_refcnt(punk))
381
-
382
- del arr
383
- self.assertEqual(initial + 4, com_refcnt(punk))
384
-
385
- del sa
386
- self.assertEqual(initial, com_refcnt(punk))
387
-
388
- # This should increase the refcount by 2
389
- sa = t.from_param((punk, None, punk, None))
390
- self.assertEqual(initial + 2, com_refcnt(punk))
391
-
392
- null = POINTER(IUnknown)()
393
- arr = get_array(sa)
394
- self.assertTrue(isinstance(arr, np.ndarray))
395
- self.assertEqual(np.dtype(object), arr.dtype)
396
- self.assertTrue((arr == (punk, null, punk, null)).all())
397
-
398
- del sa
399
- del arr
400
- self.assertEqual(initial, com_refcnt(punk))
401
-
402
218
  @unittest.skip("This fails with a 'library not registered' error. Need to figure out how to "
403
219
  "register TestComServerLib (without admin if possible).")
404
220
  def test_UDT(self):
@@ -417,55 +233,6 @@ class SafeArrayTestCase(unittest.TestCase):
417
233
  bytes = find_memleak(doit)
418
234
  self.assertFalse(bytes, "Leaks %d bytes" % bytes)
419
235
 
420
- def test_UDT_ndarray(self):
421
- np = get_numpy()
422
- if np is None:
423
- return
424
-
425
- from comtypes.gen.TestComServerLib import MYCOLOR
426
-
427
- t = _midlSAFEARRAY(MYCOLOR)
428
- self.assertTrue(t is _midlSAFEARRAY(MYCOLOR))
429
-
430
- sa = t.from_param([MYCOLOR(0, 0, 0), MYCOLOR(1, 2, 3)])
431
- arr = get_array(sa)
432
-
433
- self.assertTrue(isinstance(arr, np.ndarray))
434
- # The conversion code allows numpy to choose the dtype of
435
- # structured data. This dtype is structured under numpy 1.5, 1.7 and
436
- # 1.8, and object in 1.6. Instead of assuming either of these, check
437
- # the array contents based on the chosen type.
438
- if arr.dtype is np.dtype(object):
439
- data = [(x.red, x.green, x.blue) for x in arr]
440
- else:
441
- float_dtype = np.dtype('float64')
442
- self.assertIs(arr.dtype[0], float_dtype)
443
- self.assertIs(arr.dtype[1], float_dtype)
444
- self.assertIs(arr.dtype[2], float_dtype)
445
- data = [tuple(x) for x in arr]
446
- self.assertEqual(data, [(0.0, 0.0, 0.0), (1.0, 2.0, 3.0)])
447
-
448
- def test_datetime64_ndarray(self):
449
- np = get_numpy()
450
- if np is None:
451
- return
452
- try:
453
- np.datetime64
454
- except AttributeError:
455
- return
456
-
457
- dates = np.array([
458
- np.datetime64("2000-01-01T05:30:00", "s"),
459
- np.datetime64("1800-01-01T05:30:00", "ms"),
460
- np.datetime64("2014-03-07T00:12:56", "us"),
461
- np.datetime64("2000-01-01T12:34:56", "ns"),
462
- ])
463
-
464
- t = _midlSAFEARRAY(VARIANT)
465
- sa = t.from_param(dates)
466
- arr = get_array(sa).astype(dates.dtype)
467
- self.assertTrue((dates == arr).all())
468
-
469
236
 
470
237
  if is_resource_enabled("pythoncom"):
471
238
  try: