blob: f72b0b19c49d94d5feee3fd0a9c9902892c5cb86 [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
6import errno
7import warnings
Tim Petersc57a2852001-10-29 21:46:08 +00008
Guido van Rossum0e548712002-08-09 16:14:33 +00009import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +000010from test import support
Guido van Rossum0e548712002-08-09 16:14:33 +000011
Fred Drake7633d232002-10-17 22:09:03 +000012warnings.filterwarnings("ignore",
13 category=RuntimeWarning,
14 message="mktemp", module=__name__)
15
Guido van Rossum0e548712002-08-09 16:14:33 +000016if hasattr(os, 'stat'):
17 import stat
18 has_stat = 1
19else:
20 has_stat = 0
21
22has_textmode = (tempfile._text_openflags != tempfile._bin_openflags)
Guido van Rossum78741062002-08-17 11:41:01 +000023has_spawnl = hasattr(os, 'spawnl')
Guido van Rossum0e548712002-08-09 16:14:33 +000024
Neal Norwitz68ee0122002-08-16 19:28:59 +000025# TEST_FILES may need to be tweaked for systems depending on the maximum
26# number of files that can be opened at one time (see ulimit -n)
Jack Jansence921472003-01-08 16:30:34 +000027if sys.platform == 'mac':
28 TEST_FILES = 32
Thomas Wouters89f507f2006-12-13 04:49:30 +000029elif sys.platform in ('openbsd3', 'openbsd4'):
Martin v. Löwis99968282004-09-15 06:02:54 +000030 TEST_FILES = 48
Jack Jansence921472003-01-08 16:30:34 +000031else:
32 TEST_FILES = 100
Neal Norwitz68ee0122002-08-16 19:28:59 +000033
Guido van Rossum0e548712002-08-09 16:14:33 +000034# This is organized as one test for each chunk of code in tempfile.py,
35# in order of their appearance in the file. Testing which requires
36# threads is not done here.
37
38# Common functionality.
39class TC(unittest.TestCase):
40
41 str_check = re.compile(r"[a-zA-Z0-9_-]{6}$")
42
43 def failOnException(self, what, ei=None):
44 if ei is None:
45 ei = sys.exc_info()
46 self.fail("%s raised %s: %s" % (what, ei[0], ei[1]))
47
48 def nameCheck(self, name, dir, pre, suf):
49 (ndir, nbase) = os.path.split(name)
50 npre = nbase[:len(pre)]
51 nsuf = nbase[len(nbase)-len(suf):]
52
Martin v. Löwisd6625482003-10-12 17:37:01 +000053 # check for equality of the absolute paths!
54 self.assertEqual(os.path.abspath(ndir), os.path.abspath(dir),
Guido van Rossum0e548712002-08-09 16:14:33 +000055 "file '%s' not in directory '%s'" % (name, dir))
56 self.assertEqual(npre, pre,
57 "file '%s' does not begin with '%s'" % (nbase, pre))
58 self.assertEqual(nsuf, suf,
59 "file '%s' does not end with '%s'" % (nbase, suf))
60
61 nbase = nbase[len(pre):len(nbase)-len(suf)]
Georg Brandlab91fde2009-08-13 08:51:18 +000062 self.assertTrue(self.str_check.match(nbase),
Guido van Rossum0e548712002-08-09 16:14:33 +000063 "random string '%s' does not match /^[a-zA-Z0-9_-]{6}$/"
64 % nbase)
65
66test_classes = []
67
68class test_exports(TC):
69 def test_exports(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +000070 # There are no surprising symbols in the tempfile module
Guido van Rossum0e548712002-08-09 16:14:33 +000071 dict = tempfile.__dict__
72
73 expected = {
74 "NamedTemporaryFile" : 1,
75 "TemporaryFile" : 1,
76 "mkstemp" : 1,
77 "mkdtemp" : 1,
78 "mktemp" : 1,
79 "TMP_MAX" : 1,
80 "gettempprefix" : 1,
81 "gettempdir" : 1,
82 "tempdir" : 1,
Guido van Rossumd8faa362007-04-27 19:54:29 +000083 "template" : 1,
84 "SpooledTemporaryFile" : 1
Guido van Rossum0e548712002-08-09 16:14:33 +000085 }
86
87 unexp = []
88 for key in dict:
89 if key[0] != '_' and key not in expected:
90 unexp.append(key)
Georg Brandlab91fde2009-08-13 08:51:18 +000091 self.assertTrue(len(unexp) == 0,
Guido van Rossum0e548712002-08-09 16:14:33 +000092 "unexpected keys: %s" % unexp)
93
94test_classes.append(test_exports)
95
96
Guido van Rossum0e548712002-08-09 16:14:33 +000097class test__RandomNameSequence(TC):
98 """Test the internal iterator object _RandomNameSequence."""
99
100 def setUp(self):
101 self.r = tempfile._RandomNameSequence()
102
103 def test_get_six_char_str(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000104 # _RandomNameSequence returns a six-character string
Georg Brandla18af4e2007-04-21 15:47:16 +0000105 s = next(self.r)
Guido van Rossum0e548712002-08-09 16:14:33 +0000106 self.nameCheck(s, '', '', '')
107
108 def test_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000109 # _RandomNameSequence returns no duplicate strings (stochastic)
Guido van Rossum0e548712002-08-09 16:14:33 +0000110
111 dict = {}
112 r = self.r
Guido van Rossum805365e2007-05-07 22:24:25 +0000113 for i in range(TEST_FILES):
Georg Brandla18af4e2007-04-21 15:47:16 +0000114 s = next(r)
Guido van Rossum0e548712002-08-09 16:14:33 +0000115 self.nameCheck(s, '', '', '')
Georg Brandlab91fde2009-08-13 08:51:18 +0000116 self.assertFalse(s in dict)
Guido van Rossum0e548712002-08-09 16:14:33 +0000117 dict[s] = 1
118
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000119 def supports_iter(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000120 # _RandomNameSequence supports the iterator protocol
Guido van Rossum0e548712002-08-09 16:14:33 +0000121
122 i = 0
123 r = self.r
124 try:
125 for s in r:
126 i += 1
127 if i == 20:
128 break
129 except:
130 failOnException("iteration")
131
132test_classes.append(test__RandomNameSequence)
133
134
135class test__candidate_tempdir_list(TC):
136 """Test the internal function _candidate_tempdir_list."""
137
138 def test_nonempty_list(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000139 # _candidate_tempdir_list returns a nonempty list of strings
Guido van Rossum0e548712002-08-09 16:14:33 +0000140
141 cand = tempfile._candidate_tempdir_list()
142
Georg Brandlab91fde2009-08-13 08:51:18 +0000143 self.assertFalse(len(cand) == 0)
Guido van Rossum0e548712002-08-09 16:14:33 +0000144 for c in cand:
Georg Brandlab91fde2009-08-13 08:51:18 +0000145 self.assertTrue(isinstance(c, str),
Guido van Rossum0e548712002-08-09 16:14:33 +0000146 "%s is not a string" % c)
147
148 def test_wanted_dirs(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000149 # _candidate_tempdir_list contains the expected directories
Guido van Rossum0e548712002-08-09 16:14:33 +0000150
151 # Make sure the interesting environment variables are all set.
Hirokazu Yamamoto71959632009-04-27 01:44:28 +0000152 with support.EnvironmentVarGuard() as env:
Guido van Rossum0e548712002-08-09 16:14:33 +0000153 for envname in 'TMPDIR', 'TEMP', 'TMP':
154 dirname = os.getenv(envname)
155 if not dirname:
Walter Dörwald155374d2009-05-01 19:58:58 +0000156 env[envname] = os.path.abspath(envname)
Guido van Rossum0e548712002-08-09 16:14:33 +0000157
158 cand = tempfile._candidate_tempdir_list()
159
160 for envname in 'TMPDIR', 'TEMP', 'TMP':
161 dirname = os.getenv(envname)
162 if not dirname: raise ValueError
Georg Brandlab91fde2009-08-13 08:51:18 +0000163 self.assertTrue(dirname in cand)
Guido van Rossum0e548712002-08-09 16:14:33 +0000164
165 try:
166 dirname = os.getcwd()
167 except (AttributeError, os.error):
168 dirname = os.curdir
169
Georg Brandlab91fde2009-08-13 08:51:18 +0000170 self.assertTrue(dirname in cand)
Guido van Rossum0e548712002-08-09 16:14:33 +0000171
172 # Not practical to try to verify the presence of OS-specific
173 # paths in this list.
Guido van Rossum0e548712002-08-09 16:14:33 +0000174
175test_classes.append(test__candidate_tempdir_list)
176
177
178# We test _get_default_tempdir by testing gettempdir.
179
180
181class test__get_candidate_names(TC):
182 """Test the internal function _get_candidate_names."""
183
184 def test_retval(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000185 # _get_candidate_names returns a _RandomNameSequence object
Guido van Rossum0e548712002-08-09 16:14:33 +0000186 obj = tempfile._get_candidate_names()
Georg Brandlab91fde2009-08-13 08:51:18 +0000187 self.assertTrue(isinstance(obj, tempfile._RandomNameSequence))
Guido van Rossum0e548712002-08-09 16:14:33 +0000188
189 def test_same_thing(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000190 # _get_candidate_names always returns the same object
Guido van Rossum0e548712002-08-09 16:14:33 +0000191 a = tempfile._get_candidate_names()
192 b = tempfile._get_candidate_names()
193
Georg Brandlab91fde2009-08-13 08:51:18 +0000194 self.assertTrue(a is b)
Guido van Rossum0e548712002-08-09 16:14:33 +0000195
196test_classes.append(test__get_candidate_names)
197
198
199class test__mkstemp_inner(TC):
200 """Test the internal function _mkstemp_inner."""
201
202 class mkstemped:
203 _bflags = tempfile._bin_openflags
204 _tflags = tempfile._text_openflags
205 _close = os.close
206 _unlink = os.unlink
207
208 def __init__(self, dir, pre, suf, bin):
209 if bin: flags = self._bflags
210 else: flags = self._tflags
211
212 (self.fd, self.name) = tempfile._mkstemp_inner(dir, pre, suf, flags)
213
214 def write(self, str):
215 os.write(self.fd, str)
216
217 def __del__(self):
218 self._close(self.fd)
219 self._unlink(self.name)
Tim Petersa0d55de2002-08-09 18:01:01 +0000220
Guido van Rossum0e548712002-08-09 16:14:33 +0000221 def do_create(self, dir=None, pre="", suf="", bin=1):
222 if dir is None:
223 dir = tempfile.gettempdir()
224 try:
225 file = self.mkstemped(dir, pre, suf, bin)
226 except:
227 self.failOnException("_mkstemp_inner")
228
229 self.nameCheck(file.name, dir, pre, suf)
230 return file
231
232 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000233 # _mkstemp_inner can create files
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000234 self.do_create().write(b"blat")
235 self.do_create(pre="a").write(b"blat")
236 self.do_create(suf="b").write(b"blat")
237 self.do_create(pre="a", suf="b").write(b"blat")
238 self.do_create(pre="aa", suf=".txt").write(b"blat")
Guido van Rossum0e548712002-08-09 16:14:33 +0000239
240 def test_basic_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000241 # _mkstemp_inner can create many files (stochastic)
Guido van Rossum805365e2007-05-07 22:24:25 +0000242 extant = list(range(TEST_FILES))
Guido van Rossum0e548712002-08-09 16:14:33 +0000243 for i in extant:
244 extant[i] = self.do_create(pre="aa")
245
246 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000247 # _mkstemp_inner can create files in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000248 dir = tempfile.mkdtemp()
249 try:
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +0000250 self.do_create(dir=dir).write(b"blat")
Guido van Rossum0e548712002-08-09 16:14:33 +0000251 finally:
252 os.rmdir(dir)
253
254 def test_file_mode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000255 # _mkstemp_inner creates files with the proper mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000256 if not has_stat:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000257 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000258
259 file = self.do_create()
260 mode = stat.S_IMODE(os.stat(file.name).st_mode)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000261 expected = 0o600
Jack Jansence921472003-01-08 16:30:34 +0000262 if sys.platform in ('win32', 'os2emx', 'mac'):
Tim Petersca3ac7f2002-08-09 18:13:51 +0000263 # There's no distinction among 'user', 'group' and 'world';
264 # replicate the 'user' bits.
265 user = expected >> 6
266 expected = user * (1 + 8 + 64)
267 self.assertEqual(mode, expected)
Guido van Rossum0e548712002-08-09 16:14:33 +0000268
269 def test_noinherit(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000270 # _mkstemp_inner file handles are not inherited by child processes
Guido van Rossum78741062002-08-17 11:41:01 +0000271 if not has_spawnl:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000272 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000273
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000274 if support.verbose:
Guido van Rossum78741062002-08-17 11:41:01 +0000275 v="v"
276 else:
277 v="q"
278
Guido van Rossum0e548712002-08-09 16:14:33 +0000279 file = self.do_create()
Guido van Rossum78741062002-08-17 11:41:01 +0000280 fd = "%d" % file.fd
281
282 try:
283 me = __file__
284 except NameError:
285 me = sys.argv[0]
Guido van Rossum0e548712002-08-09 16:14:33 +0000286
287 # We have to exec something, so that FD_CLOEXEC will take
Guido van Rossum78741062002-08-17 11:41:01 +0000288 # effect. The core of this test is therefore in
289 # tf_inherit_check.py, which see.
290 tester = os.path.join(os.path.dirname(os.path.abspath(me)),
291 "tf_inherit_check.py")
Guido van Rossum0e548712002-08-09 16:14:33 +0000292
Martin v. Löwisd4210bc2003-10-23 15:55:28 +0000293 # On Windows a spawn* /path/ with embedded spaces shouldn't be quoted,
294 # but an arg with embedded spaces should be decorated with double
295 # quotes on each end
Christian Heimes895627f2007-12-08 17:28:33 +0000296 if sys.platform in ('win32',):
Martin v. Löwisd4210bc2003-10-23 15:55:28 +0000297 decorated = '"%s"' % sys.executable
298 tester = '"%s"' % tester
299 else:
300 decorated = sys.executable
301
302 retval = os.spawnl(os.P_WAIT, sys.executable, decorated, tester, v, fd)
Georg Brandlab91fde2009-08-13 08:51:18 +0000303 self.assertFalse(retval < 0,
Guido van Rossum78741062002-08-17 11:41:01 +0000304 "child process caught fatal signal %d" % -retval)
Georg Brandlab91fde2009-08-13 08:51:18 +0000305 self.assertFalse(retval > 0, "child process reports failure %d"%retval)
Guido van Rossum0e548712002-08-09 16:14:33 +0000306
307 def test_textmode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000308 # _mkstemp_inner can create files in text mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000309 if not has_textmode:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000310 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000311
Amaury Forgeot d'Arc36dfe782009-11-30 00:16:44 +0000312 # A text file is truncated at the first Ctrl+Z byte
313 f = self.do_create(bin=0)
314 f.write(b"blat\x1a")
315 f.write(b"extra\n")
316 os.lseek(f.fd, 0, os.SEEK_SET)
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000317 self.assertEqual(os.read(f.fd, 20), b"blat")
Guido van Rossum0e548712002-08-09 16:14:33 +0000318
319test_classes.append(test__mkstemp_inner)
320
321
322class test_gettempprefix(TC):
323 """Test gettempprefix()."""
324
325 def test_sane_template(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000326 # gettempprefix returns a nonempty prefix string
Guido van Rossum0e548712002-08-09 16:14:33 +0000327 p = tempfile.gettempprefix()
328
Georg Brandlab91fde2009-08-13 08:51:18 +0000329 self.assertTrue(isinstance(p, str))
330 self.assertTrue(len(p) > 0)
Guido van Rossum0e548712002-08-09 16:14:33 +0000331
332 def test_usable_template(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000333 # gettempprefix returns a usable prefix string
Guido van Rossum0e548712002-08-09 16:14:33 +0000334
335 # Create a temp directory, avoiding use of the prefix.
336 # Then attempt to create a file whose name is
337 # prefix + 'xxxxxx.xxx' in that directory.
338 p = tempfile.gettempprefix() + "xxxxxx.xxx"
339 d = tempfile.mkdtemp(prefix="")
340 try:
341 p = os.path.join(d, p)
342 try:
343 fd = os.open(p, os.O_RDWR | os.O_CREAT)
344 except:
345 self.failOnException("os.open")
346 os.close(fd)
347 os.unlink(p)
348 finally:
349 os.rmdir(d)
350
351test_classes.append(test_gettempprefix)
352
353
354class test_gettempdir(TC):
355 """Test gettempdir()."""
356
357 def test_directory_exists(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000358 # gettempdir returns a directory which exists
Guido van Rossum0e548712002-08-09 16:14:33 +0000359
360 dir = tempfile.gettempdir()
Georg Brandlab91fde2009-08-13 08:51:18 +0000361 self.assertTrue(os.path.isabs(dir) or dir == os.curdir,
Guido van Rossum0e548712002-08-09 16:14:33 +0000362 "%s is not an absolute path" % dir)
Georg Brandlab91fde2009-08-13 08:51:18 +0000363 self.assertTrue(os.path.isdir(dir),
Guido van Rossum0e548712002-08-09 16:14:33 +0000364 "%s is not a directory" % dir)
365
366 def test_directory_writable(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000367 # gettempdir returns a directory writable by the user
Guido van Rossum0e548712002-08-09 16:14:33 +0000368
369 # sneaky: just instantiate a NamedTemporaryFile, which
370 # defaults to writing into the directory returned by
371 # gettempdir.
372 try:
373 file = tempfile.NamedTemporaryFile()
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000374 file.write(b"blat")
Guido van Rossum0e548712002-08-09 16:14:33 +0000375 file.close()
376 except:
377 self.failOnException("create file in %s" % tempfile.gettempdir())
378
379 def test_same_thing(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000380 # gettempdir always returns the same object
Guido van Rossum0e548712002-08-09 16:14:33 +0000381 a = tempfile.gettempdir()
382 b = tempfile.gettempdir()
383
Georg Brandlab91fde2009-08-13 08:51:18 +0000384 self.assertTrue(a is b)
Guido van Rossum0e548712002-08-09 16:14:33 +0000385
386test_classes.append(test_gettempdir)
387
388
389class test_mkstemp(TC):
390 """Test mkstemp()."""
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000391
Thomas Wouters73e5a5b2006-06-08 15:35:45 +0000392 def do_create(self, dir=None, pre="", suf=""):
Guido van Rossum0e548712002-08-09 16:14:33 +0000393 if dir is None:
394 dir = tempfile.gettempdir()
395 try:
396 (fd, name) = tempfile.mkstemp(dir=dir, prefix=pre, suffix=suf)
Martin v. Löwisd6625482003-10-12 17:37:01 +0000397 (ndir, nbase) = os.path.split(name)
398 adir = os.path.abspath(dir)
399 self.assertEqual(adir, ndir,
400 "Directory '%s' incorrectly returned as '%s'" % (adir, ndir))
Guido van Rossum0e548712002-08-09 16:14:33 +0000401 except:
402 self.failOnException("mkstemp")
403
404 try:
405 self.nameCheck(name, dir, pre, suf)
406 finally:
407 os.close(fd)
408 os.unlink(name)
409
410 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000411 # mkstemp can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000412 self.do_create()
413 self.do_create(pre="a")
414 self.do_create(suf="b")
415 self.do_create(pre="a", suf="b")
416 self.do_create(pre="aa", suf=".txt")
Martin v. Löwisd6625482003-10-12 17:37:01 +0000417 self.do_create(dir=".")
Guido van Rossum0e548712002-08-09 16:14:33 +0000418
419 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000420 # mkstemp can create directories in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000421 dir = tempfile.mkdtemp()
422 try:
423 self.do_create(dir=dir)
424 finally:
425 os.rmdir(dir)
426
427test_classes.append(test_mkstemp)
428
429
430class test_mkdtemp(TC):
431 """Test mkdtemp()."""
432
433 def do_create(self, dir=None, pre="", suf=""):
434 if dir is None:
435 dir = tempfile.gettempdir()
436 try:
437 name = tempfile.mkdtemp(dir=dir, prefix=pre, suffix=suf)
438 except:
439 self.failOnException("mkdtemp")
440
441 try:
442 self.nameCheck(name, dir, pre, suf)
443 return name
444 except:
445 os.rmdir(name)
446 raise
447
448 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000449 # mkdtemp can create directories
Guido van Rossum0e548712002-08-09 16:14:33 +0000450 os.rmdir(self.do_create())
451 os.rmdir(self.do_create(pre="a"))
452 os.rmdir(self.do_create(suf="b"))
453 os.rmdir(self.do_create(pre="a", suf="b"))
454 os.rmdir(self.do_create(pre="aa", suf=".txt"))
Tim Petersa0d55de2002-08-09 18:01:01 +0000455
Guido van Rossum0e548712002-08-09 16:14:33 +0000456 def test_basic_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000457 # mkdtemp can create many directories (stochastic)
Guido van Rossum805365e2007-05-07 22:24:25 +0000458 extant = list(range(TEST_FILES))
Guido van Rossum0e548712002-08-09 16:14:33 +0000459 try:
460 for i in extant:
461 extant[i] = self.do_create(pre="aa")
462 finally:
463 for i in extant:
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000464 if(isinstance(i, str)):
Guido van Rossum0e548712002-08-09 16:14:33 +0000465 os.rmdir(i)
466
467 def test_choose_directory(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000468 # mkdtemp can create directories in a user-selected directory
Guido van Rossum0e548712002-08-09 16:14:33 +0000469 dir = tempfile.mkdtemp()
470 try:
471 os.rmdir(self.do_create(dir=dir))
472 finally:
473 os.rmdir(dir)
474
475 def test_mode(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000476 # mkdtemp creates directories with the proper mode
Guido van Rossum0e548712002-08-09 16:14:33 +0000477 if not has_stat:
Benjamin Petersone549ead2009-03-28 21:42:05 +0000478 return # ugh, can't use SkipTest.
Guido van Rossum0e548712002-08-09 16:14:33 +0000479
480 dir = self.do_create()
481 try:
482 mode = stat.S_IMODE(os.stat(dir).st_mode)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000483 mode &= 0o777 # Mask off sticky bits inherited from /tmp
484 expected = 0o700
Jack Jansence921472003-01-08 16:30:34 +0000485 if sys.platform in ('win32', 'os2emx', 'mac'):
Tim Petersca3ac7f2002-08-09 18:13:51 +0000486 # There's no distinction among 'user', 'group' and 'world';
487 # replicate the 'user' bits.
488 user = expected >> 6
489 expected = user * (1 + 8 + 64)
490 self.assertEqual(mode, expected)
Guido van Rossum0e548712002-08-09 16:14:33 +0000491 finally:
492 os.rmdir(dir)
493
494test_classes.append(test_mkdtemp)
495
496
497class test_mktemp(TC):
498 """Test mktemp()."""
499
500 # For safety, all use of mktemp must occur in a private directory.
501 # We must also suppress the RuntimeWarning it generates.
502 def setUp(self):
503 self.dir = tempfile.mkdtemp()
Guido van Rossum0e548712002-08-09 16:14:33 +0000504
505 def tearDown(self):
506 if self.dir:
507 os.rmdir(self.dir)
508 self.dir = None
Guido van Rossum0e548712002-08-09 16:14:33 +0000509
510 class mktemped:
511 _unlink = os.unlink
512 _bflags = tempfile._bin_openflags
513
514 def __init__(self, dir, pre, suf):
515 self.name = tempfile.mktemp(dir=dir, prefix=pre, suffix=suf)
516 # Create the file. This will raise an exception if it's
517 # mysteriously appeared in the meanwhile.
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000518 os.close(os.open(self.name, self._bflags, 0o600))
Guido van Rossum0e548712002-08-09 16:14:33 +0000519
520 def __del__(self):
521 self._unlink(self.name)
522
523 def do_create(self, pre="", suf=""):
524 try:
525 file = self.mktemped(self.dir, pre, suf)
526 except:
527 self.failOnException("mktemp")
528
529 self.nameCheck(file.name, self.dir, pre, suf)
530 return file
531
532 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000533 # mktemp can choose usable file names
Guido van Rossum0e548712002-08-09 16:14:33 +0000534 self.do_create()
535 self.do_create(pre="a")
536 self.do_create(suf="b")
537 self.do_create(pre="a", suf="b")
538 self.do_create(pre="aa", suf=".txt")
539
540 def test_many(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000541 # mktemp can choose many usable file names (stochastic)
Guido van Rossum805365e2007-05-07 22:24:25 +0000542 extant = list(range(TEST_FILES))
Guido van Rossum0e548712002-08-09 16:14:33 +0000543 for i in extant:
544 extant[i] = self.do_create(pre="aa")
545
Fred Drake8bec4832002-11-22 20:13:43 +0000546## def test_warning(self):
547## # mktemp issues a warning when used
548## warnings.filterwarnings("error",
549## category=RuntimeWarning,
550## message="mktemp")
551## self.assertRaises(RuntimeWarning,
552## tempfile.mktemp, dir=self.dir)
Guido van Rossum0e548712002-08-09 16:14:33 +0000553
554test_classes.append(test_mktemp)
555
556
557# We test _TemporaryFileWrapper by testing NamedTemporaryFile.
558
559
560class test_NamedTemporaryFile(TC):
561 """Test NamedTemporaryFile()."""
562
Guido van Rossumd8faa362007-04-27 19:54:29 +0000563 def do_create(self, dir=None, pre="", suf="", delete=True):
Guido van Rossum0e548712002-08-09 16:14:33 +0000564 if dir is None:
565 dir = tempfile.gettempdir()
566 try:
Guido van Rossumd8faa362007-04-27 19:54:29 +0000567 file = tempfile.NamedTemporaryFile(dir=dir, prefix=pre, suffix=suf,
568 delete=delete)
Guido van Rossum0e548712002-08-09 16:14:33 +0000569 except:
570 self.failOnException("NamedTemporaryFile")
571
572 self.nameCheck(file.name, dir, pre, suf)
573 return file
574
575
576 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000577 # NamedTemporaryFile can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000578 self.do_create()
579 self.do_create(pre="a")
580 self.do_create(suf="b")
581 self.do_create(pre="a", suf="b")
582 self.do_create(pre="aa", suf=".txt")
583
584 def test_creates_named(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000585 # NamedTemporaryFile creates files with names
Guido van Rossum0e548712002-08-09 16:14:33 +0000586 f = tempfile.NamedTemporaryFile()
Georg Brandlab91fde2009-08-13 08:51:18 +0000587 self.assertTrue(os.path.exists(f.name),
Guido van Rossum0e548712002-08-09 16:14:33 +0000588 "NamedTemporaryFile %s does not exist" % f.name)
589
590 def test_del_on_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000591 # A NamedTemporaryFile is deleted when closed
Guido van Rossum0e548712002-08-09 16:14:33 +0000592 dir = tempfile.mkdtemp()
593 try:
594 f = tempfile.NamedTemporaryFile(dir=dir)
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000595 f.write(b'blat')
Guido van Rossum0e548712002-08-09 16:14:33 +0000596 f.close()
Georg Brandlab91fde2009-08-13 08:51:18 +0000597 self.assertFalse(os.path.exists(f.name),
Guido van Rossum0e548712002-08-09 16:14:33 +0000598 "NamedTemporaryFile %s exists after close" % f.name)
599 finally:
600 os.rmdir(dir)
601
Guido van Rossumd8faa362007-04-27 19:54:29 +0000602 def test_dis_del_on_close(self):
603 # Tests that delete-on-close can be disabled
604 dir = tempfile.mkdtemp()
605 tmp = None
606 try:
607 f = tempfile.NamedTemporaryFile(dir=dir, delete=False)
608 tmp = f.name
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000609 f.write(b'blat')
Guido van Rossumd8faa362007-04-27 19:54:29 +0000610 f.close()
Georg Brandlab91fde2009-08-13 08:51:18 +0000611 self.assertTrue(os.path.exists(f.name),
Guido van Rossumd8faa362007-04-27 19:54:29 +0000612 "NamedTemporaryFile %s missing after close" % f.name)
613 finally:
614 if tmp is not None:
615 os.unlink(tmp)
616 os.rmdir(dir)
617
Guido van Rossum0e548712002-08-09 16:14:33 +0000618 def test_multiple_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000619 # A NamedTemporaryFile can be closed many times without error
Guido van Rossum0e548712002-08-09 16:14:33 +0000620 f = tempfile.NamedTemporaryFile()
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000621 f.write(b'abc\n')
Guido van Rossum0e548712002-08-09 16:14:33 +0000622 f.close()
623 try:
624 f.close()
625 f.close()
626 except:
627 self.failOnException("close")
628
Christian Heimes3ecfea712008-02-09 20:51:34 +0000629 def test_context_manager(self):
630 # A NamedTemporaryFile can be used as a context manager
631 with tempfile.NamedTemporaryFile() as f:
Georg Brandlab91fde2009-08-13 08:51:18 +0000632 self.assertTrue(os.path.exists(f.name))
633 self.assertFalse(os.path.exists(f.name))
Christian Heimes3ecfea712008-02-09 20:51:34 +0000634 def use_closed():
635 with f:
636 pass
Georg Brandlab91fde2009-08-13 08:51:18 +0000637 self.assertRaises(ValueError, use_closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000638
Guido van Rossum0e548712002-08-09 16:14:33 +0000639 # How to test the mode and bufsize parameters?
640
641test_classes.append(test_NamedTemporaryFile)
642
Guido van Rossumd8faa362007-04-27 19:54:29 +0000643class test_SpooledTemporaryFile(TC):
644 """Test SpooledTemporaryFile()."""
645
646 def do_create(self, max_size=0, dir=None, pre="", suf=""):
647 if dir is None:
648 dir = tempfile.gettempdir()
649 try:
650 file = tempfile.SpooledTemporaryFile(max_size=max_size, dir=dir, prefix=pre, suffix=suf)
651 except:
652 self.failOnException("SpooledTemporaryFile")
653
654 return file
655
656
657 def test_basic(self):
658 # SpooledTemporaryFile can create files
659 f = self.do_create()
Georg Brandlab91fde2009-08-13 08:51:18 +0000660 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000661 f = self.do_create(max_size=100, pre="a", suf=".txt")
Georg Brandlab91fde2009-08-13 08:51:18 +0000662 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000663
664 def test_del_on_close(self):
665 # A SpooledTemporaryFile is deleted when closed
666 dir = tempfile.mkdtemp()
667 try:
668 f = tempfile.SpooledTemporaryFile(max_size=10, dir=dir)
Georg Brandlab91fde2009-08-13 08:51:18 +0000669 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000670 f.write(b'blat ' * 5)
Georg Brandlab91fde2009-08-13 08:51:18 +0000671 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000672 filename = f.name
673 f.close()
Georg Brandlab91fde2009-08-13 08:51:18 +0000674 self.assertFalse(isinstance(filename, str) and os.path.exists(filename),
Guido van Rossumd8faa362007-04-27 19:54:29 +0000675 "SpooledTemporaryFile %s exists after close" % filename)
676 finally:
677 os.rmdir(dir)
678
679 def test_rewrite_small(self):
680 # A SpooledTemporaryFile can be written to multiple within the max_size
681 f = self.do_create(max_size=30)
Georg Brandlab91fde2009-08-13 08:51:18 +0000682 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000683 for i in range(5):
684 f.seek(0, 0)
Guido van Rossum39478e82007-08-27 17:23:59 +0000685 f.write(b'x' * 20)
Georg Brandlab91fde2009-08-13 08:51:18 +0000686 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000687
688 def test_write_sequential(self):
689 # A SpooledTemporaryFile should hold exactly max_size bytes, and roll
690 # over afterward
691 f = self.do_create(max_size=30)
Georg Brandlab91fde2009-08-13 08:51:18 +0000692 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000693 f.write(b'x' * 20)
Georg Brandlab91fde2009-08-13 08:51:18 +0000694 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000695 f.write(b'x' * 10)
Georg Brandlab91fde2009-08-13 08:51:18 +0000696 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000697 f.write(b'x')
Georg Brandlab91fde2009-08-13 08:51:18 +0000698 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000699
R David Murrayd89ee792011-03-14 09:55:46 -0400700 def test_writelines(self):
701 # Verify writelines with a SpooledTemporaryFile
702 f = self.do_create()
703 f.writelines((b'x', b'y', b'z'))
704 f.seek(0)
705 buf = f.read()
706 self.assertEqual(buf, b'xyz')
707
708 def test_writelines_sequential(self):
709 # A SpooledTemporaryFile should hold exactly max_size bytes, and roll
710 # over afterward
711 f = self.do_create(max_size=35)
712 f.writelines((b'x' * 20, b'x' * 10, b'x' * 5))
713 self.assertFalse(f._rolled)
714 f.write(b'x')
715 self.assertTrue(f._rolled)
716
Guido van Rossumd8faa362007-04-27 19:54:29 +0000717 def test_sparse(self):
718 # A SpooledTemporaryFile that is written late in the file will extend
719 # when that occurs
720 f = self.do_create(max_size=30)
Georg Brandlab91fde2009-08-13 08:51:18 +0000721 self.assertFalse(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000722 f.seek(100, 0)
Georg Brandlab91fde2009-08-13 08:51:18 +0000723 self.assertFalse(f._rolled)
Guido van Rossum39478e82007-08-27 17:23:59 +0000724 f.write(b'x')
Georg Brandlab91fde2009-08-13 08:51:18 +0000725 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000726
727 def test_fileno(self):
728 # A SpooledTemporaryFile should roll over to a real file on fileno()
729 f = self.do_create(max_size=30)
Georg Brandlab91fde2009-08-13 08:51:18 +0000730 self.assertFalse(f._rolled)
731 self.assertTrue(f.fileno() > 0)
732 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000733
Christian Heimes3ecfea712008-02-09 20:51:34 +0000734 def test_multiple_close_before_rollover(self):
Guido van Rossumd8faa362007-04-27 19:54:29 +0000735 # A SpooledTemporaryFile can be closed many times without error
736 f = tempfile.SpooledTemporaryFile()
Guido van Rossum39478e82007-08-27 17:23:59 +0000737 f.write(b'abc\n')
Georg Brandlab91fde2009-08-13 08:51:18 +0000738 self.assertFalse(f._rolled)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000739 f.close()
740 try:
741 f.close()
742 f.close()
743 except:
744 self.failOnException("close")
745
746 def test_multiple_close_after_rollover(self):
747 # A SpooledTemporaryFile can be closed many times without error
748 f = tempfile.SpooledTemporaryFile(max_size=1)
749 f.write(b'abc\n')
Georg Brandlab91fde2009-08-13 08:51:18 +0000750 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000751 f.close()
752 try:
753 f.close()
754 f.close()
755 except:
756 self.failOnException("close")
757
758 def test_bound_methods(self):
759 # It should be OK to steal a bound method from a SpooledTemporaryFile
760 # and use it independently; when the file rolls over, those bound
761 # methods should continue to function
762 f = self.do_create(max_size=30)
763 read = f.read
764 write = f.write
765 seek = f.seek
766
Guido van Rossum39478e82007-08-27 17:23:59 +0000767 write(b"a" * 35)
768 write(b"b" * 35)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000769 seek(0, 0)
Guido van Rossum9a634702007-07-09 10:24:45 +0000770 self.assertEqual(read(70), b'a'*35 + b'b'*35)
771
772 def test_text_mode(self):
773 # Creating a SpooledTemporaryFile with a text mode should produce
774 # a file object reading and writing (Unicode) text strings.
775 f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10)
776 f.write("abc\n")
777 f.seek(0)
778 self.assertEqual(f.read(), "abc\n")
779 f.write("def\n")
780 f.seek(0)
781 self.assertEqual(f.read(), "abc\ndef\n")
782 f.write("xyzzy\n")
783 f.seek(0)
784 self.assertEqual(f.read(), "abc\ndef\nxyzzy\n")
Amaury Forgeot d'Arc36dfe782009-11-30 00:16:44 +0000785 # Check that Ctrl+Z doesn't truncate the file
786 f.write("foo\x1abar\n")
787 f.seek(0)
788 self.assertEqual(f.read(), "abc\ndef\nxyzzy\nfoo\x1abar\n")
Guido van Rossum9a634702007-07-09 10:24:45 +0000789
Guido van Rossumf0c74162007-08-28 03:29:45 +0000790 def test_text_newline_and_encoding(self):
791 f = tempfile.SpooledTemporaryFile(mode='w+', max_size=10,
792 newline='', encoding='utf-8')
793 f.write("\u039B\r\n")
794 f.seek(0)
795 self.assertEqual(f.read(), "\u039B\r\n")
Georg Brandlab91fde2009-08-13 08:51:18 +0000796 self.assertFalse(f._rolled)
Guido van Rossumf0c74162007-08-28 03:29:45 +0000797
798 f.write("\u039B" * 20 + "\r\n")
799 f.seek(0)
800 self.assertEqual(f.read(), "\u039B\r\n" + ("\u039B" * 20) + "\r\n")
Georg Brandlab91fde2009-08-13 08:51:18 +0000801 self.assertTrue(f._rolled)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000802
Christian Heimes3ecfea712008-02-09 20:51:34 +0000803 def test_context_manager_before_rollover(self):
804 # A SpooledTemporaryFile can be used as a context manager
805 with tempfile.SpooledTemporaryFile(max_size=1) as f:
Georg Brandlab91fde2009-08-13 08:51:18 +0000806 self.assertFalse(f._rolled)
807 self.assertFalse(f.closed)
808 self.assertTrue(f.closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000809 def use_closed():
810 with f:
811 pass
Georg Brandlab91fde2009-08-13 08:51:18 +0000812 self.assertRaises(ValueError, use_closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000813
814 def test_context_manager_during_rollover(self):
815 # A SpooledTemporaryFile can be used as a context manager
816 with tempfile.SpooledTemporaryFile(max_size=1) as f:
Georg Brandlab91fde2009-08-13 08:51:18 +0000817 self.assertFalse(f._rolled)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000818 f.write(b'abc\n')
819 f.flush()
Georg Brandlab91fde2009-08-13 08:51:18 +0000820 self.assertTrue(f._rolled)
821 self.assertFalse(f.closed)
822 self.assertTrue(f.closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000823 def use_closed():
824 with f:
825 pass
Georg Brandlab91fde2009-08-13 08:51:18 +0000826 self.assertRaises(ValueError, use_closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000827
828 def test_context_manager_after_rollover(self):
829 # A SpooledTemporaryFile can be used as a context manager
830 f = tempfile.SpooledTemporaryFile(max_size=1)
831 f.write(b'abc\n')
832 f.flush()
Georg Brandlab91fde2009-08-13 08:51:18 +0000833 self.assertTrue(f._rolled)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000834 with f:
Georg Brandlab91fde2009-08-13 08:51:18 +0000835 self.assertFalse(f.closed)
836 self.assertTrue(f.closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000837 def use_closed():
838 with f:
839 pass
Georg Brandlab91fde2009-08-13 08:51:18 +0000840 self.assertRaises(ValueError, use_closed)
Christian Heimes3ecfea712008-02-09 20:51:34 +0000841
842
Guido van Rossumd8faa362007-04-27 19:54:29 +0000843test_classes.append(test_SpooledTemporaryFile)
844
Guido van Rossum0e548712002-08-09 16:14:33 +0000845
846class test_TemporaryFile(TC):
847 """Test TemporaryFile()."""
848
849 def test_basic(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000850 # TemporaryFile can create files
Guido van Rossum0e548712002-08-09 16:14:33 +0000851 # No point in testing the name params - the file has no name.
852 try:
853 tempfile.TemporaryFile()
854 except:
855 self.failOnException("TemporaryFile")
856
857 def test_has_no_name(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000858 # TemporaryFile creates files with no names (on this system)
Guido van Rossum0e548712002-08-09 16:14:33 +0000859 dir = tempfile.mkdtemp()
860 f = tempfile.TemporaryFile(dir=dir)
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000861 f.write(b'blat')
Guido van Rossum0e548712002-08-09 16:14:33 +0000862
863 # Sneaky: because this file has no name, it should not prevent
864 # us from removing the directory it was created in.
865 try:
866 os.rmdir(dir)
867 except:
868 ei = sys.exc_info()
869 # cleanup
870 f.close()
871 os.rmdir(dir)
872 self.failOnException("rmdir", ei)
873
874 def test_multiple_close(self):
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000875 # A TemporaryFile can be closed many times without error
Guido van Rossum0e548712002-08-09 16:14:33 +0000876 f = tempfile.TemporaryFile()
Guido van Rossumec42ffd2007-08-27 23:40:36 +0000877 f.write(b'abc\n')
Guido van Rossum0e548712002-08-09 16:14:33 +0000878 f.close()
879 try:
880 f.close()
881 f.close()
882 except:
883 self.failOnException("close")
884
885 # How to test the mode and bufsize parameters?
Guido van Rossumf0c74162007-08-28 03:29:45 +0000886 def test_mode_and_encoding(self):
887
888 def roundtrip(input, *args, **kwargs):
889 with tempfile.TemporaryFile(*args, **kwargs) as fileobj:
890 fileobj.write(input)
891 fileobj.seek(0)
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000892 self.assertEqual(input, fileobj.read())
Guido van Rossumf0c74162007-08-28 03:29:45 +0000893
894 roundtrip(b"1234", "w+b")
895 roundtrip("abdc\n", "w+")
896 roundtrip("\u039B", "w+", encoding="utf-16")
897 roundtrip("foo\r\n", "w+", newline="")
Guido van Rossum0e548712002-08-09 16:14:33 +0000898
Guido van Rossum0e548712002-08-09 16:14:33 +0000899
Guido van Rossum8ccd9b62002-08-22 20:02:03 +0000900if tempfile.NamedTemporaryFile is not tempfile.TemporaryFile:
Guido van Rossum0e548712002-08-09 16:14:33 +0000901 test_classes.append(test_TemporaryFile)
902
903def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000904 support.run_unittest(*test_classes)
Guido van Rossum0e548712002-08-09 16:14:33 +0000905
906if __name__ == "__main__":
907 test_main()