blob: bd0ba606b33acc818b670f9ed6405edc5c58a372 [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:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000022 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':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000025 attempdirs.insert(0, 'C:\\TEMP')
26 attempdirs.insert(0, '\\TEMP')
Guido van Rossumf4f756c1997-04-11 19:00:53 +000027 elif os.name == 'mac':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000028 import macfs, MACFS
29 try:
30 refnum, dirid = macfs.FindFolder(MACFS.kOnSystemDisk,
31 MACFS.kTemporaryFolderType, 0)
32 dirname = macfs.FSSpec((refnum, dirid, '')).as_pathname()
33 attempdirs.insert(0, dirname)
34 except macfs.error:
35 pass
Guido van Rossumca549821997-08-12 18:00:12 +000036 for envname in 'TMPDIR', 'TEMP', 'TMP':
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000037 if os.environ.has_key(envname):
38 attempdirs.insert(0, os.environ[envname])
Guido van Rossum3e065ad1996-08-20 20:38:59 +000039 testfile = gettempprefix() + 'test'
Guido van Rossumf4aaf861996-05-28 23:31:34 +000040 for dir in attempdirs:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000041 try:
42 filename = os.path.join(dir, testfile)
43 fp = open(filename, 'w')
44 fp.write('blat')
45 fp.close()
46 os.unlink(filename)
47 tempdir = dir
48 break
49 except IOError:
50 pass
Guido van Rossumf4aaf861996-05-28 23:31:34 +000051 if tempdir is None:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000052 msg = "Can't find a usable temporary directory amongst " + `attempdirs`
53 raise IOError, msg
Guido van Rossumf4aaf861996-05-28 23:31:34 +000054 return tempdir
Guido van Rossum41f95031992-03-31 19:02:01 +000055
56
57# Function to calculate a prefix of the filename to use
58
59def gettempprefix():
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000060 global template
61 if template == None:
62 if os.name == 'posix':
63 template = '@' + `os.getpid()` + '.'
64 elif os.name == 'nt':
65 template = '~' + `os.getpid()` + '-'
66 elif os.name == 'mac':
67 template = 'Python-Tmp-'
68 else:
69 template = 'tmp' # XXX might choose a better one
70 return template
Guido van Rossumcff34541992-01-14 18:31:56 +000071
Guido van Rossumeee94981991-11-12 15:38:08 +000072
Guido van Rossum4a3a41f1991-12-26 13:10:50 +000073# Counter for generating unique names
Guido van Rossumeee94981991-11-12 15:38:08 +000074
Guido van Rossum4a3a41f1991-12-26 13:10:50 +000075counter = 0
Guido van Rossumeee94981991-11-12 15:38:08 +000076
77
Guido van Rossum41f95031992-03-31 19:02:01 +000078# User-callable function to return a unique temporary file name
Guido van Rossumeee94981991-11-12 15:38:08 +000079
Guido van Rossumb8c42c91997-12-19 04:29:50 +000080def mktemp(suffix=""):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000081 global counter
82 dir = gettempdir()
83 pre = gettempprefix()
84 while 1:
85 counter = counter + 1
86 file = os.path.join(dir, pre + `counter` + suffix)
87 if not os.path.exists(file):
88 return file
Guido van Rossumca549821997-08-12 18:00:12 +000089
90
91class TemporaryFileWrapper:
92 """Temporary file wrapper
93
94 This class provides a wrapper around files opened for temporary use.
95 In particular, it seeks to automatically remove the file when it is
96 no longer needed.
97 """
98 def __init__(self, file, path):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +000099 self.file = file
100 self.path = path
Guido van Rossumca549821997-08-12 18:00:12 +0000101
102 def close(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000103 self.file.close()
104 os.unlink(self.path)
Guido van Rossumca549821997-08-12 18:00:12 +0000105
106 def __del__(self):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000107 try: self.close()
108 except: pass
Guido van Rossumca549821997-08-12 18:00:12 +0000109
110 def __getattr__(self, name):
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000111 file = self.__dict__['file']
112 a = getattr(file, name)
113 setattr(self, name, a)
114 return a
Guido van Rossumca549821997-08-12 18:00:12 +0000115
116
Guido van Rossumb8c42c91997-12-19 04:29:50 +0000117def TemporaryFile(mode='w+b', bufsize=-1, suffix=""):
118 name = mktemp(suffix)
119 file = open(name, mode, bufsize)
Guido van Rossumca549821997-08-12 18:00:12 +0000120 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000121 os.unlink(name)
Guido van Rossumca549821997-08-12 18:00:12 +0000122 except os.error:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000123 # Non-unix -- can't unlink file that's still open, use wrapper
124 return TemporaryFileWrapper(file, name)
Guido van Rossumca549821997-08-12 18:00:12 +0000125 else:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000126 return file