Home | History | Annotate | Download | only in test
      1 # tempfile.py unit tests.

      2 import tempfile
      3 import os
      4 import sys
      5 import re
      6 import warnings
      7 
      8 import unittest
      9 from test import test_support
     10 
     11 warnings.filterwarnings("ignore",
     12                         category=RuntimeWarning,
     13                         message="mktemp", module=__name__)
     14 
     15 if hasattr(os, 'stat'):
     16     import stat
     17     has_stat = 1
     18 else:
     19     has_stat = 0
     20 
     21 has_textmode = (tempfile._text_openflags != tempfile._bin_openflags)
     22 has_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)

     26 if sys.platform in ('openbsd3', 'openbsd4'):
     27     TEST_FILES = 48
     28 else:
     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.

     36 class 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 
     63 test_classes = []
     64 
     65 class 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 
     91 test_classes.append(test_exports)
     92 
     93 
     94 class 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 
    129 test_classes.append(test__RandomNameSequence)
    130 
    131 
    132 class 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 
    171 test_classes.append(test__candidate_tempdir_list)
    172 
    173 
    174 # We test _get_default_tempdir by testing gettempdir.

    175 
    176 
    177 class 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 
    192 test_classes.append(test__get_candidate_names)
    193 
    194 
    195 class 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 
    311 test_classes.append(test__mkstemp_inner)
    312 
    313 
    314 class 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 
    343 test_classes.append(test_gettempprefix)
    344 
    345 
    346 class 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 
    378 test_classes.append(test_gettempdir)
    379 
    380 
    381 class 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 
    419 test_classes.append(test_mkstemp)
    420 
    421 
    422 class 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 
    486 test_classes.append(test_mkdtemp)
    487 
    488 
    489 class 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 
    546 test_classes.append(test_mktemp)
    547 
    548 
    549 # We test _TemporaryFileWrapper by testing NamedTemporaryFile.

    550 
    551 
    552 class 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 
    633 test_classes.append(test_NamedTemporaryFile)
    634 
    635 class 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 
    804 test_classes.append(test_SpooledTemporaryFile)
    805 
    806 
    807 class 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 
    849 if tempfile.NamedTemporaryFile is not tempfile.TemporaryFile:
    850     test_classes.append(test_TemporaryFile)
    851 
    852 def test_main():
    853     test_support.run_unittest(*test_classes)
    854 
    855 if __name__ == "__main__":
    856     test_main()
    857