99import time
1010from pathlib import Path
1111
12- from typing import Iterator , List , Optional , Tuple , Union
12+ from typing import Iterator , List , Optional , Tuple
1313
1414
1515class ShellSession :
@@ -21,6 +21,7 @@ class ShellSession:
2121 def __init__ (self , output_filename : str ):
2222 self .output_filename = output_filename
2323 self .last_duration : float = 0
24+ self .foutput = None
2425
2526 def __enter__ (self ):
2627 self .foutput = open (self .output_filename , "a" , encoding = "utf-8" )
@@ -31,6 +32,7 @@ def __exit__(self, exc_type, exc_value, traceback):
3132 self .foutput .close ()
3233
3334 def print (self , * args , ** kwargs ):
35+ """Print a message to this shell's log."""
3436 print (* args , ** kwargs , file = self .foutput )
3537
3638 def run_command (self , cmd : str ) -> str :
@@ -114,8 +116,9 @@ class ProjectToTest:
114116 git_url : Optional [str ] = None
115117
116118 def __init__ (self ):
117- self .slug = self .git_url .split ("/" )[- 1 ]
118- self .dir = Path (self .slug )
119+ if self .git_url :
120+ self .slug = self .git_url .split ("/" )[- 1 ]
121+ self .dir = Path (self .slug )
119122
120123 def get_source (self , shell ):
121124 """Get the source of the project."""
@@ -147,6 +150,7 @@ def prep_environment(self, env):
147150 self .run_tox (env , env .pyver .toxenv , "--notest" )
148151
149152 def run_tox (self , env , toxenv , toxargs = "" ):
153+ """Run a tox command. Return the duration."""
150154 env .shell .run_command (f"{ env .python } -m tox -e { toxenv } { toxargs } " )
151155 return env .shell .last_duration
152156
@@ -155,7 +159,9 @@ def run_no_coverage(self, env):
155159
156160 def run_with_coverage (self , env , pip_args , cov_options ):
157161 self .run_tox (env , env .pyver .toxenv , "--notest" )
158- env .shell .run_command (f".tox/{ env .pyver .toxenv } /bin/python -m pip install { pip_args } " )
162+ env .shell .run_command (
163+ f".tox/{ env .pyver .toxenv } /bin/python -m pip install { pip_args } "
164+ )
159165 return self .run_tox (env , env .pyver .toxenv , "--skip-pkg-install" )
160166
161167
@@ -177,6 +183,7 @@ def run_with_coverage(self, env, pip_args, cov_options):
177183 env .shell .run_command (f".tox/{ covenv } /bin/python -m coverage debug sys" )
178184 return self .run_tox (env , covenv , "--skip-pkg-install" )
179185
186+
180187class ProjectDateutil (ToxProject ):
181188 """dateutil/dateutil"""
182189
@@ -190,11 +197,45 @@ def run_no_coverage(self, env):
190197 env .shell .run_command ("echo No option to run without coverage" )
191198 return 0
192199
200+
193201class ProjectAttrs (ToxProject ):
202+ """python-attrs/attrs"""
203+
194204 git_url = "https://github.com/python-attrs/attrs"
195205
196206
207+ class AdHocProject (ProjectToTest ):
208+ """A standalone program to run locally."""
209+
210+ def __init__ (self , python_file , pip_args = None ):
211+ super ().__init__ ()
212+ self .python_file = Path (python_file )
213+ self .pip_args = pip_args
214+ self .slug = self .python_file .name
215+
216+ def get_source (self , shell ):
217+ pass
218+
219+ def prep_environment (self , env ):
220+ env .shell .run_command (f"{ env .python } -m pip install { self .pip_args } " )
221+
222+ def run_no_coverage (self , env ):
223+ with change_dir (self .python_file .parent ):
224+ env .shell .run_command (f"{ env .python } { self .python_file .name } " )
225+ return env .shell .last_duration
226+
227+ def run_with_coverage (self , env , pip_args , cov_options ):
228+ env .shell .run_command (f"{ env .python } -m pip install { pip_args } " )
229+ with change_dir (self .python_file .parent ):
230+ env .shell .run_command (
231+ f"{ env .python } -m coverage run { self .python_file .name } "
232+ )
233+ return env .shell .last_duration
234+
235+
197236class PyVersion :
237+ """A version of Python to use."""
238+
198239 # The command to run this Python
199240 command : str
200241 # The tox environment to run this Python
@@ -236,7 +277,7 @@ def run_experiments(
236277
237278 results = []
238279 for proj in projects :
239- print (f"Testing with { proj .git_url } " )
280+ print (f"Testing with { proj .slug } " )
240281 with ShellSession (f"output_{ proj .slug } .log" ) as shell :
241282 proj .get_source (shell )
242283
@@ -264,7 +305,10 @@ def run_experiments(
264305 print (f"Tests took { dur :.3f} s" )
265306 durations .append (dur )
266307 med = statistics .median (durations )
267- result = f"Median for { proj .slug } , { pyver .command } , cov={ cov_slug } : { med :.3f} s"
308+ result = (
309+ f"Median for { proj .slug } , { pyver .command } , "
310+ + f"cov={ cov_slug } : { med :.3f} s"
311+ )
268312 print (f"## { result } " )
269313 results .append (result )
270314
@@ -281,38 +325,60 @@ def run_experiments(
281325
282326with change_dir (PERF_DIR ):
283327
284- run_experiments (
285- py_versions = [
286- Python (3 , 7 ),
287- Python (3 , 10 ),
288- ],
289- cov_versions = [
290- #("none", None, None),
291- ("6.4 timid" , "coverage==6.4" , "timid=True" ),
292- ("tip timid" , "git+https://github.com/nedbat/coveragepy.git@master" , "timid=True" ),
293- ],
294- projects = [
295- ProjectPytestHtml (),
296- ProjectAttrs (),
297- ],
298- num_runs = 3 ,
299- )
300-
301- # run_experiments(
302- # py_versions=[
303- # PyPy(3, 9),
304- # ],
305- # cov_versions=[
306- # ("none", None, None),
307- # ("6.4", "coverage==6.4", ""),
308- # (
309- # "PR 1381",
310- # "git+https://github.com/cfbolz/coveragepy.git@f_trace_lines",
311- # "",
312- # ),
313- # ],
314- # projects=[
315- # ProjectPytestHtml(),
316- # ],
317- # num_runs=3,
318- # )
328+ if 1 :
329+ run_experiments (
330+ py_versions = [
331+ Python (3 , 7 ),
332+ Python (3 , 10 ),
333+ ],
334+ cov_versions = [
335+ # ("none", None, None),
336+ ("6.4 timid" , "coverage==6.4" , "timid=True" ),
337+ (
338+ "tip timid" ,
339+ "git+https://github.com/nedbat/coveragepy.git@master" ,
340+ "timid=True" ,
341+ ),
342+ ],
343+ projects = [
344+ ProjectPytestHtml (),
345+ ProjectAttrs (),
346+ ],
347+ num_runs = 3 ,
348+ )
349+
350+ if 0 :
351+ run_experiments (
352+ py_versions = [
353+ PyPy (3 , 9 ),
354+ ],
355+ cov_versions = [
356+ ("none" , None , None ),
357+ ("6.4" , "coverage==6.4" , "" ),
358+ (
359+ "PR 1381" ,
360+ "git+https://github.com/cfbolz/coveragepy.git@f_trace_lines" ,
361+ "" ,
362+ ),
363+ ],
364+ projects = [
365+ ProjectPytestHtml (),
366+ ],
367+ num_runs = 3 ,
368+ )
369+
370+ if 0 :
371+ run_experiments (
372+ py_versions = [
373+ PyPy (3 , 9 ),
374+ ],
375+ cov_versions = [
376+ ("none" , None , None ),
377+ ("6.4" , "coverage" , "" ),
378+ ("tip" , "git+https://github.com/nedbat/coveragepy.git@master" , "" ),
379+ ],
380+ projects = [
381+ AdHocProject ("/src/bugs/bug1339/bug1339.py" ),
382+ ],
383+ num_runs = 7 ,
384+ )
0 commit comments