diff -r 9f7b97fac919 Lib/tempfile.py --- a/Lib/tempfile.py Wed Sep 17 13:19:34 2014 +0800 +++ b/Lib/tempfile.py Wed Sep 17 20:32:33 2014 +0300 @@ -697,12 +697,15 @@ class TemporaryDirectory(object): def __init__(self, suffix="", prefix=template, dir=None): self.name = mkdtemp(suffix, prefix, dir) self._finalizer = _weakref.finalize( - self, self._cleanup, self.name, + self, self._cleanup, _weakref.ref(self), self.name, warn_message="Implicitly cleaning up {!r}".format(self)) - @classmethod - def _cleanup(cls, name, warn_message=None): + @staticmethod + def _cleanup(ref, name, warn_message=None): _shutil.rmtree(name) + self = ref() + if self is not None: + self._closed = True if warn_message is not None: _warnings.warn(warn_message, ResourceWarning) diff -r 9f7b97fac919 Lib/test/test_tempfile.py --- a/Lib/test/test_tempfile.py Wed Sep 17 13:19:34 2014 +0800 +++ b/Lib/test/test_tempfile.py Wed Sep 17 20:32:33 2014 +0300 @@ -1211,6 +1211,29 @@ class TestTemporaryDirectory(BaseTestCas self.assertNotIn("Exception ", err) self.assertIn("ResourceWarning: Implicitly cleaning up", err) + def test_exit_on_shutdown(self): + # Issue #22427 + with self.do_create() as dir: + code = """if True: + import tempfile + import warnings + + def generator(): + with tempfile.TemporaryDirectory(dir={dir!r}): + yield + g = generator() + next(g) + + warnings.filterwarnings("always", category=ResourceWarning) + """.format(dir=dir) + rc, out, err = script_helper.assert_python_ok("-c", code) + tmp_name = out.decode().strip() + self.assertFalse(os.path.exists(tmp_name), + "TemporaryDirectory %s exists after cleanup" % tmp_name) + err = err.decode('utf-8', 'backslashreplace') + self.assertNotIn("Exception ", err) + self.assertIn("ResourceWarning: Implicitly cleaning up", err) + def test_warnings_on_cleanup(self): # ResourceWarning will be triggered by __del__ with self.do_create() as dir: