| # Temporary file name allocation |
| # |
| # XXX This tries to be not UNIX specific, but I don't know beans about |
| # how to choose a temp directory or filename on MS-DOS or other |
| # systems so it may have to be changed... |
| |
| |
| import os |
| |
| |
| # Parameters that the caller may set to override the defaults |
| |
| tempdir = None |
| template = None |
| |
| |
| # Function to calculate the directory to use |
| |
| def gettempdir(): |
| global tempdir |
| if tempdir is not None: |
| return tempdir |
| try: |
| pwd = os.getcwd() |
| except (AttributeError, os.error): |
| pwd = os.curdir |
| attempdirs = ['/usr/tmp', '/tmp', pwd] |
| if os.name == 'nt': |
| attempdirs.insert(0, 'C:\\TEMP') |
| attempdirs.insert(0, '\\TEMP') |
| elif os.name == 'mac': |
| import macfs, MACFS |
| try: |
| refnum, dirid = macfs.FindFolder(MACFS.kOnSystemDisk, |
| MACFS.kTemporaryFolderType, 1) |
| dirname = macfs.FSSpec((refnum, dirid, '')).as_pathname() |
| attempdirs.insert(0, dirname) |
| except macfs.error: |
| pass |
| for envname in 'TMPDIR', 'TEMP', 'TMP': |
| if os.environ.has_key(envname): |
| attempdirs.insert(0, os.environ[envname]) |
| testfile = gettempprefix() + 'test' |
| for dir in attempdirs: |
| try: |
| filename = os.path.join(dir, testfile) |
| fp = open(filename, 'w') |
| fp.write('blat') |
| fp.close() |
| os.unlink(filename) |
| tempdir = dir |
| break |
| except IOError: |
| pass |
| if tempdir is None: |
| msg = "Can't find a usable temporary directory amongst " + `attempdirs` |
| raise IOError, msg |
| return tempdir |
| |
| |
| # Function to calculate a prefix of the filename to use |
| |
| def gettempprefix(): |
| global template |
| if template == None: |
| if os.name == 'posix': |
| template = '@' + `os.getpid()` + '.' |
| elif os.name == 'nt': |
| template = '~' + `os.getpid()` + '-' |
| elif os.name == 'mac': |
| template = 'Python-Tmp-' |
| else: |
| template = 'tmp' # XXX might choose a better one |
| return template |
| |
| |
| # Counter for generating unique names |
| |
| counter = 0 |
| |
| |
| # User-callable function to return a unique temporary file name |
| |
| def mktemp(suffix=""): |
| global counter |
| dir = gettempdir() |
| pre = gettempprefix() |
| while 1: |
| counter = counter + 1 |
| file = os.path.join(dir, pre + `counter` + suffix) |
| if not os.path.exists(file): |
| return file |
| |
| |
| class TemporaryFileWrapper: |
| """Temporary file wrapper |
| |
| This class provides a wrapper around files opened for temporary use. |
| In particular, it seeks to automatically remove the file when it is |
| no longer needed. |
| """ |
| def __init__(self, file, path): |
| self.file = file |
| self.path = path |
| |
| def close(self): |
| self.file.close() |
| os.unlink(self.path) |
| |
| def __del__(self): |
| try: self.close() |
| except: pass |
| |
| def __getattr__(self, name): |
| file = self.__dict__['file'] |
| a = getattr(file, name) |
| setattr(self, name, a) |
| return a |
| |
| |
| def TemporaryFile(mode='w+b', bufsize=-1, suffix=""): |
| name = mktemp(suffix) |
| file = open(name, mode, bufsize) |
| try: |
| os.unlink(name) |
| except os.error: |
| # Non-unix -- can't unlink file that's still open, use wrapper |
| return TemporaryFileWrapper(file, name) |
| else: |
| return file |