From: Serhiy Storchaka Date: Tue, 12 Feb 2013 22:37:29 +0000 (+0200) Subject: Issue #16800: tempfile.gettempdir() no longer left temporary files when X-Git-Tag: v3.3.1rc1~180 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ff7fef9601d15cdf274b4b984c7638f33002e879;p=python Issue #16800: tempfile.gettempdir() no longer left temporary files when the disk is full. Original patch by Amir Szekely. --- ff7fef9601d15cdf274b4b984c7638f33002e879 diff --cc Lib/tempfile.py index 0cc5c04405,0dbd889609..3c3aec1eed --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@@ -172,19 -175,21 +172,22 @@@ def _get_default_tempdir() filename = _os.path.join(dir, name) try: fd = _os.open(filename, _bin_openflags, 0o600) - fp = _io.open(fd, 'wb') - fp.write(b'blat') - fp.close() - _os.unlink(filename) - del fp, fd + try: + try: + fp = _io.open(fd, 'wb', buffering=0, closefd=False) + fp.write(b'blat') + finally: + _os.close(fd) + finally: + _os.unlink(filename) return dir - except (OSError, IOError) as e: - if e.args[0] != _errno.EEXIST: - break # no point trying more names in this directory + except FileExistsError: pass - raise IOError(_errno.ENOENT, - "No usable temporary directory found in %s" % dirlist) + except OSError: + break # no point trying more names in this directory + raise FileNotFoundError(_errno.ENOENT, + "No usable temporary directory found in %s" % + dirlist) _name_sequence = None diff --cc Lib/test/test_tempfile.py index b638d873c9,cf8b35ac80..2962939ce0 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@@ -197,11 -211,53 +198,48 @@@ class TestCandidateTempdirList(BaseTest # Not practical to try to verify the presence of OS-specific # paths in this list. -test_classes.append(test__candidate_tempdir_list) - # We test _get_default_tempdir by testing gettempdir. + # We test _get_default_tempdir some more by testing gettempdir. + -class TestGetDefaultTempdir(TC): ++class TestGetDefaultTempdir(BaseTestCase): + """Test _get_default_tempdir().""" + + def test_no_files_left_behind(self): + # use a private empty directory + with tempfile.TemporaryDirectory() as our_temp_directory: + # force _get_default_tempdir() to consider our empty directory + def our_candidate_list(): + return [our_temp_directory] + + with support.swap_attr(tempfile, "_candidate_tempdir_list", + our_candidate_list): + # verify our directory is empty after _get_default_tempdir() + tempfile._get_default_tempdir() + self.assertEqual(os.listdir(our_temp_directory), []) + + def raise_OSError(*args, **kwargs): - raise OSError(-1) ++ raise OSError() + + with support.swap_attr(io, "open", raise_OSError): + # test again with failing io.open() - with self.assertRaises(IOError) as cm: ++ with self.assertRaises(FileNotFoundError): + tempfile._get_default_tempdir() - self.assertEqual(cm.exception.args[0], errno.ENOENT) + self.assertEqual(os.listdir(our_temp_directory), []) + + open = io.open + def bad_writer(*args, **kwargs): + fp = open(*args, **kwargs) + fp.write = raise_OSError + return fp + + with support.swap_attr(io, "open", bad_writer): + # test again with failing write() - with self.assertRaises(IOError) as cm: ++ with self.assertRaises(FileNotFoundError): + tempfile._get_default_tempdir() - self.assertEqual(cm.exception.errno, errno.ENOENT) + self.assertEqual(os.listdir(our_temp_directory), []) -test_classes.append(TestGetDefaultTempdir) - -class test__get_candidate_names(TC): +class TestGetCandidateNames(BaseTestCase): """Test the internal function _get_candidate_names.""" def test_retval(self):