blob: eebf78f6fd74c4047ded125dda6a5dbadbb1ae5d [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
Guido van Rossum0e548712002-08-09 16:14:33 +00003import os
4import sys
5import re
Guido van Rossum0e548712002-08-09 16:14:33 +00006import warnings
Tim Petersc57a2852001-10-29 21:46:08 +00007
Guido van Rossum0e548712002-08-09 16:14:33 +00008import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00009from test import support
Guido van Rossum0e548712002-08-09 16:14:33 +000010
Fred Drake7633d232002-10-17 22:09:03 +000011
Guido van Rossum0e548712002-08-09 16:14:33 +000012if hasattr(os, 'stat'):
13 import stat
14 has_stat = 1
15else:
16 has_stat = 0
17
18has_textmode = (tempfile._text_openflags != tempfile._bin_openflags)
Guido van Rossum78741062002-08-17 11:41:01 +000019has_spawnl = hasattr(os, 'spawnl')
Guido van Rossum0e548712002-08-09 16:14:33 +000020
Neal Norwitz68ee0122002-08-16 19:28:59 +000021# TEST_FILES may need to be tweaked for systems depending on the maximum
22# number of files that can be opened at one time (see ulimit -n)
Ronald Oussoren94f25282010-05-05 19:11:21 +000023if sys.platform in ('openbsd3', 'openbsd4'):
Martin v. Löwis99968282004-09-15 06:02:54 +000024 TEST_FILES = 48
Jack Jansence921472003-01-08 16:30:34 +000025else:
26 TEST_FILES = 100
Neal Norwitz68ee0122002-08-16 19:28:59 +000027
Guido van Rossum0e548712002-08-09 16:14:33 +000028# This is organized as one test for each chunk of code in tempfile.py,
29# in order of their appearance in the file. Testing which requires
30# threads is not done here.
31
32# Common functionality.
33class TC(unittest.TestCase):
34
35 str_check = re.compile(r"[a-zA-Z0-9_-]{6}$")
36
Brett Cannone1adece2010-03-20 22:19:55 +000037 def setUp(self):
38 self._warnings_manager = support.check_warnings()
39 self._warnings_manager.__enter__()
40 warnings.filterwarnings("ignore", category=RuntimeWarning,
41 message="mktemp", module=__name__)
42
43 def tearDown(self):
44 self._warnings_manager.__exit__(None, None, None)
45
46
Guido van Rossum0e548712002-08-09 16:14:33 +000047 def failOnException(self, what, ei=None):
48 if ei is None:
49 ei = sys.exc_info()
50 self.fail("%s raised %s: %s" % (what, ei[0], ei[1]))
51
52 def nameCheck(self, name, dir, pre, suf):
53 (ndir, nbase) = os.path.split(name)
54 npre = nbase[:len(pre)]
55 nsuf = nbase[len(nbase)-len(suf):]
56
Martin v. Löwisd6625482003-10-12 17:37:01 +000057 # check for equality of the absolute paths!
58 self.assertEqual(os.path.abspath(ndir), os.path.abspath(dir),
Guido van Rossum0e548712002-08-09 16:14:33 +000059 "file '%s' not in directory '%s'" % (name, dir))
60 self.assertEqual(npre, pre,
61 "file '%s' does not begin with '%s'" % (nbase, pre))
62 self.assertEqual(nsuf, suf,
63 "file '%s' does not end with '%s'" % (nbase, suf))
64
65 nbase = nbase[len(pre):len(nbase)-len(suf)]
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000066 self.assertTrue(self.str_check.match(nbase),
Guido van Rossum0e548712002-08-09 16:14:33 +000067 "random string '%s' does not match /^[a-zA-Z0-9_-]{6}$/"
68 % nbase)
69
70test_classes = []
71
72class test_exports(TC):
73 def test_exports(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +000074 # There are no surprising symbols in the tempfile module
Guido van Rossum0e548712002-08-09 16:14:33 +000075 dict = tempfile.__dict__
76
77 expected = {
78 "NamedTemporaryFile" : 1,
79 "TemporaryFile" : 1,
80 "mkstemp" : 1,
81 "mkdtemp" : 1,
82 "mktemp" : 1,
83 "TMP_MAX" : 1,
84 "gettempprefix" : 1,
85 "gettempdir" : 1,
86 "tempdir" : 1,
Guido van Rossumd8faa362007-04-27 19:54:29 +000087 "template" : 1,
Nick Coghlan543af752010-10-24 11:23:25 +000088 "SpooledTemporaryFile" : 1,
89 "TemporaryDirectory" : 1,
Guido van Rossum0e548712002-08-09 16:14:33 +000090 }
91
92 unexp = []
93 for key in dict:
94 if key[0] != '_' and key not in expected:
95 unexp.append(key)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000096 self.assertTrue(len(unexp) == 0,
Guido van Rossum0e548712002-08-09 16:14:33 +000097 "unexpected keys: %s" % unexp)
98
99test_classes.append(test_exports)
100
101
Guido van Rossum0e548712002-08-09 16:14:33 +0000102class test__RandomNameSequence(TC):
103 """Test the internal iterator object _RandomNameSequence."""
104
105 def setUp(self):
106 self.r = tempfile._RandomNameSequence()
Brett Cannone1adece2010-03-20 22:19:55 +0000107 super().setUp()
Guido van Rossum0e548712002-08-09 16:14:33 +0000108
109 def test_get_six_char_str(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000110 # _RandomNameSequence returns a six-character string
Georg Brandla18af4e2007-04-21 15:47:16 +0000111 s = next(self.r)
Guido van Rossum0e548712002-08-09 16:14:33 +0000112 self.nameCheck(s, '', '', '')
113
114 def test_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000115 # _RandomNameSequence returns no duplicate strings (stochastic)
Guido van Rossum0e548712002-08-09 16:14:33 +0000116
117 dict = {}
118 r = self.r
Guido van Rossum805365e2007-05-07 22:24:25 +0000119 for i in range(TEST_FILES):
Georg Brandla18af4e2007-04-21 15:47:16 +0000120 s = next(r)
Guido van Rossum0e548712002-08-09 16:14:33 +0000121 self.nameCheck(s, '', '', '')
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000122 self.assertNotIn(s, dict)
Guido van Rossum0e548712002-08-09 16:14:33 +0000123 dict[s] = 1
124
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000125 def supports_iter(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000126 # _RandomNameSequence supports the iterator protocol
Guido van Rossum0e548712002-08-09 16:14:33 +0000127
128 i = 0
129 r = self.r
130 try:
131 for s in r:
132 i += 1
133 if i == 20:
134 break
135 except:
Georg Brandl89fad142010-03-14 10:23:39 +0000136 self.failOnException("iteration")
Guido van Rossum0e548712002-08-09 16:14:33 +0000137
138test_classes.append(test__RandomNameSequence)
139
140
141class test__candidate_tempdir_list(TC):
142 """Test the internal function _candidate_tempdir_list."""
143
144 def test_nonempty_list(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000145 # _candidate_tempdir_list returns a nonempty list of strings
Guido van Rossum0e548712002-08-09 16:14:33 +0000146
147 cand = tempfile._candidate_tempdir_list()
148
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000149 self.assertFalse(len(cand) == 0)
Guido van Rossum0e548712002-08-09 16:14:33 +0000150 for c in cand:
Ezio Melottie9615932010-01-24 19:26:24 +0000151 self.assertIsInstance(c, str)
Guido van Rossum0e548712002-08-09 16:14:33 +0000152
153 def test_wanted_dirs(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000154 # _candidate_tempdir_list contains the expected directories
Guido van Rossum0e548712002-08-09 16:14:33 +0000155
156 # Make sure the interesting environment variables are all set.
Hirokazu Yamamoto71959632009-04-27 01:44:28 +0000157 with support.EnvironmentVarGuard() as env:
Guido van Rossum0e548712002-08-09 16:14:33 +0000158 for envname in 'TMPDIR', 'TEMP', 'TMP':
159 dirname = os.getenv(envname)
160 if not dirname:
Walter Dörwald155374d2009-05-01 19:58:58 +0000161 env[envname] = os.path.abspath(envname)
Guido van Rossum0e548712002-08-09 16:14:33 +0000162
163 cand = tempfile._candidate_tempdir_list()
164
165 for envname in 'TMPDIR', 'TEMP', 'TMP':
166 dirname = os.getenv(envname)
167 if not dirname: raise ValueError
Benjamin Peterson577473f2010-01-19 00:09:57 +0000168 self.assertIn(dirname, cand)
Guido van Rossum0e548712002-08-09 16:14:33 +0000169
170 try:
171 dirname = os.getcwd()
172 except (AttributeError, os.error):
173 dirname = os.curdir
174
Benjamin Peterson577473f2010-01-19 00:09:57 +0000175 self.assertIn(dirname, cand)
Guido van Rossum0e548712002-08-09 16:14:33 +0000176
177 # Not practical to try to verify the presence of OS-specific
178 # paths in this list.
Guido van Rossum0e548712002-08-09 16:14:33 +0000179
180test_classes.append(test__candidate_tempdir_list)
181
182
183# We test _get_default_tempdir by testing gettempdir.
184
185
186class test__get_candidate_names(TC):
187 """Test the internal function _get_candidate_names."""
188
189 def test_retval(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000190 # _get_candidate_names returns a _RandomNameSequence object
Guido van Rossum0e548712002-08-09 16:14:33 +0000191 obj = tempfile._get_candidate_names()
Ezio Melottie9615932010-01-24 19:26:24 +0000192 self.assertIsInstance(obj, tempfile._RandomNameSequence)
Guido van Rossum0e548712002-08-09 16:14:33 +0000193
194 def test_same_thing(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000195 # _get_candidate_names always returns the same object
Guido van Rossum0e548712002-08-09 16:14:33 +0000196 a = tempfile._get_candidate_names()
197 b = tempfile._get_candidate_names()
198
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000199 self.assertTrue(a is b)
Guido van Rossum0e548712002-08-09 16:14:33 +0000200
201test_classes.append(test__get_candidate_names)
202
203
204class test__mkstemp_inner(TC):
205 """Test the internal function _mkstemp_inner."""
206
207 class mkstemped:
208 _bflags = tempfile._bin_openflags
209 _tflags = tempfile._text_openflags
210 _close = os.close
211 _unlink = os.unlink
212
213 def __init__(self, dir, pre, suf, bin):
214 if bin: flags = self._bflags
215 else: flags = self._tflags
216
217 (self.fd, self.name) = tempfile._mkstemp_inner(dir, pre, suf, flags)
218
219 def write(self, str):
220 os.write(self.fd, str)
221
222 def __del__(self):
223 self._close(self.fd)
224 self._unlink(self.name)
Tim Petersa0d55de2002-08-09 18:01:01 +0000225
Guido van Rossum0e548712002-08-09 16:14:33 +0000226 def do_create(self, dir=None, pre="", suf="", bin=1):
227 if dir is None:
228 dir = tempfile.gettempdir()
229 try:
230 file = self.mkstemped(dir, pre, suf, bin)
231 except:
232 self.failOnException("_mkstemp_inner")
233
234 self.nameCheck(file.name, dir, pre, suf)
235 return file
236
237 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000238 # _mkstemp_inner can create files
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000239 self.do_create().write(b"blat")
240 self.do_create(pre="a").write(b"blat")
241 self.do_create(suf="b").write(b"blat")
242 self.do_create(pre="a", suf="b").write(b"blat")
243 self.do_create(pre="aa", suf=".txt").write(b"blat")
Guido van Rossum0e548712002-08-09 16:14:33 +0000244
245 def test_basic_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000246 # _mkstemp_inner can create many files (stochastic)
Guido van Rossum805365e2007-05-07 22:24:25 +0000247 extant = list(range(TEST_FILES))
Guido van Rossum0e548712002-08-09 16:14:33 +0000248 for i in extant:
249 extant[i] = self.do_create(pre="aa")
250
251 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000252 # _mkstemp_inner can create files in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000253 dir = tempfile.mkdtemp()
254 try:
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +0000255 self.do_create(dir=dir).write(b"blat")
Guido van Rossum0e548712002-08-09 16:14:33 +0000256 finally:
257 os.rmdir(dir)
258
259 def test_file_mode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000260 # _mkstemp_inner creates files with the proper mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000261 if not has_stat:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000262 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000263
264 file = self.do_create()
265 mode = stat.S_IMODE(os.stat(file.name).st_mode)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000266 expected = 0o600
Ronald Oussoren94f25282010-05-05 19:11:21 +0000267 if sys.platform in ('win32', 'os2emx'):
Tim Petersca3ac7f2002-08-09 18:13:51 +0000268 # There's no distinction among 'user', 'group' and 'world';
269 # replicate the 'user' bits.
270 user = expected >> 6
271 expected = user * (1 + 8 + 64)
272 self.assertEqual(mode, expected)
Guido van Rossum0e548712002-08-09 16:14:33 +0000273
274 def test_noinherit(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000275 # _mkstemp_inner file handles are not inherited by child processes
Guido van Rossum78741062002-08-17 11:41:01 +0000276 if not has_spawnl:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000277 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000278
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000279 if support.verbose:
Guido van Rossum78741062002-08-17 11:41:01 +0000280 v="v"
281 else:
282 v="q"
283
Guido van Rossum0e548712002-08-09 16:14:33 +0000284 file = self.do_create()
Guido van Rossum78741062002-08-17 11:41:01 +0000285 fd = "%d" % file.fd
286
287 try:
288 me = __file__
289 except NameError:
290 me = sys.argv[0]
Guido van Rossum0e548712002-08-09 16:14:33 +0000291
292 # We have to exec something, so that FD_CLOEXEC will take
Guido van Rossum78741062002-08-17 11:41:01 +0000293 # effect. The core of this test is therefore in
294 # tf_inherit_check.py, which see.
295 tester = os.path.join(os.path.dirname(os.path.abspath(me)),
296 "tf_inherit_check.py")
Guido van Rossum0e548712002-08-09 16:14:33 +0000297
Martin v. Löwisd4210bc2003-10-23 15:55:28 +0000298 # On Windows a spawn* /path/ with embedded spaces shouldn't be quoted,
299 # but an arg with embedded spaces should be decorated with double
300 # quotes on each end
Christian Heimes895627f2007-12-08 17:28:33 +0000301 if sys.platform in ('win32',):
Martin v. Löwisd4210bc2003-10-23 15:55:28 +0000302 decorated = '"%s"' % sys.executable
303 tester = '"%s"' % tester
304 else:
305 decorated = sys.executable
306
307 retval = os.spawnl(os.P_WAIT, sys.executable, decorated, tester, v, fd)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000308 self.assertFalse(retval < 0,
Guido van Rossum78741062002-08-17 11:41:01 +0000309 "child process caught fatal signal %d" % -retval)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000310 self.assertFalse(retval > 0, "child process reports failure %d"%retval)
Guido van Rossum0e548712002-08-09 16:14:33 +0000311
312 def test_textmode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000313 # _mkstemp_inner can create files in text mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000314 if not has_textmode:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000315 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000316
Amaury Forgeot d'Arc7d0bddd2009-11-30 00:08:56 +0000317 # A text file is truncated at the first Ctrl+Z byte
318 f = self.do_create(bin=0)
319 f.write(b"blat\x1a")
320 f.write(b"extra\n")
321 os.lseek(f.fd, 0, os.SEEK_SET)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000322 self.assertEqual(os.read(f.fd, 20), b"blat")
Guido van Rossum0e548712002-08-09 16:14:33 +0000323
324test_classes.append(test__mkstemp_inner)
325
326
327class test_gettempprefix(TC):
328 """Test gettempprefix()."""
329
330 def test_sane_template(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000331 # gettempprefix returns a nonempty prefix string
Guido van Rossum0e548712002-08-09 16:14:33 +0000332 p = tempfile.gettempprefix()
333
Ezio Melottie9615932010-01-24 19:26:24 +0000334 self.assertIsInstance(p, str)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000335 self.assertTrue(len(p) > 0)
Guido van Rossum0e548712002-08-09 16:14:33 +0000336
337 def test_usable_template(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000338 # gettempprefix returns a usable prefix string
Guido van Rossum0e548712002-08-09 16:14:33 +0000339
340 # Create a temp directory, avoiding use of the prefix.
341 # Then attempt to create a file whose name is
342 # prefix + 'xxxxxx.xxx' in that directory.
343 p = tempfile.gettempprefix() + "xxxxxx.xxx"
344 d = tempfile.mkdtemp(prefix="")
345 try:
346 p = os.path.join(d, p)
347 try:
348 fd = os.open(p, os.O_RDWR | os.O_CREAT)
349 except:
350 self.failOnException("os.open")
351 os.close(fd)
352 os.unlink(p)
353 finally:
354 os.rmdir(d)
355
356test_classes.append(test_gettempprefix)
357
358
359class test_gettempdir(TC):
360 """Test gettempdir()."""
361
362 def test_directory_exists(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000363 # gettempdir returns a directory which exists
Guido van Rossum0e548712002-08-09 16:14:33 +0000364
365 dir = tempfile.gettempdir()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000366 self.assertTrue(os.path.isabs(dir) or dir == os.curdir,
Guido van Rossum0e548712002-08-09 16:14:33 +0000367 "%s is not an absolute path" % dir)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000368 self.assertTrue(os.path.isdir(dir),
Guido van Rossum0e548712002-08-09 16:14:33 +0000369 "%s is not a directory" % dir)
370
371 def test_directory_writable(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000372 # gettempdir returns a directory writable by the user
Guido van Rossum0e548712002-08-09 16:14:33 +0000373
374 # sneaky: just instantiate a NamedTemporaryFile, which
375 # defaults to writing into the directory returned by
376 # gettempdir.
377 try:
378 file = tempfile.NamedTemporaryFile()
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000379 file.write(b"blat")
Guido van Rossum0e548712002-08-09 16:14:33 +0000380 file.close()
381 except:
382 self.failOnException("create file in %s" % tempfile.gettempdir())
383
384 def test_same_thing(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000385 # gettempdir always returns the same object
Guido van Rossum0e548712002-08-09 16:14:33 +0000386 a = tempfile.gettempdir()
387 b = tempfile.gettempdir()
388
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000389 self.assertTrue(a is b)
Guido van Rossum0e548712002-08-09 16:14:33 +0000390
391test_classes.append(test_gettempdir)
392
393
394class test_mkstemp(TC):
395 """Test mkstemp()."""
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000396
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000397 def do_create(self, dir=None, pre="", suf=""):
Guido van Rossum0e548712002-08-09 16:14:33 +0000398 if dir is None:
399 dir = tempfile.gettempdir()
400 try:
401 (fd, name) = tempfile.mkstemp(dir=dir, prefix=pre, suffix=suf)
Martin v. Löwisd6625482003-10-12 17:37:01 +0000402 (ndir, nbase) = os.path.split(name)
403 adir = os.path.abspath(dir)
404 self.assertEqual(adir, ndir,
405 "Directory '%s' incorrectly returned as '%s'" % (adir, ndir))
Guido van Rossum0e548712002-08-09 16:14:33 +0000406 except:
407 self.failOnException("mkstemp")
408
409 try:
410 self.nameCheck(name, dir, pre, suf)
411 finally:
412 os.close(fd)
413 os.unlink(name)
414
415 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000416 # mkstemp can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000417 self.do_create()
418 self.do_create(pre="a")
419 self.do_create(suf="b")
420 self.do_create(pre="a", suf="b")
421 self.do_create(pre="aa", suf=".txt")
Martin v. Löwisd6625482003-10-12 17:37:01 +0000422 self.do_create(dir=".")
Guido van Rossum0e548712002-08-09 16:14:33 +0000423
424 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000425 # mkstemp can create directories in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000426 dir = tempfile.mkdtemp()
427 try:
428 self.do_create(dir=dir)
429 finally:
430 os.rmdir(dir)
431
432test_classes.append(test_mkstemp)
433
434
435class test_mkdtemp(TC):
436 """Test mkdtemp()."""
437
438 def do_create(self, dir=None, pre="", suf=""):
439 if dir is None:
440 dir = tempfile.gettempdir()
441 try:
442 name = tempfile.mkdtemp(dir=dir, prefix=pre, suffix=suf)
443 except:
444 self.failOnException("mkdtemp")
445
446 try:
447 self.nameCheck(name, dir, pre, suf)
448 return name
449 except:
450 os.rmdir(name)
451 raise
452
453 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000454 # mkdtemp can create directories
Guido van Rossum0e548712002-08-09 16:14:33 +0000455 os.rmdir(self.do_create())
456 os.rmdir(self.do_create(pre="a"))
457 os.rmdir(self.do_create(suf="b"))
458 os.rmdir(self.do_create(pre="a", suf="b"))
459 os.rmdir(self.do_create(pre="aa", suf=".txt"))
Tim Petersa0d55de2002-08-09 18:01:01 +0000460
Guido van Rossum0e548712002-08-09 16:14:33 +0000461 def test_basic_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000462 # mkdtemp can create many directories (stochastic)
Guido van Rossum805365e2007-05-07 22:24:25 +0000463 extant = list(range(TEST_FILES))
Guido van Rossum0e548712002-08-09 16:14:33 +0000464 try:
465 for i in extant:
466 extant[i] = self.do_create(pre="aa")
467 finally:
468 for i in extant:
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000469 if(isinstance(i, str)):
Guido van Rossum0e548712002-08-09 16:14:33 +0000470 os.rmdir(i)
471
472 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000473 # mkdtemp can create directories in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000474 dir = tempfile.mkdtemp()
475 try:
476 os.rmdir(self.do_create(dir=dir))
477 finally:
478 os.rmdir(dir)
479
480 def test_mode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000481 # mkdtemp creates directories with the proper mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000482 if not has_stat:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000483 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000484
485 dir = self.do_create()
486 try:
487 mode = stat.S_IMODE(os.stat(dir).st_mode)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000488 mode &= 0o777 # Mask off sticky bits inherited from /tmp
489 expected = 0o700
Ronald Oussoren94f25282010-05-05 19:11:21 +0000490 if sys.platform in ('win32', 'os2emx'):
Tim Petersca3ac7f2002-08-09 18:13:51 +0000491 # There's no distinction among 'user', 'group' and 'world';
492 # replicate the 'user' bits.
493 user = expected >> 6
494 expected = user * (1 + 8 + 64)
495 self.assertEqual(mode, expected)
Guido van Rossum0e548712002-08-09 16:14:33 +0000496 finally:
497 os.rmdir(dir)
498
499test_classes.append(test_mkdtemp)
500
501
502class test_mktemp(TC):
503 """Test mktemp()."""
504
505 # For safety, all use of mktemp must occur in a private directory.
506 # We must also suppress the RuntimeWarning it generates.
507 def setUp(self):
508 self.dir = tempfile.mkdtemp()
Brett Cannone1adece2010-03-20 22:19:55 +0000509 super().setUp()
Guido van Rossum0e548712002-08-09 16:14:33 +0000510
511 def tearDown(self):
512 if self.dir:
513 os.rmdir(self.dir)
514 self.dir = None
Brett Cannone1adece2010-03-20 22:19:55 +0000515 super().tearDown()
Guido van Rossum0e548712002-08-09 16:14:33 +0000516
517 class mktemped:
518 _unlink = os.unlink
519 _bflags = tempfile._bin_openflags
520
521 def __init__(self, dir, pre, suf):
522 self.name = tempfile.mktemp(dir=dir, prefix=pre, suffix=suf)
523 # Create the file. This will raise an exception if it's
524 # mysteriously appeared in the meanwhile.
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000525 os.close(os.open(self.name, self._bflags, 0o600))
Guido van Rossum0e548712002-08-09 16:14:33 +0000526
527 def __del__(self):
528 self._unlink(self.name)
529
530 def do_create(self, pre="", suf=""):
531 try:
532 file = self.mktemped(self.dir, pre, suf)
533 except:
534 self.failOnException("mktemp")
535
536 self.nameCheck(file.name, self.dir, pre, suf)
537 return file
538
539 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000540 # mktemp can choose usable file names
Guido van Rossum0e548712002-08-09 16:14:33 +0000541 self.do_create()
542 self.do_create(pre="a")
543 self.do_create(suf="b")
544 self.do_create(pre="a", suf="b")
545 self.do_create(pre="aa", suf=".txt")
546
547 def test_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000548 # mktemp can choose many usable file names (stochastic)
Guido van Rossum805365e2007-05-07 22:24:25 +0000549 extant = list(range(TEST_FILES))
Guido van Rossum0e548712002-08-09 16:14:33 +0000550 for i in extant:
551 extant[i] = self.do_create(pre="aa")
552
Fred Drake8bec4832002-11-22 20:13:43 +0000553## def test_warning(self):
554## # mktemp issues a warning when used
555## warnings.filterwarnings("error",
556## category=RuntimeWarning,
557## message="mktemp")
558## self.assertRaises(RuntimeWarning,
559## tempfile.mktemp, dir=self.dir)
Guido van Rossum0e548712002-08-09 16:14:33 +0000560
561test_classes.append(test_mktemp)
562
563
564# We test _TemporaryFileWrapper by testing NamedTemporaryFile.
565
566
567class test_NamedTemporaryFile(TC):
568 """Test NamedTemporaryFile()."""
569
Guido van Rossumd8faa362007-04-27 19:54:29 +0000570 def do_create(self, dir=None, pre="", suf="", delete=True):
Guido van Rossum0e548712002-08-09 16:14:33 +0000571 if dir is None:
572 dir = tempfile.gettempdir()
573 try:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000574 file = tempfile.NamedTemporaryFile(dir=dir, prefix=pre, suffix=suf,
575 delete=delete)
Guido van Rossum0e548712002-08-09 16:14:33 +0000576 except:
577 self.failOnException("NamedTemporaryFile")
578
579 self.nameCheck(file.name, dir, pre, suf)
580 return file
581
582
583 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000584 # NamedTemporaryFile can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000585 self.do_create()
586 self.do_create(pre="a")
587 self.do_create(suf="b")
588 self.do_create(pre="a", suf="b")
589 self.do_create(pre="aa", suf=".txt")
590
591 def test_creates_named(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000592 # NamedTemporaryFile creates files with names
Guido van Rossum0e548712002-08-09 16:14:33 +0000593 f = tempfile.NamedTemporaryFile()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000594 self.assertTrue(os.path.exists(f.name),
Guido van Rossum0e548712002-08-09 16:14:33 +0000595 "NamedTemporaryFile %s does not exist" % f.name)
596
597 def test_del_on_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000598 # A NamedTemporaryFile is deleted when closed
Guido van Rossum0e548712002-08-09 16:14:33 +0000599 dir = tempfile.mkdtemp()
600 try:
601 f = tempfile.NamedTemporaryFile(dir=dir)
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000602 f.write(b'blat')
Guido van Rossum0e548712002-08-09 16:14:33 +0000603 f.close()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000604 self.assertFalse(os.path.exists(f.name),
Guido van Rossum0e548712002-08-09 16:14:33 +0000605 "NamedTemporaryFile %s exists after close" % f.name)
606 finally:
607 os.rmdir(dir)
608
Guido van Rossumd8faa362007-04-27 19:54:29 +0000609 def test_dis_del_on_close(self):
610 # Tests that delete-on-close can be disabled
611 dir = tempfile.mkdtemp()
612 tmp = None
613 try:
614 f = tempfile.NamedTemporaryFile(dir=dir, delete=False)
615 tmp = f.name
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000616 f.write(b'blat')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000617 f.close()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000618 self.assertTrue(os.path.exists(f.name),
Guido van Rossumd8faa362007-04-27 19:54:29 +0000619 "NamedTemporaryFile %s missing after close" % f.name)
620 finally:
621 if tmp is not None:
622 os.unlink(tmp)
623 os.rmdir(dir)
624
Guido van Rossum0e548712002-08-09 16:14:33 +0000625 def test_multiple_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000626 # A NamedTemporaryFile can be closed many times without error
Guido van Rossum0e548712002-08-09 16:14:33 +0000627 f = tempfile.NamedTemporaryFile()
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000628 f.write(b'abc\n')
Guido van Rossum0e548712002-08-09 16:14:33 +0000629 f.close()
630 try:
631 f.close()
632 f.close()
633 except:
634 self.failOnException("close")
635
Christian Heimes3ecfea712008-02-09 20:51:34 +0000636 def test_context_manager(self):
637 # A NamedTemporaryFile can be used as a context manager
638 with tempfile.NamedTemporaryFile() as f:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000639 self.assertTrue(os.path.exists(f.name))
640 self.assertFalse(os.path.exists(f.name))
Christian Heimes3ecfea712008-02-09 20:51:34 +0000641 def use_closed():
642 with f:
643 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000644 self.assertRaises(ValueError, use_closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000645
Guido van Rossum0e548712002-08-09 16:14:33 +0000646 # How to test the mode and bufsize parameters?
647
648test_classes.append(test_NamedTemporaryFile)
649
Guido van Rossumd8faa362007-04-27 19:54:29 +0000650class test_SpooledTemporaryFile(TC):
651 """Test SpooledTemporaryFile()."""
652
653 def do_create(self, max_size=0, dir=None, pre="", suf=""):
654 if dir is None:
655 dir = tempfile.gettempdir()
656 try:
657 file = tempfile.SpooledTemporaryFile(max_size=max_size, dir=dir, prefix=pre, suffix=suf)
658 except:
659 self.failOnException("SpooledTemporaryFile")
660
661 return file
662
663
664 def test_basic(self):
665 # SpooledTemporaryFile can create files
666 f = self.do_create()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000667 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000668 f = self.do_create(max_size=100, pre="a", suf=".txt")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000669 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000670
671 def test_del_on_close(self):
672 # A SpooledTemporaryFile is deleted when closed
673 dir = tempfile.mkdtemp()
674 try:
675 f = tempfile.SpooledTemporaryFile(max_size=10, dir=dir)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000676 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000677 f.write(b'blat ' * 5)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000678 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000679 filename = f.name
680 f.close()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000681 self.assertFalse(isinstance(filename, str) and os.path.exists(filename),
Guido van Rossumd8faa362007-04-27 19:54:29 +0000682 "SpooledTemporaryFile %s exists after close" % filename)
683 finally:
684 os.rmdir(dir)
685
686 def test_rewrite_small(self):
687 # A SpooledTemporaryFile can be written to multiple within the max_size
688 f = self.do_create(max_size=30)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000689 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000690 for i in range(5):
691 f.seek(0, 0)
Guido van Rossum39478e82007-08-27 17:23:59 +0000692 f.write(b'x' * 20)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000693 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000694
695 def test_write_sequential(self):
696 # A SpooledTemporaryFile should hold exactly max_size bytes, and roll
697 # over afterward
698 f = self.do_create(max_size=30)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000699 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000700 f.write(b'x' * 20)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000701 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000702 f.write(b'x' * 10)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000703 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000704 f.write(b'x')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000705 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000706
707 def test_sparse(self):
708 # A SpooledTemporaryFile that is written late in the file will extend
709 # when that occurs
710 f = self.do_create(max_size=30)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000711 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000712 f.seek(100, 0)
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')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000715 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000716
717 def test_fileno(self):
718 # A SpooledTemporaryFile should roll over to a real file on fileno()
719 f = self.do_create(max_size=30)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000720 self.assertFalse(f._rolled)
721 self.assertTrue(f.fileno() > 0)
722 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000723
Christian Heimes3ecfea712008-02-09 20:51:34 +0000724 def test_multiple_close_before_rollover(self):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000725 # A SpooledTemporaryFile can be closed many times without error
726 f = tempfile.SpooledTemporaryFile()
Guido van Rossum39478e82007-08-27 17:23:59 +0000727 f.write(b'abc\n')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000728 self.assertFalse(f._rolled)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000729 f.close()
730 try:
731 f.close()
732 f.close()
733 except:
734 self.failOnException("close")
735
736 def test_multiple_close_after_rollover(self):
737 # A SpooledTemporaryFile can be closed many times without error
738 f = tempfile.SpooledTemporaryFile(max_size=1)
739 f.write(b'abc\n')
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000740 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000741 f.close()
742 try:
743 f.close()
744 f.close()
745 except:
746 self.failOnException("close")
747
748 def test_bound_methods(self):
749 # It should be OK to steal a bound method from a SpooledTemporaryFile
750 # and use it independently; when the file rolls over, those bound
751 # methods should continue to function
752 f = self.do_create(max_size=30)
753 read = f.read
754 write = f.write
755 seek = f.seek
756
Guido van Rossum39478e82007-08-27 17:23:59 +0000757 write(b"a" * 35)
758 write(b"b" * 35)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000759 seek(0, 0)
Guido van Rossum9a634702007-07-09 10:24:45 +0000760 self.assertEqual(read(70), b'a'*35 + b'b'*35)
761
762 def test_text_mode(self):
763 # Creating a SpooledTemporaryFile with a text mode should produce
764 # a file object reading and writing (Unicode) text strings.
765 f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10)
766 f.write("abc\n")
767 f.seek(0)
768 self.assertEqual(f.read(), "abc\n")
769 f.write("def\n")
770 f.seek(0)
771 self.assertEqual(f.read(), "abc\ndef\n")
772 f.write("xyzzy\n")
773 f.seek(0)
774 self.assertEqual(f.read(), "abc\ndef\nxyzzy\n")
Amaury Forgeot d'Arc7d0bddd2009-11-30 00:08:56 +0000775 # Check that Ctrl+Z doesn't truncate the file
776 f.write("foo\x1abar\n")
777 f.seek(0)
778 self.assertEqual(f.read(), "abc\ndef\nxyzzy\nfoo\x1abar\n")
Guido van Rossum9a634702007-07-09 10:24:45 +0000779
Guido van Rossumf0c74162007-08-28 03:29:45 +0000780 def test_text_newline_and_encoding(self):
781 f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10,
782 newline='', encoding='utf-8')
783 f.write("\u039B\r\n")
784 f.seek(0)
785 self.assertEqual(f.read(), "\u039B\r\n")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000786 self.assertFalse(f._rolled)
Guido van Rossumf0c74162007-08-28 03:29:45 +0000787
788 f.write("\u039B" * 20 + "\r\n")
789 f.seek(0)
790 self.assertEqual(f.read(), "\u039B\r\n" + ("\u039B" * 20) + "\r\n")
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000791 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000792
Christian Heimes3ecfea712008-02-09 20:51:34 +0000793 def test_context_manager_before_rollover(self):
794 # A SpooledTemporaryFile can be used as a context manager
795 with tempfile.SpooledTemporaryFile(max_size=1) as f:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000796 self.assertFalse(f._rolled)
797 self.assertFalse(f.closed)
798 self.assertTrue(f.closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000799 def use_closed():
800 with f:
801 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000802 self.assertRaises(ValueError, use_closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000803
804 def test_context_manager_during_rollover(self):
805 # A SpooledTemporaryFile can be used as a context manager
806 with tempfile.SpooledTemporaryFile(max_size=1) as f:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000807 self.assertFalse(f._rolled)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000808 f.write(b'abc\n')
809 f.flush()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000810 self.assertTrue(f._rolled)
811 self.assertFalse(f.closed)
812 self.assertTrue(f.closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000813 def use_closed():
814 with f:
815 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000816 self.assertRaises(ValueError, use_closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000817
818 def test_context_manager_after_rollover(self):
819 # A SpooledTemporaryFile can be used as a context manager
820 f = tempfile.SpooledTemporaryFile(max_size=1)
821 f.write(b'abc\n')
822 f.flush()
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000823 self.assertTrue(f._rolled)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000824 with f:
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000825 self.assertFalse(f.closed)
826 self.assertTrue(f.closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000827 def use_closed():
828 with f:
829 pass
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000830 self.assertRaises(ValueError, use_closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000831
832
Guido van Rossumd8faa362007-04-27 19:54:29 +0000833test_classes.append(test_SpooledTemporaryFile)
834
Guido van Rossum0e548712002-08-09 16:14:33 +0000835
836class test_TemporaryFile(TC):
837 """Test TemporaryFile()."""
838
839 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000840 # TemporaryFile can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000841 # No point in testing the name params - the file has no name.
842 try:
843 tempfile.TemporaryFile()
844 except:
845 self.failOnException("TemporaryFile")
846
847 def test_has_no_name(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000848 # TemporaryFile creates files with no names (on this system)
Guido van Rossum0e548712002-08-09 16:14:33 +0000849 dir = tempfile.mkdtemp()
850 f = tempfile.TemporaryFile(dir=dir)
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000851 f.write(b'blat')
Guido van Rossum0e548712002-08-09 16:14:33 +0000852
853 # Sneaky: because this file has no name, it should not prevent
854 # us from removing the directory it was created in.
855 try:
856 os.rmdir(dir)
857 except:
858 ei = sys.exc_info()
859 # cleanup
860 f.close()
861 os.rmdir(dir)
862 self.failOnException("rmdir", ei)
863
864 def test_multiple_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000865 # A TemporaryFile can be closed many times without error
Guido van Rossum0e548712002-08-09 16:14:33 +0000866 f = tempfile.TemporaryFile()
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000867 f.write(b'abc\n')
Guido van Rossum0e548712002-08-09 16:14:33 +0000868 f.close()
869 try:
870 f.close()
871 f.close()
872 except:
873 self.failOnException("close")
874
875 # How to test the mode and bufsize parameters?
Guido van Rossumf0c74162007-08-28 03:29:45 +0000876 def test_mode_and_encoding(self):
877
878 def roundtrip(input, *args, **kwargs):
879 with tempfile.TemporaryFile(*args, **kwargs) as fileobj:
880 fileobj.write(input)
881 fileobj.seek(0)
Ezio Melottib3aedd42010-11-20 19:04:17 +0000882 self.assertEqual(input, fileobj.read())
Guido van Rossumf0c74162007-08-28 03:29:45 +0000883
884 roundtrip(b"1234", "w+b")
885 roundtrip("abdc\n", "w+")
886 roundtrip("\u039B", "w+", encoding="utf-16")
887 roundtrip("foo\r\n", "w+", newline="")
Guido van Rossum0e548712002-08-09 16:14:33 +0000888
Guido van Rossum0e548712002-08-09 16:14:33 +0000889
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000890if tempfile.NamedTemporaryFile is not tempfile.TemporaryFile:
Guido van Rossum0e548712002-08-09 16:14:33 +0000891 test_classes.append(test_TemporaryFile)
892
Nick Coghlan543af752010-10-24 11:23:25 +0000893
894# Helper for test_del_on_shutdown
895class NulledModules:
896 def __init__(self, *modules):
897 self.refs = [mod.__dict__ for mod in modules]
898 self.contents = [ref.copy() for ref in self.refs]
899
900 def __enter__(self):
901 for d in self.refs:
902 for key in d:
903 d[key] = None
904
905 def __exit__(self, *exc_info):
906 for d, c in zip(self.refs, self.contents):
907 d.clear()
908 d.update(c)
909
910class test_TemporaryDirectory(TC):
911 """Test TemporaryDirectory()."""
912
913 def do_create(self, dir=None, pre="", suf="", recurse=1):
914 if dir is None:
915 dir = tempfile.gettempdir()
916 try:
917 tmp = tempfile.TemporaryDirectory(dir=dir, prefix=pre, suffix=suf)
918 except:
919 self.failOnException("TemporaryDirectory")
920 self.nameCheck(tmp.name, dir, pre, suf)
921 # Create a subdirectory and some files
922 if recurse:
923 self.do_create(tmp.name, pre, suf, recurse-1)
924 with open(os.path.join(tmp.name, "test.txt"), "wb") as f:
925 f.write(b"Hello world!")
926 return tmp
927
Nick Coghlan6b22f3f2010-12-12 15:24:21 +0000928 def test_mkdtemp_failure(self):
929 # Check no additional exception if mkdtemp fails
930 # Previously would raise AttributeError instead
931 # (noted as part of Issue #10888)
932 #with self.assertRaises(os.error):
933 tempfile.TemporaryDirectory(prefix="[]<>?*!:")
934
Nick Coghlan543af752010-10-24 11:23:25 +0000935 def test_explicit_cleanup(self):
936 # A TemporaryDirectory is deleted when cleaned up
937 dir = tempfile.mkdtemp()
938 try:
939 d = self.do_create(dir=dir)
940 self.assertTrue(os.path.exists(d.name),
941 "TemporaryDirectory %s does not exist" % d.name)
942 d.cleanup()
943 self.assertFalse(os.path.exists(d.name),
944 "TemporaryDirectory %s exists after cleanup" % d.name)
945 finally:
946 os.rmdir(dir)
947
948 @support.cpython_only
949 def test_del_on_collection(self):
950 # A TemporaryDirectory is deleted when garbage collected
951 dir = tempfile.mkdtemp()
952 try:
953 d = self.do_create(dir=dir)
954 name = d.name
955 del d # Rely on refcounting to invoke __del__
956 self.assertFalse(os.path.exists(name),
957 "TemporaryDirectory %s exists after __del__" % name)
958 finally:
959 os.rmdir(dir)
960
961 @unittest.expectedFailure # See issue #10188
962 def test_del_on_shutdown(self):
963 # A TemporaryDirectory may be cleaned up during shutdown
964 # Make sure it works with the relevant modules nulled out
Nick Coghlan6b22f3f2010-12-12 15:24:21 +0000965 with self.do_create() as dir:
Nick Coghlan543af752010-10-24 11:23:25 +0000966 d = self.do_create(dir=dir)
967 # Mimic the nulling out of modules that
968 # occurs during system shutdown
969 modules = [os, os.path]
970 if has_stat:
971 modules.append(stat)
Nick Coghlan6b22f3f2010-12-12 15:24:21 +0000972 # Currently broken, so suppress the warning
973 # that is otherwise emitted on stdout
974 with support.captured_stderr() as err:
975 with NulledModules(*modules):
976 d.cleanup()
977 # Currently broken, so stop spurious exception by
978 # indicating the object has already been closed
979 d._closed = True
980 # And this assert will fail, as expected by the
981 # unittest decorator...
Nick Coghlan543af752010-10-24 11:23:25 +0000982 self.assertFalse(os.path.exists(d.name),
983 "TemporaryDirectory %s exists after cleanup" % d.name)
Nick Coghlan6b22f3f2010-12-12 15:24:21 +0000984
985 def test_warnings_on_cleanup(self):
986 # Two kinds of warning on shutdown
987 # Issue 10888: may write to stderr if modules are nulled out
988 # ResourceWarning will be triggered by __del__
989 with self.do_create() as dir:
990 d = self.do_create(dir=dir)
991
992 #Check for the Issue 10888 message
993 modules = [os, os.path]
994 if has_stat:
995 modules.append(stat)
996 with support.captured_stderr() as err:
997 with NulledModules(*modules):
998 d.cleanup()
999 message = err.getvalue()
1000 self.assertIn("while cleaning up", message)
1001 self.assertIn(d.name, message)
1002
1003 # Check for the resource warning
1004 with support.check_warnings(('Implicitly', ResourceWarning), quiet=False):
1005 warnings.filterwarnings("always", category=ResourceWarning)
1006 d.__del__()
1007 self.assertFalse(os.path.exists(d.name),
1008 "TemporaryDirectory %s exists after __del__" % d.name)
Nick Coghlan543af752010-10-24 11:23:25 +00001009
1010 def test_multiple_close(self):
1011 # Can be cleaned-up many times without error
1012 d = self.do_create()
1013 d.cleanup()
1014 try:
1015 d.cleanup()
1016 d.cleanup()
1017 except:
1018 self.failOnException("cleanup")
1019
1020 def test_context_manager(self):
1021 # Can be used as a context manager
1022 d = self.do_create()
1023 with d as name:
1024 self.assertTrue(os.path.exists(name))
1025 self.assertEqual(name, d.name)
1026 self.assertFalse(os.path.exists(name))
1027
1028
1029test_classes.append(test_TemporaryDirectory)
1030
Guido van Rossum0e548712002-08-09 16:14:33 +00001031def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001032 support.run_unittest(*test_classes)
Guido van Rossum0e548712002-08-09 16:14:33 +00001033
1034if __name__ == "__main__":
1035 test_main()