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.
- {comtypes-1.1.14 → comtypes-1.2.1}/CHANGES.txt +37 -0
- comtypes-1.2.1/PKG-INFO +79 -0
- comtypes-1.2.1/README.md +59 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/__init__.py +302 -555
- comtypes-1.2.1/comtypes/_memberspec.py +520 -0
- comtypes-1.2.1/comtypes/_npsupport.py +143 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/automation.py +99 -11
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/__init__.py +80 -26
- comtypes-1.2.1/comtypes/client/_generate.py +274 -0
- comtypes-1.2.1/comtypes/hints.pyi +26 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/persist.py +14 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/safearray.py +22 -21
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/__init__.py +0 -7
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_client.py +35 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_dict.py +0 -4
- comtypes-1.2.1/comtypes/test/test_npsupport.py +343 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_safearray.py +2 -235
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_variant.py +6 -59
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/tools/codegenerator.py +454 -337
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/tools/tlbparser.py +56 -75
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/tools/typedesc.py +31 -3
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/tools/typedesc_base.py +28 -1
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/typeinfo.py +291 -121
- comtypes-1.2.1/comtypes.egg-info/PKG-INFO +79 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes.egg-info/SOURCES.txt +4 -1
- {comtypes-1.1.14 → comtypes-1.2.1}/setup.cfg +0 -1
- {comtypes-1.1.14 → comtypes-1.2.1}/setup.py +15 -8
- comtypes-1.1.14/PKG-INFO +0 -50
- comtypes-1.1.14/README.md +0 -31
- comtypes-1.1.14/comtypes/client/_generate.py +0 -257
- comtypes-1.1.14/comtypes/npsupport.py +0 -125
- comtypes-1.1.14/comtypes.egg-info/PKG-INFO +0 -50
- {comtypes-1.1.14 → comtypes-1.2.1}/LICENSE.txt +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/MANIFEST.in +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/clear_comtypes_cache.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/GUID.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/_comobject.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/_meta.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/_safearray.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/_code_cache.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/_constants.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/_events.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/dynamic.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/client/lazybind.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/connectionpoints.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/errorinfo.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/git.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/hresult.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/logutil.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/messageloop.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/patcher.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/__init__.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/automation.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/connectionpoints.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/inprocserver.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/localserver.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/register.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/server/w_getopt.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/shelllink.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestComServer.idl +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestComServer.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestComServer.tlb +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestDispServer.idl +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestDispServer.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/TestDispServer.tlb +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/find_memleak.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/mylib.idl +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/mytypelib.idl +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/runtests.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/setup.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_BSTR.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_DISPPARAMS.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_GUID.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_QueryService.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_agilent.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_avmc.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_basic.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_casesensitivity.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_collections.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_comserver.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_createwrappers.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_dispinterface.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_dyndispatch.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_excel.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_findgendir.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_getactiveobj.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_ie.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_jscript.js +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_msscript.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_outparam.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_propputref.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_pump_events.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_sapi.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_server.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_showevents.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_subinterface.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_typeinfo.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_urlhistory.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_win32com_interop.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_wmi.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/test/test_word.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/tools/__init__.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/util.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes/viewobject.py +0 -0
- {comtypes-1.1.14 → comtypes-1.2.1}/comtypes.egg-info/dependency_links.txt +0 -0
- {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,
|
|
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
|
|
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:
|