From 5e193ac0bd6bd4d4a122fd9aa2446ee70e5f2bf1 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 24 Sep 2014 13:26:25 +0300 Subject: [PATCH] Issue #22427: TemporaryDirectory no longer attempts to clean up twice when used in the with statement in generator. --- Lib/tempfile.py | 15 +++------------ Lib/test/test_tempfile.py | 24 ++++++++++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Lib/tempfile.py b/Lib/tempfile.py index f0e25fc2d54..35fd8b4cab8 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -663,11 +663,6 @@ class TemporaryDirectory(object): in it are removed. """ - # Handle mkdtemp raising an exception - name = None - _finalizer = None - _closed = False - def __init__(self, suffix="", prefix=template, dir=None): self.name = mkdtemp(suffix, prefix, dir) self._finalizer = _weakref.finalize( @@ -675,10 +670,9 @@ class TemporaryDirectory(object): warn_message="Implicitly cleaning up {!r}".format(self)) @classmethod - def _cleanup(cls, name, warn_message=None): + def _cleanup(cls, name, warn_message): _shutil.rmtree(name) - if warn_message is not None: - _warnings.warn(warn_message, ResourceWarning) + _warnings.warn(warn_message, ResourceWarning) def __repr__(self): @@ -691,8 +685,5 @@ class TemporaryDirectory(object): self.cleanup() def cleanup(self): - if self._finalizer is not None: - self._finalizer.detach() - if self.name is not None and not self._closed: + if self._finalizer.detach(): _shutil.rmtree(self.name) - self._closed = True diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index ec975f82a6f..2e10fddae0f 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -1211,6 +1211,30 @@ class TestTemporaryDirectory(BaseTestCase): 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 sys + import tempfile + import warnings + + def generator(): + with tempfile.TemporaryDirectory(dir={dir!r}) as tmp: + yield tmp + g = generator() + sys.stdout.buffer.write(next(g).encode()) + + 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: diff --git a/Misc/NEWS b/Misc/NEWS index f21ece633c9..5b8cbca531b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -13,6 +13,9 @@ Core and Builtins Library ------- +- Issue #22427: TemporaryDirectory no longer attempts to clean up twice when + used in the with statement in generator. + - Issue #20912: Now directories added to ZIP file have correct Unix and MS-DOS directory attributes.