summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_tempfile.py
diff options
context:
space:
mode:
authorEv2geny <ev2geny@gmail.com>2022-10-04 22:37:33 (GMT)
committerGitHub <noreply@github.com>2022-10-04 22:37:33 (GMT)
commit743453a5541d3a6f19046459d22a7991ecb88223 (patch)
treebbecc400935d6ea5564292bba5c963e03520141a /Lib/test/test_tempfile.py
parentbbc7cd649a6ef56eb09278f3e746ca89b9d592c9 (diff)
downloadcpython-743453a5541d3a6f19046459d22a7991ecb88223.zip
cpython-743453a5541d3a6f19046459d22a7991ecb88223.tar.gz
cpython-743453a5541d3a6f19046459d22a7991ecb88223.tar.bz2
gh-58451: Add optional delete_on_close parameter to NamedTemporaryFile (GH-97015)
Diffstat (limited to 'Lib/test/test_tempfile.py')
-rw-r--r--Lib/test/test_tempfile.py100
1 files changed, 99 insertions, 1 deletions
diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py
index ccf7ea0..7c2c8de 100644
--- a/Lib/test/test_tempfile.py
+++ b/Lib/test/test_tempfile.py
@@ -11,6 +11,7 @@ import contextlib
import stat
import types
import weakref
+import gc
from unittest import mock
import unittest
@@ -1013,6 +1014,102 @@ class TestNamedTemporaryFile(BaseTestCase):
pass
self.assertRaises(ValueError, use_closed)
+ def test_context_man_not_del_on_close_if_delete_on_close_false(self):
+ # Issue gh-58451: tempfile.NamedTemporaryFile is not particulary useful
+ # on Windows
+ # A NamedTemporaryFile is NOT deleted when closed if
+ # delete_on_close=False, but is deleted on context manager exit
+ dir = tempfile.mkdtemp()
+ try:
+ with tempfile.NamedTemporaryFile(dir=dir,
+ delete=True,
+ delete_on_close=False) as f:
+ f.write(b'blat')
+ f_name = f.name
+ f.close()
+ with self.subTest():
+ # Testing that file is not deleted on close
+ self.assertTrue(os.path.exists(f.name),
+ f"NamedTemporaryFile {f.name!r} is incorrectly "
+ f"deleted on closure when delete_on_close=False")
+
+ with self.subTest():
+ # Testing that file is deleted on context manager exit
+ self.assertFalse(os.path.exists(f.name),
+ f"NamedTemporaryFile {f.name!r} exists "
+ f"after context manager exit")
+
+ finally:
+ os.rmdir(dir)
+
+ def test_context_man_ok_to_delete_manually(self):
+ # In the case of delete=True, a NamedTemporaryFile can be manually
+ # deleted in a with-statement context without causing an error.
+ dir = tempfile.mkdtemp()
+ try:
+ with tempfile.NamedTemporaryFile(dir=dir,
+ delete=True,
+ delete_on_close=False) as f:
+ f.write(b'blat')
+ f.close()
+ os.unlink(f.name)
+
+ finally:
+ os.rmdir(dir)
+
+ def test_context_man_not_del_if_delete_false(self):
+ # A NamedTemporaryFile is not deleted if delete = False
+ dir = tempfile.mkdtemp()
+ f_name = ""
+ try:
+ # Test that delete_on_close=True has no effect if delete=False.
+ with tempfile.NamedTemporaryFile(dir=dir, delete=False,
+ delete_on_close=True) as f:
+ f.write(b'blat')
+ f_name = f.name
+ self.assertTrue(os.path.exists(f.name),
+ f"NamedTemporaryFile {f.name!r} exists after close")
+ finally:
+ os.unlink(f_name)
+ os.rmdir(dir)
+
+ def test_del_by_finalizer(self):
+ # A NamedTemporaryFile is deleted when finalized in the case of
+ # delete=True, delete_on_close=False, and no with-statement is used.
+ def my_func(dir):
+ f = tempfile.NamedTemporaryFile(dir=dir, delete=True,
+ delete_on_close=False)
+ tmp_name = f.name
+ f.write(b'blat')
+ # Testing extreme case, where the file is not explicitly closed
+ # f.close()
+ return tmp_name
+ # Make sure that the garbage collector has finalized the file object.
+ gc.collect()
+ dir = tempfile.mkdtemp()
+ try:
+ tmp_name = my_func(dir)
+ self.assertFalse(os.path.exists(tmp_name),
+ f"NamedTemporaryFile {tmp_name!r} "
+ f"exists after finalizer ")
+ finally:
+ os.rmdir(dir)
+
+ def test_correct_finalizer_work_if_already_deleted(self):
+ # There should be no error in the case of delete=True,
+ # delete_on_close=False, no with-statement is used, and the file is
+ # deleted manually.
+ def my_func(dir)->str:
+ f = tempfile.NamedTemporaryFile(dir=dir, delete=True,
+ delete_on_close=False)
+ tmp_name = f.name
+ f.write(b'blat')
+ f.close()
+ os.unlink(tmp_name)
+ return tmp_name
+ # Make sure that the garbage collector has finalized the file object.
+ gc.collect()
+
def test_bad_mode(self):
dir = tempfile.mkdtemp()
self.addCleanup(os_helper.rmtree, dir)
@@ -1081,7 +1178,8 @@ class TestSpooledTemporaryFile(BaseTestCase):
missing_attrs = iobase_attrs - spooledtempfile_attrs
self.assertFalse(
missing_attrs,
- 'SpooledTemporaryFile missing attributes from IOBase/BufferedIOBase/TextIOBase'
+ 'SpooledTemporaryFile missing attributes from '
+ 'IOBase/BufferedIOBase/TextIOBase'
)
def test_del_on_close(self):