|
| 1 | +import sys |
| 2 | + |
1 | 3 | import pytest
|
2 | 4 | from _pytest._code.code import ExceptionChainRepr
|
3 | 5 | from _pytest.pathlib import Path
|
@@ -314,27 +316,52 @@ def check_longrepr(longrepr):
|
314 | 316 | # elsewhere and we do check the contents of the longrepr object after loading it.
|
315 | 317 | loaded_report.longrepr.toterminal(tw_mock)
|
316 | 318 |
|
317 |
| - def test_chained_exceptions_no_reprcrash( |
318 |
| - self, testdir, tw_mock, |
319 |
| - ): |
| 319 | + def test_chained_exceptions_no_reprcrash(self, testdir, tw_mock): |
320 | 320 | """Regression test for tracebacks without a reprcrash (#5971)
|
321 | 321 |
|
322 | 322 | This happens notably on exceptions raised by multiprocess.pool: the exception transfer
|
323 | 323 | from subprocess to main process creates an artificial exception, which ExceptionInfo
|
324 | 324 | can't obtain the ReprFileLocation from.
|
325 | 325 | """
|
326 |
| - testdir.makepyfile( |
| 326 | + # somehow in Python 3.5 on Windows this test fails with: |
| 327 | + # File "c:\...\3.5.4\x64\Lib\multiprocessing\connection.py", line 302, in _recv_bytes |
| 328 | + # overlapped=True) |
| 329 | + # OSError: [WinError 6] The handle is invalid |
| 330 | + # |
| 331 | + # so in this platform we opted to use a mock traceback which is identical to the |
| 332 | + # one produced by the multiprocessing module |
| 333 | + if sys.version_info[:2] <= (3, 5) and sys.platform.startswith("win"): |
| 334 | + testdir.makepyfile( |
| 335 | + """ |
| 336 | + # equivalent of multiprocessing.pool.RemoteTraceback |
| 337 | + class RemoteTraceback(Exception): |
| 338 | + def __init__(self, tb): |
| 339 | + self.tb = tb |
| 340 | + def __str__(self): |
| 341 | + return self.tb |
| 342 | + def test_a(): |
| 343 | + try: |
| 344 | + raise ValueError('value error') |
| 345 | + except ValueError as e: |
| 346 | + # equivalent to how multiprocessing.pool.rebuild_exc does it |
| 347 | + e.__cause__ = RemoteTraceback('runtime error') |
| 348 | + raise e |
327 | 349 | """
|
328 |
| - from concurrent.futures import ProcessPoolExecutor |
| 350 | + ) |
| 351 | + else: |
| 352 | + testdir.makepyfile( |
| 353 | + """ |
| 354 | + from concurrent.futures import ProcessPoolExecutor |
329 | 355 |
|
330 |
| - def func(): |
331 |
| - raise ValueError('value error') |
| 356 | + def func(): |
| 357 | + raise ValueError('value error') |
| 358 | +
|
| 359 | + def test_a(): |
| 360 | + with ProcessPoolExecutor() as p: |
| 361 | + p.submit(func).result() |
| 362 | + """ |
| 363 | + ) |
332 | 364 |
|
333 |
| - def test_a(): |
334 |
| - with ProcessPoolExecutor() as p: |
335 |
| - p.submit(func).result() |
336 |
| - """ |
337 |
| - ) |
338 | 365 | reprec = testdir.inline_run()
|
339 | 366 |
|
340 | 367 | reports = reprec.getreports("pytest_runtest_logreport")
|
|
0 commit comments