4
4
import datetime
5
5
import unittest
6
6
7
- import comtypes .test
8
- from comtypes .client import CreateObject
7
+ from comtypes .client import CreateObject , GetModule
8
+
9
+ ################################################################
10
+ #
11
+ # TODO:
12
+ #
13
+ # It seems bad that only external test like this
14
+ # can verify the behavior of `comtypes` implementation.
15
+ # Find a different built-in win32 API to use.
16
+ #
17
+ ################################################################
18
+
19
+ try :
20
+ GetModule (("{00020813-0000-0000-C000-000000000046}" ,)) # Excel libUUID
21
+ from comtypes .gen .Excel import xlRangeValueDefault
22
+ IMPORT_FAILED = False
23
+ except (ImportError , OSError ):
24
+ IMPORT_FAILED = True
25
+
26
+
27
+ @unittest .skipIf (IMPORT_FAILED , "This depends on Excel." )
28
+ @unittest .skip ("There is difference of `Range.Value` behavior "
29
+ "between Python >= 3.8.x and Python <= 3.7.x." )
30
+ class BaseTest (unittest .TestCase ):
31
+ # `dynamic = True/False` must be defined in subclasses!
32
+
33
+ def setUp (self ):
34
+ self .xl = CreateObject ("Excel.Application" , dynamic = self .dynamic )
9
35
10
- comtypes .test .requires ("ui" )
11
-
12
-
13
- def setUpModule ():
14
- raise unittest .SkipTest ("External test dependencies like this seem bad. Find a different "
15
- "built-in win32 API to use." )
16
-
17
-
18
- xlRangeValueDefault = 10
19
- xlRangeValueXMLSpreadsheet = 11
20
- xlRangeValueMSPersistXML = 12
21
-
22
- class Test (unittest .TestCase ):
23
-
24
- def test_earlybound (self ):
25
- self ._doit (False )
26
-
27
- def test_latebound (self ):
28
- self ._doit (True )
29
-
30
- def _doit (self , dynamic ):
31
- self .xl = CreateObject ("Excel.Application" , dynamic = dynamic )
36
+ def tearDown (self ):
37
+ # Close all open workbooks without saving, then quit excel.
38
+ for wb in self .xl .Workbooks :
39
+ wb .Close (0 )
40
+ self .xl .Quit ()
41
+ del self .xl
32
42
43
+ def test (self ):
33
44
xl = self .xl
34
45
xl .Visible = 0
35
46
self .assertEqual (xl .Visible , False )
@@ -39,41 +50,33 @@ def _doit(self, dynamic):
39
50
wb = xl .Workbooks .Add ()
40
51
41
52
# Test with empty-tuple argument
42
- xl .Range ["A1" , "C1" ].Value [()] = (10 ,"20" ,31.4 )
53
+ xl .Range ["A1" , "C1" ].Value [()] = (10 ,"20" ,31.4 ) # XXX: in Python >= 3.8.x, cannot set values to A1:C1
43
54
xl .Range ["A2:C2" ].Value [()] = ('x' ,'y' ,'z' )
44
55
# Test with empty slice argument
45
56
xl .Range ["A3:C3" ].Value [:] = ('3' ,'2' ,'1' )
46
- ## not (yet?) implemented:
47
- ## xl.Range["A4:C4"].Value = ('3','2','1' )
57
+ # not implemented:
58
+ # xl.Range["A4:C4"].Value = ("3", "2" ,"1" )
48
59
49
60
# call property to retrieve value
61
+ expected_values = ((10.0 , 20.0 , 31.4 ),
62
+ ("x" , "y" , "z" ),
63
+ (3.0 , 2.0 , 1.0 ))
64
+ # XXX: in Python >= 3.8.x, fails below
50
65
self .assertEqual (xl .Range ["A1:C3" ].Value (),
51
- ((10.0 , 20.0 , 31.4 ),
52
- ("x" , "y" , "z" ),
53
- (3.0 , 2.0 , 1.0 )))
66
+ expected_values )
54
67
# index with empty tuple
55
68
self .assertEqual (xl .Range ["A1:C3" ].Value [()],
56
- ((10.0 , 20.0 , 31.4 ),
57
- ("x" , "y" , "z" ),
58
- (3.0 , 2.0 , 1.0 )))
69
+ expected_values )
59
70
# index with empty slice
60
71
self .assertEqual (xl .Range ["A1:C3" ].Value [:],
61
- ((10.0 , 20.0 , 31.4 ),
62
- ("x" , "y" , "z" ),
63
- (3.0 , 2.0 , 1.0 )))
72
+ expected_values )
64
73
self .assertEqual (xl .Range ["A1:C3" ].Value [xlRangeValueDefault ],
65
- ((10.0 , 20.0 , 31.4 ),
66
- ("x" , "y" , "z" ),
67
- (3.0 , 2.0 , 1.0 )))
74
+ expected_values )
68
75
self .assertEqual (xl .Range ["A1" , "C3" ].Value [()],
69
- ((10.0 , 20.0 , 31.4 ),
70
- ("x" , "y" , "z" ),
71
- (3.0 , 2.0 , 1.0 )))
76
+ expected_values )
72
77
73
- r = xl .Range ["A1:C3" ]
74
- i = iter (r )
75
-
76
- # Test for iteration support in 'Range' interface
78
+ # Test for iteration support in "Range" interface
79
+ iter (xl .Range ["A1:C3" ])
77
80
self .assertEqual ([c .Value () for c in xl .Range ["A1:C3" ]],
78
81
[10.0 , 20.0 , 31.4 ,
79
82
"x" , "y" , "z" ,
@@ -83,12 +86,14 @@ def _doit(self, dynamic):
83
86
# With comtypes, one must write xl.Cells.Item(1, b)
84
87
85
88
for i in range (20 ):
86
- xl .Cells .Item [i + 1 ,i + 1 ].Value [()] = "Hi %d" % i
87
- print (xl .Cells .Item [i + 1 , i + 1 ].Value [()])
89
+ val = "Hi %d" % i
90
+ xl .Cells .Item [i + 1 ,i + 1 ].Value [()] = val
91
+ self .assertEqual (xl .Cells .Item [i + 1 , i + 1 ].Value [()], val )
88
92
89
93
for i in range (20 ):
90
- xl .Cells (i + 1 ,i + 1 ).Value [()] = "Hi %d" % i
91
- print (xl .Cells (i + 1 , i + 1 ).Value [()])
94
+ val = "Hi %d" % i
95
+ xl .Cells (i + 1 ,i + 1 ).Value [()] = val
96
+ self .assertEqual (xl .Cells (i + 1 , i + 1 ).Value [()], val )
92
97
93
98
# test dates out with Excel
94
99
xl .Range ["A5" ].Value [()] = "Excel time"
@@ -111,11 +116,17 @@ def _doit(self, dynamic):
111
116
sh .Range [sh .Cells .Item [1 ,1 ],sh .Cells .Item [3 ,3 ]].Copy (sh .Cells .Item [4 ,1 ])
112
117
sh .Range [sh .Cells .Item [4 ,1 ],sh .Cells .Item [6 ,3 ]].Select ()
113
118
114
- def tearDown (self ):
115
- # Close all open workbooks without saving, then quit excel.
116
- for wb in self .xl .Workbooks :
117
- wb .Close (0 )
118
- self .xl .Quit ()
119
+
120
+ class Test_EarlyBind (BaseTest ):
121
+ dynamic = False
122
+
123
+
124
+ class Test_LateBind (BaseTest ):
125
+ dynamic = True
126
+
127
+
128
+ del BaseTest # to avoid running `BaseTest`
129
+
119
130
120
131
if __name__ == "__main__" :
121
132
unittest .main ()
0 commit comments