1# tempfile.py unit tests.
2import tempfile
3import os
4import sys
5import re
6import warnings
7
8import unittest
9from test import test_support
10
11warnings.filterwarnings("ignore",
12                        category=RuntimeWarning,
13                        message="mktemp", module=__name__)
14
15if hasattr(os, 'stat'):
16    import stat
17    has_stat = 1
18else:
19    has_stat = 0
20
21has_textmode = (tempfile._text_openflags != tempfile._bin_openflags)
22has_spawnl = hasattr(os, 'spawnl')
23
24# TEST_FILES may need to be tweaked for systems depending on the maximum
25# number of files that can be opened at one time (see ulimit -n)
26if sys.platform in ('openbsd3', 'openbsd4'):
27    TEST_FILES = 48
28else:
29    TEST_FILES = 100
30
31# This is organized as one test for each chunk of code in tempfile.py,
32# in order of their appearance in the file.  Testing which requires
33# threads is not done here.
34
35# Common functionality.
36class TC(unittest.TestCase):
37
38    str_check = re.compile(r"[a-zA-Z0-9_-]{6}$")
39
40    def failOnException(self, what, ei=None):
41        if ei is None:
42            ei = sys.exc_info()
43        self.fail("%s raised %s: %s" % (what, ei[0], ei[1]))
44
45    def nameCheck(self, name, dir, pre, suf):
46        (ndir, nbase) = os.path.split(name)
47        npre  = nbase[:len(pre)]
48        nsuf  = nbase[len(nbase)-len(suf):]
49
50        # check for equality of the absolute paths!
51        self.assertEqual(os.path.abspath(ndir), os.path.abspath(dir),
52                         "file '%s' not in directory '%s'" % (name, dir))
53        self.assertEqual(npre, pre,
54                         "file '%s' does not begin with '%s'" % (nbase, pre))
55        self.assertEqual(nsuf, suf,
56                         "file '%s' does not end with '%s'" % (nbase, suf))
57
58        nbase = nbase[len(pre):len(nbase)-len(suf)]
59        self.assertTrue(self.str_check.match(nbase),
60                     "random string '%s' does not match /^[a-zA-Z0-9_-]{6}$/"
61                     % nbase)
62
63test_classes = []
64
65class test_exports(TC):
66    def test_exports(self):
67        # There are no surprising symbols in the tempfile module
68        dict = tempfile.__dict__
69
70        expected = {
71            "NamedTemporaryFile" : 1,
72            "TemporaryFile" : 1,
73            "mkstemp" : 1,
74            "mkdtemp" : 1,
75            "mktemp" : 1,
76            "TMP_MAX" : 1,
77            "gettempprefix" : 1,
78            "gettempdir" : 1,
79            "tempdir" : 1,
80            "template" : 1,
81            "SpooledTemporaryFile" : 1
82        }
83
84        unexp = []
85        for key in dict:
86            if key[0] != '_' and key not in expected:
87                unexp.append(key)
88        self.assertTrue(len(unexp) == 0,
89                        "unexpected keys: %s" % unexp)
90
91test_classes.append(test_exports)
92
93
94class test__RandomNameSequence(TC):
95    """Test the internal iterator object _RandomNameSequence."""
96
97    def setUp(self):
98        self.r = tempfile._RandomNameSequence()
99
100    def test_get_six_char_str(self):
101        # _RandomNameSequence returns a six-character string
102        s = self.r.next()
103        self.nameCheck(s, '', '', '')
104
105    def test_many(self):
106        # _RandomNameSequence returns no duplicate strings (stochastic)
107
108        dict = {}
109        r = self.r
110        for i in xrange(TEST_FILES):
111            s = r.next()
112            self.nameCheck(s, '', '', '')
113            self.assertNotIn(s, dict)
114            dict[s] = 1
115
116    def test_supports_iter(self):
117        # _RandomNameSequence supports the iterator protocol
118
119        i = 0
120        r = self.r
121        try:
122            for s in r:
123                i += 1
124                if i == 20:
125                    break
126        except:
127            self.failOnException("iteration")
128
129test_classes.append(test__RandomNameSequence)
130
131
132class test__candidate_tempdir_list(TC):
133    """Test the internal function _candidate_tempdir_list."""
134
135    def test_nonempty_list(self):
136        # _candidate_tempdir_list returns a nonempty list of strings
137
138        cand = tempfile._candidate_tempdir_list()
139
140        self.assertFalse(len(cand) == 0)
141        for c in cand:
142            self.assertIsInstance(c, basestring)
143
144    def test_wanted_dirs(self):
145        # _candidate_tempdir_list contains the expected directories
146
147        # Make sure the interesting environment variables are all set.
148        with test_support.EnvironmentVarGuard() as env:
149            for envname in 'TMPDIR', 'TEMP', 'TMP':
150                dirname = os.getenv(envname)
151                if not dirname:
152                    env[envname] = os.path.abspath(envname)
153
154            cand = tempfile._candidate_tempdir_list()
155
156            for envname in 'TMPDIR', 'TEMP', 'TMP':
157                dirname = os.getenv(envname)
158                if not dirname: raise ValueError
159                self.assertIn(dirname, cand)
160
161            try:
162                dirname = os.getcwd()
163            except (AttributeError, os.error):
164                dirname = os.curdir
165
166            self.assertIn(dirname, cand)
167
168            # Not practical to try to verify the presence of OS-specific
169            # paths in this list.
170
171test_classes.append(test__candidate_tempdir_list)
172
173
174# We test _get_default_tempdir by testing gettempdir.
175
176
177class test__get_candidate_names(TC):
178    """Test the internal function _get_candidate_names."""
179
180    def test_retval(self):
181        # _get_candidate_names returns a _RandomNameSequence object
182        obj = tempfile._get_candidate_names()
183        self.assertIsInstance(obj, tempfile._RandomNameSequence)
184
185    def test_same_thing(self):
186        # _get_candidate_names always returns the same object
187        a = tempfile._get_candidate_names()
188        b = tempfile._get_candidate_names()
189
190        self.assertTrue(a is b)
191
192test_classes.append(test__get_candidate_names)
193
194
195class test__mkstemp_inner(TC):
196    """Test the internal function _mkstemp_inner."""
197
198    class mkstemped:
199        _bflags = tempfile._bin_openflags
200        _tflags = tempfile._text_openflags
201        _close = os.close
202        _unlink = os.unlink
203
204        def __init__(self, dir, pre, suf, bin):
205            if bin: flags = self._bflags
206            else:   flags = self._tflags
207
208            (self.fd, self.name) = tempfile._mkstemp_inner(dir, pre, suf, flags)
209
210        def write(self, str):
211            os.write(self.fd, str)
212
213        def __del__(self):
214            self._close(self.fd)
215            self._unlink(self.name)
216
217    def do_create(self, dir=None, pre="", suf="", bin=1):
218        if dir is None:
219            dir = tempfile.gettempdir()
220        try:
221            file = self.mkstemped(dir, pre, suf, bin)
222        except:
223            self.failOnException("_mkstemp_inner")
224
225        self.nameCheck(file.name, dir, pre, suf)
226        return file
227
228    def test_basic(self):
229        # _mkstemp_inner can create files
230        self.do_create().write("blat")
231        self.do_create(pre="a").write("blat")
232        self.do_create(suf="b").write("blat")
233        self.do_create(pre="a", suf="b").write("blat")
234        self.do_create(pre="aa", suf=".txt").write("blat")
235
236    def test_basic_many(self):
237        # _mkstemp_inner can create many files (stochastic)
238        extant = range(TEST_FILES)
239        for i in extant:
240            extant[i] = self.do_create(pre="aa")
241
242    def test_choose_directory(self):
243        # _mkstemp_inner can create files in a user-selected directory
244        dir = tempfile.mkdtemp()
245        try:
246            self.do_create(dir=dir).write("blat")
247        finally:
248            os.rmdir(dir)
249
250    def test_file_mode(self):
251        # _mkstemp_inner creates files with the proper mode
252        if not has_stat:
253            return            # ugh, can't use SkipTest.
254
255        file = self.do_create()
256        mode = stat.S_IMODE(os.stat(file.name).st_mode)
257        expected = 0600
258        if sys.platform in ('win32', 'os2emx'):
259            # There's no distinction among 'user', 'group' and 'world';
260            # replicate the 'user' bits.
261            user = expected >> 6
262            expected = user * (1 + 8 + 64)
263        self.assertEqual(mode, expected)
264
265    def test_noinherit(self):
266        # _mkstemp_inner file handles are not inherited by child processes
267        if not has_spawnl:
268            return            # ugh, can't use SkipTest.
269
270        if test_support.verbose:
271            v="v"
272        else:
273            v="q"
274
275        file = self.do_create()
276        fd = "%d" % file.fd
277
278        try:
279            me = __file__
280        except NameError:
281            me = sys.argv[0]
282
283        # We have to exec something, so that FD_CLOEXEC will take
284        # effect.  The core of this test is therefore in
285        # tf_inherit_check.py, which see.
286        tester = os.path.join(os.path.dirname(os.path.abspath(me)),
287                              "tf_inherit_check.py")
288
289        # On Windows a spawn* /path/ with embedded spaces shouldn't be quoted,
290        # but an arg with embedded spaces should be decorated with double
291        # quotes on each end
292        if sys.platform in ('win32',):
293            decorated = '"%s"' % sys.executable
294            tester = '"%s"' % tester
295        else:
296            decorated = sys.executable
297
298        retval = os.spawnl(os.P_WAIT, sys.executable, decorated, tester, v, fd)
299        self.assertFalse(retval < 0,
300                    "child process caught fatal signal %d" % -retval)
301        self.assertFalse(retval > 0, "child process reports failure %d"%retval)
302
303    def test_textmode(self):
304        # _mkstemp_inner can create files in text mode
305        if not has_textmode:
306            return            # ugh, can't use SkipTest.
307
308        self.do_create(bin=0).write("blat\n")
309        # XXX should test that the file really is a text file
310
311test_classes.append(test__mkstemp_inner)
312
313
314class test_gettempprefix(TC):
315    """Test gettempprefix()."""
316
317    def test_sane_template(self):
318        # gettempprefix returns a nonempty prefix string
319        p = tempfile.gettempprefix()
320
321        self.assertIsInstance(p, basestring)
322        self.assertTrue(len(p) > 0)
323
324    def test_usable_template(self):
325        # gettempprefix returns a usable prefix string
326
327        # Create a temp directory, avoiding use of the prefix.
328        # Then attempt to create a file whose name is
329        # prefix + 'xxxxxx.xxx' in that directory.
330        p = tempfile.gettempprefix() + "xxxxxx.xxx"
331        d = tempfile.mkdtemp(prefix="")
332        try:
333            p = os.path.join(d, p)
334            try:
335                fd = os.open(p, os.O_RDWR | os.O_CREAT)
336            except:
337                self.failOnException("os.open")
338            os.close(fd)
339            os.unlink(p)
340        finally:
341            os.rmdir(d)
342
343test_classes.append(test_gettempprefix)
344
345
346class test_gettempdir(TC):
347    """Test gettempdir()."""
348
349    def test_directory_exists(self):
350        # gettempdir returns a directory which exists
351
352        dir = tempfile.gettempdir()
353        self.assertTrue(os.path.isabs(dir) or dir == os.curdir,
354                     "%s is not an absolute path" % dir)
355        self.assertTrue(os.path.isdir(dir),
356                     "%s is not a directory" % dir)
357
358    def test_directory_writable(self):
359        # gettempdir returns a directory writable by the user
360
361        # sneaky: just instantiate a NamedTemporaryFile, which
362        # defaults to writing into the directory returned by
363        # gettempdir.
364        try:
365            file = tempfile.NamedTemporaryFile()
366            file.write("blat")
367            file.close()
368        except:
369            self.failOnException("create file in %s" % tempfile.gettempdir())
370
371    def test_same_thing(self):
372        # gettempdir always returns the same object
373        a = tempfile.gettempdir()
374        b = tempfile.gettempdir()
375
376        self.assertTrue(a is b)
377
378test_classes.append(test_gettempdir)
379
380
381class test_mkstemp(TC):
382    """Test mkstemp()."""
383
384    def do_create(self, dir=None, pre="", suf=""):
385        if dir is None:
386            dir = tempfile.gettempdir()
387        try:
388            (fd, name) = tempfile.mkstemp(dir=dir, prefix=pre, suffix=suf)
389            (ndir, nbase) = os.path.split(name)
390            adir = os.path.abspath(dir)
391            self.assertEqual(adir, ndir,
392                "Directory '%s' incorrectly returned as '%s'" % (adir, ndir))
393        except:
394            self.failOnException("mkstemp")
395
396        try:
397            self.nameCheck(name, dir, pre, suf)
398        finally:
399            os.close(fd)
400            os.unlink(name)
401
402    def test_basic(self):
403        # mkstemp can create files
404        self.do_create()
405        self.do_create(pre="a")
406        self.do_create(suf="b")
407        self.do_create(pre="a", suf="b")
408        self.do_create(pre="aa", suf=".txt")
409        self.do_create(dir=".")
410
411    def test_choose_directory(self):
412        # mkstemp can create directories in a user-selected directory
413        dir = tempfile.mkdtemp()
414        try:
415            self.do_create(dir=dir)
416        finally:
417            os.rmdir(dir)
418
419test_classes.append(test_mkstemp)
420
421
422class test_mkdtemp(TC):
423    """Test mkdtemp()."""
424
425    def do_create(self, dir=None, pre="", suf=""):
426        if dir is None:
427            dir = tempfile.gettempdir()
428        try:
429            name = tempfile.mkdtemp(dir=dir, prefix=pre, suffix=suf)
430        except:
431            self.failOnException("mkdtemp")
432
433        try:
434            self.nameCheck(name, dir, pre, suf)
435            return name
436        except:
437            os.rmdir(name)
438            raise
439
440    def test_basic(self):
441        # mkdtemp can create directories
442        os.rmdir(self.do_create())
443        os.rmdir(self.do_create(pre="a"))
444        os.rmdir(self.do_create(suf="b"))
445        os.rmdir(self.do_create(pre="a", suf="b"))
446        os.rmdir(self.do_create(pre="aa", suf=".txt"))
447
448    def test_basic_many(self):
449        # mkdtemp can create many directories (stochastic)
450        extant = range(TEST_FILES)
451        try:
452            for i in extant:
453                extant[i] = self.do_create(pre="aa")
454        finally:
455            for i in extant:
456                if(isinstance(i, basestring)):
457                    os.rmdir(i)
458
459    def test_choose_directory(self):
460        # mkdtemp can create directories in a user-selected directory
461        dir = tempfile.mkdtemp()
462        try:
463            os.rmdir(self.do_create(dir=dir))
464        finally:
465            os.rmdir(dir)
466
467    def test_mode(self):
468        # mkdtemp creates directories with the proper mode
469        if not has_stat:
470            return            # ugh, can't use SkipTest.
471
472        dir = self.do_create()
473        try:
474            mode = stat.S_IMODE(os.stat(dir).st_mode)
475            mode &= 0777 # Mask off sticky bits inherited from /tmp
476            expected = 0700
477            if sys.platform in ('win32', 'os2emx'):
478                # There's no distinction among 'user', 'group' and 'world';
479                # replicate the 'user' bits.
480                user = expected >> 6
481                expected = user * (1 + 8 + 64)
482            self.assertEqual(mode, expected)
483        finally:
484            os.rmdir(dir)
485
486test_classes.append(test_mkdtemp)
487
488
489class test_mktemp(TC):
490    """Test mktemp()."""
491
492    # For safety, all use of mktemp must occur in a private directory.
493    # We must also suppress the RuntimeWarning it generates.
494    def setUp(self):
495        self.dir = tempfile.mkdtemp()
496
497    def tearDown(self):
498        if self.dir:
499            os.rmdir(self.dir)
500            self.dir = None
501
502    class mktemped:
503        _unlink = os.unlink
504        _bflags = tempfile._bin_openflags
505
506        def __init__(self, dir, pre, suf):
507            self.name = tempfile.mktemp(dir=dir, prefix=pre, suffix=suf)
508            # Create the file.  This will raise an exception if it's
509            # mysteriously appeared in the meanwhile.
510            os.close(os.open(self.name, self._bflags, 0600))
511
512        def __del__(self):
513            self._unlink(self.name)
514
515    def do_create(self, pre="", suf=""):
516        try:
517            file = self.mktemped(self.dir, pre, suf)
518        except:
519            self.failOnException("mktemp")
520
521        self.nameCheck(file.name, self.dir, pre, suf)
522        return file
523
524    def test_basic(self):
525        # mktemp can choose usable file names
526        self.do_create()
527        self.do_create(pre="a")
528        self.do_create(suf="b")
529        self.do_create(pre="a", suf="b")
530        self.do_create(pre="aa", suf=".txt")
531
532    def test_many(self):
533        # mktemp can choose many usable file names (stochastic)
534        extant = range(TEST_FILES)
535        for i in extant:
536            extant[i] = self.do_create(pre="aa")
537
538##     def test_warning(self):
539##         # mktemp issues a warning when used
540##         warnings.filterwarnings("error",
541##                                 category=RuntimeWarning,
542##                                 message="mktemp")
543##         self.assertRaises(RuntimeWarning,
544##                           tempfile.mktemp, dir=self.dir)
545
546test_classes.append(test_mktemp)
547
548
549# We test _TemporaryFileWrapper by testing NamedTemporaryFile.
550
551
552class test_NamedTemporaryFile(TC):
553    """Test NamedTemporaryFile()."""
554
555    def do_create(self, dir=None, pre="", suf="", delete=True):
556        if dir is None:
557            dir = tempfile.gettempdir()
558        try:
559            file = tempfile.NamedTemporaryFile(dir=dir, prefix=pre, suffix=suf,
560                                               delete=delete)
561        except:
562            self.failOnException("NamedTemporaryFile")
563
564        self.nameCheck(file.name, dir, pre, suf)
565        return file
566
567
568    def test_basic(self):
569        # NamedTemporaryFile can create files
570        self.do_create()
571        self.do_create(pre="a")
572        self.do_create(suf="b")
573        self.do_create(pre="a", suf="b")
574        self.do_create(pre="aa", suf=".txt")
575
576    def test_creates_named(self):
577        # NamedTemporaryFile creates files with names
578        f = tempfile.NamedTemporaryFile()
579        self.assertTrue(os.path.exists(f.name),
580                        "NamedTemporaryFile %s does not exist" % f.name)
581
582    def test_del_on_close(self):
583        # A NamedTemporaryFile is deleted when closed
584        dir = tempfile.mkdtemp()
585        try:
586            f = tempfile.NamedTemporaryFile(dir=dir)
587            f.write('blat')
588            f.close()
589            self.assertFalse(os.path.exists(f.name),
590                        "NamedTemporaryFile %s exists after close" % f.name)
591        finally:
592            os.rmdir(dir)
593
594    def test_dis_del_on_close(self):
595        # Tests that delete-on-close can be disabled
596        dir = tempfile.mkdtemp()
597        tmp = None
598        try:
599            f = tempfile.NamedTemporaryFile(dir=dir, delete=False)
600            tmp = f.name
601            f.write('blat')
602            f.close()
603            self.assertTrue(os.path.exists(f.name),
604                        "NamedTemporaryFile %s missing after close" % f.name)
605        finally:
606            if tmp is not None:
607                os.unlink(tmp)
608            os.rmdir(dir)
609
610    def test_multiple_close(self):
611        # A NamedTemporaryFile can be closed many times without error
612        f = tempfile.NamedTemporaryFile()
613        f.write('abc\n')
614        f.close()
615        try:
616            f.close()
617            f.close()
618        except:
619            self.failOnException("close")
620
621    def test_context_manager(self):
622        # A NamedTemporaryFile can be used as a context manager
623        with tempfile.NamedTemporaryFile() as f:
624            self.assertTrue(os.path.exists(f.name))
625        self.assertFalse(os.path.exists(f.name))
626        def use_closed():
627            with f:
628                pass
629        self.assertRaises(ValueError, use_closed)
630
631    # How to test the mode and bufsize parameters?
632
633test_classes.append(test_NamedTemporaryFile)
634
635class test_SpooledTemporaryFile(TC):
636    """Test SpooledTemporaryFile()."""
637
638    def do_create(self, max_size=0, dir=None, pre="", suf=""):
639        if dir is None:
640            dir = tempfile.gettempdir()
641        try:
642            file = tempfile.SpooledTemporaryFile(max_size=max_size, dir=dir, prefix=pre, suffix=suf)
643        except:
644            self.failOnException("SpooledTemporaryFile")
645
646        return file
647
648
649    def test_basic(self):
650        # SpooledTemporaryFile can create files
651        f = self.do_create()
652        self.assertFalse(f._rolled)
653        f = self.do_create(max_size=100, pre="a", suf=".txt")
654        self.assertFalse(f._rolled)
655
656    def test_del_on_close(self):
657        # A SpooledTemporaryFile is deleted when closed
658        dir = tempfile.mkdtemp()
659        try:
660            f = tempfile.SpooledTemporaryFile(max_size=10, dir=dir)
661            self.assertFalse(f._rolled)
662            f.write('blat ' * 5)
663            self.assertTrue(f._rolled)
664            filename = f.name
665            f.close()
666            self.assertFalse(os.path.exists(filename),
667                        "SpooledTemporaryFile %s exists after close" % filename)
668        finally:
669            os.rmdir(dir)
670
671    def test_rewrite_small(self):
672        # A SpooledTemporaryFile can be written to multiple within the max_size
673        f = self.do_create(max_size=30)
674        self.assertFalse(f._rolled)
675        for i in range(5):
676            f.seek(0, 0)
677            f.write('x' * 20)
678        self.assertFalse(f._rolled)
679
680    def test_write_sequential(self):
681        # A SpooledTemporaryFile should hold exactly max_size bytes, and roll
682        # over afterward
683        f = self.do_create(max_size=30)
684        self.assertFalse(f._rolled)
685        f.write('x' * 20)
686        self.assertFalse(f._rolled)
687        f.write('x' * 10)
688        self.assertFalse(f._rolled)
689        f.write('x')
690        self.assertTrue(f._rolled)
691
692    def test_writelines(self):
693        # Verify writelines with a SpooledTemporaryFile
694        f = self.do_create()
695        f.writelines((b'x', b'y', b'z'))
696        f.seek(0)
697        buf = f.read()
698        self.assertEqual(buf, b'xyz')
699
700    def test_writelines_sequential(self):
701        # A SpooledTemporaryFile should hold exactly max_size bytes, and roll
702        # over afterward
703        f = self.do_create(max_size=35)
704        f.writelines((b'x' * 20, b'x' * 10, b'x' * 5))
705        self.assertFalse(f._rolled)
706        f.write(b'x')
707        self.assertTrue(f._rolled)
708
709    def test_sparse(self):
710        # A SpooledTemporaryFile that is written late in the file will extend
711        # when that occurs
712        f = self.do_create(max_size=30)
713        self.assertFalse(f._rolled)
714        f.seek(100, 0)
715        self.assertFalse(f._rolled)
716        f.write('x')
717        self.assertTrue(f._rolled)
718
719    def test_fileno(self):
720        # A SpooledTemporaryFile should roll over to a real file on fileno()
721        f = self.do_create(max_size=30)
722        self.assertFalse(f._rolled)
723        self.assertTrue(f.fileno() > 0)
724        self.assertTrue(f._rolled)
725
726    def test_multiple_close_before_rollover(self):
727        # A SpooledTemporaryFile can be closed many times without error
728        f = tempfile.SpooledTemporaryFile()
729        f.write('abc\n')
730        self.assertFalse(f._rolled)
731        f.close()
732        try:
733            f.close()
734            f.close()
735        except:
736            self.failOnException("close")
737
738    def test_multiple_close_after_rollover(self):
739        # A SpooledTemporaryFile can be closed many times without error
740        f = tempfile.SpooledTemporaryFile(max_size=1)
741        f.write('abc\n')
742        self.assertTrue(f._rolled)
743        f.close()
744        try:
745            f.close()
746            f.close()
747        except:
748            self.failOnException("close")
749
750    def test_bound_methods(self):
751        # It should be OK to steal a bound method from a SpooledTemporaryFile
752        # and use it independently; when the file rolls over, those bound
753        # methods should continue to function
754        f = self.do_create(max_size=30)
755        read = f.read
756        write = f.write
757        seek = f.seek
758
759        write("a" * 35)
760        write("b" * 35)
761        seek(0, 0)
762        self.assertTrue(read(70) == 'a'*35 + 'b'*35)
763
764    def test_context_manager_before_rollover(self):
765        # A SpooledTemporaryFile can be used as a context manager
766        with tempfile.SpooledTemporaryFile(max_size=1) as f:
767            self.assertFalse(f._rolled)
768            self.assertFalse(f.closed)
769        self.assertTrue(f.closed)
770        def use_closed():
771            with f:
772                pass
773        self.assertRaises(ValueError, use_closed)
774
775    def test_context_manager_during_rollover(self):
776        # A SpooledTemporaryFile can be used as a context manager
777        with tempfile.SpooledTemporaryFile(max_size=1) as f:
778            self.assertFalse(f._rolled)
779            f.write('abc\n')
780            f.flush()
781            self.assertTrue(f._rolled)
782            self.assertFalse(f.closed)
783        self.assertTrue(f.closed)
784        def use_closed():
785            with f:
786                pass
787        self.assertRaises(ValueError, use_closed)
788
789    def test_context_manager_after_rollover(self):
790        # A SpooledTemporaryFile can be used as a context manager
791        f = tempfile.SpooledTemporaryFile(max_size=1)
792        f.write('abc\n')
793        f.flush()
794        self.assertTrue(f._rolled)
795        with f:
796            self.assertFalse(f.closed)
797        self.assertTrue(f.closed)
798        def use_closed():
799            with f:
800                pass
801        self.assertRaises(ValueError, use_closed)
802
803
804test_classes.append(test_SpooledTemporaryFile)
805
806
807class test_TemporaryFile(TC):
808    """Test TemporaryFile()."""
809
810    def test_basic(self):
811        # TemporaryFile can create files
812        # No point in testing the name params - the file has no name.
813        try:
814            tempfile.TemporaryFile()
815        except:
816            self.failOnException("TemporaryFile")
817
818    def test_has_no_name(self):
819        # TemporaryFile creates files with no names (on this system)
820        dir = tempfile.mkdtemp()
821        f = tempfile.TemporaryFile(dir=dir)
822        f.write('blat')
823
824        # Sneaky: because this file has no name, it should not prevent
825        # us from removing the directory it was created in.
826        try:
827            os.rmdir(dir)
828        except:
829            ei = sys.exc_info()
830            # cleanup
831            f.close()
832            os.rmdir(dir)
833            self.failOnException("rmdir", ei)
834
835    def test_multiple_close(self):
836        # A TemporaryFile can be closed many times without error
837        f = tempfile.TemporaryFile()
838        f.write('abc\n')
839        f.close()
840        try:
841            f.close()
842            f.close()
843        except:
844            self.failOnException("close")
845
846    # How to test the mode and bufsize parameters?
847
848
849if tempfile.NamedTemporaryFile is not tempfile.TemporaryFile:
850    test_classes.append(test_TemporaryFile)
851
852def test_main():
853    test_support.run_unittest(*test_classes)
854
855if __name__ == "__main__":
856    test_main()
857