BLD: prevent asv from calling sys.stdin.close() by using different launch method by qwhelan · Pull Request #25237 · pandas-dev/pandas (original) (raw)

This should fix the asv dev errors seen in #24953, though this may add a lot of runtime overhead so input on approaches appreciated.

When running asv dev, the default --launch-method=fork calls sys.stdin.close() in the main process where all benchmarks run. The function DataFrame._repr_html_() attempts to import IPython, which itself attempts a call on sys.stdin as part of IPython.__init__, which fails due to it having been closed by asv. This leads to the following output:

[ 30.00%] ··· frame_methods.Repr.time_html_repr_trunc_mi                                                                                                                                              failed
[ 30.00%] ···· Traceback (most recent call last):
                 File "/home/chris/code/asv/asv/benchmark.py", line 1170, in main_run_server
                   main_run(run_args)
                 File "/home/chris/code/asv/asv/benchmark.py", line 1044, in main_run
                   result = benchmark.do_run()
                 File "/home/chris/code/asv/asv/benchmark.py", line 523, in do_run
                   return self.run(*self._current_params)
                 File "/home/chris/code/asv/asv/benchmark.py", line 617, in run
                   min_run_count=self.min_run_count)
                 File "/home/chris/code/asv/asv/benchmark.py", line 680, in benchmark_timing
                   timing = timer.timeit(number)
                 File "/home/chris/anaconda3/lib/python3.7/timeit.py", line 176, in timeit
                   timing = self.inner(it, self.timer)
                 File "<timeit-src>", line 6, in inner
                 File "/home/chris/code/pandas/asv_bench/benchmarks/frame_methods.py", line 226, in time_html_repr_trunc_mi
                   self.df3._repr_html_()
                 File "/home/chris/code/pandas/pandas/core/frame.py", line 652, in _repr_html_
                   import IPython
                 File "/home/chris/anaconda3/lib/python3.7/site-packages/IPython/__init__.py", line 55, in <module>
                   from .terminal.embed import embed
                 File "/home/chris/anaconda3/lib/python3.7/site-packages/IPython/terminal/embed.py", line 16, in <module>
                   from IPython.terminal.interactiveshell import TerminalInteractiveShell
                 File "/home/chris/anaconda3/lib/python3.7/site-packages/IPython/terminal/interactiveshell.py", line 81, in <module>
                   if not _stream or not hasattr(_stream, 'isatty') or not _stream.isatty():
               ValueError: I/O operation on closed file

Long term, this needs to be changed upstream in asv. Short term, I see a couple options:

This PR implements the latter by using the --launch-method=spawn, but it's to be seen how much overhead that introduces.

The command asv dev is shorthand for asv run --quick --show-stderr --python=same. Unfortunately, the asv dev command does not expose the --launch-method flag, so we have to substitute with the extended form.