diff --git a/py/_process/forkedfunc.py b/py/_process/forkedfunc.py index 1c285306..8072f4df 100644 --- a/py/_process/forkedfunc.py +++ b/py/_process/forkedfunc.py @@ -107,7 +107,7 @@ def _removetemp(self): self.tempdir.remove() def __del__(self): - if self.pid is not None: # only clean up in main process + if getattr(self, "pid", None) is not None: # only clean up in main process self._removetemp() diff --git a/testing/process/test_forkedfunc.py b/testing/process/test_forkedfunc.py index ae0d9ab7..686d2c10 100644 --- a/testing/process/test_forkedfunc.py +++ b/testing/process/test_forkedfunc.py @@ -1,3 +1,5 @@ +import gc + import pytest import py, sys, os @@ -16,6 +18,18 @@ def test_tempdir_gets_gc_collected(monkeypatch): assert ff.tempdir.check() ff.__del__() assert not ff.tempdir.check() + +def test_no_second_exception_if_fork_fails(monkeypatch): + def raise_oserror(): + # BlockingIOError on py3k + raise OSError("Resource temporarily unavailable") + monkeypatch.setattr(os, "fork", raise_oserror) + with pytest.raises(OSError, match="Resource temporarily unavailable"): + py.process.ForkedFunc(boxf1) + # Make sure the ForkedFunc is collected + # That may be triggered by refcounting while exiting the with statement, + # but gc.collect() should work even on PyPy. + gc.collect() def test_basic_forkedfunc(): result = py.process.ForkedFunc(boxf1).waitfinish()