Function runtest() (used by single-process mode) always returns tuple with test result as integer and test time as float.
This tuple is passed as second argument to function accumulate_result(), which has (in Python 3.6):
def accumulate_result(self, test, result):
ok, test_time = result
self.test_times.append((test_time, test))
test_times is later used by code, which expects that times are floats:
if self.ns.print_slow:
self.test_times.sort(reverse=True)
print("10 slowest tests:")
for time, test in self.test_times[:10]:
print("%s: %.1fs" % (test, time))
Code used by multi-process mode can return tuple with integer and string (describing error in subprocess), which with --slow option would cause TypeError.
Example:
In terminal 1:
$ LD_LIBRARY_PATH="$(pwd)" ./python -m test.regrtest -j2 --slow test_lib2to3
In terminal 2 (sufficiently quickly):
$ kill -SIGINT $(ps aux | grep '"test_lib2to3"' | grep -v grep | awk '{print $2}')
Output in terminal 1:
Test suite interrupted by signal SIGINT.
1 test omitted:
test_lib2to3
10 slowest tests:
Traceback (most recent call last):
File "/tmp/cpython/Lib/runpy.py", line 170, in _run_module_as_main
"__main__", mod_spec)
File "/tmp/cpython/Lib/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/tmp/cpython/Lib/test/regrtest.py", line 39, in <module>
main_in_temp_cwd()
File "/tmp/cpython/Lib/test/libregrtest/main.py", line 451, in main_in_temp_cwd
main()
File "/tmp/cpython/Lib/test/libregrtest/main.py", line 429, in main
Regrtest().main(tests=tests, **kwargs)
File "/tmp/cpython/Lib/test/libregrtest/main.py", line 389, in main
self.display_result()
File "/tmp/cpython/Lib/test/libregrtest/main.py", line 261, in display_result
print("%s: %.1fs" % (test, time))
TypeError: a float is required
My suggested fix is to return string describing error as third element of that tuple.
Apparently problem was only reproducible in Python 3, because in Python 3, in "while finished < use_mp" loop, accumulate_result() is called early before checking if result[0] is INTERRUPTED or CHILD_ERROR, while in Python 2, accumulate_result() is called after check for result[0].