blob: 437b02b49efed4986e98653e077786608071ac16 [file] [log] [blame]
Guido van Rossum0e548712002-08-09 16:14:33 +00001# tempfile.py unit tests.
Tim Petersc57a2852001-10-29 21:46:08 +00002import tempfile
Serhiy Storchaka7451a722013-02-09 22:25:49 +02003import errno
Serhiy Storchakaf6b361e2013-02-13 00:35:30 +02004import io
Guido van Rossum0e548712002-08-09 16:14:33 +00005import os
Antoine Pitrou4558bad2011-11-25 21:28:15 +01006import signal
Guido van Rossum0e548712002-08-09 16:14:33 +00007import sys
8import re
Guido van Rossum0e548712002-08-09 16:14:33 +00009import warnings
Tim Petersc57a2852001-10-29 21:46:08 +000010
Guido van Rossum0e548712002-08-09 16:14:33 +000011import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +000012from test import support
Guido van Rossum0e548712002-08-09 16:14:33 +000013
Fred Drake7633d232002-10-17 22:09:03 +000014
Guido van Rossum0e548712002-08-09 16:14:33 +000015if hasattr(os, 'stat'):
16 import stat
17 has_stat = 1
18else:
19 has_stat = 0
20
21has_textmode = (tempfile._text_openflags != tempfile._bin_openflags)
Guido van Rossum78741062002-08-17 11:41:01 +000022has_spawnl = hasattr(os, 'spawnl')
Guido van Rossum0e548712002-08-09 16:14:33 +000023
Neal Norwitz68ee0122002-08-16 19:28:59 +000024# TEST_FILES may need to be tweaked for systems depending on the maximum
25# number of files that can be opened at one time (see ulimit -n)
Victor Stinner9c3de4a2011-08-17 20:49:41 +020026if sys.platform.startswith('openbsd'):
Martin v. Löwis99968282004-09-15 06:02:54 +000027 TEST_FILES = 48
Jack Jansence921472003-01-08 16:30:34 +000028else:
29 TEST_FILES = 100
Neal Norwitz68ee0122002-08-16 19:28:59 +000030
Guido van Rossum0e548712002-08-09 16:14:33 +000031# This is organized as one test for each chunk of code in tempfile.py,
32# in order of their appearance in the file. Testing which requires
33# threads is not done here.
34
35# Common functionality.
Antoine Pitroueab2a502012-03-10 16:34:40 +010036class BaseTestCase(unittest.TestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +000037
38 str_check = re.compile(r"[a-zA-Z0-9_-]{6}$")
39
Brett Cannone1adece2010-03-20 22:19:55 +000040 def setUp(self):
41 self._warnings_manager = support.check_warnings()
42 self._warnings_manager.__enter__()
43 warnings.filterwarnings("ignore", category=RuntimeWarning,
44 message="mktemp", module=__name__)
45
46 def tearDown(self):
47 self._warnings_manager.__exit__(None, None, None)
48
49
Guido van Rossum0e548712002-08-09 16:14:33 +000050 def nameCheck(self, name, dir, pre, suf):
51 (ndir, nbase) = os.path.split(name)
52 npre = nbase[:len(pre)]
53 nsuf = nbase[len(nbase)-len(suf):]
54
Martin v. Löwisd6625482003-10-12 17:37:01 +000055 # check for equality of the absolute paths!
56 self.assertEqual(os.path.abspath(ndir), os.path.abspath(dir),
Guido van Rossum0e548712002-08-09 16:14:33 +000057 "file '%s' not in directory '%s'" % (name, dir))
58 self.assertEqual(npre, pre,
59 "file '%s' does not begin with '%s'" % (nbase, pre))
60 self.assertEqual(nsuf, suf,
61 "file '%s' does not end with '%s'" % (nbase, suf))
62
63 nbase = nbase[len(pre):len(nbase)-len(suf)]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000064 self.assertTrue(self.str_check.match(nbase),
Guido van Rossum0e548712002-08-09 16:14:33 +000065 "random string '%s' does not match /^[a-zA-Z0-9_-]{6}$/"
66 % nbase)
67
Guido van Rossum0e548712002-08-09 16:14:33 +000068
Antoine Pitroueab2a502012-03-10 16:34:40 +010069class TestExports(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +000070 def test_exports(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +000071 # There are no surprising symbols in the tempfile module
Guido van Rossum0e548712002-08-09 16:14:33 +000072 dict = tempfile.__dict__
73
74 expected = {
75 "NamedTemporaryFile" : 1,
76 "TemporaryFile" : 1,
77 "mkstemp" : 1,
78 "mkdtemp" : 1,
79 "mktemp" : 1,
80 "TMP_MAX" : 1,
81 "gettempprefix" : 1,
82 "gettempdir" : 1,
83 "tempdir" : 1,
Guido van Rossumd8faa362007-04-27 19:54:29 +000084 "template" : 1,
Nick Coghlan543af752010-10-24 11:23:25 +000085 "SpooledTemporaryFile" : 1,
86 "TemporaryDirectory" : 1,
Guido van Rossum0e548712002-08-09 16:14:33 +000087 }
88
89 unexp = []
90 for key in dict:
91 if key[0] != '_' and key not in expected:
92 unexp.append(key)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000093 self.assertTrue(len(unexp) == 0,
Guido van Rossum0e548712002-08-09 16:14:33 +000094 "unexpected keys: %s" % unexp)
95
Guido van Rossum0e548712002-08-09 16:14:33 +000096
Antoine Pitroueab2a502012-03-10 16:34:40 +010097class TestRandomNameSequence(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +000098 """Test the internal iterator object _RandomNameSequence."""
99
100 def setUp(self):
101 self.r = tempfile._RandomNameSequence()
Brett Cannone1adece2010-03-20 22:19:55 +0000102 super().setUp()
Guido van Rossum0e548712002-08-09 16:14:33 +0000103
104 def test_get_six_char_str(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000105 # _RandomNameSequence returns a six-character string
Georg Brandla18af4e2007-04-21 15:47:16 +0000106 s = next(self.r)
Guido van Rossum0e548712002-08-09 16:14:33 +0000107 self.nameCheck(s, '', '', '')
108
109 def test_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000110 # _RandomNameSequence returns no duplicate strings (stochastic)
Guido van Rossum0e548712002-08-09 16:14:33 +0000111
112 dict = {}
113 r = self.r
Guido van Rossum805365e2007-05-07 22:24:25 +0000114 for i in range(TEST_FILES):
Georg Brandla18af4e2007-04-21 15:47:16 +0000115 s = next(r)
Guido van Rossum0e548712002-08-09 16:14:33 +0000116 self.nameCheck(s, '', '', '')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000117 self.assertNotIn(s, dict)
Guido van Rossum0e548712002-08-09 16:14:33 +0000118 dict[s] = 1
119
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000120 def supports_iter(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000121 # _RandomNameSequence supports the iterator protocol
Guido van Rossum0e548712002-08-09 16:14:33 +0000122
123 i = 0
124 r = self.r
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100125 for s in r:
126 i += 1
127 if i == 20:
128 break
Guido van Rossum0e548712002-08-09 16:14:33 +0000129
Antoine Pitrou4558bad2011-11-25 21:28:15 +0100130 @unittest.skipUnless(hasattr(os, 'fork'),
131 "os.fork is required for this test")
132 def test_process_awareness(self):
133 # ensure that the random source differs between
134 # child and parent.
135 read_fd, write_fd = os.pipe()
136 pid = None
137 try:
138 pid = os.fork()
139 if not pid:
140 os.close(read_fd)
141 os.write(write_fd, next(self.r).encode("ascii"))
142 os.close(write_fd)
143 # bypass the normal exit handlers- leave those to
144 # the parent.
145 os._exit(0)
146 parent_value = next(self.r)
147 child_value = os.read(read_fd, len(parent_value)).decode("ascii")
148 finally:
149 if pid:
150 # best effort to ensure the process can't bleed out
151 # via any bugs above
152 try:
153 os.kill(pid, signal.SIGKILL)
Andrew Svetlov3438fa42012-12-17 23:35:18 +0200154 except OSError:
Antoine Pitrou4558bad2011-11-25 21:28:15 +0100155 pass
156 os.close(read_fd)
157 os.close(write_fd)
158 self.assertNotEqual(child_value, parent_value)
159
160
Guido van Rossum0e548712002-08-09 16:14:33 +0000161
Antoine Pitroueab2a502012-03-10 16:34:40 +0100162class TestCandidateTempdirList(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +0000163 """Test the internal function _candidate_tempdir_list."""
164
165 def test_nonempty_list(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000166 # _candidate_tempdir_list returns a nonempty list of strings
Guido van Rossum0e548712002-08-09 16:14:33 +0000167
168 cand = tempfile._candidate_tempdir_list()
169
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000170 self.assertFalse(len(cand) == 0)
Guido van Rossum0e548712002-08-09 16:14:33 +0000171 for c in cand:
Ezio Melottie9615932010-01-24 19:26:24 +0000172 self.assertIsInstance(c, str)
Guido van Rossum0e548712002-08-09 16:14:33 +0000173
174 def test_wanted_dirs(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000175 # _candidate_tempdir_list contains the expected directories
Guido van Rossum0e548712002-08-09 16:14:33 +0000176
177 # Make sure the interesting environment variables are all set.
Hirokazu Yamamoto71959632009-04-27 01:44:28 +0000178 with support.EnvironmentVarGuard() as env:
Guido van Rossum0e548712002-08-09 16:14:33 +0000179 for envname in 'TMPDIR', 'TEMP', 'TMP':
180 dirname = os.getenv(envname)
181 if not dirname:
Walter Dörwald155374d2009-05-01 19:58:58 +0000182 env[envname] = os.path.abspath(envname)
Guido van Rossum0e548712002-08-09 16:14:33 +0000183
184 cand = tempfile._candidate_tempdir_list()
185
186 for envname in 'TMPDIR', 'TEMP', 'TMP':
187 dirname = os.getenv(envname)
188 if not dirname: raise ValueError
Benjamin Peterson577473f2010-01-19 00:09:57 +0000189 self.assertIn(dirname, cand)
Guido van Rossum0e548712002-08-09 16:14:33 +0000190
191 try:
192 dirname = os.getcwd()
Andrew Svetlovad28c7f2012-12-18 22:02:39 +0200193 except (AttributeError, OSError):
Guido van Rossum0e548712002-08-09 16:14:33 +0000194 dirname = os.curdir
195
Benjamin Peterson577473f2010-01-19 00:09:57 +0000196 self.assertIn(dirname, cand)
Guido van Rossum0e548712002-08-09 16:14:33 +0000197
198 # Not practical to try to verify the presence of OS-specific
199 # paths in this list.
Guido van Rossum0e548712002-08-09 16:14:33 +0000200
Guido van Rossum0e548712002-08-09 16:14:33 +0000201
Serhiy Storchakaf6b361e2013-02-13 00:35:30 +0200202# We test _get_default_tempdir some more by testing gettempdir.
Guido van Rossum0e548712002-08-09 16:14:33 +0000203
Serhiy Storchakaff7fef92013-02-13 00:37:29 +0200204class TestGetDefaultTempdir(BaseTestCase):
Serhiy Storchakaf6b361e2013-02-13 00:35:30 +0200205 """Test _get_default_tempdir()."""
206
207 def test_no_files_left_behind(self):
208 # use a private empty directory
209 with tempfile.TemporaryDirectory() as our_temp_directory:
210 # force _get_default_tempdir() to consider our empty directory
211 def our_candidate_list():
212 return [our_temp_directory]
213
214 with support.swap_attr(tempfile, "_candidate_tempdir_list",
215 our_candidate_list):
216 # verify our directory is empty after _get_default_tempdir()
217 tempfile._get_default_tempdir()
218 self.assertEqual(os.listdir(our_temp_directory), [])
219
220 def raise_OSError(*args, **kwargs):
Serhiy Storchakaff7fef92013-02-13 00:37:29 +0200221 raise OSError()
Serhiy Storchakaf6b361e2013-02-13 00:35:30 +0200222
223 with support.swap_attr(io, "open", raise_OSError):
224 # test again with failing io.open()
Serhiy Storchakaff7fef92013-02-13 00:37:29 +0200225 with self.assertRaises(FileNotFoundError):
Serhiy Storchakaf6b361e2013-02-13 00:35:30 +0200226 tempfile._get_default_tempdir()
Serhiy Storchakaf6b361e2013-02-13 00:35:30 +0200227 self.assertEqual(os.listdir(our_temp_directory), [])
228
229 open = io.open
230 def bad_writer(*args, **kwargs):
231 fp = open(*args, **kwargs)
232 fp.write = raise_OSError
233 return fp
234
235 with support.swap_attr(io, "open", bad_writer):
236 # test again with failing write()
Serhiy Storchakaff7fef92013-02-13 00:37:29 +0200237 with self.assertRaises(FileNotFoundError):
Serhiy Storchakaf6b361e2013-02-13 00:35:30 +0200238 tempfile._get_default_tempdir()
Serhiy Storchakaf6b361e2013-02-13 00:35:30 +0200239 self.assertEqual(os.listdir(our_temp_directory), [])
Guido van Rossum0e548712002-08-09 16:14:33 +0000240
241
Antoine Pitroueab2a502012-03-10 16:34:40 +0100242class TestGetCandidateNames(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +0000243 """Test the internal function _get_candidate_names."""
244
245 def test_retval(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000246 # _get_candidate_names returns a _RandomNameSequence object
Guido van Rossum0e548712002-08-09 16:14:33 +0000247 obj = tempfile._get_candidate_names()
Ezio Melottie9615932010-01-24 19:26:24 +0000248 self.assertIsInstance(obj, tempfile._RandomNameSequence)
Guido van Rossum0e548712002-08-09 16:14:33 +0000249
250 def test_same_thing(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000251 # _get_candidate_names always returns the same object
Guido van Rossum0e548712002-08-09 16:14:33 +0000252 a = tempfile._get_candidate_names()
253 b = tempfile._get_candidate_names()
254
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000255 self.assertTrue(a is b)
Guido van Rossum0e548712002-08-09 16:14:33 +0000256
Guido van Rossum0e548712002-08-09 16:14:33 +0000257
Antoine Pitroueab2a502012-03-10 16:34:40 +0100258class TestMkstempInner(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +0000259 """Test the internal function _mkstemp_inner."""
260
261 class mkstemped:
262 _bflags = tempfile._bin_openflags
263 _tflags = tempfile._text_openflags
264 _close = os.close
265 _unlink = os.unlink
266
267 def __init__(self, dir, pre, suf, bin):
268 if bin: flags = self._bflags
269 else: flags = self._tflags
270
271 (self.fd, self.name) = tempfile._mkstemp_inner(dir, pre, suf, flags)
272
273 def write(self, str):
274 os.write(self.fd, str)
275
276 def __del__(self):
277 self._close(self.fd)
278 self._unlink(self.name)
Tim Petersa0d55de2002-08-09 18:01:01 +0000279
Guido van Rossum0e548712002-08-09 16:14:33 +0000280 def do_create(self, dir=None, pre="", suf="", bin=1):
281 if dir is None:
282 dir = tempfile.gettempdir()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100283 file = self.mkstemped(dir, pre, suf, bin)
Guido van Rossum0e548712002-08-09 16:14:33 +0000284
285 self.nameCheck(file.name, dir, pre, suf)
286 return file
287
288 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000289 # _mkstemp_inner can create files
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000290 self.do_create().write(b"blat")
291 self.do_create(pre="a").write(b"blat")
292 self.do_create(suf="b").write(b"blat")
293 self.do_create(pre="a", suf="b").write(b"blat")
294 self.do_create(pre="aa", suf=".txt").write(b"blat")
Guido van Rossum0e548712002-08-09 16:14:33 +0000295
296 def test_basic_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000297 # _mkstemp_inner can create many files (stochastic)
Guido van Rossum805365e2007-05-07 22:24:25 +0000298 extant = list(range(TEST_FILES))
Guido van Rossum0e548712002-08-09 16:14:33 +0000299 for i in extant:
300 extant[i] = self.do_create(pre="aa")
301
302 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000303 # _mkstemp_inner can create files in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000304 dir = tempfile.mkdtemp()
305 try:
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +0000306 self.do_create(dir=dir).write(b"blat")
Guido van Rossum0e548712002-08-09 16:14:33 +0000307 finally:
308 os.rmdir(dir)
309
310 def test_file_mode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000311 # _mkstemp_inner creates files with the proper mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000312 if not has_stat:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000313 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000314
315 file = self.do_create()
316 mode = stat.S_IMODE(os.stat(file.name).st_mode)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000317 expected = 0o600
Jesus Cea4791a242012-10-05 03:15:39 +0200318 if sys.platform == 'win32':
Tim Petersca3ac7f2002-08-09 18:13:51 +0000319 # There's no distinction among 'user', 'group' and 'world';
320 # replicate the 'user' bits.
321 user = expected >> 6
322 expected = user * (1 + 8 + 64)
323 self.assertEqual(mode, expected)
Guido van Rossum0e548712002-08-09 16:14:33 +0000324
325 def test_noinherit(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000326 # _mkstemp_inner file handles are not inherited by child processes
Guido van Rossum78741062002-08-17 11:41:01 +0000327 if not has_spawnl:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000328 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000329
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000330 if support.verbose:
Guido van Rossum78741062002-08-17 11:41:01 +0000331 v="v"
332 else:
333 v="q"
334
Guido van Rossum0e548712002-08-09 16:14:33 +0000335 file = self.do_create()
Guido van Rossum78741062002-08-17 11:41:01 +0000336 fd = "%d" % file.fd
337
338 try:
339 me = __file__
340 except NameError:
341 me = sys.argv[0]
Guido van Rossum0e548712002-08-09 16:14:33 +0000342
343 # We have to exec something, so that FD_CLOEXEC will take
Guido van Rossum78741062002-08-17 11:41:01 +0000344 # effect. The core of this test is therefore in
345 # tf_inherit_check.py, which see.
346 tester = os.path.join(os.path.dirname(os.path.abspath(me)),
347 "tf_inherit_check.py")
Guido van Rossum0e548712002-08-09 16:14:33 +0000348
Martin v. Löwisd4210bc2003-10-23 15:55:28 +0000349 # On Windows a spawn* /path/ with embedded spaces shouldn't be quoted,
350 # but an arg with embedded spaces should be decorated with double
351 # quotes on each end
Jesus Cea4791a242012-10-05 03:15:39 +0200352 if sys.platform == 'win32':
Martin v. Löwisd4210bc2003-10-23 15:55:28 +0000353 decorated = '"%s"' % sys.executable
354 tester = '"%s"' % tester
355 else:
356 decorated = sys.executable
357
358 retval = os.spawnl(os.P_WAIT, sys.executable, decorated, tester, v, fd)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000359 self.assertFalse(retval < 0,
Guido van Rossum78741062002-08-17 11:41:01 +0000360 "child process caught fatal signal %d" % -retval)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000361 self.assertFalse(retval > 0, "child process reports failure %d"%retval)
Guido van Rossum0e548712002-08-09 16:14:33 +0000362
363 def test_textmode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000364 # _mkstemp_inner can create files in text mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000365 if not has_textmode:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000366 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000367
Amaury Forgeot d'Arc7d0bddd2009-11-30 00:08:56 +0000368 # A text file is truncated at the first Ctrl+Z byte
369 f = self.do_create(bin=0)
370 f.write(b"blat\x1a")
371 f.write(b"extra\n")
372 os.lseek(f.fd, 0, os.SEEK_SET)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000373 self.assertEqual(os.read(f.fd, 20), b"blat")
Guido van Rossum0e548712002-08-09 16:14:33 +0000374
Guido van Rossum0e548712002-08-09 16:14:33 +0000375
Antoine Pitroueab2a502012-03-10 16:34:40 +0100376class TestGetTempPrefix(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +0000377 """Test gettempprefix()."""
378
379 def test_sane_template(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000380 # gettempprefix returns a nonempty prefix string
Guido van Rossum0e548712002-08-09 16:14:33 +0000381 p = tempfile.gettempprefix()
382
Ezio Melottie9615932010-01-24 19:26:24 +0000383 self.assertIsInstance(p, str)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000384 self.assertTrue(len(p) > 0)
Guido van Rossum0e548712002-08-09 16:14:33 +0000385
386 def test_usable_template(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000387 # gettempprefix returns a usable prefix string
Guido van Rossum0e548712002-08-09 16:14:33 +0000388
389 # Create a temp directory, avoiding use of the prefix.
390 # Then attempt to create a file whose name is
391 # prefix + 'xxxxxx.xxx' in that directory.
392 p = tempfile.gettempprefix() + "xxxxxx.xxx"
393 d = tempfile.mkdtemp(prefix="")
394 try:
395 p = os.path.join(d, p)
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100396 fd = os.open(p, os.O_RDWR | os.O_CREAT)
Guido van Rossum0e548712002-08-09 16:14:33 +0000397 os.close(fd)
398 os.unlink(p)
399 finally:
400 os.rmdir(d)
401
Guido van Rossum0e548712002-08-09 16:14:33 +0000402
Antoine Pitroueab2a502012-03-10 16:34:40 +0100403class TestGetTempDir(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +0000404 """Test gettempdir()."""
405
406 def test_directory_exists(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000407 # gettempdir returns a directory which exists
Guido van Rossum0e548712002-08-09 16:14:33 +0000408
409 dir = tempfile.gettempdir()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000410 self.assertTrue(os.path.isabs(dir) or dir == os.curdir,
Guido van Rossum0e548712002-08-09 16:14:33 +0000411 "%s is not an absolute path" % dir)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000412 self.assertTrue(os.path.isdir(dir),
Guido van Rossum0e548712002-08-09 16:14:33 +0000413 "%s is not a directory" % dir)
414
415 def test_directory_writable(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000416 # gettempdir returns a directory writable by the user
Guido van Rossum0e548712002-08-09 16:14:33 +0000417
418 # sneaky: just instantiate a NamedTemporaryFile, which
419 # defaults to writing into the directory returned by
420 # gettempdir.
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100421 file = tempfile.NamedTemporaryFile()
422 file.write(b"blat")
423 file.close()
Guido van Rossum0e548712002-08-09 16:14:33 +0000424
425 def test_same_thing(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000426 # gettempdir always returns the same object
Guido van Rossum0e548712002-08-09 16:14:33 +0000427 a = tempfile.gettempdir()
428 b = tempfile.gettempdir()
429
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000430 self.assertTrue(a is b)
Guido van Rossum0e548712002-08-09 16:14:33 +0000431
Guido van Rossum0e548712002-08-09 16:14:33 +0000432
Antoine Pitroueab2a502012-03-10 16:34:40 +0100433class TestMkstemp(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +0000434 """Test mkstemp()."""
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000435
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000436 def do_create(self, dir=None, pre="", suf=""):
Guido van Rossum0e548712002-08-09 16:14:33 +0000437 if dir is None:
438 dir = tempfile.gettempdir()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100439 (fd, name) = tempfile.mkstemp(dir=dir, prefix=pre, suffix=suf)
440 (ndir, nbase) = os.path.split(name)
441 adir = os.path.abspath(dir)
442 self.assertEqual(adir, ndir,
443 "Directory '%s' incorrectly returned as '%s'" % (adir, ndir))
Guido van Rossum0e548712002-08-09 16:14:33 +0000444
445 try:
446 self.nameCheck(name, dir, pre, suf)
447 finally:
448 os.close(fd)
449 os.unlink(name)
450
451 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000452 # mkstemp can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000453 self.do_create()
454 self.do_create(pre="a")
455 self.do_create(suf="b")
456 self.do_create(pre="a", suf="b")
457 self.do_create(pre="aa", suf=".txt")
Martin v. Löwisd6625482003-10-12 17:37:01 +0000458 self.do_create(dir=".")
Guido van Rossum0e548712002-08-09 16:14:33 +0000459
460 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000461 # mkstemp can create directories in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000462 dir = tempfile.mkdtemp()
463 try:
464 self.do_create(dir=dir)
465 finally:
466 os.rmdir(dir)
467
Guido van Rossum0e548712002-08-09 16:14:33 +0000468
Antoine Pitroueab2a502012-03-10 16:34:40 +0100469class TestMkdtemp(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +0000470 """Test mkdtemp()."""
471
472 def do_create(self, dir=None, pre="", suf=""):
473 if dir is None:
474 dir = tempfile.gettempdir()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100475 name = tempfile.mkdtemp(dir=dir, prefix=pre, suffix=suf)
Guido van Rossum0e548712002-08-09 16:14:33 +0000476
477 try:
478 self.nameCheck(name, dir, pre, suf)
479 return name
480 except:
481 os.rmdir(name)
482 raise
483
484 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000485 # mkdtemp can create directories
Guido van Rossum0e548712002-08-09 16:14:33 +0000486 os.rmdir(self.do_create())
487 os.rmdir(self.do_create(pre="a"))
488 os.rmdir(self.do_create(suf="b"))
489 os.rmdir(self.do_create(pre="a", suf="b"))
490 os.rmdir(self.do_create(pre="aa", suf=".txt"))
Tim Petersa0d55de2002-08-09 18:01:01 +0000491
Guido van Rossum0e548712002-08-09 16:14:33 +0000492 def test_basic_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000493 # mkdtemp can create many directories (stochastic)
Guido van Rossum805365e2007-05-07 22:24:25 +0000494 extant = list(range(TEST_FILES))
Guido van Rossum0e548712002-08-09 16:14:33 +0000495 try:
496 for i in extant:
497 extant[i] = self.do_create(pre="aa")
498 finally:
499 for i in extant:
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000500 if(isinstance(i, str)):
Guido van Rossum0e548712002-08-09 16:14:33 +0000501 os.rmdir(i)
502
503 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000504 # mkdtemp can create directories in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000505 dir = tempfile.mkdtemp()
506 try:
507 os.rmdir(self.do_create(dir=dir))
508 finally:
509 os.rmdir(dir)
510
511 def test_mode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000512 # mkdtemp creates directories with the proper mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000513 if not has_stat:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000514 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000515
516 dir = self.do_create()
517 try:
518 mode = stat.S_IMODE(os.stat(dir).st_mode)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000519 mode &= 0o777 # Mask off sticky bits inherited from /tmp
520 expected = 0o700
Jesus Cea4791a242012-10-05 03:15:39 +0200521 if sys.platform == 'win32':
Tim Petersca3ac7f2002-08-09 18:13:51 +0000522 # There's no distinction among 'user', 'group' and 'world';
523 # replicate the 'user' bits.
524 user = expected >> 6
525 expected = user * (1 + 8 + 64)
526 self.assertEqual(mode, expected)
Guido van Rossum0e548712002-08-09 16:14:33 +0000527 finally:
528 os.rmdir(dir)
529
Guido van Rossum0e548712002-08-09 16:14:33 +0000530
Antoine Pitroueab2a502012-03-10 16:34:40 +0100531class TestMktemp(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +0000532 """Test mktemp()."""
533
534 # For safety, all use of mktemp must occur in a private directory.
535 # We must also suppress the RuntimeWarning it generates.
536 def setUp(self):
537 self.dir = tempfile.mkdtemp()
Brett Cannone1adece2010-03-20 22:19:55 +0000538 super().setUp()
Guido van Rossum0e548712002-08-09 16:14:33 +0000539
540 def tearDown(self):
541 if self.dir:
542 os.rmdir(self.dir)
543 self.dir = None
Brett Cannone1adece2010-03-20 22:19:55 +0000544 super().tearDown()
Guido van Rossum0e548712002-08-09 16:14:33 +0000545
546 class mktemped:
547 _unlink = os.unlink
548 _bflags = tempfile._bin_openflags
549
550 def __init__(self, dir, pre, suf):
551 self.name = tempfile.mktemp(dir=dir, prefix=pre, suffix=suf)
552 # Create the file. This will raise an exception if it's
553 # mysteriously appeared in the meanwhile.
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000554 os.close(os.open(self.name, self._bflags, 0o600))
Guido van Rossum0e548712002-08-09 16:14:33 +0000555
556 def __del__(self):
557 self._unlink(self.name)
558
559 def do_create(self, pre="", suf=""):
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100560 file = self.mktemped(self.dir, pre, suf)
Guido van Rossum0e548712002-08-09 16:14:33 +0000561
562 self.nameCheck(file.name, self.dir, pre, suf)
563 return file
564
565 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000566 # mktemp can choose usable file names
Guido van Rossum0e548712002-08-09 16:14:33 +0000567 self.do_create()
568 self.do_create(pre="a")
569 self.do_create(suf="b")
570 self.do_create(pre="a", suf="b")
571 self.do_create(pre="aa", suf=".txt")
572
573 def test_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000574 # mktemp can choose many usable file names (stochastic)
Guido van Rossum805365e2007-05-07 22:24:25 +0000575 extant = list(range(TEST_FILES))
Guido van Rossum0e548712002-08-09 16:14:33 +0000576 for i in extant:
577 extant[i] = self.do_create(pre="aa")
578
Fred Drake8bec4832002-11-22 20:13:43 +0000579## def test_warning(self):
580## # mktemp issues a warning when used
581## warnings.filterwarnings("error",
582## category=RuntimeWarning,
583## message="mktemp")
584## self.assertRaises(RuntimeWarning,
585## tempfile.mktemp, dir=self.dir)
Guido van Rossum0e548712002-08-09 16:14:33 +0000586
Guido van Rossum0e548712002-08-09 16:14:33 +0000587
588# We test _TemporaryFileWrapper by testing NamedTemporaryFile.
589
590
Antoine Pitroueab2a502012-03-10 16:34:40 +0100591class TestNamedTemporaryFile(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +0000592 """Test NamedTemporaryFile()."""
593
Guido van Rossumd8faa362007-04-27 19:54:29 +0000594 def do_create(self, dir=None, pre="", suf="", delete=True):
Guido van Rossum0e548712002-08-09 16:14:33 +0000595 if dir is None:
596 dir = tempfile.gettempdir()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100597 file = tempfile.NamedTemporaryFile(dir=dir, prefix=pre, suffix=suf,
598 delete=delete)
Guido van Rossum0e548712002-08-09 16:14:33 +0000599
600 self.nameCheck(file.name, dir, pre, suf)
601 return file
602
603
604 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000605 # NamedTemporaryFile can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000606 self.do_create()
607 self.do_create(pre="a")
608 self.do_create(suf="b")
609 self.do_create(pre="a", suf="b")
610 self.do_create(pre="aa", suf=".txt")
611
612 def test_creates_named(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000613 # NamedTemporaryFile creates files with names
Guido van Rossum0e548712002-08-09 16:14:33 +0000614 f = tempfile.NamedTemporaryFile()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000615 self.assertTrue(os.path.exists(f.name),
Guido van Rossum0e548712002-08-09 16:14:33 +0000616 "NamedTemporaryFile %s does not exist" % f.name)
617
618 def test_del_on_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000619 # A NamedTemporaryFile is deleted when closed
Guido van Rossum0e548712002-08-09 16:14:33 +0000620 dir = tempfile.mkdtemp()
621 try:
622 f = tempfile.NamedTemporaryFile(dir=dir)
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000623 f.write(b'blat')
Guido van Rossum0e548712002-08-09 16:14:33 +0000624 f.close()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000625 self.assertFalse(os.path.exists(f.name),
Guido van Rossum0e548712002-08-09 16:14:33 +0000626 "NamedTemporaryFile %s exists after close" % f.name)
627 finally:
628 os.rmdir(dir)
629
Guido van Rossumd8faa362007-04-27 19:54:29 +0000630 def test_dis_del_on_close(self):
631 # Tests that delete-on-close can be disabled
632 dir = tempfile.mkdtemp()
633 tmp = None
634 try:
635 f = tempfile.NamedTemporaryFile(dir=dir, delete=False)
636 tmp = f.name
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000637 f.write(b'blat')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000638 f.close()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000639 self.assertTrue(os.path.exists(f.name),
Guido van Rossumd8faa362007-04-27 19:54:29 +0000640 "NamedTemporaryFile %s missing after close" % f.name)
641 finally:
642 if tmp is not None:
643 os.unlink(tmp)
644 os.rmdir(dir)
645
Guido van Rossum0e548712002-08-09 16:14:33 +0000646 def test_multiple_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000647 # A NamedTemporaryFile can be closed many times without error
Guido van Rossum0e548712002-08-09 16:14:33 +0000648 f = tempfile.NamedTemporaryFile()
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000649 f.write(b'abc\n')
Guido van Rossum0e548712002-08-09 16:14:33 +0000650 f.close()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100651 f.close()
652 f.close()
Guido van Rossum0e548712002-08-09 16:14:33 +0000653
Christian Heimes3ecfea712008-02-09 20:51:34 +0000654 def test_context_manager(self):
655 # A NamedTemporaryFile can be used as a context manager
656 with tempfile.NamedTemporaryFile() as f:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000657 self.assertTrue(os.path.exists(f.name))
658 self.assertFalse(os.path.exists(f.name))
Christian Heimes3ecfea712008-02-09 20:51:34 +0000659 def use_closed():
660 with f:
661 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000662 self.assertRaises(ValueError, use_closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000663
Guido van Rossum0e548712002-08-09 16:14:33 +0000664 # How to test the mode and bufsize parameters?
665
Guido van Rossum0e548712002-08-09 16:14:33 +0000666
Antoine Pitroueab2a502012-03-10 16:34:40 +0100667class TestSpooledTemporaryFile(BaseTestCase):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000668 """Test SpooledTemporaryFile()."""
669
670 def do_create(self, max_size=0, dir=None, pre="", suf=""):
671 if dir is None:
672 dir = tempfile.gettempdir()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100673 file = tempfile.SpooledTemporaryFile(max_size=max_size, dir=dir, prefix=pre, suffix=suf)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000674
675 return file
676
677
678 def test_basic(self):
679 # SpooledTemporaryFile can create files
680 f = self.do_create()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000681 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000682 f = self.do_create(max_size=100, pre="a", suf=".txt")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000683 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000684
685 def test_del_on_close(self):
686 # A SpooledTemporaryFile is deleted when closed
687 dir = tempfile.mkdtemp()
688 try:
689 f = tempfile.SpooledTemporaryFile(max_size=10, dir=dir)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000690 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000691 f.write(b'blat ' * 5)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000692 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000693 filename = f.name
694 f.close()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000695 self.assertFalse(isinstance(filename, str) and os.path.exists(filename),
Guido van Rossumd8faa362007-04-27 19:54:29 +0000696 "SpooledTemporaryFile %s exists after close" % filename)
697 finally:
698 os.rmdir(dir)
699
700 def test_rewrite_small(self):
701 # A SpooledTemporaryFile can be written to multiple within the max_size
702 f = self.do_create(max_size=30)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000703 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000704 for i in range(5):
705 f.seek(0, 0)
Guido van Rossum39478e82007-08-27 17:23:59 +0000706 f.write(b'x' * 20)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000707 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000708
709 def test_write_sequential(self):
710 # A SpooledTemporaryFile should hold exactly max_size bytes, and roll
711 # over afterward
712 f = self.do_create(max_size=30)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000713 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000714 f.write(b'x' * 20)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000715 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000716 f.write(b'x' * 10)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000717 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000718 f.write(b'x')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000719 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000720
R David Murrayd89ee792011-03-14 09:55:46 -0400721 def test_writelines(self):
722 # Verify writelines with a SpooledTemporaryFile
723 f = self.do_create()
724 f.writelines((b'x', b'y', b'z'))
725 f.seek(0)
726 buf = f.read()
727 self.assertEqual(buf, b'xyz')
728
729 def test_writelines_sequential(self):
730 # A SpooledTemporaryFile should hold exactly max_size bytes, and roll
731 # over afterward
732 f = self.do_create(max_size=35)
733 f.writelines((b'x' * 20, b'x' * 10, b'x' * 5))
734 self.assertFalse(f._rolled)
735 f.write(b'x')
736 self.assertTrue(f._rolled)
737
Guido van Rossumd8faa362007-04-27 19:54:29 +0000738 def test_sparse(self):
739 # A SpooledTemporaryFile that is written late in the file will extend
740 # when that occurs
741 f = self.do_create(max_size=30)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000742 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000743 f.seek(100, 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000744 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000745 f.write(b'x')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000746 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000747
748 def test_fileno(self):
749 # A SpooledTemporaryFile should roll over to a real file on fileno()
750 f = self.do_create(max_size=30)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000751 self.assertFalse(f._rolled)
752 self.assertTrue(f.fileno() > 0)
753 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000754
Christian Heimes3ecfea712008-02-09 20:51:34 +0000755 def test_multiple_close_before_rollover(self):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000756 # A SpooledTemporaryFile can be closed many times without error
757 f = tempfile.SpooledTemporaryFile()
Guido van Rossum39478e82007-08-27 17:23:59 +0000758 f.write(b'abc\n')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000759 self.assertFalse(f._rolled)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000760 f.close()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100761 f.close()
762 f.close()
Christian Heimes3ecfea712008-02-09 20:51:34 +0000763
764 def test_multiple_close_after_rollover(self):
765 # A SpooledTemporaryFile can be closed many times without error
766 f = tempfile.SpooledTemporaryFile(max_size=1)
767 f.write(b'abc\n')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000768 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000769 f.close()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100770 f.close()
771 f.close()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000772
773 def test_bound_methods(self):
774 # It should be OK to steal a bound method from a SpooledTemporaryFile
775 # and use it independently; when the file rolls over, those bound
776 # methods should continue to function
777 f = self.do_create(max_size=30)
778 read = f.read
779 write = f.write
780 seek = f.seek
781
Guido van Rossum39478e82007-08-27 17:23:59 +0000782 write(b"a" * 35)
783 write(b"b" * 35)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000784 seek(0, 0)
Guido van Rossum9a634702007-07-09 10:24:45 +0000785 self.assertEqual(read(70), b'a'*35 + b'b'*35)
786
Serhiy Storchakabbbbe8e2013-02-09 12:21:14 +0200787 def test_properties(self):
788 f = tempfile.SpooledTemporaryFile(max_size=10)
789 f.write(b'x' * 10)
790 self.assertFalse(f._rolled)
791 self.assertEqual(f.mode, 'w+b')
792 self.assertIsNone(f.name)
793 with self.assertRaises(AttributeError):
794 f.newlines
795 with self.assertRaises(AttributeError):
796 f.encoding
797
798 f.write(b'x')
799 self.assertTrue(f._rolled)
800 self.assertEqual(f.mode, 'rb+')
801 self.assertIsNotNone(f.name)
802 with self.assertRaises(AttributeError):
803 f.newlines
804 with self.assertRaises(AttributeError):
805 f.encoding
806
Guido van Rossum9a634702007-07-09 10:24:45 +0000807 def test_text_mode(self):
808 # Creating a SpooledTemporaryFile with a text mode should produce
809 # a file object reading and writing (Unicode) text strings.
810 f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10)
811 f.write("abc\n")
812 f.seek(0)
813 self.assertEqual(f.read(), "abc\n")
814 f.write("def\n")
815 f.seek(0)
816 self.assertEqual(f.read(), "abc\ndef\n")
Serhiy Storchakabbbbe8e2013-02-09 12:21:14 +0200817 self.assertFalse(f._rolled)
818 self.assertEqual(f.mode, 'w+')
819 self.assertIsNone(f.name)
820 self.assertIsNone(f.newlines)
821 self.assertIsNone(f.encoding)
822
Guido van Rossum9a634702007-07-09 10:24:45 +0000823 f.write("xyzzy\n")
824 f.seek(0)
825 self.assertEqual(f.read(), "abc\ndef\nxyzzy\n")
Amaury Forgeot d'Arc7d0bddd2009-11-30 00:08:56 +0000826 # Check that Ctrl+Z doesn't truncate the file
827 f.write("foo\x1abar\n")
828 f.seek(0)
829 self.assertEqual(f.read(), "abc\ndef\nxyzzy\nfoo\x1abar\n")
Serhiy Storchakabbbbe8e2013-02-09 12:21:14 +0200830 self.assertTrue(f._rolled)
831 self.assertEqual(f.mode, 'w+')
832 self.assertIsNotNone(f.name)
Serhiy Storchaka497cee42013-02-10 14:43:46 +0200833 self.assertEqual(f.newlines, os.linesep)
Serhiy Storchakabbbbe8e2013-02-09 12:21:14 +0200834 self.assertIsNotNone(f.encoding)
Guido van Rossum9a634702007-07-09 10:24:45 +0000835
Guido van Rossumf0c74162007-08-28 03:29:45 +0000836 def test_text_newline_and_encoding(self):
837 f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10,
838 newline='', encoding='utf-8')
839 f.write("\u039B\r\n")
840 f.seek(0)
841 self.assertEqual(f.read(), "\u039B\r\n")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000842 self.assertFalse(f._rolled)
Serhiy Storchakabbbbe8e2013-02-09 12:21:14 +0200843 self.assertEqual(f.mode, 'w+')
844 self.assertIsNone(f.name)
845 self.assertIsNone(f.newlines)
846 self.assertIsNone(f.encoding)
Guido van Rossumf0c74162007-08-28 03:29:45 +0000847
848 f.write("\u039B" * 20 + "\r\n")
849 f.seek(0)
850 self.assertEqual(f.read(), "\u039B\r\n" + ("\u039B" * 20) + "\r\n")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000851 self.assertTrue(f._rolled)
Serhiy Storchakabbbbe8e2013-02-09 12:21:14 +0200852 self.assertEqual(f.mode, 'w+')
853 self.assertIsNotNone(f.name)
854 self.assertIsNotNone(f.newlines)
855 self.assertEqual(f.encoding, 'utf-8')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000856
Christian Heimes3ecfea712008-02-09 20:51:34 +0000857 def test_context_manager_before_rollover(self):
858 # A SpooledTemporaryFile can be used as a context manager
859 with tempfile.SpooledTemporaryFile(max_size=1) as f:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000860 self.assertFalse(f._rolled)
861 self.assertFalse(f.closed)
862 self.assertTrue(f.closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000863 def use_closed():
864 with f:
865 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000866 self.assertRaises(ValueError, use_closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000867
868 def test_context_manager_during_rollover(self):
869 # A SpooledTemporaryFile can be used as a context manager
870 with tempfile.SpooledTemporaryFile(max_size=1) as f:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000871 self.assertFalse(f._rolled)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000872 f.write(b'abc\n')
873 f.flush()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000874 self.assertTrue(f._rolled)
875 self.assertFalse(f.closed)
876 self.assertTrue(f.closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000877 def use_closed():
878 with f:
879 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000880 self.assertRaises(ValueError, use_closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000881
882 def test_context_manager_after_rollover(self):
883 # A SpooledTemporaryFile can be used as a context manager
884 f = tempfile.SpooledTemporaryFile(max_size=1)
885 f.write(b'abc\n')
886 f.flush()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000887 self.assertTrue(f._rolled)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000888 with f:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000889 self.assertFalse(f.closed)
890 self.assertTrue(f.closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000891 def use_closed():
892 with f:
893 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000894 self.assertRaises(ValueError, use_closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000895
Antoine Pitrou0e86a582011-11-25 18:03:09 +0100896 def test_truncate_with_size_parameter(self):
897 # A SpooledTemporaryFile can be truncated to zero size
898 f = tempfile.SpooledTemporaryFile(max_size=10)
899 f.write(b'abcdefg\n')
900 f.seek(0)
901 f.truncate()
902 self.assertFalse(f._rolled)
903 self.assertEqual(f._file.getvalue(), b'')
904 # A SpooledTemporaryFile can be truncated to a specific size
905 f = tempfile.SpooledTemporaryFile(max_size=10)
906 f.write(b'abcdefg\n')
907 f.truncate(4)
908 self.assertFalse(f._rolled)
909 self.assertEqual(f._file.getvalue(), b'abcd')
910 # A SpooledTemporaryFile rolls over if truncated to large size
911 f = tempfile.SpooledTemporaryFile(max_size=10)
912 f.write(b'abcdefg\n')
913 f.truncate(20)
914 self.assertTrue(f._rolled)
915 if has_stat:
916 self.assertEqual(os.fstat(f.fileno()).st_size, 20)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000917
Guido van Rossum0e548712002-08-09 16:14:33 +0000918
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000919if tempfile.NamedTemporaryFile is not tempfile.TemporaryFile:
Antoine Pitroueab2a502012-03-10 16:34:40 +0100920
921 class TestTemporaryFile(BaseTestCase):
922 """Test TemporaryFile()."""
923
924 def test_basic(self):
925 # TemporaryFile can create files
926 # No point in testing the name params - the file has no name.
927 tempfile.TemporaryFile()
928
929 def test_has_no_name(self):
930 # TemporaryFile creates files with no names (on this system)
931 dir = tempfile.mkdtemp()
932 f = tempfile.TemporaryFile(dir=dir)
933 f.write(b'blat')
934
935 # Sneaky: because this file has no name, it should not prevent
936 # us from removing the directory it was created in.
937 try:
938 os.rmdir(dir)
939 except:
940 # cleanup
941 f.close()
942 os.rmdir(dir)
943 raise
944
945 def test_multiple_close(self):
946 # A TemporaryFile can be closed many times without error
947 f = tempfile.TemporaryFile()
948 f.write(b'abc\n')
949 f.close()
950 f.close()
951 f.close()
952
953 # How to test the mode and bufsize parameters?
954 def test_mode_and_encoding(self):
955
956 def roundtrip(input, *args, **kwargs):
957 with tempfile.TemporaryFile(*args, **kwargs) as fileobj:
958 fileobj.write(input)
959 fileobj.seek(0)
960 self.assertEqual(input, fileobj.read())
961
962 roundtrip(b"1234", "w+b")
963 roundtrip("abdc\n", "w+")
964 roundtrip("\u039B", "w+", encoding="utf-16")
965 roundtrip("foo\r\n", "w+", newline="")
Guido van Rossum0e548712002-08-09 16:14:33 +0000966
Nick Coghlan543af752010-10-24 11:23:25 +0000967
968# Helper for test_del_on_shutdown
969class NulledModules:
970 def __init__(self, *modules):
971 self.refs = [mod.__dict__ for mod in modules]
972 self.contents = [ref.copy() for ref in self.refs]
973
974 def __enter__(self):
975 for d in self.refs:
976 for key in d:
977 d[key] = None
978
979 def __exit__(self, *exc_info):
980 for d, c in zip(self.refs, self.contents):
981 d.clear()
982 d.update(c)
983
Antoine Pitroueab2a502012-03-10 16:34:40 +0100984class TestTemporaryDirectory(BaseTestCase):
Nick Coghlan543af752010-10-24 11:23:25 +0000985 """Test TemporaryDirectory()."""
986
987 def do_create(self, dir=None, pre="", suf="", recurse=1):
988 if dir is None:
989 dir = tempfile.gettempdir()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100990 tmp = tempfile.TemporaryDirectory(dir=dir, prefix=pre, suffix=suf)
Nick Coghlan543af752010-10-24 11:23:25 +0000991 self.nameCheck(tmp.name, dir, pre, suf)
992 # Create a subdirectory and some files
993 if recurse:
994 self.do_create(tmp.name, pre, suf, recurse-1)
995 with open(os.path.join(tmp.name, "test.txt"), "wb") as f:
996 f.write(b"Hello world!")
997 return tmp
998
Nick Coghlan6b22f3f2010-12-12 15:24:21 +0000999 def test_mkdtemp_failure(self):
1000 # Check no additional exception if mkdtemp fails
1001 # Previously would raise AttributeError instead
Nick Coghlan3c54ea62010-12-13 03:02:43 +00001002 # (noted as part of Issue #10188)
1003 with tempfile.TemporaryDirectory() as nonexistent:
1004 pass
Serhiy Storchaka7451a722013-02-09 22:25:49 +02001005 with self.assertRaises(FileNotFoundError) as cm:
Nick Coghlan3c54ea62010-12-13 03:02:43 +00001006 tempfile.TemporaryDirectory(dir=nonexistent)
Serhiy Storchaka7451a722013-02-09 22:25:49 +02001007 self.assertEqual(cm.exception.errno, errno.ENOENT)
Nick Coghlan6b22f3f2010-12-12 15:24:21 +00001008
Nick Coghlan543af752010-10-24 11:23:25 +00001009 def test_explicit_cleanup(self):
1010 # A TemporaryDirectory is deleted when cleaned up
1011 dir = tempfile.mkdtemp()
1012 try:
1013 d = self.do_create(dir=dir)
1014 self.assertTrue(os.path.exists(d.name),
1015 "TemporaryDirectory %s does not exist" % d.name)
1016 d.cleanup()
1017 self.assertFalse(os.path.exists(d.name),
1018 "TemporaryDirectory %s exists after cleanup" % d.name)
1019 finally:
1020 os.rmdir(dir)
1021
Charles-François Natalidef35432011-07-29 18:59:24 +02001022 @support.skip_unless_symlink
1023 def test_cleanup_with_symlink_to_a_directory(self):
1024 # cleanup() should not follow symlinks to directories (issue #12464)
1025 d1 = self.do_create()
1026 d2 = self.do_create()
1027
1028 # Symlink d1/foo -> d2
1029 os.symlink(d2.name, os.path.join(d1.name, "foo"))
1030
1031 # This call to cleanup() should not follow the "foo" symlink
1032 d1.cleanup()
1033
1034 self.assertFalse(os.path.exists(d1.name),
1035 "TemporaryDirectory %s exists after cleanup" % d1.name)
1036 self.assertTrue(os.path.exists(d2.name),
1037 "Directory pointed to by a symlink was deleted")
1038 self.assertEqual(os.listdir(d2.name), ['test.txt'],
1039 "Contents of the directory pointed to by a symlink "
1040 "were deleted")
1041 d2.cleanup()
1042
Nick Coghlan543af752010-10-24 11:23:25 +00001043 @support.cpython_only
1044 def test_del_on_collection(self):
1045 # A TemporaryDirectory is deleted when garbage collected
1046 dir = tempfile.mkdtemp()
1047 try:
1048 d = self.do_create(dir=dir)
1049 name = d.name
1050 del d # Rely on refcounting to invoke __del__
1051 self.assertFalse(os.path.exists(name),
1052 "TemporaryDirectory %s exists after __del__" % name)
1053 finally:
1054 os.rmdir(dir)
1055
1056 @unittest.expectedFailure # See issue #10188
1057 def test_del_on_shutdown(self):
1058 # A TemporaryDirectory may be cleaned up during shutdown
1059 # Make sure it works with the relevant modules nulled out
Nick Coghlan6b22f3f2010-12-12 15:24:21 +00001060 with self.do_create() as dir:
Nick Coghlan543af752010-10-24 11:23:25 +00001061 d = self.do_create(dir=dir)
1062 # Mimic the nulling out of modules that
1063 # occurs during system shutdown
1064 modules = [os, os.path]
1065 if has_stat:
1066 modules.append(stat)
Nick Coghlan6b22f3f2010-12-12 15:24:21 +00001067 # Currently broken, so suppress the warning
1068 # that is otherwise emitted on stdout
1069 with support.captured_stderr() as err:
1070 with NulledModules(*modules):
1071 d.cleanup()
1072 # Currently broken, so stop spurious exception by
1073 # indicating the object has already been closed
1074 d._closed = True
1075 # And this assert will fail, as expected by the
1076 # unittest decorator...
Nick Coghlan543af752010-10-24 11:23:25 +00001077 self.assertFalse(os.path.exists(d.name),
1078 "TemporaryDirectory %s exists after cleanup" % d.name)
Nick Coghlan6b22f3f2010-12-12 15:24:21 +00001079
1080 def test_warnings_on_cleanup(self):
1081 # Two kinds of warning on shutdown
1082 # Issue 10888: may write to stderr if modules are nulled out
1083 # ResourceWarning will be triggered by __del__
1084 with self.do_create() as dir:
Nick Coghlane98e8a32010-12-13 16:32:51 +00001085 if os.sep != '\\':
1086 # Embed a backslash in order to make sure string escaping
1087 # in the displayed error message is dealt with correctly
1088 suffix = '\\check_backslash_handling'
1089 else:
1090 suffix = ''
1091 d = self.do_create(dir=dir, suf=suffix)
Nick Coghlan6b22f3f2010-12-12 15:24:21 +00001092
1093 #Check for the Issue 10888 message
1094 modules = [os, os.path]
1095 if has_stat:
1096 modules.append(stat)
1097 with support.captured_stderr() as err:
1098 with NulledModules(*modules):
1099 d.cleanup()
Nick Coghlane98e8a32010-12-13 16:32:51 +00001100 message = err.getvalue().replace('\\\\', '\\')
Nick Coghlan6b22f3f2010-12-12 15:24:21 +00001101 self.assertIn("while cleaning up", message)
1102 self.assertIn(d.name, message)
1103
1104 # Check for the resource warning
1105 with support.check_warnings(('Implicitly', ResourceWarning), quiet=False):
1106 warnings.filterwarnings("always", category=ResourceWarning)
1107 d.__del__()
1108 self.assertFalse(os.path.exists(d.name),
1109 "TemporaryDirectory %s exists after __del__" % d.name)
Nick Coghlan543af752010-10-24 11:23:25 +00001110
1111 def test_multiple_close(self):
1112 # Can be cleaned-up many times without error
1113 d = self.do_create()
1114 d.cleanup()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +01001115 d.cleanup()
1116 d.cleanup()
Nick Coghlan543af752010-10-24 11:23:25 +00001117
1118 def test_context_manager(self):
1119 # Can be used as a context manager
1120 d = self.do_create()
1121 with d as name:
1122 self.assertTrue(os.path.exists(name))
1123 self.assertEqual(name, d.name)
1124 self.assertFalse(os.path.exists(name))
1125
1126
Guido van Rossum0e548712002-08-09 16:14:33 +00001127def test_main():
Antoine Pitroueab2a502012-03-10 16:34:40 +01001128 support.run_unittest(__name__)
Guido van Rossum0e548712002-08-09 16:14:33 +00001129
1130if __name__ == "__main__":
1131 test_main()