diff --git a/joblib/test/test_parallel.py b/joblib/test/test_parallel.py index e15c9955c..8d7673951 100644 --- a/joblib/test/test_parallel.py +++ b/joblib/test/test_parallel.py @@ -1032,6 +1032,7 @@ def test_parallel_with_unpicklable_functions_in_args( INTERACTIVE_DEFINED_FUNCTION_AND_CLASS_SCRIPT_CONTENT = """\ import sys +import faulthandler # Make sure that joblib is importable in the subprocess launching this # script. This is needed in case we run the tests from the joblib root # folder without having installed joblib @@ -1056,6 +1057,9 @@ def square(x, ignored=None, ignored2=None): # Here, we do not need the `if __name__ == "__main__":` safeguard when # using the default `loky` backend (even on Windows). +# To make debugging easier +faulthandler.dump_traceback_later(30, exit=True) + # The following baroque function call is meant to check that joblib # introspection rightfully uses cloudpickle instead of the (faster) pickle # module of the standard library when necessary. In particular cloudpickle is @@ -1078,9 +1082,11 @@ def test_parallel_with_interactively_defined_functions_default_backend(tmpdir): # filesystem script. script = tmpdir.join('joblib_interactively_defined_function.py') script.write(INTERACTIVE_DEFINED_FUNCTION_AND_CLASS_SCRIPT_CONTENT) - check_subprocess_call([sys.executable, script.strpath], - stdout_regex=r'\[0, 1, 4, 9, 16\]', - timeout=5) + check_subprocess_call( + [sys.executable, script.strpath], + stdout_regex=r'\[0, 1, 4, 9, 16\]', + timeout=None, # rely on faulthandler to kill the process + ) INTERACTIVELY_DEFINED_SUBCLASS_WITH_METHOD_SCRIPT_CONTENT = """\ diff --git a/joblib/testing.py b/joblib/testing.py index 28f79311c..f8939f056 100644 --- a/joblib/testing.py +++ b/joblib/testing.py @@ -50,9 +50,10 @@ def kill_process(): warnings.warn("Timeout running {}".format(cmd)) proc.kill() - timer = threading.Timer(timeout, kill_process) try: - timer.start() + if timeout is not None: + timer = threading.Timer(timeout, kill_process) + timer.start() stdout, stderr = proc.communicate() stdout, stderr = stdout.decode(), stderr.decode() if proc.returncode != 0: @@ -74,4 +75,5 @@ def kill_process(): stderr_regex, stderr)) finally: - timer.cancel() + if timeout is not None: + timer.cancel()