blob: b56d64899ae7395763e8dd853de71ffb16083876 [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)
154 except EnvironmentError:
155 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()
193 except (AttributeError, os.error):
194 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
Ronald Oussoren94f25282010-05-05 19:11:21 +0000318 if sys.platform in ('win32', 'os2emx'):
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
Christian Heimes895627f2007-12-08 17:28:33 +0000352 if sys.platform in ('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
Eli Benderskyf315df32013-09-06 06:11:19 -0700375 def test_collision_with_existing_directory(self):
376 # _mkstemp_inner tries another name when a directory with
377 # the chosen name already exists
378 container_dir = tempfile.mkdtemp()
379 try:
380 def mock_get_candidate_names():
381 return iter(['aaa', 'aaa', 'bbb'])
382 with support.swap_attr(tempfile,
383 '_get_candidate_names',
384 mock_get_candidate_names):
385 dir = tempfile.mkdtemp(dir=container_dir)
386 self.assertTrue(dir.endswith('aaa'))
387
388 flags = tempfile._bin_openflags
389 (fd, name) = tempfile._mkstemp_inner(container_dir,
390 tempfile.template,
391 '',
392 flags)
393 try:
394 self.assertTrue(name.endswith('bbb'))
395 finally:
396 os.close(fd)
397 os.unlink(name)
398 finally:
399 support.rmtree(container_dir)
400
Guido van Rossum0e548712002-08-09 16:14:33 +0000401
Antoine Pitroueab2a502012-03-10 16:34:40 +0100402class TestGetTempPrefix(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +0000403 """Test gettempprefix()."""
404
405 def test_sane_template(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000406 # gettempprefix returns a nonempty prefix string
Guido van Rossum0e548712002-08-09 16:14:33 +0000407 p = tempfile.gettempprefix()
408
Ezio Melottie9615932010-01-24 19:26:24 +0000409 self.assertIsInstance(p, str)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000410 self.assertTrue(len(p) > 0)
Guido van Rossum0e548712002-08-09 16:14:33 +0000411
412 def test_usable_template(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000413 # gettempprefix returns a usable prefix string
Guido van Rossum0e548712002-08-09 16:14:33 +0000414
415 # Create a temp directory, avoiding use of the prefix.
416 # Then attempt to create a file whose name is
417 # prefix + 'xxxxxx.xxx' in that directory.
418 p = tempfile.gettempprefix() + "xxxxxx.xxx"
419 d = tempfile.mkdtemp(prefix="")
420 try:
421 p = os.path.join(d, p)
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100422 fd = os.open(p, os.O_RDWR | os.O_CREAT)
Guido van Rossum0e548712002-08-09 16:14:33 +0000423 os.close(fd)
424 os.unlink(p)
425 finally:
426 os.rmdir(d)
427
Guido van Rossum0e548712002-08-09 16:14:33 +0000428
Antoine Pitroueab2a502012-03-10 16:34:40 +0100429class TestGetTempDir(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +0000430 """Test gettempdir()."""
431
432 def test_directory_exists(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000433 # gettempdir returns a directory which exists
Guido van Rossum0e548712002-08-09 16:14:33 +0000434
435 dir = tempfile.gettempdir()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000436 self.assertTrue(os.path.isabs(dir) or dir == os.curdir,
Guido van Rossum0e548712002-08-09 16:14:33 +0000437 "%s is not an absolute path" % dir)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000438 self.assertTrue(os.path.isdir(dir),
Guido van Rossum0e548712002-08-09 16:14:33 +0000439 "%s is not a directory" % dir)
440
441 def test_directory_writable(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000442 # gettempdir returns a directory writable by the user
Guido van Rossum0e548712002-08-09 16:14:33 +0000443
444 # sneaky: just instantiate a NamedTemporaryFile, which
445 # defaults to writing into the directory returned by
446 # gettempdir.
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100447 file = tempfile.NamedTemporaryFile()
448 file.write(b"blat")
449 file.close()
Guido van Rossum0e548712002-08-09 16:14:33 +0000450
451 def test_same_thing(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000452 # gettempdir always returns the same object
Guido van Rossum0e548712002-08-09 16:14:33 +0000453 a = tempfile.gettempdir()
454 b = tempfile.gettempdir()
455
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000456 self.assertTrue(a is b)
Guido van Rossum0e548712002-08-09 16:14:33 +0000457
Guido van Rossum0e548712002-08-09 16:14:33 +0000458
Antoine Pitroueab2a502012-03-10 16:34:40 +0100459class TestMkstemp(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +0000460 """Test mkstemp()."""
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000461
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000462 def do_create(self, dir=None, pre="", suf=""):
Guido van Rossum0e548712002-08-09 16:14:33 +0000463 if dir is None:
464 dir = tempfile.gettempdir()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100465 (fd, name) = tempfile.mkstemp(dir=dir, prefix=pre, suffix=suf)
466 (ndir, nbase) = os.path.split(name)
467 adir = os.path.abspath(dir)
468 self.assertEqual(adir, ndir,
469 "Directory '%s' incorrectly returned as '%s'" % (adir, ndir))
Guido van Rossum0e548712002-08-09 16:14:33 +0000470
471 try:
472 self.nameCheck(name, dir, pre, suf)
473 finally:
474 os.close(fd)
475 os.unlink(name)
476
477 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000478 # mkstemp can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000479 self.do_create()
480 self.do_create(pre="a")
481 self.do_create(suf="b")
482 self.do_create(pre="a", suf="b")
483 self.do_create(pre="aa", suf=".txt")
Martin v. Löwisd6625482003-10-12 17:37:01 +0000484 self.do_create(dir=".")
Guido van Rossum0e548712002-08-09 16:14:33 +0000485
486 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000487 # mkstemp can create directories in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000488 dir = tempfile.mkdtemp()
489 try:
490 self.do_create(dir=dir)
491 finally:
492 os.rmdir(dir)
493
Guido van Rossum0e548712002-08-09 16:14:33 +0000494
Antoine Pitroueab2a502012-03-10 16:34:40 +0100495class TestMkdtemp(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +0000496 """Test mkdtemp()."""
497
498 def do_create(self, dir=None, pre="", suf=""):
499 if dir is None:
500 dir = tempfile.gettempdir()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100501 name = tempfile.mkdtemp(dir=dir, prefix=pre, suffix=suf)
Guido van Rossum0e548712002-08-09 16:14:33 +0000502
503 try:
504 self.nameCheck(name, dir, pre, suf)
505 return name
506 except:
507 os.rmdir(name)
508 raise
509
510 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000511 # mkdtemp can create directories
Guido van Rossum0e548712002-08-09 16:14:33 +0000512 os.rmdir(self.do_create())
513 os.rmdir(self.do_create(pre="a"))
514 os.rmdir(self.do_create(suf="b"))
515 os.rmdir(self.do_create(pre="a", suf="b"))
516 os.rmdir(self.do_create(pre="aa", suf=".txt"))
Tim Petersa0d55de2002-08-09 18:01:01 +0000517
Guido van Rossum0e548712002-08-09 16:14:33 +0000518 def test_basic_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000519 # mkdtemp can create many directories (stochastic)
Guido van Rossum805365e2007-05-07 22:24:25 +0000520 extant = list(range(TEST_FILES))
Guido van Rossum0e548712002-08-09 16:14:33 +0000521 try:
522 for i in extant:
523 extant[i] = self.do_create(pre="aa")
524 finally:
525 for i in extant:
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000526 if(isinstance(i, str)):
Guido van Rossum0e548712002-08-09 16:14:33 +0000527 os.rmdir(i)
528
529 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000530 # mkdtemp can create directories in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000531 dir = tempfile.mkdtemp()
532 try:
533 os.rmdir(self.do_create(dir=dir))
534 finally:
535 os.rmdir(dir)
536
537 def test_mode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000538 # mkdtemp creates directories with the proper mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000539 if not has_stat:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000540 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000541
542 dir = self.do_create()
543 try:
544 mode = stat.S_IMODE(os.stat(dir).st_mode)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000545 mode &= 0o777 # Mask off sticky bits inherited from /tmp
546 expected = 0o700
Ronald Oussoren94f25282010-05-05 19:11:21 +0000547 if sys.platform in ('win32', 'os2emx'):
Tim Petersca3ac7f2002-08-09 18:13:51 +0000548 # There's no distinction among 'user', 'group' and 'world';
549 # replicate the 'user' bits.
550 user = expected >> 6
551 expected = user * (1 + 8 + 64)
552 self.assertEqual(mode, expected)
Guido van Rossum0e548712002-08-09 16:14:33 +0000553 finally:
554 os.rmdir(dir)
555
Guido van Rossum0e548712002-08-09 16:14:33 +0000556
Antoine Pitroueab2a502012-03-10 16:34:40 +0100557class TestMktemp(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +0000558 """Test mktemp()."""
559
560 # For safety, all use of mktemp must occur in a private directory.
561 # We must also suppress the RuntimeWarning it generates.
562 def setUp(self):
563 self.dir = tempfile.mkdtemp()
Brett Cannone1adece2010-03-20 22:19:55 +0000564 super().setUp()
Guido van Rossum0e548712002-08-09 16:14:33 +0000565
566 def tearDown(self):
567 if self.dir:
568 os.rmdir(self.dir)
569 self.dir = None
Brett Cannone1adece2010-03-20 22:19:55 +0000570 super().tearDown()
Guido van Rossum0e548712002-08-09 16:14:33 +0000571
572 class mktemped:
573 _unlink = os.unlink
574 _bflags = tempfile._bin_openflags
575
576 def __init__(self, dir, pre, suf):
577 self.name = tempfile.mktemp(dir=dir, prefix=pre, suffix=suf)
578 # Create the file. This will raise an exception if it's
579 # mysteriously appeared in the meanwhile.
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000580 os.close(os.open(self.name, self._bflags, 0o600))
Guido van Rossum0e548712002-08-09 16:14:33 +0000581
582 def __del__(self):
583 self._unlink(self.name)
584
585 def do_create(self, pre="", suf=""):
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100586 file = self.mktemped(self.dir, pre, suf)
Guido van Rossum0e548712002-08-09 16:14:33 +0000587
588 self.nameCheck(file.name, self.dir, pre, suf)
589 return file
590
591 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000592 # mktemp can choose usable file names
Guido van Rossum0e548712002-08-09 16:14:33 +0000593 self.do_create()
594 self.do_create(pre="a")
595 self.do_create(suf="b")
596 self.do_create(pre="a", suf="b")
597 self.do_create(pre="aa", suf=".txt")
598
599 def test_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000600 # mktemp can choose many usable file names (stochastic)
Guido van Rossum805365e2007-05-07 22:24:25 +0000601 extant = list(range(TEST_FILES))
Guido van Rossum0e548712002-08-09 16:14:33 +0000602 for i in extant:
603 extant[i] = self.do_create(pre="aa")
604
Fred Drake8bec4832002-11-22 20:13:43 +0000605## def test_warning(self):
606## # mktemp issues a warning when used
607## warnings.filterwarnings("error",
608## category=RuntimeWarning,
609## message="mktemp")
610## self.assertRaises(RuntimeWarning,
611## tempfile.mktemp, dir=self.dir)
Guido van Rossum0e548712002-08-09 16:14:33 +0000612
Guido van Rossum0e548712002-08-09 16:14:33 +0000613
614# We test _TemporaryFileWrapper by testing NamedTemporaryFile.
615
616
Antoine Pitroueab2a502012-03-10 16:34:40 +0100617class TestNamedTemporaryFile(BaseTestCase):
Guido van Rossum0e548712002-08-09 16:14:33 +0000618 """Test NamedTemporaryFile()."""
619
Guido van Rossumd8faa362007-04-27 19:54:29 +0000620 def do_create(self, dir=None, pre="", suf="", delete=True):
Guido van Rossum0e548712002-08-09 16:14:33 +0000621 if dir is None:
622 dir = tempfile.gettempdir()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100623 file = tempfile.NamedTemporaryFile(dir=dir, prefix=pre, suffix=suf,
624 delete=delete)
Guido van Rossum0e548712002-08-09 16:14:33 +0000625
626 self.nameCheck(file.name, dir, pre, suf)
627 return file
628
629
630 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000631 # NamedTemporaryFile can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000632 self.do_create()
633 self.do_create(pre="a")
634 self.do_create(suf="b")
635 self.do_create(pre="a", suf="b")
636 self.do_create(pre="aa", suf=".txt")
637
638 def test_creates_named(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000639 # NamedTemporaryFile creates files with names
Guido van Rossum0e548712002-08-09 16:14:33 +0000640 f = tempfile.NamedTemporaryFile()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000641 self.assertTrue(os.path.exists(f.name),
Guido van Rossum0e548712002-08-09 16:14:33 +0000642 "NamedTemporaryFile %s does not exist" % f.name)
643
644 def test_del_on_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000645 # A NamedTemporaryFile is deleted when closed
Guido van Rossum0e548712002-08-09 16:14:33 +0000646 dir = tempfile.mkdtemp()
647 try:
648 f = tempfile.NamedTemporaryFile(dir=dir)
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000649 f.write(b'blat')
Guido van Rossum0e548712002-08-09 16:14:33 +0000650 f.close()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000651 self.assertFalse(os.path.exists(f.name),
Guido van Rossum0e548712002-08-09 16:14:33 +0000652 "NamedTemporaryFile %s exists after close" % f.name)
653 finally:
654 os.rmdir(dir)
655
Guido van Rossumd8faa362007-04-27 19:54:29 +0000656 def test_dis_del_on_close(self):
657 # Tests that delete-on-close can be disabled
658 dir = tempfile.mkdtemp()
659 tmp = None
660 try:
661 f = tempfile.NamedTemporaryFile(dir=dir, delete=False)
662 tmp = f.name
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000663 f.write(b'blat')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000664 f.close()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000665 self.assertTrue(os.path.exists(f.name),
Guido van Rossumd8faa362007-04-27 19:54:29 +0000666 "NamedTemporaryFile %s missing after close" % f.name)
667 finally:
668 if tmp is not None:
669 os.unlink(tmp)
670 os.rmdir(dir)
671
Guido van Rossum0e548712002-08-09 16:14:33 +0000672 def test_multiple_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000673 # A NamedTemporaryFile can be closed many times without error
Guido van Rossum0e548712002-08-09 16:14:33 +0000674 f = tempfile.NamedTemporaryFile()
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000675 f.write(b'abc\n')
Guido van Rossum0e548712002-08-09 16:14:33 +0000676 f.close()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100677 f.close()
678 f.close()
Guido van Rossum0e548712002-08-09 16:14:33 +0000679
Christian Heimes3ecfea712008-02-09 20:51:34 +0000680 def test_context_manager(self):
681 # A NamedTemporaryFile can be used as a context manager
682 with tempfile.NamedTemporaryFile() as f:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000683 self.assertTrue(os.path.exists(f.name))
684 self.assertFalse(os.path.exists(f.name))
Christian Heimes3ecfea712008-02-09 20:51:34 +0000685 def use_closed():
686 with f:
687 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000688 self.assertRaises(ValueError, use_closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000689
Guido van Rossum0e548712002-08-09 16:14:33 +0000690 # How to test the mode and bufsize parameters?
691
Guido van Rossum0e548712002-08-09 16:14:33 +0000692
Antoine Pitroueab2a502012-03-10 16:34:40 +0100693class TestSpooledTemporaryFile(BaseTestCase):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000694 """Test SpooledTemporaryFile()."""
695
696 def do_create(self, max_size=0, dir=None, pre="", suf=""):
697 if dir is None:
698 dir = tempfile.gettempdir()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100699 file = tempfile.SpooledTemporaryFile(max_size=max_size, dir=dir, prefix=pre, suffix=suf)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000700
701 return file
702
703
704 def test_basic(self):
705 # SpooledTemporaryFile can create files
706 f = self.do_create()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000707 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000708 f = self.do_create(max_size=100, pre="a", suf=".txt")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000709 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000710
711 def test_del_on_close(self):
712 # A SpooledTemporaryFile is deleted when closed
713 dir = tempfile.mkdtemp()
714 try:
715 f = tempfile.SpooledTemporaryFile(max_size=10, dir=dir)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000716 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000717 f.write(b'blat ' * 5)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000718 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000719 filename = f.name
720 f.close()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000721 self.assertFalse(isinstance(filename, str) and os.path.exists(filename),
Guido van Rossumd8faa362007-04-27 19:54:29 +0000722 "SpooledTemporaryFile %s exists after close" % filename)
723 finally:
724 os.rmdir(dir)
725
726 def test_rewrite_small(self):
727 # A SpooledTemporaryFile can be written to multiple within the max_size
728 f = self.do_create(max_size=30)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000729 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000730 for i in range(5):
731 f.seek(0, 0)
Guido van Rossum39478e82007-08-27 17:23:59 +0000732 f.write(b'x' * 20)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000733 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000734
735 def test_write_sequential(self):
736 # A SpooledTemporaryFile should hold exactly max_size bytes, and roll
737 # over afterward
738 f = self.do_create(max_size=30)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000739 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000740 f.write(b'x' * 20)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000741 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000742 f.write(b'x' * 10)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000743 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000744 f.write(b'x')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000745 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000746
R David Murrayd89ee792011-03-14 09:55:46 -0400747 def test_writelines(self):
748 # Verify writelines with a SpooledTemporaryFile
749 f = self.do_create()
750 f.writelines((b'x', b'y', b'z'))
751 f.seek(0)
752 buf = f.read()
753 self.assertEqual(buf, b'xyz')
754
755 def test_writelines_sequential(self):
756 # A SpooledTemporaryFile should hold exactly max_size bytes, and roll
757 # over afterward
758 f = self.do_create(max_size=35)
759 f.writelines((b'x' * 20, b'x' * 10, b'x' * 5))
760 self.assertFalse(f._rolled)
761 f.write(b'x')
762 self.assertTrue(f._rolled)
763
Guido van Rossumd8faa362007-04-27 19:54:29 +0000764 def test_sparse(self):
765 # A SpooledTemporaryFile that is written late in the file will extend
766 # when that occurs
767 f = self.do_create(max_size=30)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000768 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000769 f.seek(100, 0)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000770 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000771 f.write(b'x')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000772 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000773
774 def test_fileno(self):
775 # A SpooledTemporaryFile should roll over to a real file on fileno()
776 f = self.do_create(max_size=30)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000777 self.assertFalse(f._rolled)
778 self.assertTrue(f.fileno() > 0)
779 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000780
Christian Heimes3ecfea712008-02-09 20:51:34 +0000781 def test_multiple_close_before_rollover(self):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000782 # A SpooledTemporaryFile can be closed many times without error
783 f = tempfile.SpooledTemporaryFile()
Guido van Rossum39478e82007-08-27 17:23:59 +0000784 f.write(b'abc\n')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000785 self.assertFalse(f._rolled)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000786 f.close()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100787 f.close()
788 f.close()
Christian Heimes3ecfea712008-02-09 20:51:34 +0000789
790 def test_multiple_close_after_rollover(self):
791 # A SpooledTemporaryFile can be closed many times without error
792 f = tempfile.SpooledTemporaryFile(max_size=1)
793 f.write(b'abc\n')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000794 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000795 f.close()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +0100796 f.close()
797 f.close()
Guido van Rossumd8faa362007-04-27 19:54:29 +0000798
799 def test_bound_methods(self):
800 # It should be OK to steal a bound method from a SpooledTemporaryFile
801 # and use it independently; when the file rolls over, those bound
802 # methods should continue to function
803 f = self.do_create(max_size=30)
804 read = f.read
805 write = f.write
806 seek = f.seek
807
Guido van Rossum39478e82007-08-27 17:23:59 +0000808 write(b"a" * 35)
809 write(b"b" * 35)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000810 seek(0, 0)
Guido van Rossum9a634702007-07-09 10:24:45 +0000811 self.assertEqual(read(70), b'a'*35 + b'b'*35)
812
Serhiy Storchakabbbbe8e2013-02-09 12:21:14 +0200813 def test_properties(self):
814 f = tempfile.SpooledTemporaryFile(max_size=10)
815 f.write(b'x' * 10)
816 self.assertFalse(f._rolled)
817 self.assertEqual(f.mode, 'w+b')
818 self.assertIsNone(f.name)
819 with self.assertRaises(AttributeError):
820 f.newlines
821 with self.assertRaises(AttributeError):
822 f.encoding
823
824 f.write(b'x')
825 self.assertTrue(f._rolled)
826 self.assertEqual(f.mode, 'rb+')
827 self.assertIsNotNone(f.name)
828 with self.assertRaises(AttributeError):
829 f.newlines
830 with self.assertRaises(AttributeError):
831 f.encoding
832
Guido van Rossum9a634702007-07-09 10:24:45 +0000833 def test_text_mode(self):
834 # Creating a SpooledTemporaryFile with a text mode should produce
835 # a file object reading and writing (Unicode) text strings.
836 f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10)
837 f.write("abc\n")
838 f.seek(0)
839 self.assertEqual(f.read(), "abc\n")
840 f.write("def\n")
841 f.seek(0)
842 self.assertEqual(f.read(), "abc\ndef\n")
Serhiy Storchakabbbbe8e2013-02-09 12:21:14 +0200843 self.assertFalse(f._rolled)
844 self.assertEqual(f.mode, 'w+')
845 self.assertIsNone(f.name)
846 self.assertIsNone(f.newlines)
847 self.assertIsNone(f.encoding)
848
Guido van Rossum9a634702007-07-09 10:24:45 +0000849 f.write("xyzzy\n")
850 f.seek(0)
851 self.assertEqual(f.read(), "abc\ndef\nxyzzy\n")
Amaury Forgeot d'Arc7d0bddd2009-11-30 00:08:56 +0000852 # Check that Ctrl+Z doesn't truncate the file
853 f.write("foo\x1abar\n")
854 f.seek(0)
855 self.assertEqual(f.read(), "abc\ndef\nxyzzy\nfoo\x1abar\n")
Serhiy Storchakabbbbe8e2013-02-09 12:21:14 +0200856 self.assertTrue(f._rolled)
857 self.assertEqual(f.mode, 'w+')
858 self.assertIsNotNone(f.name)
Serhiy Storchaka497cee42013-02-10 14:43:46 +0200859 self.assertEqual(f.newlines, os.linesep)
Serhiy Storchakabbbbe8e2013-02-09 12:21:14 +0200860 self.assertIsNotNone(f.encoding)
Guido van Rossum9a634702007-07-09 10:24:45 +0000861
Guido van Rossumf0c74162007-08-28 03:29:45 +0000862 def test_text_newline_and_encoding(self):
863 f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10,
864 newline='', encoding='utf-8')
865 f.write("\u039B\r\n")
866 f.seek(0)
867 self.assertEqual(f.read(), "\u039B\r\n")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000868 self.assertFalse(f._rolled)
Serhiy Storchakabbbbe8e2013-02-09 12:21:14 +0200869 self.assertEqual(f.mode, 'w+')
870 self.assertIsNone(f.name)
871 self.assertIsNone(f.newlines)
872 self.assertIsNone(f.encoding)
Guido van Rossumf0c74162007-08-28 03:29:45 +0000873
874 f.write("\u039B" * 20 + "\r\n")
875 f.seek(0)
876 self.assertEqual(f.read(), "\u039B\r\n" + ("\u039B" * 20) + "\r\n")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000877 self.assertTrue(f._rolled)
Serhiy Storchakabbbbe8e2013-02-09 12:21:14 +0200878 self.assertEqual(f.mode, 'w+')
879 self.assertIsNotNone(f.name)
880 self.assertIsNotNone(f.newlines)
881 self.assertEqual(f.encoding, 'utf-8')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000882
Christian Heimes3ecfea712008-02-09 20:51:34 +0000883 def test_context_manager_before_rollover(self):
884 # A SpooledTemporaryFile can be used as a context manager
885 with tempfile.SpooledTemporaryFile(max_size=1) as f:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000886 self.assertFalse(f._rolled)
887 self.assertFalse(f.closed)
888 self.assertTrue(f.closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000889 def use_closed():
890 with f:
891 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000892 self.assertRaises(ValueError, use_closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000893
894 def test_context_manager_during_rollover(self):
895 # A SpooledTemporaryFile can be used as a context manager
896 with tempfile.SpooledTemporaryFile(max_size=1) as f:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000897 self.assertFalse(f._rolled)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000898 f.write(b'abc\n')
899 f.flush()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000900 self.assertTrue(f._rolled)
901 self.assertFalse(f.closed)
902 self.assertTrue(f.closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000903 def use_closed():
904 with f:
905 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000906 self.assertRaises(ValueError, use_closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000907
908 def test_context_manager_after_rollover(self):
909 # A SpooledTemporaryFile can be used as a context manager
910 f = tempfile.SpooledTemporaryFile(max_size=1)
911 f.write(b'abc\n')
912 f.flush()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000913 self.assertTrue(f._rolled)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000914 with f:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000915 self.assertFalse(f.closed)
916 self.assertTrue(f.closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000917 def use_closed():
918 with f:
919 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000920 self.assertRaises(ValueError, use_closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000921
Antoine Pitrou0e86a582011-11-25 18:03:09 +0100922 def test_truncate_with_size_parameter(self):
923 # A SpooledTemporaryFile can be truncated to zero size
924 f = tempfile.SpooledTemporaryFile(max_size=10)
925 f.write(b'abcdefg\n')
926 f.seek(0)
927 f.truncate()
928 self.assertFalse(f._rolled)
929 self.assertEqual(f._file.getvalue(), b'')
930 # A SpooledTemporaryFile can be truncated to a specific size
931 f = tempfile.SpooledTemporaryFile(max_size=10)
932 f.write(b'abcdefg\n')
933 f.truncate(4)
934 self.assertFalse(f._rolled)
935 self.assertEqual(f._file.getvalue(), b'abcd')
936 # A SpooledTemporaryFile rolls over if truncated to large size
937 f = tempfile.SpooledTemporaryFile(max_size=10)
938 f.write(b'abcdefg\n')
939 f.truncate(20)
940 self.assertTrue(f._rolled)
941 if has_stat:
942 self.assertEqual(os.fstat(f.fileno()).st_size, 20)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000943
Guido van Rossum0e548712002-08-09 16:14:33 +0000944
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000945if tempfile.NamedTemporaryFile is not tempfile.TemporaryFile:
Antoine Pitroueab2a502012-03-10 16:34:40 +0100946
947 class TestTemporaryFile(BaseTestCase):
948 """Test TemporaryFile()."""
949
950 def test_basic(self):
951 # TemporaryFile can create files
952 # No point in testing the name params - the file has no name.
953 tempfile.TemporaryFile()
954
955 def test_has_no_name(self):
956 # TemporaryFile creates files with no names (on this system)
957 dir = tempfile.mkdtemp()
958 f = tempfile.TemporaryFile(dir=dir)
959 f.write(b'blat')
960
961 # Sneaky: because this file has no name, it should not prevent
962 # us from removing the directory it was created in.
963 try:
964 os.rmdir(dir)
965 except:
966 # cleanup
967 f.close()
968 os.rmdir(dir)
969 raise
970
971 def test_multiple_close(self):
972 # A TemporaryFile can be closed many times without error
973 f = tempfile.TemporaryFile()
974 f.write(b'abc\n')
975 f.close()
976 f.close()
977 f.close()
978
979 # How to test the mode and bufsize parameters?
980 def test_mode_and_encoding(self):
981
982 def roundtrip(input, *args, **kwargs):
983 with tempfile.TemporaryFile(*args, **kwargs) as fileobj:
984 fileobj.write(input)
985 fileobj.seek(0)
986 self.assertEqual(input, fileobj.read())
987
988 roundtrip(b"1234", "w+b")
989 roundtrip("abdc\n", "w+")
990 roundtrip("\u039B", "w+", encoding="utf-16")
991 roundtrip("foo\r\n", "w+", newline="")
Guido van Rossum0e548712002-08-09 16:14:33 +0000992
Nick Coghlan543af752010-10-24 11:23:25 +0000993
994# Helper for test_del_on_shutdown
995class NulledModules:
996 def __init__(self, *modules):
997 self.refs = [mod.__dict__ for mod in modules]
998 self.contents = [ref.copy() for ref in self.refs]
999
1000 def __enter__(self):
1001 for d in self.refs:
1002 for key in d:
1003 d[key] = None
1004
1005 def __exit__(self, *exc_info):
1006 for d, c in zip(self.refs, self.contents):
1007 d.clear()
1008 d.update(c)
1009
Antoine Pitroueab2a502012-03-10 16:34:40 +01001010class TestTemporaryDirectory(BaseTestCase):
Nick Coghlan543af752010-10-24 11:23:25 +00001011 """Test TemporaryDirectory()."""
1012
1013 def do_create(self, dir=None, pre="", suf="", recurse=1):
1014 if dir is None:
1015 dir = tempfile.gettempdir()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +01001016 tmp = tempfile.TemporaryDirectory(dir=dir, prefix=pre, suffix=suf)
Nick Coghlan543af752010-10-24 11:23:25 +00001017 self.nameCheck(tmp.name, dir, pre, suf)
1018 # Create a subdirectory and some files
1019 if recurse:
1020 self.do_create(tmp.name, pre, suf, recurse-1)
1021 with open(os.path.join(tmp.name, "test.txt"), "wb") as f:
1022 f.write(b"Hello world!")
1023 return tmp
1024
Nick Coghlan6b22f3f2010-12-12 15:24:21 +00001025 def test_mkdtemp_failure(self):
1026 # Check no additional exception if mkdtemp fails
1027 # Previously would raise AttributeError instead
Nick Coghlan3c54ea62010-12-13 03:02:43 +00001028 # (noted as part of Issue #10188)
1029 with tempfile.TemporaryDirectory() as nonexistent:
1030 pass
Serhiy Storchaka7451a722013-02-09 22:25:49 +02001031 with self.assertRaises(FileNotFoundError) as cm:
Nick Coghlan3c54ea62010-12-13 03:02:43 +00001032 tempfile.TemporaryDirectory(dir=nonexistent)
Serhiy Storchaka7451a722013-02-09 22:25:49 +02001033 self.assertEqual(cm.exception.errno, errno.ENOENT)
Nick Coghlan6b22f3f2010-12-12 15:24:21 +00001034
Nick Coghlan543af752010-10-24 11:23:25 +00001035 def test_explicit_cleanup(self):
1036 # A TemporaryDirectory is deleted when cleaned up
1037 dir = tempfile.mkdtemp()
1038 try:
1039 d = self.do_create(dir=dir)
1040 self.assertTrue(os.path.exists(d.name),
1041 "TemporaryDirectory %s does not exist" % d.name)
1042 d.cleanup()
1043 self.assertFalse(os.path.exists(d.name),
1044 "TemporaryDirectory %s exists after cleanup" % d.name)
1045 finally:
1046 os.rmdir(dir)
1047
Charles-François Natalidef35432011-07-29 18:59:24 +02001048 @support.skip_unless_symlink
1049 def test_cleanup_with_symlink_to_a_directory(self):
1050 # cleanup() should not follow symlinks to directories (issue #12464)
1051 d1 = self.do_create()
1052 d2 = self.do_create()
1053
1054 # Symlink d1/foo -> d2
1055 os.symlink(d2.name, os.path.join(d1.name, "foo"))
1056
1057 # This call to cleanup() should not follow the "foo" symlink
1058 d1.cleanup()
1059
1060 self.assertFalse(os.path.exists(d1.name),
1061 "TemporaryDirectory %s exists after cleanup" % d1.name)
1062 self.assertTrue(os.path.exists(d2.name),
1063 "Directory pointed to by a symlink was deleted")
1064 self.assertEqual(os.listdir(d2.name), ['test.txt'],
1065 "Contents of the directory pointed to by a symlink "
1066 "were deleted")
1067 d2.cleanup()
1068
Nick Coghlan543af752010-10-24 11:23:25 +00001069 @support.cpython_only
1070 def test_del_on_collection(self):
1071 # A TemporaryDirectory is deleted when garbage collected
1072 dir = tempfile.mkdtemp()
1073 try:
1074 d = self.do_create(dir=dir)
1075 name = d.name
1076 del d # Rely on refcounting to invoke __del__
1077 self.assertFalse(os.path.exists(name),
1078 "TemporaryDirectory %s exists after __del__" % name)
1079 finally:
1080 os.rmdir(dir)
1081
1082 @unittest.expectedFailure # See issue #10188
1083 def test_del_on_shutdown(self):
1084 # A TemporaryDirectory may be cleaned up during shutdown
1085 # Make sure it works with the relevant modules nulled out
Nick Coghlan6b22f3f2010-12-12 15:24:21 +00001086 with self.do_create() as dir:
Nick Coghlan543af752010-10-24 11:23:25 +00001087 d = self.do_create(dir=dir)
1088 # Mimic the nulling out of modules that
1089 # occurs during system shutdown
1090 modules = [os, os.path]
1091 if has_stat:
1092 modules.append(stat)
Nick Coghlan6b22f3f2010-12-12 15:24:21 +00001093 # Currently broken, so suppress the warning
1094 # that is otherwise emitted on stdout
1095 with support.captured_stderr() as err:
1096 with NulledModules(*modules):
1097 d.cleanup()
1098 # Currently broken, so stop spurious exception by
1099 # indicating the object has already been closed
1100 d._closed = True
1101 # And this assert will fail, as expected by the
1102 # unittest decorator...
Nick Coghlan543af752010-10-24 11:23:25 +00001103 self.assertFalse(os.path.exists(d.name),
1104 "TemporaryDirectory %s exists after cleanup" % d.name)
Nick Coghlan6b22f3f2010-12-12 15:24:21 +00001105
1106 def test_warnings_on_cleanup(self):
1107 # Two kinds of warning on shutdown
1108 # Issue 10888: may write to stderr if modules are nulled out
1109 # ResourceWarning will be triggered by __del__
1110 with self.do_create() as dir:
Nick Coghlane98e8a32010-12-13 16:32:51 +00001111 if os.sep != '\\':
1112 # Embed a backslash in order to make sure string escaping
1113 # in the displayed error message is dealt with correctly
1114 suffix = '\\check_backslash_handling'
1115 else:
1116 suffix = ''
1117 d = self.do_create(dir=dir, suf=suffix)
Nick Coghlan6b22f3f2010-12-12 15:24:21 +00001118
1119 #Check for the Issue 10888 message
1120 modules = [os, os.path]
1121 if has_stat:
1122 modules.append(stat)
1123 with support.captured_stderr() as err:
1124 with NulledModules(*modules):
1125 d.cleanup()
Nick Coghlane98e8a32010-12-13 16:32:51 +00001126 message = err.getvalue().replace('\\\\', '\\')
Nick Coghlan6b22f3f2010-12-12 15:24:21 +00001127 self.assertIn("while cleaning up", message)
1128 self.assertIn(d.name, message)
1129
1130 # Check for the resource warning
1131 with support.check_warnings(('Implicitly', ResourceWarning), quiet=False):
1132 warnings.filterwarnings("always", category=ResourceWarning)
1133 d.__del__()
1134 self.assertFalse(os.path.exists(d.name),
1135 "TemporaryDirectory %s exists after __del__" % d.name)
Nick Coghlan543af752010-10-24 11:23:25 +00001136
1137 def test_multiple_close(self):
1138 # Can be cleaned-up many times without error
1139 d = self.do_create()
1140 d.cleanup()
Antoine Pitrou8cd8d5e2012-03-10 16:20:24 +01001141 d.cleanup()
1142 d.cleanup()
Nick Coghlan543af752010-10-24 11:23:25 +00001143
1144 def test_context_manager(self):
1145 # Can be used as a context manager
1146 d = self.do_create()
1147 with d as name:
1148 self.assertTrue(os.path.exists(name))
1149 self.assertEqual(name, d.name)
1150 self.assertFalse(os.path.exists(name))
1151
1152
Guido van Rossum0e548712002-08-09 16:14:33 +00001153def test_main():
Antoine Pitroueab2a502012-03-10 16:34:40 +01001154 support.run_unittest(__name__)
Guido van Rossum0e548712002-08-09 16:14:33 +00001155
1156if __name__ == "__main__":
1157 test_main()