1 # tempfile.py unit tests.
10 from test
import test_support
12 warnings
.filterwarnings("ignore",
13 category
=RuntimeWarning,
14 message
="mktemp", module
=__name__
)
16 if hasattr(os
, 'stat'):
22 has_textmode
= (tempfile
._text
_openflags
!= tempfile
._bin
_openflags
)
23 has_spawnl
= hasattr(os
, 'spawnl')
25 # 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)
27 if sys
.platform
== 'mac':
29 elif sys
.platform
in ('openbsd3', 'openbsd4'):
34 # 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.
38 # Common functionality.
39 class TC(unittest
.TestCase
):
41 str_check
= re
.compile(r
"[a-zA-Z0-9_-]{6}$")
43 def failOnException(self
, what
, ei
=None):
46 self
.fail("%s raised %s: %s" % (what
, ei
[0], ei
[1]))
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
):]
53 # check for equality of the absolute paths!
54 self
.assertEqual(os
.path
.abspath(ndir
), os
.path
.abspath(dir),
55 "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
))
61 nbase
= nbase
[len(pre
):len(nbase
)-len(suf
)]
62 self
.assertTrue(self
.str_check
.match(nbase
),
63 "random string '%s' does not match /^[a-zA-Z0-9_-]{6}$/"
68 class test_exports(TC
):
69 def test_exports(self
):
70 # There are no surprising symbols in the tempfile module
71 dict = tempfile
.__dict
__
74 "NamedTemporaryFile" : 1,
84 "SpooledTemporaryFile" : 1
89 if key
[0] != '_' and key
not in expected
:
91 self
.assertTrue(len(unexp
) == 0,
92 "unexpected keys: %s" % unexp
)
94 test_classes
.append(test_exports
)
97 class test__RandomNameSequence(TC
):
98 """Test the internal iterator object _RandomNameSequence."""
101 self
.r
= tempfile
._RandomNameSequence
()
103 def test_get_six_char_str(self
):
104 # _RandomNameSequence returns a six-character string
106 self
.nameCheck(s
, '', '', '')
109 # _RandomNameSequence returns no duplicate strings (stochastic)
113 for i
in xrange(TEST_FILES
):
115 self
.nameCheck(s
, '', '', '')
116 self
.assertFalse(s
in dict)
119 def test_supports_iter(self
):
120 # _RandomNameSequence supports the iterator protocol
130 failOnException("iteration")
132 test_classes
.append(test__RandomNameSequence
)
135 class test__candidate_tempdir_list(TC
):
136 """Test the internal function _candidate_tempdir_list."""
138 def test_nonempty_list(self
):
139 # _candidate_tempdir_list returns a nonempty list of strings
141 cand
= tempfile
._candidate
_tempdir
_list
()
143 self
.assertFalse(len(cand
) == 0)
145 self
.assertTrue(isinstance(c
, basestring
),
146 "%s is not a string" % c
)
148 def test_wanted_dirs(self
):
149 # _candidate_tempdir_list contains the expected directories
151 # Make sure the interesting environment variables are all set.
152 with test_support
.EnvironmentVarGuard() as env
:
153 for envname
in 'TMPDIR', 'TEMP', 'TMP':
154 dirname
= os
.getenv(envname
)
156 env
[envname
] = os
.path
.abspath(envname
)
158 cand
= tempfile
._candidate
_tempdir
_list
()
160 for envname
in 'TMPDIR', 'TEMP', 'TMP':
161 dirname
= os
.getenv(envname
)
162 if not dirname
: raise ValueError
163 self
.assertTrue(dirname
in cand
)
166 dirname
= os
.getcwd()
167 except (AttributeError, os
.error
):
170 self
.assertTrue(dirname
in cand
)
172 # Not practical to try to verify the presence of OS-specific
173 # paths in this list.
175 test_classes
.append(test__candidate_tempdir_list
)
178 # We test _get_default_tempdir by testing gettempdir.
181 class test__get_candidate_names(TC
):
182 """Test the internal function _get_candidate_names."""
184 def test_retval(self
):
185 # _get_candidate_names returns a _RandomNameSequence object
186 obj
= tempfile
._get
_candidate
_names
()
187 self
.assertTrue(isinstance(obj
, tempfile
._RandomNameSequence
))
189 def test_same_thing(self
):
190 # _get_candidate_names always returns the same object
191 a
= tempfile
._get
_candidate
_names
()
192 b
= tempfile
._get
_candidate
_names
()
194 self
.assertTrue(a
is b
)
196 test_classes
.append(test__get_candidate_names
)
199 class test__mkstemp_inner(TC
):
200 """Test the internal function _mkstemp_inner."""
203 _bflags
= tempfile
._bin
_openflags
204 _tflags
= tempfile
._text
_openflags
208 def __init__(self
, dir, pre
, suf
, bin
):
209 if bin
: flags
= self
._bflags
210 else: flags
= self
._tflags
212 (self
.fd
, self
.name
) = tempfile
._mkstemp
_inner
(dir, pre
, suf
, flags
)
214 def write(self
, str):
215 os
.write(self
.fd
, str)
219 self
._unlink
(self
.name
)
221 def do_create(self
, dir=None, pre
="", suf
="", bin
=1):
223 dir = tempfile
.gettempdir()
225 file = self
.mkstemped(dir, pre
, suf
, bin
)
227 self
.failOnException("_mkstemp_inner")
229 self
.nameCheck(file.name
, dir, pre
, suf
)
232 def test_basic(self
):
233 # _mkstemp_inner can create files
234 self
.do_create().write("blat")
235 self
.do_create(pre
="a").write("blat")
236 self
.do_create(suf
="b").write("blat")
237 self
.do_create(pre
="a", suf
="b").write("blat")
238 self
.do_create(pre
="aa", suf
=".txt").write("blat")
240 def test_basic_many(self
):
241 # _mkstemp_inner can create many files (stochastic)
242 extant
= range(TEST_FILES
)
244 extant
[i
] = self
.do_create(pre
="aa")
246 def test_choose_directory(self
):
247 # _mkstemp_inner can create files in a user-selected directory
248 dir = tempfile
.mkdtemp()
250 self
.do_create(dir=dir).write("blat")
254 def test_file_mode(self
):
255 # _mkstemp_inner creates files with the proper mode
257 return # ugh, can't use SkipTest.
259 file = self
.do_create()
260 mode
= stat
.S_IMODE(os
.stat(file.name
).st_mode
)
262 if sys
.platform
in ('win32', 'os2emx', 'mac'):
263 # There's no distinction among 'user', 'group' and 'world';
264 # replicate the 'user' bits.
266 expected
= user
* (1 + 8 + 64)
267 self
.assertEqual(mode
, expected
)
269 def test_noinherit(self
):
270 # _mkstemp_inner file handles are not inherited by child processes
272 return # ugh, can't use SkipTest.
274 if test_support
.verbose
:
279 file = self
.do_create()
287 # We have to exec something, so that FD_CLOEXEC will take
288 # 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")
293 # On Windows a spawn* /path/ with embedded spaces shouldn't be quoted,
294 # but an arg with embedded spaces should be decorated with double
296 if sys
.platform
in ('win32',):
297 decorated
= '"%s"' % sys
.executable
298 tester
= '"%s"' % tester
300 decorated
= sys
.executable
302 retval
= os
.spawnl(os
.P_WAIT
, sys
.executable
, decorated
, tester
, v
, fd
)
303 self
.assertFalse(retval
< 0,
304 "child process caught fatal signal %d" % -retval
)
305 self
.assertFalse(retval
> 0, "child process reports failure %d"%retval
)
307 def test_textmode(self
):
308 # _mkstemp_inner can create files in text mode
310 return # ugh, can't use SkipTest.
312 self
.do_create(bin
=0).write("blat\n")
313 # XXX should test that the file really is a text file
315 test_classes
.append(test__mkstemp_inner
)
318 class test_gettempprefix(TC
):
319 """Test gettempprefix()."""
321 def test_sane_template(self
):
322 # gettempprefix returns a nonempty prefix string
323 p
= tempfile
.gettempprefix()
325 self
.assertTrue(isinstance(p
, basestring
))
326 self
.assertTrue(len(p
) > 0)
328 def test_usable_template(self
):
329 # gettempprefix returns a usable prefix string
331 # Create a temp directory, avoiding use of the prefix.
332 # Then attempt to create a file whose name is
333 # prefix + 'xxxxxx.xxx' in that directory.
334 p
= tempfile
.gettempprefix() + "xxxxxx.xxx"
335 d
= tempfile
.mkdtemp(prefix
="")
337 p
= os
.path
.join(d
, p
)
339 fd
= os
.open(p
, os
.O_RDWR | os
.O_CREAT
)
341 self
.failOnException("os.open")
347 test_classes
.append(test_gettempprefix
)
350 class test_gettempdir(TC
):
351 """Test gettempdir()."""
353 def test_directory_exists(self
):
354 # gettempdir returns a directory which exists
356 dir = tempfile
.gettempdir()
357 self
.assertTrue(os
.path
.isabs(dir) or dir == os
.curdir
,
358 "%s is not an absolute path" % dir)
359 self
.assertTrue(os
.path
.isdir(dir),
360 "%s is not a directory" % dir)
362 def test_directory_writable(self
):
363 # gettempdir returns a directory writable by the user
365 # sneaky: just instantiate a NamedTemporaryFile, which
366 # defaults to writing into the directory returned by
369 file = tempfile
.NamedTemporaryFile()
373 self
.failOnException("create file in %s" % tempfile
.gettempdir())
375 def test_same_thing(self
):
376 # gettempdir always returns the same object
377 a
= tempfile
.gettempdir()
378 b
= tempfile
.gettempdir()
380 self
.assertTrue(a
is b
)
382 test_classes
.append(test_gettempdir
)
385 class test_mkstemp(TC
):
386 """Test mkstemp()."""
388 def do_create(self
, dir=None, pre
="", suf
=""):
390 dir = tempfile
.gettempdir()
392 (fd
, name
) = tempfile
.mkstemp(dir=dir, prefix
=pre
, suffix
=suf
)
393 (ndir
, nbase
) = os
.path
.split(name
)
394 adir
= os
.path
.abspath(dir)
395 self
.assertEqual(adir
, ndir
,
396 "Directory '%s' incorrectly returned as '%s'" % (adir
, ndir
))
398 self
.failOnException("mkstemp")
401 self
.nameCheck(name
, dir, pre
, suf
)
406 def test_basic(self
):
407 # mkstemp can create files
409 self
.do_create(pre
="a")
410 self
.do_create(suf
="b")
411 self
.do_create(pre
="a", suf
="b")
412 self
.do_create(pre
="aa", suf
=".txt")
413 self
.do_create(dir=".")
415 def test_choose_directory(self
):
416 # mkstemp can create directories in a user-selected directory
417 dir = tempfile
.mkdtemp()
419 self
.do_create(dir=dir)
423 test_classes
.append(test_mkstemp
)
426 class test_mkdtemp(TC
):
427 """Test mkdtemp()."""
429 def do_create(self
, dir=None, pre
="", suf
=""):
431 dir = tempfile
.gettempdir()
433 name
= tempfile
.mkdtemp(dir=dir, prefix
=pre
, suffix
=suf
)
435 self
.failOnException("mkdtemp")
438 self
.nameCheck(name
, dir, pre
, suf
)
444 def test_basic(self
):
445 # mkdtemp can create directories
446 os
.rmdir(self
.do_create())
447 os
.rmdir(self
.do_create(pre
="a"))
448 os
.rmdir(self
.do_create(suf
="b"))
449 os
.rmdir(self
.do_create(pre
="a", suf
="b"))
450 os
.rmdir(self
.do_create(pre
="aa", suf
=".txt"))
452 def test_basic_many(self
):
453 # mkdtemp can create many directories (stochastic)
454 extant
= range(TEST_FILES
)
457 extant
[i
] = self
.do_create(pre
="aa")
460 if(isinstance(i
, basestring
)):
463 def test_choose_directory(self
):
464 # mkdtemp can create directories in a user-selected directory
465 dir = tempfile
.mkdtemp()
467 os
.rmdir(self
.do_create(dir=dir))
472 # mkdtemp creates directories with the proper mode
474 return # ugh, can't use SkipTest.
476 dir = self
.do_create()
478 mode
= stat
.S_IMODE(os
.stat(dir).st_mode
)
479 mode
&= 0777 # Mask off sticky bits inherited from /tmp
481 if sys
.platform
in ('win32', 'os2emx', 'mac'):
482 # There's no distinction among 'user', 'group' and 'world';
483 # replicate the 'user' bits.
485 expected
= user
* (1 + 8 + 64)
486 self
.assertEqual(mode
, expected
)
490 test_classes
.append(test_mkdtemp
)
493 class test_mktemp(TC
):
496 # For safety, all use of mktemp must occur in a private directory.
497 # We must also suppress the RuntimeWarning it generates.
499 self
.dir = tempfile
.mkdtemp()
508 _bflags
= tempfile
._bin
_openflags
510 def __init__(self
, dir, pre
, suf
):
511 self
.name
= tempfile
.mktemp(dir=dir, prefix
=pre
, suffix
=suf
)
512 # Create the file. This will raise an exception if it's
513 # mysteriously appeared in the meanwhile.
514 os
.close(os
.open(self
.name
, self
._bflags
, 0600))
517 self
._unlink
(self
.name
)
519 def do_create(self
, pre
="", suf
=""):
521 file = self
.mktemped(self
.dir, pre
, suf
)
523 self
.failOnException("mktemp")
525 self
.nameCheck(file.name
, self
.dir, pre
, suf
)
528 def test_basic(self
):
529 # mktemp can choose usable file names
531 self
.do_create(pre
="a")
532 self
.do_create(suf
="b")
533 self
.do_create(pre
="a", suf
="b")
534 self
.do_create(pre
="aa", suf
=".txt")
537 # mktemp can choose many usable file names (stochastic)
538 extant
= range(TEST_FILES
)
540 extant
[i
] = self
.do_create(pre
="aa")
542 ## def test_warning(self):
543 ## # mktemp issues a warning when used
544 ## warnings.filterwarnings("error",
545 ## category=RuntimeWarning,
547 ## self.assertRaises(RuntimeWarning,
548 ## tempfile.mktemp, dir=self.dir)
550 test_classes
.append(test_mktemp
)
553 # We test _TemporaryFileWrapper by testing NamedTemporaryFile.
556 class test_NamedTemporaryFile(TC
):
557 """Test NamedTemporaryFile()."""
559 def do_create(self
, dir=None, pre
="", suf
="", delete
=True):
561 dir = tempfile
.gettempdir()
563 file = tempfile
.NamedTemporaryFile(dir=dir, prefix
=pre
, suffix
=suf
,
566 self
.failOnException("NamedTemporaryFile")
568 self
.nameCheck(file.name
, dir, pre
, suf
)
572 def test_basic(self
):
573 # NamedTemporaryFile can create files
575 self
.do_create(pre
="a")
576 self
.do_create(suf
="b")
577 self
.do_create(pre
="a", suf
="b")
578 self
.do_create(pre
="aa", suf
=".txt")
580 def test_creates_named(self
):
581 # NamedTemporaryFile creates files with names
582 f
= tempfile
.NamedTemporaryFile()
583 self
.assertTrue(os
.path
.exists(f
.name
),
584 "NamedTemporaryFile %s does not exist" % f
.name
)
586 def test_del_on_close(self
):
587 # A NamedTemporaryFile is deleted when closed
588 dir = tempfile
.mkdtemp()
590 f
= tempfile
.NamedTemporaryFile(dir=dir)
593 self
.assertFalse(os
.path
.exists(f
.name
),
594 "NamedTemporaryFile %s exists after close" % f
.name
)
598 def test_dis_del_on_close(self
):
599 # Tests that delete-on-close can be disabled
600 dir = tempfile
.mkdtemp()
603 f
= tempfile
.NamedTemporaryFile(dir=dir, delete
=False)
607 self
.assertTrue(os
.path
.exists(f
.name
),
608 "NamedTemporaryFile %s missing after close" % f
.name
)
614 def test_multiple_close(self
):
615 # A NamedTemporaryFile can be closed many times without error
616 f
= tempfile
.NamedTemporaryFile()
623 self
.failOnException("close")
625 def test_context_manager(self
):
626 # A NamedTemporaryFile can be used as a context manager
627 with tempfile
.NamedTemporaryFile() as f
:
628 self
.assertTrue(os
.path
.exists(f
.name
))
629 self
.assertFalse(os
.path
.exists(f
.name
))
633 self
.assertRaises(ValueError, use_closed
)
635 # How to test the mode and bufsize parameters?
637 test_classes
.append(test_NamedTemporaryFile
)
639 class test_SpooledTemporaryFile(TC
):
640 """Test SpooledTemporaryFile()."""
642 def do_create(self
, max_size
=0, dir=None, pre
="", suf
=""):
644 dir = tempfile
.gettempdir()
646 file = tempfile
.SpooledTemporaryFile(max_size
=max_size
, dir=dir, prefix
=pre
, suffix
=suf
)
648 self
.failOnException("SpooledTemporaryFile")
653 def test_basic(self
):
654 # SpooledTemporaryFile can create files
656 self
.assertFalse(f
._rolled
)
657 f
= self
.do_create(max_size
=100, pre
="a", suf
=".txt")
658 self
.assertFalse(f
._rolled
)
660 def test_del_on_close(self
):
661 # A SpooledTemporaryFile is deleted when closed
662 dir = tempfile
.mkdtemp()
664 f
= tempfile
.SpooledTemporaryFile(max_size
=10, dir=dir)
665 self
.assertFalse(f
._rolled
)
667 self
.assertTrue(f
._rolled
)
670 self
.assertFalse(os
.path
.exists(filename
),
671 "SpooledTemporaryFile %s exists after close" % filename
)
675 def test_rewrite_small(self
):
676 # A SpooledTemporaryFile can be written to multiple within the max_size
677 f
= self
.do_create(max_size
=30)
678 self
.assertFalse(f
._rolled
)
682 self
.assertFalse(f
._rolled
)
684 def test_write_sequential(self
):
685 # A SpooledTemporaryFile should hold exactly max_size bytes, and roll
687 f
= self
.do_create(max_size
=30)
688 self
.assertFalse(f
._rolled
)
690 self
.assertFalse(f
._rolled
)
692 self
.assertFalse(f
._rolled
)
694 self
.assertTrue(f
._rolled
)
696 def test_sparse(self
):
697 # A SpooledTemporaryFile that is written late in the file will extend
699 f
= self
.do_create(max_size
=30)
700 self
.assertFalse(f
._rolled
)
702 self
.assertFalse(f
._rolled
)
704 self
.assertTrue(f
._rolled
)
706 def test_fileno(self
):
707 # A SpooledTemporaryFile should roll over to a real file on fileno()
708 f
= self
.do_create(max_size
=30)
709 self
.assertFalse(f
._rolled
)
710 self
.assertTrue(f
.fileno() > 0)
711 self
.assertTrue(f
._rolled
)
713 def test_multiple_close_before_rollover(self
):
714 # A SpooledTemporaryFile can be closed many times without error
715 f
= tempfile
.SpooledTemporaryFile()
717 self
.assertFalse(f
._rolled
)
723 self
.failOnException("close")
725 def test_multiple_close_after_rollover(self
):
726 # A SpooledTemporaryFile can be closed many times without error
727 f
= tempfile
.SpooledTemporaryFile(max_size
=1)
729 self
.assertTrue(f
._rolled
)
735 self
.failOnException("close")
737 def test_bound_methods(self
):
738 # It should be OK to steal a bound method from a SpooledTemporaryFile
739 # and use it independently; when the file rolls over, those bound
740 # methods should continue to function
741 f
= self
.do_create(max_size
=30)
749 self
.assertTrue(read(70) == 'a'*35 + 'b'*35)
751 def test_context_manager_before_rollover(self
):
752 # A SpooledTemporaryFile can be used as a context manager
753 with tempfile
.SpooledTemporaryFile(max_size
=1) as f
:
754 self
.assertFalse(f
._rolled
)
755 self
.assertFalse(f
.closed
)
756 self
.assertTrue(f
.closed
)
760 self
.assertRaises(ValueError, use_closed
)
762 def test_context_manager_during_rollover(self
):
763 # A SpooledTemporaryFile can be used as a context manager
764 with tempfile
.SpooledTemporaryFile(max_size
=1) as f
:
765 self
.assertFalse(f
._rolled
)
768 self
.assertTrue(f
._rolled
)
769 self
.assertFalse(f
.closed
)
770 self
.assertTrue(f
.closed
)
774 self
.assertRaises(ValueError, use_closed
)
776 def test_context_manager_after_rollover(self
):
777 # A SpooledTemporaryFile can be used as a context manager
778 f
= tempfile
.SpooledTemporaryFile(max_size
=1)
781 self
.assertTrue(f
._rolled
)
783 self
.assertFalse(f
.closed
)
784 self
.assertTrue(f
.closed
)
788 self
.assertRaises(ValueError, use_closed
)
791 test_classes
.append(test_SpooledTemporaryFile
)
794 class test_TemporaryFile(TC
):
795 """Test TemporaryFile()."""
797 def test_basic(self
):
798 # TemporaryFile can create files
799 # No point in testing the name params - the file has no name.
801 tempfile
.TemporaryFile()
803 self
.failOnException("TemporaryFile")
805 def test_has_no_name(self
):
806 # TemporaryFile creates files with no names (on this system)
807 dir = tempfile
.mkdtemp()
808 f
= tempfile
.TemporaryFile(dir=dir)
811 # Sneaky: because this file has no name, it should not prevent
812 # us from removing the directory it was created in.
820 self
.failOnException("rmdir", ei
)
822 def test_multiple_close(self
):
823 # A TemporaryFile can be closed many times without error
824 f
= tempfile
.TemporaryFile()
831 self
.failOnException("close")
833 # How to test the mode and bufsize parameters?
836 if tempfile
.NamedTemporaryFile
is not tempfile
.TemporaryFile
:
837 test_classes
.append(test_TemporaryFile
)
840 test_support
.run_unittest(*test_classes
)
842 if __name__
== "__main__":