1
+ import itertools
1
2
import timeit
2
3
import unittest
3
4
import sys
@@ -23,8 +24,9 @@ class FakeTimer:
23
24
BASE_TIME = 42.0
24
25
def __init__ (self , seconds_per_increment = 1.0 ):
25
26
self .count = 0
27
+ self .global_setup_calls = 0
26
28
self .setup_calls = 0
27
- self .seconds_per_increment = seconds_per_increment
29
+ self .seconds_per_increment = seconds_per_increment
28
30
timeit ._fake_timer = self
29
31
30
32
def __call__ (self ):
@@ -33,6 +35,9 @@ def __call__(self):
33
35
def inc (self ):
34
36
self .count += 1
35
37
38
+ def global_setup (self ):
39
+ self .global_setup_calls += 1
40
+
36
41
def setup (self ):
37
42
self .setup_calls += 1
38
43
@@ -81,6 +86,15 @@ def test_timer_invalid_stmt(self):
81
86
self .assertRaises (SyntaxError , timeit .Timer ,
82
87
setup = 'while False:\n pass' , stmt = ' break' )
83
88
89
+ def test_timer_invalid_global_setup (self ):
90
+ self .assertRaises (ValueError , timeit .Timer , global_setup = None )
91
+ self .assertRaises (SyntaxError , timeit .Timer , global_setup = 'return' )
92
+ self .assertRaises (SyntaxError , timeit .Timer , global_setup = 'yield' )
93
+ self .assertRaises (SyntaxError , timeit .Timer , global_setup = 'yield from ()' )
94
+ self .assertRaises (SyntaxError , timeit .Timer , global_setup = 'break' )
95
+ self .assertRaises (SyntaxError , timeit .Timer , global_setup = 'continue' )
96
+ self .assertRaises (SyntaxError , timeit .Timer , global_setup = ' pass' )
97
+
84
98
def test_timer_invalid_setup (self ):
85
99
self .assertRaises (ValueError , timeit .Timer , setup = None )
86
100
self .assertRaises (SyntaxError , timeit .Timer , setup = 'return' )
@@ -91,30 +105,62 @@ def test_timer_invalid_setup(self):
91
105
self .assertRaises (SyntaxError , timeit .Timer , setup = 'from timeit import *' )
92
106
self .assertRaises (SyntaxError , timeit .Timer , setup = ' pass' )
93
107
108
+ def test_timer_empty_global_setup (self ):
109
+ timeit .Timer (global_setup = '' )
110
+ timeit .Timer (global_setup = ' \n \t \f ' )
111
+ timeit .Timer (global_setup = '# comment' )
112
+
94
113
def test_timer_empty_stmt (self ):
95
114
timeit .Timer (stmt = '' )
96
115
timeit .Timer (stmt = ' \n \t \f ' )
97
116
timeit .Timer (stmt = '# comment' )
98
117
118
+ def test_timer_global_setup_future (self ):
119
+ timer = timeit .Timer (stmt = 'print(f.__annotations__)' ,
120
+ setup = 'def f(x: int): pass' ,
121
+ global_setup = 'from __future__ import annotations' )
122
+ with captured_stdout () as stdout :
123
+ timer .timeit (1 )
124
+ self .assertEqual (stdout .getvalue ().strip (), str ({'x' : 'int' }))
125
+
126
+ def test_timer_global_setup_side_effect (self ):
127
+ timer = timeit .Timer (stmt = 'print(s)' , global_setup = 's = 1' )
128
+ with captured_stdout () as stdout :
129
+ timer .timeit (5 )
130
+ self .assertEqual (stdout .getvalue (), '1\n ' * 5 )
131
+
132
+ def test_timer_callable_global_setup_side_effect (self ):
133
+ self .fake_timer = FakeTimer ()
134
+ timer = timeit .Timer (global_setup = self .fake_callable_global_setup )
135
+ timer .timeit (5 )
136
+ self .assertEqual (self .fake_timer .count , 0 )
137
+ self .assertEqual (self .fake_timer .setup_calls , 0 )
138
+ self .assertEqual (self .fake_timer .global_setup_calls , 1 )
139
+
140
+ fake_global_setup = "import timeit\n timeit._fake_timer.global_setup()"
99
141
fake_setup = "import timeit\n timeit._fake_timer.setup()"
100
142
fake_stmt = "import timeit\n timeit._fake_timer.inc()"
101
143
144
+ def fake_callable_global_setup (self ):
145
+ self .fake_timer .global_setup ()
146
+
102
147
def fake_callable_setup (self ):
103
148
self .fake_timer .setup ()
104
149
105
150
def fake_callable_stmt (self ):
106
151
self .fake_timer .inc ()
107
152
108
- def timeit (self , stmt , setup , number = None , globals = None ):
153
+ def timeit (self , stmt , setup , global_setup , number = None , globals = None ):
109
154
self .fake_timer = FakeTimer ()
110
155
t = timeit .Timer (stmt = stmt , setup = setup , timer = self .fake_timer ,
111
- globals = globals )
156
+ globals = globals , global_setup = global_setup )
112
157
kwargs = {}
113
158
if number is None :
114
159
number = DEFAULT_NUMBER
115
160
else :
116
161
kwargs ['number' ] = number
117
162
delta_time = t .timeit (** kwargs )
163
+ self .assertEqual (self .fake_timer .global_setup_calls , 1 )
118
164
self .assertEqual (self .fake_timer .setup_calls , 1 )
119
165
self .assertEqual (self .fake_timer .count , number )
120
166
self .assertEqual (delta_time , number )
@@ -123,21 +169,20 @@ def timeit(self, stmt, setup, number=None, globals=None):
123
169
#def test_timeit_default_iters(self):
124
170
# self.timeit(self.fake_stmt, self.fake_setup)
125
171
126
- def test_timeit_zero_iters (self ):
127
- self .timeit (self .fake_stmt , self .fake_setup , number = 0 )
128
-
129
- def test_timeit_few_iters (self ):
130
- self .timeit (self .fake_stmt , self .fake_setup , number = 3 )
131
-
132
- def test_timeit_callable_stmt (self ):
133
- self .timeit (self .fake_callable_stmt , self .fake_setup , number = 3 )
134
-
135
- def test_timeit_callable_setup (self ):
136
- self .timeit (self .fake_stmt , self .fake_callable_setup , number = 3 )
137
-
138
- def test_timeit_callable_stmt_and_setup (self ):
139
- self .timeit (self .fake_callable_stmt ,
140
- self .fake_callable_setup , number = 3 )
172
+ def test_timeit_simple (self ):
173
+ for number , (callable_stmt , callable_setup , callable_global_setup ) in (
174
+ itertools .product ([0 , 3 ], itertools .product ([True , False ], repeat = 3 ))
175
+ ):
176
+ with self .subTest (
177
+ number = number ,
178
+ callable_stmt = callable_stmt ,
179
+ callable_setup = callable_setup ,
180
+ callable_global_setup = callable_global_setup ,
181
+ ):
182
+ stmt = self .fake_stmt if callable_stmt else self .fake_callable_stmt
183
+ setup = self .fake_setup if callable_setup else self .fake_callable_setup
184
+ global_setup = self .fake_global_setup if callable_global_setup else self .fake_callable_global_setup
185
+ self .timeit (stmt , setup , global_setup , number = number )
141
186
142
187
# Takes too long to run in debug build.
143
188
#def test_timeit_function(self):
@@ -161,9 +206,10 @@ def test_timeit_globals_args(self):
161
206
timeit .timeit (stmt = 'local_timer.inc()' , timer = local_timer ,
162
207
globals = locals (), number = 3 )
163
208
164
- def repeat (self , stmt , setup , repeat = None , number = None ):
209
+ def repeat (self , stmt , setup , global_setup , repeat = None , number = None ):
165
210
self .fake_timer = FakeTimer ()
166
- t = timeit .Timer (stmt = stmt , setup = setup , timer = self .fake_timer )
211
+ t = timeit .Timer (stmt = stmt , setup = setup , timer = self .fake_timer ,
212
+ global_setup = global_setup )
167
213
kwargs = {}
168
214
if repeat is None :
169
215
repeat = DEFAULT_REPEAT
@@ -174,6 +220,7 @@ def repeat(self, stmt, setup, repeat=None, number=None):
174
220
else :
175
221
kwargs ['number' ] = number
176
222
delta_times = t .repeat (** kwargs )
223
+ self .assertEqual (self .fake_timer .global_setup_calls , 1 )
177
224
self .assertEqual (self .fake_timer .setup_calls , repeat )
178
225
self .assertEqual (self .fake_timer .count , repeat * number )
179
226
self .assertEqual (delta_times , repeat * [float (number )])
@@ -182,26 +229,23 @@ def repeat(self, stmt, setup, repeat=None, number=None):
182
229
#def test_repeat_default(self):
183
230
# self.repeat(self.fake_stmt, self.fake_setup)
184
231
185
- def test_repeat_zero_reps (self ):
186
- self .repeat (self .fake_stmt , self .fake_setup , repeat = 0 )
187
-
188
- def test_repeat_zero_iters (self ):
189
- self .repeat (self .fake_stmt , self .fake_setup , number = 0 )
190
-
191
- def test_repeat_few_reps_and_iters (self ):
192
- self .repeat (self .fake_stmt , self .fake_setup , repeat = 3 , number = 5 )
193
-
194
- def test_repeat_callable_stmt (self ):
195
- self .repeat (self .fake_callable_stmt , self .fake_setup ,
196
- repeat = 3 , number = 5 )
197
-
198
- def test_repeat_callable_setup (self ):
199
- self .repeat (self .fake_stmt , self .fake_callable_setup ,
200
- repeat = 3 , number = 5 )
201
-
202
- def test_repeat_callable_stmt_and_setup (self ):
203
- self .repeat (self .fake_callable_stmt , self .fake_callable_setup ,
204
- repeat = 3 , number = 5 )
232
+ def test_repeat_simple (self ):
233
+ for repeat , (callable_stmt , callable_setup , callable_global_setup ) in (
234
+ itertools .product ([0 , 3 ], itertools .product ([True , False ], repeat = 3 ))
235
+ ):
236
+ # do not use number = None for repeat > 0 as it would be too large
237
+ number = 5 if repeat > 0 else None
238
+ with self .subTest (
239
+ repeat = repeat ,
240
+ number = number ,
241
+ callable_stmt = callable_stmt ,
242
+ callable_setup = callable_setup ,
243
+ callable_global_setup = callable_global_setup ,
244
+ ):
245
+ stmt = self .fake_stmt if callable_stmt else self .fake_callable_stmt
246
+ setup = self .fake_setup if callable_setup else self .fake_callable_setup
247
+ global_setup = self .fake_global_setup if callable_global_setup else self .fake_callable_global_setup
248
+ self .repeat (stmt , setup , global_setup , repeat = repeat , number = number )
205
249
206
250
# Takes too long to run in debug build.
207
251
#def test_repeat_function(self):
@@ -274,6 +318,18 @@ def test_main_fixed_iters(self):
274
318
s = self .run_main (seconds_per_increment = 2.0 , switches = ['-n35' ])
275
319
self .assertEqual (s , "35 loops, best of 5: 2 sec per loop\n " )
276
320
321
+ def test_main_global_setup (self ):
322
+ s = self .run_main (seconds_per_increment = 2.0 ,
323
+ switches = ['-n35' , '-g' , 'print("CustomSetup")' ])
324
+ self .assertEqual (s , "CustomSetup\n " +
325
+ "35 loops, best of 5: 2 sec per loop\n " )
326
+
327
+ def test_main_multiple_global_setups (self ):
328
+ s = self .run_main (seconds_per_increment = 2.0 ,
329
+ switches = ['-n35' , '-g' , 'a = "CustomSetup"' , '-g' , 'print(a)' ])
330
+ self .assertEqual (s , "CustomSetup\n " +
331
+ "35 loops, best of 5: 2 sec per loop\n " )
332
+
277
333
def test_main_setup (self ):
278
334
s = self .run_main (seconds_per_increment = 2.0 ,
279
335
switches = ['-n35' , '-s' , 'print("CustomSetup")' ])
0 commit comments