Skip to content

Commit 5e193ac

Browse files
Issue #22427: TemporaryDirectory no longer attempts to clean up twice when
used in the with statement in generator.
1 parent b87630c commit 5e193ac

File tree

3 files changed

+30
-12
lines changed

3 files changed

+30
-12
lines changed

Lib/tempfile.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -663,22 +663,16 @@ class TemporaryDirectory(object):
663663
in it are removed.
664664
"""
665665

666-
# Handle mkdtemp raising an exception
667-
name = None
668-
_finalizer = None
669-
_closed = False
670-
671666
def __init__(self, suffix="", prefix=template, dir=None):
672667
self.name = mkdtemp(suffix, prefix, dir)
673668
self._finalizer = _weakref.finalize(
674669
self, self._cleanup, self.name,
675670
warn_message="Implicitly cleaning up {!r}".format(self))
676671

677672
@classmethod
678-
def _cleanup(cls, name, warn_message=None):
673+
def _cleanup(cls, name, warn_message):
679674
_shutil.rmtree(name)
680-
if warn_message is not None:
681-
_warnings.warn(warn_message, ResourceWarning)
675+
_warnings.warn(warn_message, ResourceWarning)
682676

683677

684678
def __repr__(self):
@@ -691,8 +685,5 @@ def __exit__(self, exc, value, tb):
691685
self.cleanup()
692686

693687
def cleanup(self):
694-
if self._finalizer is not None:
695-
self._finalizer.detach()
696-
if self.name is not None and not self._closed:
688+
if self._finalizer.detach():
697689
_shutil.rmtree(self.name)
698-
self._closed = True

Lib/test/test_tempfile.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,6 +1211,30 @@ def test_del_on_shutdown(self):
12111211
self.assertNotIn("Exception ", err)
12121212
self.assertIn("ResourceWarning: Implicitly cleaning up", err)
12131213

1214+
def test_exit_on_shutdown(self):
1215+
# Issue #22427
1216+
with self.do_create() as dir:
1217+
code = """if True:
1218+
import sys
1219+
import tempfile
1220+
import warnings
1221+
1222+
def generator():
1223+
with tempfile.TemporaryDirectory(dir={dir!r}) as tmp:
1224+
yield tmp
1225+
g = generator()
1226+
sys.stdout.buffer.write(next(g).encode())
1227+
1228+
warnings.filterwarnings("always", category=ResourceWarning)
1229+
""".format(dir=dir)
1230+
rc, out, err = script_helper.assert_python_ok("-c", code)
1231+
tmp_name = out.decode().strip()
1232+
self.assertFalse(os.path.exists(tmp_name),
1233+
"TemporaryDirectory %s exists after cleanup" % tmp_name)
1234+
err = err.decode('utf-8', 'backslashreplace')
1235+
self.assertNotIn("Exception ", err)
1236+
self.assertIn("ResourceWarning: Implicitly cleaning up", err)
1237+
12141238
def test_warnings_on_cleanup(self):
12151239
# ResourceWarning will be triggered by __del__
12161240
with self.do_create() as dir:

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ Core and Builtins
1313
Library
1414
-------
1515

16+
- Issue #22427: TemporaryDirectory no longer attempts to clean up twice when
17+
used in the with statement in generator.
18+
1619
- Issue #20912: Now directories added to ZIP file have correct Unix and MS-DOS
1720
directory attributes.
1821

0 commit comments

Comments
 (0)