From 7a0d1b387dede074b82205954a8ecb4604ba8c38 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Tue, 14 Jan 2020 10:51:44 -0300 Subject: [PATCH] Use a dummy RemoteTraceback for test in Python 3.5 Windows Somehow in Python 3.5 on Windows this test fails with: File "c:\hostedtoolcache\windows\python\3.5.4\x64\Lib\multiprocessing\connection.py", line 302, in _recv_bytes overlapped=True) OSError: [WinError 6] The handle is invalid This only happens in this platform and Python version, decided to use a dummy traceback as originally done in #6412. (cherry picked from commit b9c136b809a33009ad514672666c515953957b33) --- testing/test_reports.py | 51 +++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/testing/test_reports.py b/testing/test_reports.py index d0bafec2351..8c509ec479d 100644 --- a/testing/test_reports.py +++ b/testing/test_reports.py @@ -1,3 +1,5 @@ +import sys + import pytest from _pytest._code.code import ExceptionChainRepr from _pytest.pathlib import Path @@ -314,27 +316,52 @@ def check_longrepr(longrepr): # elsewhere and we do check the contents of the longrepr object after loading it. loaded_report.longrepr.toterminal(tw_mock) - def test_chained_exceptions_no_reprcrash( - self, testdir, tw_mock, - ): + def test_chained_exceptions_no_reprcrash(self, testdir, tw_mock): """Regression test for tracebacks without a reprcrash (#5971) This happens notably on exceptions raised by multiprocess.pool: the exception transfer from subprocess to main process creates an artificial exception, which ExceptionInfo can't obtain the ReprFileLocation from. """ - testdir.makepyfile( + # somehow in Python 3.5 on Windows this test fails with: + # File "c:\...\3.5.4\x64\Lib\multiprocessing\connection.py", line 302, in _recv_bytes + # overlapped=True) + # OSError: [WinError 6] The handle is invalid + # + # so in this platform we opted to use a mock traceback which is identical to the + # one produced by the multiprocessing module + if sys.version_info[:2] <= (3, 5) and sys.platform.startswith("win"): + testdir.makepyfile( + """ + # equivalent of multiprocessing.pool.RemoteTraceback + class RemoteTraceback(Exception): + def __init__(self, tb): + self.tb = tb + def __str__(self): + return self.tb + def test_a(): + try: + raise ValueError('value error') + except ValueError as e: + # equivalent to how multiprocessing.pool.rebuild_exc does it + e.__cause__ = RemoteTraceback('runtime error') + raise e """ - from concurrent.futures import ProcessPoolExecutor + ) + else: + testdir.makepyfile( + """ + from concurrent.futures import ProcessPoolExecutor - def func(): - raise ValueError('value error') + def func(): + raise ValueError('value error') + + def test_a(): + with ProcessPoolExecutor() as p: + p.submit(func).result() + """ + ) - def test_a(): - with ProcessPoolExecutor() as p: - p.submit(func).result() - """ - ) reprec = testdir.inline_run() reports = reprec.getreports("pytest_runtest_logreport")