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