Search code examples
pythontemporary-files

Python `tempfile.gettempdir()` does not respect TMPDIR


I am using a shared linux cluster and want my temporary directory to be /tmp/username rather than the default /tmp.

According to the tempfile docs, gettempdir() should use the $TMPDIR environment variable to determine the temporary directory.

However, this does not seem to be the case?!

$ export TMPDIR='/tmp/username' 
$ python -c "\
import os
import tempfile
print(os.environ['TMPDIR'])
print(tempfile.gettempdir())"
/tmp/username
/tmp

Any suggestions?


Solution

  • Does the directory exist? Is it writable by the user? If not, it won't work and Python will fallback to other locations. You can see the code here, reproduced here for reference:

    def _get_default_tempdir():
        """Calculate the default directory to use for temporary files.
        This routine should be called exactly once.
    
        We determine whether or not a candidate temp dir is usable by
        trying to create and write to a file in that directory.  If this
        is successful, the test file is deleted.  To prevent denial of
        service, the name of the test file must be randomized."""
    
        namer = _RandomNameSequence()
        dirlist = _candidate_tempdir_list()
        flags = _text_openflags
    
        for dir in dirlist:
            if dir != _os.curdir:
                dir = _os.path.normcase(_os.path.abspath(dir))
            # Try only a few names per directory.
            for seq in xrange(100):
                name = namer.next()
                filename = _os.path.join(dir, name)
                try:
                    fd = _os.open(filename, flags, 0o600)
                    try:
                        try:
                            with _io.open(fd, 'wb', closefd=False) as fp:
                                fp.write(b'blat')
                        finally:
                            _os.close(fd)
                    finally:
                        _os.unlink(filename)
                    return dir
                except (OSError, IOError) as e:
                    if e.args[0] == _errno.EEXIST:
                        continue
                    if (_os.name == 'nt' and e.args[0] == _errno.EACCES and
                        _os.path.isdir(dir) and _os.access(dir, _os.W_OK)):
                        # On windows, when a directory with the chosen name already
                        # exists, EACCES error code is returned instead of EEXIST.
                        continue
                    break # no point trying more names in this directory
        raise IOError, (_errno.ENOENT,
                        ("No usable temporary directory found in %s" % dirlist))