@@ -159,6 +159,7 @@ def run_no_coverage(self, env):
159
159
return self .run_tox (env , env .pyver .toxenv , "--skip-pkg-install" )
160
160
161
161
def run_with_coverage (self , env , pip_args , cov_options ):
162
+ assert not cov_options , f"ToxProject.run_with_coverage can't take cov_options={ cov_options !r} "
162
163
self .run_tox (env , env .pyver .toxenv , "--notest" )
163
164
env .shell .run_command (
164
165
f".tox/{ env .pyver .toxenv } /bin/python -m pip install { pip_args } "
@@ -286,6 +287,16 @@ def __init__(self, path, slug):
286
287
self .slug = slug
287
288
self .toxenv = None
288
289
290
+ @dataclasses .dataclass
291
+ class Coverage :
292
+ """A version of coverage.py to use, maybe None."""
293
+ # Short word for messages, directories, etc
294
+ slug : str
295
+ # Arguments for "pip install ..."
296
+ pip_args : Optional [str ] = None
297
+ # Tweaks to the .coveragerc file
298
+ options : Optional [str ] = None
299
+
289
300
290
301
@dataclasses .dataclass
291
302
class Env :
@@ -296,67 +307,78 @@ class Env:
296
307
shell : ShellSession
297
308
298
309
299
- def run_experiment (
300
- py_versions : List [PyVersion ],
301
- cov_versions : List [Tuple [str , Optional [str ], Optional [str ]]],
302
- projects : List [ProjectToTest ],
303
- num_runs : int = 3 ,
304
- rows : Optional [List [str ]] = None ,
305
- column : Optional [str ] = None ,
306
- ratios : Iterable [Tuple [str , str , str ]] = (),
307
- ):
308
- """Run test suites under different conditions."""
309
-
310
- result_data : Dict [Tuple [str , str , str ], float ] = {}
311
- results = []
312
- for proj in projects :
313
- print (f"Testing with { proj .slug } " )
314
- with ShellSession (f"output_{ proj .slug } .log" ) as shell :
315
- proj .get_source (shell )
316
-
317
- for pyver in py_versions :
318
- print (f"Making venv for { proj .slug } { pyver .slug } " )
319
- venv_dir = f"venv_{ proj .slug } _{ pyver .slug } "
320
- shell .run_command (f"{ pyver .command } -m venv { venv_dir } " )
321
- python = Path .cwd () / f"{ venv_dir } /bin/python"
322
- shell .run_command (f"{ python } -V" )
323
- env = Env (pyver , python , shell )
324
-
325
- with change_dir (Path (proj .slug )):
326
- print (f"Prepping for { proj .slug } { pyver .slug } " )
327
- proj .prep_environment (env )
328
- for cov_slug , cov_pip , cov_options in cov_versions :
329
- durations = []
330
- for run_num in range (num_runs ):
331
- print (
332
- f"Running tests, cov={ cov_slug } , { run_num + 1 } of { num_runs } "
310
+ ResultData = Dict [Tuple [str , str , str ], float ]
311
+
312
+ class Experiment :
313
+ """A particular time experiment to run."""
314
+
315
+ def __init__ (
316
+ self ,
317
+ py_versions : List [PyVersion ],
318
+ cov_versions : List [Coverage ],
319
+ projects : List [ProjectToTest ],
320
+ ):
321
+ self .py_versions = py_versions
322
+ self .cov_versions = cov_versions
323
+ self .projects = projects
324
+ self .result_data : ResultData = {}
325
+
326
+ def run (self , num_runs : int = 3 ) -> None :
327
+ results = []
328
+ for proj in self .projects :
329
+ print (f"Testing with { proj .slug } " )
330
+ with ShellSession (f"output_{ proj .slug } .log" ) as shell :
331
+ proj .get_source (shell )
332
+
333
+ for pyver in self .py_versions :
334
+ print (f"Making venv for { proj .slug } { pyver .slug } " )
335
+ venv_dir = f"venv_{ proj .slug } _{ pyver .slug } "
336
+ shell .run_command (f"{ pyver .command } -m venv { venv_dir } " )
337
+ python = Path .cwd () / f"{ venv_dir } /bin/python"
338
+ shell .run_command (f"{ python } -V" )
339
+ env = Env (pyver , python , shell )
340
+
341
+ with change_dir (Path (proj .slug )):
342
+ print (f"Prepping for { proj .slug } { pyver .slug } " )
343
+ proj .prep_environment (env )
344
+ for cov_ver in self .cov_versions :
345
+ durations = []
346
+ for run_num in range (num_runs ):
347
+ print (
348
+ f"Running tests, cov={ cov_ver .slug } , { run_num + 1 } of { num_runs } "
349
+ )
350
+ if cov_ver .pip_args is None :
351
+ dur = proj .run_no_coverage (env )
352
+ else :
353
+ dur = proj .run_with_coverage (
354
+ env , cov_ver .pip_args , cov_ver .options ,
355
+ )
356
+ print (f"Tests took { dur :.3f} s" )
357
+ durations .append (dur )
358
+ med = statistics .median (durations )
359
+ result = (
360
+ f"Median for { proj .slug } , { pyver .slug } , "
361
+ + f"cov={ cov_ver .slug } : { med :.3f} s"
333
362
)
334
- if cov_pip is None :
335
- dur = proj .run_no_coverage (env )
336
- else :
337
- dur = proj .run_with_coverage (env , cov_pip , cov_options )
338
- print (f"Tests took { dur :.3f} s" )
339
- durations .append (dur )
340
- med = statistics .median (durations )
341
- result = (
342
- f"Median for { proj .slug } , { pyver .slug } , "
343
- + f"cov={ cov_slug } : { med :.3f} s"
344
- )
345
- print (f"## { result } " )
346
- results .append (result )
347
- result_key = (proj .slug , pyver .slug , cov_slug )
348
- result_data [result_key ] = med
349
-
350
- print ("# Results" )
351
- for result in results :
352
- print (result )
353
-
354
- if rows :
355
- assert column
363
+ print (f"## { result } " )
364
+ results .append (result )
365
+ result_key = (proj .slug , pyver .slug , cov_ver .slug )
366
+ self .result_data [result_key ] = med
367
+
368
+ print ("# Results" )
369
+ for result in results :
370
+ print (result )
371
+
372
+ def show_results (
373
+ self ,
374
+ rows : List [str ],
375
+ column : str ,
376
+ ratios : Iterable [Tuple [str , str , str ]] = (),
377
+ ) -> None :
356
378
dimensions = {
357
- "cov" : [cov_slug for cov_slug , _ , _ in cov_versions ],
358
- "pyver" : [pyver .slug for pyver in py_versions ],
359
- "proj" : [proj .slug for proj in projects ],
379
+ "cov" : [cov_ver . slug for cov_ver in self . cov_versions ],
380
+ "pyver" : [pyver .slug for pyver in self . py_versions ],
381
+ "proj" : [proj .slug for proj in self . projects ],
360
382
}
361
383
362
384
table_axes = [dimensions [rowname ] for rowname in rows ]
@@ -381,12 +403,12 @@ def as_table_row(vals):
381
403
for col in dimensions [column ]:
382
404
key = (* tup , col )
383
405
key = tuple (key [i ] for i in remap )
384
- result_time = result_data [key ]
406
+ result_time = self . result_data [key ] # type: ignore
385
407
row .append (f"{ result_time :.3f} s" )
386
408
col_data [col ] = result_time
387
409
for _ , num , denom in ratios :
388
410
ratio = col_data [num ] / col_data [denom ]
389
- row .append (f"{ ratio :.3f } " )
411
+ row .append (f"{ int ( ratio * 100 ):d } % " )
390
412
print (as_table_row (row ))
391
413
392
414
@@ -399,16 +421,16 @@ def as_table_row(vals):
399
421
with change_dir (PERF_DIR ):
400
422
401
423
if 1 :
402
- run_experiment (
424
+ exp = Experiment (
403
425
py_versions = [
404
426
Python (3 , 10 ),
405
427
Python (3 , 11 ),
406
- AdHocPython ("/usr/local/cpython" , "gh93493" ),
428
+ # AdHocPython("/usr/local/cpython", "gh93493"),
407
429
],
408
430
cov_versions = [
409
- ("none" , None , None ),
410
- ("6.4.1" , "coverage==6.4.1" , " " ),
411
- # (
431
+ Coverage ("none" ),
432
+ Coverage ("6.4.1" , "coverage==6.4.1" ),
433
+ # Coverage (
412
434
# "tip timid",
413
435
# "git+https://github.com/nedbat/coveragepy.git@master",
414
436
# "timid=True",
@@ -421,24 +443,26 @@ def as_table_row(vals):
421
443
SlipcoverBenchmark ("bm_sudoku.py" ),
422
444
SlipcoverBenchmark ("bm_spectral_norm.py" ),
423
445
],
424
- num_runs = 3 ,
446
+ )
447
+ exp .run (num_runs = 3 )
448
+ exp .show_results (
425
449
rows = ["cov" , "proj" ],
426
450
column = "pyver" ,
427
451
ratios = [
428
452
("3.11 vs 3.10" , "python3.11" , "python3.10" ),
429
- ("fix vs 3.10" , "gh93493" , "python3.10" ),
453
+ # ("fix vs 3.10", "gh93493", "python3.10"),
430
454
],
431
455
)
432
456
433
457
if 0 :
434
- run_experiment (
458
+ exp = Experiment (
435
459
py_versions = [
436
460
PyPy (3 , 9 ),
437
461
],
438
462
cov_versions = [
439
- ("none" , None , None ),
440
- ("6.4" , "coverage==6.4" , "" ),
441
- (
463
+ Coverage ("none" , None , None ),
464
+ Coverage ("6.4" , "coverage==6.4" , "" ),
465
+ Coverage (
442
466
"PR 1381" ,
443
467
"git+https://github.com/cfbolz/coveragepy.git@f_trace_lines" ,
444
468
"" ,
@@ -447,21 +471,21 @@ def as_table_row(vals):
447
471
projects = [
448
472
ProjectPytestHtml (),
449
473
],
450
- num_runs = 3 ,
451
474
)
475
+ exp .run (num_runs = 3 )
452
476
453
477
if 0 :
454
- run_experiment (
478
+ exp = Experiment (
455
479
py_versions = [
456
480
PyPy (3 , 9 ),
457
481
],
458
482
cov_versions = [
459
- ("none" , None , None ),
460
- ("6.4" , "coverage" , "" ),
461
- ("tip" , "git+https://github.com/nedbat/coveragepy.git@master" , "" ),
483
+ Coverage ("none" , None , None ),
484
+ Coverage ("6.4" , "coverage" , "" ),
485
+ Coverage ("tip" , "git+https://github.com/nedbat/coveragepy.git@master" , "" ),
462
486
],
463
487
projects = [
464
488
AdHocProject ("/src/bugs/bug1339/bug1339.py" ),
465
489
],
466
- num_runs = 7 ,
467
490
)
491
+ exp .run (num_runs = 7 )
0 commit comments