blob: 652d1963d3d7f07acd7f5cc426a00b199d2cd5bb [file] [log] [blame]
Guido van Rossumeee94981991-11-12 15:38:08 +00001# Temporary file name allocation
Guido van Rossum41f95031992-03-31 19:02:01 +00002#
3# XXX This tries to be not UNIX specific, but I don't know beans about
4# how to choose a temp directory or filename on MS-DOS or other
5# systems so it may have to be changed...
Guido van Rossumeee94981991-11-12 15:38:08 +00006
7
Guido van Rossum41f95031992-03-31 19:02:01 +00008import os
Guido van Rossumeee94981991-11-12 15:38:08 +00009
Guido van Rossumeee94981991-11-12 15:38:08 +000010
Guido van Rossum41f95031992-03-31 19:02:01 +000011# Parameters that the caller may set to override the defaults
Guido van Rossumcff34541992-01-14 18:31:56 +000012
Guido van Rossum41f95031992-03-31 19:02:01 +000013tempdir = None
14template = None
15
16
17# Function to calculate the directory to use
18
19def gettempdir():
Guido van Rossumf4aaf861996-05-28 23:31:34 +000020 global tempdir
Guido van Rossum4033ad71996-08-08 18:33:56 +000021 if tempdir is not None:
22 return tempdir
Guido van Rossumf4aaf861996-05-28 23:31:34 +000023 attempdirs = ['/usr/tmp', '/tmp', os.getcwd(), os.curdir]
Guido van Rossum3e065ad1996-08-20 20:38:59 +000024 if os.name == 'nt':
25 attempdirs.insert(0, 'C:\\TEMP')
26 attempdirs.insert(0, '\\TEMP')
Guido van Rossumf4f756c1997-04-11 19:00:53 +000027 elif os.name == 'mac':
28 import macfs, MACFS
29 try:
30 refnum, dirid = macfs.FindFolder(MACFS.kOnSystemDisk, MACFS.kTemporaryFolderType, 0)
31 dirname = macfs.FSSpec((refnum, dirid, '')).as_pathname()
32 attempdirs.insert(0, dirname)
33 except macfs.error:
34 pass
Guido van Rossumca549821997-08-12 18:00:12 +000035 for envname in 'TMPDIR', 'TEMP', 'TMP':
36 if os.environ.has_key(envname):
37 attempdirs.insert(0, os.environ[envname])
Guido van Rossum3e065ad1996-08-20 20:38:59 +000038 testfile = gettempprefix() + 'test'
Guido van Rossumf4aaf861996-05-28 23:31:34 +000039 for dir in attempdirs:
40 try:
41 filename = os.path.join(dir, testfile)
42 fp = open(filename, 'w')
43 fp.write('blat')
44 fp.close()
45 os.unlink(filename)
46 tempdir = dir
47 break
48 except IOError:
49 pass
50 if tempdir is None:
51 msg = "Can't find a usable temporary directory amongst " + `attempdirs`
52 raise IOError, msg
53 return tempdir
Guido van Rossum41f95031992-03-31 19:02:01 +000054
55
56# Function to calculate a prefix of the filename to use
57
58def gettempprefix():
59 global template
60 if template == None:
61 if os.name == 'posix':
62 template = '@' + `os.getpid()` + '.'
Guido van Rossumf4f756c1997-04-11 19:00:53 +000063 elif os.name == 'mac':
64 template = 'Python-Tmp-'
Guido van Rossum41f95031992-03-31 19:02:01 +000065 else:
66 template = 'tmp' # XXX might choose a better one
67 return template
Guido van Rossumcff34541992-01-14 18:31:56 +000068
Guido van Rossumeee94981991-11-12 15:38:08 +000069
Guido van Rossum4a3a41f1991-12-26 13:10:50 +000070# Counter for generating unique names
Guido van Rossumeee94981991-11-12 15:38:08 +000071
Guido van Rossum4a3a41f1991-12-26 13:10:50 +000072counter = 0
Guido van Rossumeee94981991-11-12 15:38:08 +000073
74
Guido van Rossum41f95031992-03-31 19:02:01 +000075# User-callable function to return a unique temporary file name
Guido van Rossumeee94981991-11-12 15:38:08 +000076
77def mktemp():
Guido van Rossum4a3a41f1991-12-26 13:10:50 +000078 global counter
Guido van Rossum41f95031992-03-31 19:02:01 +000079 dir = gettempdir()
80 pre = gettempprefix()
Guido van Rossumeee94981991-11-12 15:38:08 +000081 while 1:
Guido van Rossum41f95031992-03-31 19:02:01 +000082 counter = counter + 1
83 file = os.path.join(dir, pre + `counter`)
84 if not os.path.exists(file):
85 return file
Guido van Rossumca549821997-08-12 18:00:12 +000086
87
88class TemporaryFileWrapper:
89 """Temporary file wrapper
90
91 This class provides a wrapper around files opened for temporary use.
92 In particular, it seeks to automatically remove the file when it is
93 no longer needed.
94 """
95 def __init__(self, file, path):
96 self.file=file
97 self.path=path
98
99 def close(self):
100 self.file.close()
101 os.unlink(self.path)
102
103 def __del__(self):
104 try: self.close()
105 except: pass
106
107 def __getattr__(self, name):
108 file=self.__dict__['file']
109 a=getattr(file, name)
110 setattr(self, name, a)
111 return a
112
113
114def TemporaryFile(mode='w+b', bufsize=-1):
115 name=mktemp()
116 file=open(name,mode,bufsize)
117 try:
118 os.unlink(name)
119 except os.error:
120 # Non-unix -- can't unlink file that's still open, use wrapper
121 return TemporaryFileWrapper(file, name)
122 else:
123 return file