blob: 2403f30c2f432fa55cd59ee89574877e1d442d99 [file] [log] [blame]
Georg Brandlbde4ad42006-01-20 21:36:02 +00001r"""OS routines for Mac, NT, or Posix depending on what system we're on.
Guido van Rossum31104f41992-01-14 18:28:36 +00002
Guido van Rossum54f22ed2000-02-04 15:10:34 +00003This exports:
Alexandre Vassalottieca20b62008-05-16 02:54:33 +00004 - all functions from posix, nt, os2, or ce, e.g. unlink, stat, etc.
5 - os.path is either posixpath or ntpath
6 - os.name is either 'posix', 'nt', 'os2' or 'ce'.
Guido van Rossum54f22ed2000-02-04 15:10:34 +00007 - os.curdir is a string representing the current directory ('.' or ':')
8 - os.pardir is a string representing the parent directory ('..' or '::')
9 - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\')
Georg Brandled5b9b32008-12-05 07:45:54 +000010 - os.extsep is the extension separator (always '.')
Guido van Rossum4b8c6ea2000-02-04 15:39:30 +000011 - os.altsep is the alternate pathname separator (None or '/')
Guido van Rossum54f22ed2000-02-04 15:10:34 +000012 - os.pathsep is the component separator used in $PATH etc
Guido van Rossum4b8c6ea2000-02-04 15:39:30 +000013 - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
Guido van Rossum54f22ed2000-02-04 15:10:34 +000014 - os.defpath is the default search path for executables
Martin v. Löwisbdec50f2004-06-08 08:29:33 +000015 - os.devnull is the file path of the null device ('/dev/null', etc.)
Guido van Rossum31104f41992-01-14 18:28:36 +000016
Guido van Rossum54f22ed2000-02-04 15:10:34 +000017Programs that import and use 'os' stand a better chance of being
18portable between different platforms. Of course, they must then
19only use functions that are defined by all platforms (e.g., unlink
20and opendir), and leave all pathname manipulation to os.path
21(e.g., split and join).
22"""
Guido van Rossum31104f41992-01-14 18:28:36 +000023
Skip Montanaro269b83b2001-02-06 01:07:02 +000024#'
25
Christian Heimes45f9af32007-11-27 21:50:00 +000026import sys, errno
Charles-François Natali7372b062012-02-05 15:15:38 +010027import stat as st
Guido van Rossuma28dab51997-08-29 22:36:47 +000028
29_names = sys.builtin_module_names
30
Tim Petersc4e09402003-04-25 07:11:48 +000031# Note: more names are added to __all__ later.
Brett Cannon13962fc2008-08-18 01:45:29 +000032__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
Martin v. Löwis22b457e2005-01-16 08:40:58 +000033 "defpath", "name", "path", "devnull",
34 "SEEK_SET", "SEEK_CUR", "SEEK_END"]
Skip Montanaro269b83b2001-02-06 01:07:02 +000035
Charles-François Natali7372b062012-02-05 15:15:38 +010036def _exists(name):
37 return name in globals()
38
Skip Montanaro269b83b2001-02-06 01:07:02 +000039def _get_exports_list(module):
40 try:
41 return list(module.__all__)
42 except AttributeError:
43 return [n for n in dir(module) if n[0] != '_']
44
Brett Cannonfd074152012-04-14 14:10:13 -040045# Any new dependencies of the os module and/or changes in path separator
46# requires updating importlib as well.
Guido van Rossuma28dab51997-08-29 22:36:47 +000047if 'posix' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000048 name = 'posix'
Guido van Rossume9387ea1998-05-22 15:26:04 +000049 linesep = '\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000050 from posix import *
51 try:
52 from posix import _exit
53 except ImportError:
54 pass
Skip Montanaro117910d2003-02-14 19:35:31 +000055 import posixpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000056
Skip Montanaro269b83b2001-02-06 01:07:02 +000057 import posix
58 __all__.extend(_get_exports_list(posix))
59 del posix
60
Guido van Rossuma28dab51997-08-29 22:36:47 +000061elif 'nt' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000062 name = 'nt'
Guido van Rossume9387ea1998-05-22 15:26:04 +000063 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000064 from nt import *
Tim Peters6757c1e2003-01-08 21:20:57 +000065 try:
66 from nt import _exit
67 except ImportError:
68 pass
Skip Montanaro117910d2003-02-14 19:35:31 +000069 import ntpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000070
Skip Montanaro269b83b2001-02-06 01:07:02 +000071 import nt
72 __all__.extend(_get_exports_list(nt))
73 del nt
74
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000075elif 'os2' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000076 name = 'os2'
Guido van Rossume9387ea1998-05-22 15:26:04 +000077 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000078 from os2 import *
79 try:
80 from os2 import _exit
81 except ImportError:
82 pass
Andrew MacIntyre5cef5712002-02-24 05:32:32 +000083 if sys.version.find('EMX GCC') == -1:
Skip Montanaro117910d2003-02-14 19:35:31 +000084 import ntpath as path
Andrew MacIntyre5cef5712002-02-24 05:32:32 +000085 else:
Skip Montanaro117910d2003-02-14 19:35:31 +000086 import os2emxpath as path
Andrew MacIntyre89f98652003-12-02 12:33:01 +000087 from _emx_link import link
Tim Petersf2715e02003-02-19 02:35:07 +000088
Skip Montanaro269b83b2001-02-06 01:07:02 +000089 import os2
90 __all__.extend(_get_exports_list(os2))
91 del os2
92
Guido van Rossum18df5d41999-06-11 01:37:27 +000093elif 'ce' in _names:
94 name = 'ce'
95 linesep = '\r\n'
Guido van Rossum18df5d41999-06-11 01:37:27 +000096 from ce import *
Tim Peters6757c1e2003-01-08 21:20:57 +000097 try:
98 from ce import _exit
99 except ImportError:
100 pass
Guido van Rossum18df5d41999-06-11 01:37:27 +0000101 # We can use the standard Windows path.
Skip Montanaro117910d2003-02-14 19:35:31 +0000102 import ntpath as path
Tim Petersf2715e02003-02-19 02:35:07 +0000103
Skip Montanaro269b83b2001-02-06 01:07:02 +0000104 import ce
105 __all__.extend(_get_exports_list(ce))
106 del ce
107
Guido van Rossum2979b011994-08-01 11:18:30 +0000108else:
Collin Winter828f04a2007-08-31 00:04:24 +0000109 raise ImportError('no os specific module found')
Guido van Rossume65cce51993-11-08 15:05:21 +0000110
Skip Montanaro117910d2003-02-14 19:35:31 +0000111sys.modules['os.path'] = path
Georg Brandled5b9b32008-12-05 07:45:54 +0000112from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
113 devnull)
Skip Montanaro269b83b2001-02-06 01:07:02 +0000114
Guido van Rossuma28dab51997-08-29 22:36:47 +0000115del _names
116
Martin v. Löwis22b457e2005-01-16 08:40:58 +0000117# Python uses fixed values for the SEEK_ constants; they are mapped
118# to native constants if necessary in posixmodule.c
Jesus Cea2b47f0a2012-04-26 16:39:35 +0200119# Other possible SEEK values are directly imported from posixmodule.c
Martin v. Löwis22b457e2005-01-16 08:40:58 +0000120SEEK_SET = 0
121SEEK_CUR = 1
122SEEK_END = 2
123
Terry Reedy5a22b652010-12-02 07:05:56 +0000124
125def _get_masked_mode(mode):
126 mask = umask(0)
127 umask(mask)
128 return mode & ~mask
129
Guido van Rossum4def7de1998-07-24 20:48:03 +0000130# Super directory utilities.
131# (Inspired by Eric Raymond; the doc strings are mostly his)
132
Terry Reedy5a22b652010-12-02 07:05:56 +0000133def makedirs(name, mode=0o777, exist_ok=False):
134 """makedirs(path [, mode=0o777][, exist_ok=False])
Guido van Rossum4def7de1998-07-24 20:48:03 +0000135
136 Super-mkdir; create a leaf directory and all intermediate ones.
137 Works like mkdir, except that any intermediate path segment (not
Terry Reedy5a22b652010-12-02 07:05:56 +0000138 just the rightmost) will be created if it does not exist. If the
139 target directory with the same mode as we specified already exists,
140 raises an OSError if exist_ok is False, otherwise no exception is
141 raised. This is recursive.
Guido van Rossum4def7de1998-07-24 20:48:03 +0000142
143 """
144 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000145 if not tail:
146 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000147 if head and tail and not path.exists(head):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000148 try:
Terry Reedy5a22b652010-12-02 07:05:56 +0000149 makedirs(head, mode, exist_ok)
Guido van Rossumb940e112007-01-10 16:19:56 +0000150 except OSError as e:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000151 # be happy if someone already created the path
Christian Heimes45f9af32007-11-27 21:50:00 +0000152 if e.errno != errno.EEXIST:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000153 raise
Andrew M. Kuchling6fccc8a2003-12-23 16:33:28 +0000154 if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists
155 return
Terry Reedy5a22b652010-12-02 07:05:56 +0000156 try:
157 mkdir(name, mode)
158 except OSError as e:
Terry Reedy5a22b652010-12-02 07:05:56 +0000159 if not (e.errno == errno.EEXIST and exist_ok and path.isdir(name) and
160 st.S_IMODE(lstat(name).st_mode) == _get_masked_mode(mode)):
161 raise
Guido van Rossum4def7de1998-07-24 20:48:03 +0000162
163def removedirs(name):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000164 """removedirs(path)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000165
Fredrik Lundh96c1c7a2005-11-12 15:55:04 +0000166 Super-rmdir; remove a leaf directory and all empty intermediate
Guido van Rossum4def7de1998-07-24 20:48:03 +0000167 ones. Works like rmdir except that, if the leaf directory is
168 successfully removed, directories corresponding to rightmost path
Tim Petersc4e09402003-04-25 07:11:48 +0000169 segments will be pruned away until either the whole path is
Guido van Rossum4def7de1998-07-24 20:48:03 +0000170 consumed or an error occurs. Errors during this latter phase are
171 ignored -- they generally mean that a directory was not empty.
172
173 """
174 rmdir(name)
175 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000176 if not tail:
177 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000178 while head and tail:
179 try:
180 rmdir(head)
181 except error:
182 break
183 head, tail = path.split(head)
184
185def renames(old, new):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000186 """renames(old, new)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000187
188 Super-rename; create directories as necessary and delete any left
189 empty. Works like rename, except creation of any intermediate
190 directories needed to make the new pathname good is attempted
191 first. After the rename, directories corresponding to rightmost
192 path segments of the old name will be pruned way until either the
193 whole path is consumed or a nonempty directory is found.
194
195 Note: this function can fail with the new directory structure made
196 if you lack permissions needed to unlink the leaf directory or
197 file.
198
199 """
200 head, tail = path.split(new)
201 if head and tail and not path.exists(head):
202 makedirs(head)
203 rename(old, new)
204 head, tail = path.split(old)
205 if head and tail:
206 try:
207 removedirs(head)
208 except error:
209 pass
210
Skip Montanaro269b83b2001-02-06 01:07:02 +0000211__all__.extend(["makedirs", "removedirs", "renames"])
212
Guido van Rossumd8faa362007-04-27 19:54:29 +0000213def walk(top, topdown=True, onerror=None, followlinks=False):
Tim Petersc4e09402003-04-25 07:11:48 +0000214 """Directory tree generator.
215
216 For each directory in the directory tree rooted at top (including top
217 itself, but excluding '.' and '..'), yields a 3-tuple
218
219 dirpath, dirnames, filenames
220
221 dirpath is a string, the path to the directory. dirnames is a list of
222 the names of the subdirectories in dirpath (excluding '.' and '..').
223 filenames is a list of the names of the non-directory files in dirpath.
224 Note that the names in the lists are just names, with no path components.
225 To get a full path (which begins with top) to a file or directory in
226 dirpath, do os.path.join(dirpath, name).
227
228 If optional arg 'topdown' is true or not specified, the triple for a
229 directory is generated before the triples for any of its subdirectories
230 (directories are generated top down). If topdown is false, the triple
231 for a directory is generated after the triples for all of its
232 subdirectories (directories are generated bottom up).
233
234 When topdown is true, the caller can modify the dirnames list in-place
235 (e.g., via del or slice assignment), and walk will only recurse into the
236 subdirectories whose names remain in dirnames; this can be used to prune
237 the search, or to impose a specific order of visiting. Modifying
238 dirnames when topdown is false is ineffective, since the directories in
239 dirnames have already been generated by the time dirnames itself is
240 generated.
241
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000242 By default errors from the os.listdir() call are ignored. If
243 optional arg 'onerror' is specified, it should be a function; it
244 will be called with one argument, an os.error instance. It can
245 report the error to continue with the walk, or raise the exception
246 to abort the walk. Note that the filename is available as the
247 filename attribute of the exception object.
248
Guido van Rossumd8faa362007-04-27 19:54:29 +0000249 By default, os.walk does not follow symbolic links to subdirectories on
250 systems that support them. In order to get this functionality, set the
251 optional argument 'followlinks' to true.
252
Tim Petersc4e09402003-04-25 07:11:48 +0000253 Caution: if you pass a relative pathname for top, don't change the
254 current working directory between resumptions of walk. walk never
255 changes the current directory, and assumes that the client doesn't
256 either.
257
258 Example:
259
Christian Heimes5d8da202008-05-06 13:58:24 +0000260 import os
Tim Petersc4e09402003-04-25 07:11:48 +0000261 from os.path import join, getsize
Christian Heimes5d8da202008-05-06 13:58:24 +0000262 for root, dirs, files in os.walk('python/Lib/email'):
Neal Norwitz752abd02008-05-13 04:55:24 +0000263 print(root, "consumes", end="")
264 print(sum([getsize(join(root, name)) for name in files]), end="")
265 print("bytes in", len(files), "non-directory files")
Tim Petersc4e09402003-04-25 07:11:48 +0000266 if 'CVS' in dirs:
267 dirs.remove('CVS') # don't visit CVS directories
268 """
269
Benjamin Petersonf6489f92009-11-25 17:46:26 +0000270 islink, join, isdir = path.islink, path.join, path.isdir
Tim Petersc4e09402003-04-25 07:11:48 +0000271
272 # We may not have read permission for top, in which case we can't
Alexandre Vassalotti4e6531e2008-05-09 20:00:17 +0000273 # get a list of the files the directory contains. os.walk
Tim Petersc4e09402003-04-25 07:11:48 +0000274 # always suppressed the exception then, rather than blow up for a
275 # minor reason when (say) a thousand readable directories are still
276 # left to visit. That logic is copied here.
277 try:
278 # Note that listdir and error are globals in this module due
279 # to earlier import-*.
280 names = listdir(top)
Guido van Rossumb940e112007-01-10 16:19:56 +0000281 except error as err:
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000282 if onerror is not None:
283 onerror(err)
Tim Petersc4e09402003-04-25 07:11:48 +0000284 return
285
286 dirs, nondirs = [], []
287 for name in names:
288 if isdir(join(top, name)):
289 dirs.append(name)
290 else:
291 nondirs.append(name)
292
293 if topdown:
294 yield top, dirs, nondirs
295 for name in dirs:
Benjamin Petersonf6489f92009-11-25 17:46:26 +0000296 new_path = join(top, name)
297 if followlinks or not islink(new_path):
298 for x in walk(new_path, topdown, onerror, followlinks):
Tim Petersc4e09402003-04-25 07:11:48 +0000299 yield x
300 if not topdown:
301 yield top, dirs, nondirs
302
303__all__.append("walk")
304
Charles-François Natali7372b062012-02-05 15:15:38 +0100305if _exists("openat"):
306
307 def fwalk(top, topdown=True, onerror=None, followlinks=False):
308 """Directory tree generator.
309
310 This behaves exactly like walk(), except that it yields a 4-tuple
311
312 dirpath, dirnames, filenames, dirfd
313
314 `dirpath`, `dirnames` and `filenames` are identical to walk() output,
315 and `dirfd` is a file descriptor referring to the directory `dirpath`.
316
317 The advantage of walkfd() over walk() is that it's safe against symlink
318 races (when followlinks is False).
319
320 Caution:
321 Since fwalk() yields file descriptors, those are only valid until the
322 next iteration step, so you should dup() them if you want to keep them
323 for a longer period.
324
325 Example:
326
327 import os
328 for root, dirs, files, rootfd in os.fwalk('python/Lib/email'):
329 print(root, "consumes", end="")
330 print(sum([os.fstatat(rootfd, name).st_size for name in files]),
331 end="")
332 print("bytes in", len(files), "non-directory files")
333 if 'CVS' in dirs:
334 dirs.remove('CVS') # don't visit CVS directories
335 """
336 # Note: To guard against symlink races, we use the standard
337 # lstat()/open()/fstat() trick.
338 orig_st = lstat(top)
339 topfd = open(top, O_RDONLY)
340 try:
341 if (followlinks or (st.S_ISDIR(orig_st.st_mode) and
Charles-François Natali84c0ca02012-04-22 15:55:43 +0200342 path.samestat(orig_st, fstat(topfd)))):
Charles-François Natali7372b062012-02-05 15:15:38 +0100343 for x in _fwalk(topfd, top, topdown, onerror, followlinks):
344 yield x
345 finally:
346 close(topfd)
347
348 def _fwalk(topfd, toppath, topdown, onerror, followlinks):
349 # Note: This uses O(depth of the directory tree) file descriptors: if
350 # necessary, it can be adapted to only require O(1) FDs, see issue
351 # #13734.
352
353 # whether to follow symlinks
354 flag = 0 if followlinks else AT_SYMLINK_NOFOLLOW
355
Charles-François Natali77940902012-02-06 19:54:48 +0100356 names = flistdir(topfd)
Charles-François Natali7372b062012-02-05 15:15:38 +0100357 dirs, nondirs = [], []
358 for name in names:
359 # Here, we don't use AT_SYMLINK_NOFOLLOW to be consistent with
360 # walk() which reports symlinks to directories as directories. We do
361 # however check for symlinks before recursing into a subdirectory.
362 if st.S_ISDIR(fstatat(topfd, name).st_mode):
363 dirs.append(name)
364 else:
365 nondirs.append(name)
366
367 if topdown:
368 yield toppath, dirs, nondirs, topfd
369
370 for name in dirs:
371 try:
372 orig_st = fstatat(topfd, name, flag)
373 dirfd = openat(topfd, name, O_RDONLY)
374 except error as err:
375 if onerror is not None:
376 onerror(err)
377 return
378 try:
Charles-François Natali84c0ca02012-04-22 15:55:43 +0200379 if followlinks or path.samestat(orig_st, fstat(dirfd)):
Charles-François Natali7372b062012-02-05 15:15:38 +0100380 dirpath = path.join(toppath, name)
381 for x in _fwalk(dirfd, dirpath, topdown, onerror, followlinks):
382 yield x
383 finally:
384 close(dirfd)
385
386 if not topdown:
387 yield toppath, dirs, nondirs, topfd
388
389 __all__.append("fwalk")
390
Guido van Rossuma28dab51997-08-29 22:36:47 +0000391# Make sure os.environ exists, at least
392try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000393 environ
Guido van Rossuma28dab51997-08-29 22:36:47 +0000394except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000395 environ = {}
Guido van Rossuma28dab51997-08-29 22:36:47 +0000396
Guido van Rossume65cce51993-11-08 15:05:21 +0000397def execl(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000398 """execl(file, *args)
399
400 Execute the executable file with argument list args, replacing the
401 current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000402 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000403
404def execle(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000405 """execle(file, *args, env)
406
407 Execute the executable file with argument list args and
408 environment env, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000409 env = args[-1]
410 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000411
412def execlp(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000413 """execlp(file, *args)
414
415 Execute the executable file (which is searched for along $PATH)
416 with argument list args, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000417 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000418
Guido van Rossum030afb11995-03-14 17:27:18 +0000419def execlpe(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000420 """execlpe(file, *args, env)
421
422 Execute the executable file (which is searched for along $PATH)
423 with argument list args and environment env, replacing the current
Tim Peters2344fae2001-01-15 00:50:52 +0000424 process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000425 env = args[-1]
426 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000427
Guido van Rossume65cce51993-11-08 15:05:21 +0000428def execvp(file, args):
Matthias Klosea09c54f2010-01-31 16:48:44 +0000429 """execvp(file, args)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000430
431 Execute the executable file (which is searched for along $PATH)
432 with argument list args, replacing the current process.
Thomas Wouters7e474022000-07-16 12:04:32 +0000433 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000434 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000435
436def execvpe(file, args, env):
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000437 """execvpe(file, args, env)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000438
439 Execute the executable file (which is searched for along $PATH)
440 with argument list args and environment env , replacing the
441 current process.
Tim Peters2344fae2001-01-15 00:50:52 +0000442 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000443 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000444
Skip Montanaro269b83b2001-02-06 01:07:02 +0000445__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
446
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000447def _execvpe(file, args, env=None):
448 if env is not None:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000449 exec_func = execve
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000450 argrest = (args, env)
451 else:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000452 exec_func = execv
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000453 argrest = (args,)
454 env = environ
Guido van Rossumaed51d82002-08-05 16:13:24 +0000455
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000456 head, tail = path.split(file)
457 if head:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000458 exec_func(file, *argrest)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000459 return
Guido van Rossume7ba4952007-06-06 23:52:48 +0000460 last_exc = saved_exc = None
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000461 saved_tb = None
Victor Stinnerb745a742010-05-18 17:17:23 +0000462 path_list = get_exec_path(env)
463 if name != 'nt':
464 file = fsencode(file)
465 path_list = map(fsencode, path_list)
466 for dir in path_list:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000467 fullname = path.join(dir, file)
468 try:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000469 exec_func(fullname, *argrest)
Guido van Rossumb940e112007-01-10 16:19:56 +0000470 except error as e:
Guido van Rossume7ba4952007-06-06 23:52:48 +0000471 last_exc = e
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000472 tb = sys.exc_info()[2]
Christian Heimes45f9af32007-11-27 21:50:00 +0000473 if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000474 and saved_exc is None):
475 saved_exc = e
476 saved_tb = tb
477 if saved_exc:
Benjamin Peterson4b068192009-02-20 03:19:25 +0000478 raise saved_exc.with_traceback(saved_tb)
479 raise last_exc.with_traceback(tb)
Guido van Rossumd74fb6b2001-03-02 06:43:49 +0000480
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000481
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000482def get_exec_path(env=None):
483 """Returns the sequence of directories that will be searched for the
484 named executable (similar to a shell) when launching a process.
485
486 *env* must be an environment variable dict or None. If *env* is None,
487 os.environ will be used.
488 """
Victor Stinner273b7662010-11-06 12:59:33 +0000489 # Use a local import instead of a global import to limit the number of
490 # modules loaded at startup: the os module is always loaded at startup by
491 # Python. It may also avoid a bootstrap issue.
Victor Stinner6f35eda2010-10-29 00:38:58 +0000492 import warnings
493
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000494 if env is None:
495 env = environ
Victor Stinnerb745a742010-05-18 17:17:23 +0000496
Victor Stinnerbb4f2182010-11-07 15:43:39 +0000497 # {b'PATH': ...}.get('PATH') and {'PATH': ...}.get(b'PATH') emit a
498 # BytesWarning when using python -b or python -bb: ignore the warning
Victor Stinner273b7662010-11-06 12:59:33 +0000499 with warnings.catch_warnings():
500 warnings.simplefilter("ignore", BytesWarning)
Victor Stinnerb745a742010-05-18 17:17:23 +0000501
Victor Stinnerb745a742010-05-18 17:17:23 +0000502 try:
Victor Stinner273b7662010-11-06 12:59:33 +0000503 path_list = env.get('PATH')
504 except TypeError:
505 path_list = None
Victor Stinnerb745a742010-05-18 17:17:23 +0000506
Victor Stinner273b7662010-11-06 12:59:33 +0000507 if supports_bytes_environ:
508 try:
509 path_listb = env[b'PATH']
510 except (KeyError, TypeError):
511 pass
512 else:
513 if path_list is not None:
514 raise ValueError(
515 "env cannot contain 'PATH' and b'PATH' keys")
516 path_list = path_listb
517
518 if path_list is not None and isinstance(path_list, bytes):
519 path_list = fsdecode(path_list)
Victor Stinnerb745a742010-05-18 17:17:23 +0000520
521 if path_list is None:
522 path_list = defpath
523 return path_list.split(pathsep)
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000524
525
Skip Montanaro289bc052007-08-17 02:30:27 +0000526# Change environ to automatically call putenv(), unsetenv if they exist.
Raymond Hettinger158c9c22011-02-22 00:41:50 +0000527from collections.abc import MutableMapping
Skip Montanaro289bc052007-08-17 02:30:27 +0000528
529class _Environ(MutableMapping):
Victor Stinner84ae1182010-05-06 22:05:07 +0000530 def __init__(self, data, encodekey, decodekey, encodevalue, decodevalue, putenv, unsetenv):
531 self.encodekey = encodekey
532 self.decodekey = decodekey
533 self.encodevalue = encodevalue
534 self.decodevalue = decodevalue
Skip Montanaro289bc052007-08-17 02:30:27 +0000535 self.putenv = putenv
536 self.unsetenv = unsetenv
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000537 self._data = data
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000538
Skip Montanaro289bc052007-08-17 02:30:27 +0000539 def __getitem__(self, key):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000540 value = self._data[self.encodekey(key)]
Victor Stinner84ae1182010-05-06 22:05:07 +0000541 return self.decodevalue(value)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000542
Skip Montanaro289bc052007-08-17 02:30:27 +0000543 def __setitem__(self, key, value):
Victor Stinner84ae1182010-05-06 22:05:07 +0000544 key = self.encodekey(key)
545 value = self.encodevalue(value)
Skip Montanaro289bc052007-08-17 02:30:27 +0000546 self.putenv(key, value)
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000547 self._data[key] = value
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000548
Skip Montanaro289bc052007-08-17 02:30:27 +0000549 def __delitem__(self, key):
Victor Stinner84ae1182010-05-06 22:05:07 +0000550 key = self.encodekey(key)
Skip Montanaro289bc052007-08-17 02:30:27 +0000551 self.unsetenv(key)
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000552 del self._data[key]
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000553
Skip Montanaro289bc052007-08-17 02:30:27 +0000554 def __iter__(self):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000555 for key in self._data:
Victor Stinner84ae1182010-05-06 22:05:07 +0000556 yield self.decodekey(key)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000557
Skip Montanaro289bc052007-08-17 02:30:27 +0000558 def __len__(self):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000559 return len(self._data)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000560
561 def __repr__(self):
Victor Stinnerbed71172010-07-28 21:25:42 +0000562 return 'environ({{{}}})'.format(', '.join(
Victor Stinnerd73c1a32010-07-28 21:23:23 +0000563 ('{!r}: {!r}'.format(self.decodekey(key), self.decodevalue(value))
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000564 for key, value in self._data.items())))
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000565
Skip Montanaro289bc052007-08-17 02:30:27 +0000566 def copy(self):
567 return dict(self)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000568
Skip Montanaro289bc052007-08-17 02:30:27 +0000569 def setdefault(self, key, value):
570 if key not in self:
571 self[key] = value
572 return self[key]
573
574try:
575 _putenv = putenv
576except NameError:
577 _putenv = lambda key, value: None
Martin v. Löwisa90f4382001-03-07 09:05:45 +0000578else:
Skip Montanaro289bc052007-08-17 02:30:27 +0000579 __all__.append("putenv")
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000580
Skip Montanaro289bc052007-08-17 02:30:27 +0000581try:
582 _unsetenv = unsetenv
583except NameError:
584 _unsetenv = lambda key: _putenv(key, "")
585else:
586 __all__.append("unsetenv")
Guido van Rossumc524d952001-10-19 01:31:59 +0000587
Victor Stinner84ae1182010-05-06 22:05:07 +0000588def _createenviron():
589 if name in ('os2', 'nt'):
590 # Where Env Var Names Must Be UPPERCASE
591 def check_str(value):
592 if not isinstance(value, str):
593 raise TypeError("str expected, not %s" % type(value).__name__)
594 return value
595 encode = check_str
596 decode = str
597 def encodekey(key):
598 return encode(key).upper()
599 data = {}
600 for key, value in environ.items():
601 data[encodekey(key)] = value
602 else:
603 # Where Env Var Names Can Be Mixed Case
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000604 encoding = sys.getfilesystemencoding()
Victor Stinner84ae1182010-05-06 22:05:07 +0000605 def encode(value):
606 if not isinstance(value, str):
607 raise TypeError("str expected, not %s" % type(value).__name__)
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000608 return value.encode(encoding, 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000609 def decode(value):
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000610 return value.decode(encoding, 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000611 encodekey = encode
612 data = environ
613 return _Environ(data,
614 encodekey, decode,
615 encode, decode,
616 _putenv, _unsetenv)
Guido van Rossumc524d952001-10-19 01:31:59 +0000617
Victor Stinner84ae1182010-05-06 22:05:07 +0000618# unicode environ
619environ = _createenviron()
620del _createenviron
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000621
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000622
Jack Jansenb11ce9b2003-01-08 16:33:40 +0000623def getenv(key, default=None):
Tim Peters2c60f7a2003-01-29 03:49:43 +0000624 """Get an environment variable, return None if it doesn't exist.
Victor Stinner84ae1182010-05-06 22:05:07 +0000625 The optional second argument can specify an alternate default.
626 key, default and the result are str."""
Tim Peters2c60f7a2003-01-29 03:49:43 +0000627 return environ.get(key, default)
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000628
Victor Stinnerb745a742010-05-18 17:17:23 +0000629supports_bytes_environ = name not in ('os2', 'nt')
630__all__.extend(("getenv", "supports_bytes_environ"))
631
632if supports_bytes_environ:
Victor Stinner84ae1182010-05-06 22:05:07 +0000633 def _check_bytes(value):
634 if not isinstance(value, bytes):
635 raise TypeError("bytes expected, not %s" % type(value).__name__)
636 return value
637
638 # bytes environ
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000639 environb = _Environ(environ._data,
Victor Stinner84ae1182010-05-06 22:05:07 +0000640 _check_bytes, bytes,
641 _check_bytes, bytes,
642 _putenv, _unsetenv)
643 del _check_bytes
644
645 def getenvb(key, default=None):
646 """Get an environment variable, return None if it doesn't exist.
647 The optional second argument can specify an alternate default.
648 key, default and the result are bytes."""
649 return environb.get(key, default)
Victor Stinner70120e22010-07-29 17:19:38 +0000650
651 __all__.extend(("environb", "getenvb"))
Victor Stinner84ae1182010-05-06 22:05:07 +0000652
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000653def _fscodec():
654 encoding = sys.getfilesystemencoding()
655 if encoding == 'mbcs':
Victor Stinnere882aac2010-10-24 21:12:26 +0000656 errors = 'strict'
Victor Stinner313a1202010-06-11 23:56:51 +0000657 else:
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000658 errors = 'surrogateescape'
Victor Stinnere8d51452010-08-19 01:05:19 +0000659
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000660 def fsencode(filename):
661 """
662 Encode filename to the filesystem encoding with 'surrogateescape' error
663 handler, return bytes unchanged. On Windows, use 'strict' error handler if
664 the file system encoding is 'mbcs' (which is the default encoding).
665 """
666 if isinstance(filename, bytes):
667 return filename
668 elif isinstance(filename, str):
669 return filename.encode(encoding, errors)
Victor Stinnere8d51452010-08-19 01:05:19 +0000670 else:
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000671 raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
672
673 def fsdecode(filename):
674 """
675 Decode filename from the filesystem encoding with 'surrogateescape' error
676 handler, return str unchanged. On Windows, use 'strict' error handler if
677 the file system encoding is 'mbcs' (which is the default encoding).
678 """
679 if isinstance(filename, str):
680 return filename
681 elif isinstance(filename, bytes):
682 return filename.decode(encoding, errors)
683 else:
684 raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
685
686 return fsencode, fsdecode
687
688fsencode, fsdecode = _fscodec()
689del _fscodec
Victor Stinner449c4662010-05-08 11:10:09 +0000690
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000691# Supply spawn*() (probably only for Unix)
692if _exists("fork") and not _exists("spawnv") and _exists("execv"):
693
694 P_WAIT = 0
695 P_NOWAIT = P_NOWAITO = 1
696
697 # XXX Should we support P_DETACH? I suppose it could fork()**2
698 # and close the std I/O streams. Also, P_OVERLAY is the same
699 # as execv*()?
700
701 def _spawnvef(mode, file, args, env, func):
702 # Internal helper; func is the exec*() function to use
703 pid = fork()
704 if not pid:
705 # Child
706 try:
707 if env is None:
708 func(file, args)
709 else:
710 func(file, args, env)
711 except:
712 _exit(127)
713 else:
714 # Parent
715 if mode == P_NOWAIT:
716 return pid # Caller is responsible for waiting!
717 while 1:
718 wpid, sts = waitpid(pid, 0)
719 if WIFSTOPPED(sts):
720 continue
721 elif WIFSIGNALED(sts):
722 return -WTERMSIG(sts)
723 elif WIFEXITED(sts):
724 return WEXITSTATUS(sts)
725 else:
Collin Winter828f04a2007-08-31 00:04:24 +0000726 raise error("Not stopped, signaled or exited???")
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000727
728 def spawnv(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000729 """spawnv(mode, file, args) -> integer
730
731Execute file with arguments from args in a subprocess.
732If mode == P_NOWAIT return the pid of the process.
733If mode == P_WAIT return the process's exit code if it exits normally;
Tim Peters2344fae2001-01-15 00:50:52 +0000734otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000735 return _spawnvef(mode, file, args, None, execv)
736
737 def spawnve(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000738 """spawnve(mode, file, args, env) -> integer
739
740Execute file with arguments from args in a subprocess with the
741specified environment.
742If mode == P_NOWAIT return the pid of the process.
743If mode == P_WAIT return the process's exit code if it exits normally;
744otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000745 return _spawnvef(mode, file, args, env, execve)
746
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000747 # Note: spawnvp[e] is't currently supported on Windows
748
749 def spawnvp(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000750 """spawnvp(mode, file, args) -> integer
751
752Execute file (which is looked for along $PATH) with arguments from
753args in a subprocess.
754If mode == P_NOWAIT return the pid of the process.
755If mode == P_WAIT return the process's exit code if it exits normally;
756otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000757 return _spawnvef(mode, file, args, None, execvp)
758
759 def spawnvpe(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000760 """spawnvpe(mode, file, args, env) -> integer
761
762Execute file (which is looked for along $PATH) with arguments from
763args in a subprocess with the supplied environment.
764If mode == P_NOWAIT return the pid of the process.
765If mode == P_WAIT return the process's exit code if it exits normally;
766otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000767 return _spawnvef(mode, file, args, env, execvpe)
768
769if _exists("spawnv"):
770 # These aren't supplied by the basic Windows code
771 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000772
773 def spawnl(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000774 """spawnl(mode, file, *args) -> integer
775
776Execute file with arguments from args in a subprocess.
777If mode == P_NOWAIT return the pid of the process.
778If mode == P_WAIT return the process's exit code if it exits normally;
779otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000780 return spawnv(mode, file, args)
781
782 def spawnle(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000783 """spawnle(mode, file, *args, env) -> integer
784
785Execute file with arguments from args in a subprocess with the
786supplied environment.
787If mode == P_NOWAIT return the pid of the process.
788If mode == P_WAIT return the process's exit code if it exits normally;
789otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000790 env = args[-1]
791 return spawnve(mode, file, args[:-1], env)
792
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000793
794 __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
795
796
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000797if _exists("spawnvp"):
798 # At the moment, Windows doesn't implement spawnvp[e],
799 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000800 def spawnlp(mode, file, *args):
Neal Norwitzb7f68102003-07-02 02:49:33 +0000801 """spawnlp(mode, file, *args) -> integer
Guido van Rossume0cd2912000-04-21 18:35:36 +0000802
803Execute file (which is looked for along $PATH) with arguments from
804args in a subprocess with the supplied environment.
805If mode == P_NOWAIT return the pid of the process.
806If mode == P_WAIT return the process's exit code if it exits normally;
807otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000808 return spawnvp(mode, file, args)
809
810 def spawnlpe(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000811 """spawnlpe(mode, file, *args, env) -> integer
812
813Execute file (which is looked for along $PATH) with arguments from
814args in a subprocess with the supplied environment.
815If mode == P_NOWAIT return the pid of the process.
816If mode == P_WAIT return the process's exit code if it exits normally;
817otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000818 env = args[-1]
819 return spawnvpe(mode, file, args[:-1], env)
Guido van Rossume0cd2912000-04-21 18:35:36 +0000820
821
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000822 __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
Skip Montanaro269b83b2001-02-06 01:07:02 +0000823
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000824import copyreg as _copyreg
Michael W. Hudson0e025302002-03-06 17:11:18 +0000825
826def _make_stat_result(tup, dict):
827 return stat_result(tup, dict)
828
829def _pickle_stat_result(sr):
830 (type, args) = sr.__reduce__()
831 return (_make_stat_result, args)
832
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000833try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000834 _copyreg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000835except NameError: # stat_result may not exist
836 pass
Michael W. Hudson0e025302002-03-06 17:11:18 +0000837
838def _make_statvfs_result(tup, dict):
839 return statvfs_result(tup, dict)
840
841def _pickle_statvfs_result(sr):
842 (type, args) = sr.__reduce__()
843 return (_make_statvfs_result, args)
844
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000845try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000846 _copyreg.pickle(statvfs_result, _pickle_statvfs_result,
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000847 _make_statvfs_result)
Michael W. Hudsone5363b72002-03-15 10:21:59 +0000848except NameError: # statvfs_result may not exist
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000849 pass
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000850
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000851# Supply os.popen()
Antoine Pitrou877766d2011-03-19 17:00:37 +0100852def popen(cmd, mode="r", buffering=-1):
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000853 if not isinstance(cmd, str):
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000854 raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
855 if mode not in ("r", "w"):
856 raise ValueError("invalid mode %r" % mode)
Antoine Pitrou877766d2011-03-19 17:00:37 +0100857 if buffering == 0 or buffering == None:
858 raise ValueError("popen() does not support unbuffered streams")
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000859 import subprocess, io
860 if mode == "r":
861 proc = subprocess.Popen(cmd,
862 shell=True,
863 stdout=subprocess.PIPE,
864 bufsize=buffering)
865 return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
866 else:
867 proc = subprocess.Popen(cmd,
868 shell=True,
869 stdin=subprocess.PIPE,
870 bufsize=buffering)
871 return _wrap_close(io.TextIOWrapper(proc.stdin), proc)
872
873# Helper for popen() -- a proxy for a file whose close waits for the process
874class _wrap_close:
875 def __init__(self, stream, proc):
876 self._stream = stream
877 self._proc = proc
878 def close(self):
879 self._stream.close()
Amaury Forgeot d'Arc97e5f282009-07-11 09:35:13 +0000880 returncode = self._proc.wait()
881 if returncode == 0:
882 return None
883 if name == 'nt':
884 return returncode
885 else:
886 return returncode << 8 # Shift left to match old behavior
Antoine Pitrouac625352009-12-09 00:01:27 +0000887 def __enter__(self):
888 return self
889 def __exit__(self, *args):
890 self.close()
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000891 def __getattr__(self, name):
892 return getattr(self._stream, name)
Thomas Heller476157b2007-09-04 11:27:47 +0000893 def __iter__(self):
894 return iter(self._stream)
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000895
Amaury Forgeot d'Arcbdbddf82008-08-01 00:06:49 +0000896# Supply os.fdopen()
897def fdopen(fd, *args, **kwargs):
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000898 if not isinstance(fd, int):
899 raise TypeError("invalid fd type (%s, expected integer)" % type(fd))
900 import io
Amaury Forgeot d'Arcbdbddf82008-08-01 00:06:49 +0000901 return io.open(fd, *args, **kwargs)