1
- # -*- coding: utf-8 -*-
2
- # This file should be kept compatible with both Python 2.6 and Python >= 3.0.
3
-
4
1
import itertools
5
2
import os
6
3
import platform
14
11
TEXT_ENCODING = 'utf8'
15
12
NEWLINES = 'lf'
16
13
17
- # Compatibility
18
- try :
19
- xrange
20
- except NameError :
21
- xrange = range
22
14
23
15
def text_open (fn , mode , encoding = None ):
24
16
try :
25
17
return open (fn , mode , encoding = encoding or TEXT_ENCODING )
26
18
except TypeError :
27
- if 'r' in mode :
28
- mode += 'U' # 'U' mode is needed only in Python 2.x
29
19
return open (fn , mode )
30
20
21
+
31
22
def get_file_sizes ():
32
23
for s in ['20 KiB' , '400 KiB' , '10 MiB' ]:
33
24
size , unit = s .split ()
34
25
size = int (size ) * {'KiB' : 1024 , 'MiB' : 1024 ** 2 }[unit ]
35
26
yield s .replace (' ' , '' ), size
36
27
28
+
37
29
def get_binary_files ():
38
30
return ((name + ".bin" , size ) for name , size in get_file_sizes ())
39
31
32
+
40
33
def get_text_files ():
41
- return (("%s-%s-%s .txt" % ( name , TEXT_ENCODING , NEWLINES ) , size )
34
+ return ((f" { name } - { TEXT_ENCODING } - { NEWLINES } .txt" , size )
42
35
for name , size in get_file_sizes ())
43
36
37
+
44
38
def with_open_mode (mode ):
45
39
def decorate (f ):
46
40
f .file_open_mode = mode
47
41
return f
48
42
return decorate
49
43
44
+
50
45
def with_sizes (* sizes ):
51
46
def decorate (f ):
52
47
f .file_sizes = sizes
@@ -64,6 +59,7 @@ def read_bytewise(f):
64
59
while f .read (1 ):
65
60
pass
66
61
62
+
67
63
@with_open_mode ("r" )
68
64
@with_sizes ("medium" )
69
65
def read_small_chunks (f ):
@@ -72,6 +68,7 @@ def read_small_chunks(f):
72
68
while f .read (20 ):
73
69
pass
74
70
71
+
75
72
@with_open_mode ("r" )
76
73
@with_sizes ("medium" )
77
74
def read_big_chunks (f ):
@@ -80,6 +77,7 @@ def read_big_chunks(f):
80
77
while f .read (4096 ):
81
78
pass
82
79
80
+
83
81
@with_open_mode ("r" )
84
82
@with_sizes ("small" , "medium" , "large" )
85
83
def read_whole_file (f ):
@@ -88,6 +86,7 @@ def read_whole_file(f):
88
86
while f .read ():
89
87
pass
90
88
89
+
91
90
@with_open_mode ("rt" )
92
91
@with_sizes ("medium" )
93
92
def read_lines (f ):
@@ -96,26 +95,29 @@ def read_lines(f):
96
95
for line in f :
97
96
pass
98
97
98
+
99
99
@with_open_mode ("r" )
100
100
@with_sizes ("medium" )
101
101
def seek_forward_bytewise (f ):
102
102
""" seek forward one unit at a time """
103
103
f .seek (0 , 2 )
104
104
size = f .tell ()
105
105
f .seek (0 , 0 )
106
- for i in xrange (0 , size - 1 ):
106
+ for i in range (0 , size - 1 ):
107
107
f .seek (i , 0 )
108
108
109
+
109
110
@with_open_mode ("r" )
110
111
@with_sizes ("medium" )
111
112
def seek_forward_blockwise (f ):
112
113
""" seek forward 1000 units at a time """
113
114
f .seek (0 , 2 )
114
115
size = f .tell ()
115
116
f .seek (0 , 0 )
116
- for i in xrange (0 , size - 1 , 1000 ):
117
+ for i in range (0 , size - 1 , 1000 ):
117
118
f .seek (i , 0 )
118
119
120
+
119
121
@with_open_mode ("rb" )
120
122
@with_sizes ("medium" )
121
123
def read_seek_bytewise (f ):
@@ -124,6 +126,7 @@ def read_seek_bytewise(f):
124
126
while f .read (1 ):
125
127
f .seek (1 , 1 )
126
128
129
+
127
130
@with_open_mode ("rb" )
128
131
@with_sizes ("medium" )
129
132
def read_seek_blockwise (f ):
@@ -137,28 +140,31 @@ def read_seek_blockwise(f):
137
140
@with_sizes ("small" )
138
141
def write_bytewise (f , source ):
139
142
""" write one unit at a time """
140
- for i in xrange (0 , len (source )):
143
+ for i in range (0 , len (source )):
141
144
f .write (source [i :i + 1 ])
142
145
146
+
143
147
@with_open_mode ("w" )
144
148
@with_sizes ("medium" )
145
149
def write_small_chunks (f , source ):
146
150
""" write 20 units at a time """
147
- for i in xrange (0 , len (source ), 20 ):
151
+ for i in range (0 , len (source ), 20 ):
148
152
f .write (source [i :i + 20 ])
149
153
154
+
150
155
@with_open_mode ("w" )
151
156
@with_sizes ("medium" )
152
157
def write_medium_chunks (f , source ):
153
158
""" write 4096 units at a time """
154
- for i in xrange (0 , len (source ), 4096 ):
159
+ for i in range (0 , len (source ), 4096 ):
155
160
f .write (source [i :i + 4096 ])
156
161
162
+
157
163
@with_open_mode ("w" )
158
164
@with_sizes ("large" )
159
165
def write_large_chunks (f , source ):
160
166
""" write 1e6 units at a time """
161
- for i in xrange (0 , len (source ), 1000000 ):
167
+ for i in range (0 , len (source ), 1000000 ):
162
168
f .write (source [i :i + 1000000 ])
163
169
164
170
@@ -167,59 +173,65 @@ def write_large_chunks(f, source):
167
173
def modify_bytewise (f , source ):
168
174
""" modify one unit at a time """
169
175
f .seek (0 )
170
- for i in xrange (0 , len (source )):
176
+ for i in range (0 , len (source )):
171
177
f .write (source [i :i + 1 ])
172
178
179
+
173
180
@with_open_mode ("w+" )
174
181
@with_sizes ("medium" )
175
182
def modify_small_chunks (f , source ):
176
183
""" modify 20 units at a time """
177
184
f .seek (0 )
178
- for i in xrange (0 , len (source ), 20 ):
185
+ for i in range (0 , len (source ), 20 ):
179
186
f .write (source [i :i + 20 ])
180
187
188
+
181
189
@with_open_mode ("w+" )
182
190
@with_sizes ("medium" )
183
191
def modify_medium_chunks (f , source ):
184
192
""" modify 4096 units at a time """
185
193
f .seek (0 )
186
- for i in xrange (0 , len (source ), 4096 ):
194
+ for i in range (0 , len (source ), 4096 ):
187
195
f .write (source [i :i + 4096 ])
188
196
197
+
189
198
@with_open_mode ("wb+" )
190
199
@with_sizes ("medium" )
191
200
def modify_seek_forward_bytewise (f , source ):
192
201
""" alternate write & seek one unit """
193
202
f .seek (0 )
194
- for i in xrange (0 , len (source ), 2 ):
203
+ for i in range (0 , len (source ), 2 ):
195
204
f .write (source [i :i + 1 ])
196
205
f .seek (i + 2 )
197
206
207
+
198
208
@with_open_mode ("wb+" )
199
209
@with_sizes ("medium" )
200
210
def modify_seek_forward_blockwise (f , source ):
201
211
""" alternate write & seek 1000 units """
202
212
f .seek (0 )
203
- for i in xrange (0 , len (source ), 2000 ):
213
+ for i in range (0 , len (source ), 2000 ):
204
214
f .write (source [i :i + 1000 ])
205
215
f .seek (i + 2000 )
206
216
217
+
207
218
# XXX the 2 following tests don't work with py3k's text IO
208
219
@with_open_mode ("wb+" )
209
220
@with_sizes ("medium" )
210
221
def read_modify_bytewise (f , source ):
211
222
""" alternate read & write one unit """
212
223
f .seek (0 )
213
- for i in xrange (0 , len (source ), 2 ):
224
+ for i in range (0 , len (source ), 2 ):
214
225
f .read (1 )
215
226
f .write (source [i + 1 :i + 2 ])
216
227
228
+
217
229
@with_open_mode ("wb+" )
218
230
@with_sizes ("medium" )
219
231
def read_modify_blockwise (f , source ):
220
232
""" alternate read & write 1000 units """
221
233
f .seek (0 )
222
- for i in xrange (0 , len (source ), 2000 ):
234
+ for i in range (0 , len (source ), 2000 ):
223
235
f .read (1000 )
224
236
f .write (source [i + 1000 :i + 2000 ])
225
237
@@ -242,6 +254,7 @@ def read_modify_blockwise(f, source):
242
254
read_modify_bytewise , read_modify_blockwise ,
243
255
]
244
256
257
+
245
258
def run_during (duration , func ):
246
259
_t = time .time
247
260
n = 0
@@ -257,6 +270,7 @@ def run_during(duration, func):
257
270
real = (end [4 ] if start [4 ] else time .time ()) - real_start
258
271
return n , real , sum (end [0 :2 ]) - sum (start [0 :2 ])
259
272
273
+
260
274
def warm_cache (filename ):
261
275
with open (filename , "rb" ) as f :
262
276
f .read ()
@@ -266,18 +280,17 @@ def run_all_tests(options):
266
280
def print_label (filename , func ):
267
281
name = re .split (r'[-.]' , filename )[0 ]
268
282
out .write (
269
- ("[%s] %s... "
270
- % (name .center (7 ), func .__doc__ .strip ())
271
- ).ljust (52 ))
283
+ f"[{ name .center (7 )} ] { func .__doc__ .strip ()} ... " .ljust (52 ))
272
284
out .flush ()
273
285
274
286
def print_results (size , n , real , cpu ):
275
287
bw = n * float (size ) / 1024 ** 2 / real
276
288
bw = ("%4d MiB/s" if bw > 100 else "%.3g MiB/s" ) % bw
277
289
out .write (bw .rjust (12 ) + "\n " )
278
290
if cpu < 0.90 * real :
279
- out .write (" warning: test above used only %d%% CPU, "
280
- "result may be flawed!\n " % (100.0 * cpu / real ))
291
+ out .write (" warning: test above used only "
292
+ f"{ cpu / real :%} CPU, "
293
+ "result may be flawed!\n " )
281
294
282
295
def run_one_test (name , size , open_func , test_func , * args ):
283
296
mode = test_func .file_open_mode
@@ -308,22 +321,15 @@ def run_test_family(tests, mode_filter, files, open_func, *make_args):
308
321
"large" : 2 ,
309
322
}
310
323
311
- print ("Python %s" % sys .version )
312
- if sys .version_info < (3 , 3 ):
313
- if sys .maxunicode > 0xffff :
314
- text = "UCS-4 (wide build)"
315
- else :
316
- text = "UTF-16 (narrow build)"
317
- else :
318
- text = "PEP 393"
319
- print ("Unicode: %s" % text )
324
+ print (f"Python { sys .version } " )
325
+ print ("Unicode: PEP 393" )
320
326
print (platform .platform ())
321
327
binary_files = list (get_binary_files ())
322
328
text_files = list (get_text_files ())
323
329
if "b" in options :
324
330
print ("Binary unit = one byte" )
325
331
if "t" in options :
326
- print ("Text unit = one character (%s -decoded)" % TEXT_ENCODING )
332
+ print (f "Text unit = one character ({ TEXT_ENCODING } -decoded)" )
327
333
328
334
# Binary reads
329
335
if "b" in options and "r" in options :
@@ -338,6 +344,7 @@ def run_test_family(tests, mode_filter, files, open_func, *make_args):
338
344
# Binary writes
339
345
if "b" in options and "w" in options :
340
346
print ("\n ** Binary append **\n " )
347
+
341
348
def make_test_source (name , size ):
342
349
with open (name , "rb" ) as f :
343
350
return f .read ()
@@ -347,6 +354,7 @@ def make_test_source(name, size):
347
354
# Text writes
348
355
if "t" in options and "w" in options :
349
356
print ("\n ** Text append **\n " )
357
+
350
358
def make_test_source (name , size ):
351
359
with text_open (name , "r" ) as f :
352
360
return f .read ()
@@ -356,6 +364,7 @@ def make_test_source(name, size):
356
364
# Binary overwrites
357
365
if "b" in options and "w" in options :
358
366
print ("\n ** Binary overwrite **\n " )
367
+
359
368
def make_test_source (name , size ):
360
369
with open (name , "rb" ) as f :
361
370
return f .read ()
@@ -365,6 +374,7 @@ def make_test_source(name, size):
365
374
# Text overwrites
366
375
if "t" in options and "w" in options :
367
376
print ("\n ** Text overwrite **\n " )
377
+
368
378
def make_test_source (name , size ):
369
379
with text_open (name , "r" ) as f :
370
380
return f .read ()
@@ -388,7 +398,7 @@ def prepare_files():
388
398
break
389
399
else :
390
400
raise RuntimeError (
391
- "Couldn't find chunk marker in %s !" % __file__ )
401
+ f "Couldn't find chunk marker in { __file__ } !" )
392
402
if NEWLINES == "all" :
393
403
it = itertools .cycle (["\n " , "\r " , "\r \n " ])
394
404
else :
@@ -414,6 +424,7 @@ def prepare_files():
414
424
f .write (head )
415
425
f .write (tail )
416
426
427
+
417
428
def main ():
418
429
global TEXT_ENCODING , NEWLINES
419
430
@@ -433,7 +444,7 @@ def main():
433
444
help = "run write & modify tests" )
434
445
parser .add_option ("-E" , "--encoding" ,
435
446
action = "store" , dest = "encoding" , default = None ,
436
- help = "encoding for text tests (default: %s)" % TEXT_ENCODING )
447
+ help = f "encoding for text tests (default: { TEXT_ENCODING } )" )
437
448
parser .add_option ("-N" , "--newlines" ,
438
449
action = "store" , dest = "newlines" , default = 'lf' ,
439
450
help = "line endings for text tests "
@@ -446,7 +457,7 @@ def main():
446
457
parser .error ("unexpected arguments" )
447
458
NEWLINES = options .newlines .lower ()
448
459
if NEWLINES not in ('lf' , 'cr' , 'crlf' , 'all' ):
449
- parser .error ("invalid 'newlines' option: %r" % NEWLINES )
460
+ parser .error (f "invalid 'newlines' option: { NEWLINES !r } " )
450
461
451
462
test_options = ""
452
463
if options .read :
@@ -471,6 +482,7 @@ def main():
471
482
prepare_files ()
472
483
run_all_tests (test_options )
473
484
485
+
474
486
if __name__ == "__main__" :
475
487
main ()
476
488
0 commit comments