blob: bd1802345bbf8682dff1820f563f4961889469e9 [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
119SEEK_SET = 0
120SEEK_CUR = 1
121SEEK_END = 2
122
Terry Reedy5a22b652010-12-02 07:05:56 +0000123
124def _get_masked_mode(mode):
125 mask = umask(0)
126 umask(mask)
127 return mode & ~mask
128
Charles-François Natali7372b062012-02-05 15:15:38 +0100129def _are_same_file(stat1, stat2):
130 """Helper function that checks whether two stat results refer to the same
131 file.
132 """
133 return (stat1.st_ino == stat2.st_ino and stat1.st_dev == stat2.st_dev)
134#
Skip Montanaro269b83b2001-02-06 01:07:02 +0000135
Guido van Rossum4def7de1998-07-24 20:48:03 +0000136# Super directory utilities.
137# (Inspired by Eric Raymond; the doc strings are mostly his)
138
Terry Reedy5a22b652010-12-02 07:05:56 +0000139def makedirs(name, mode=0o777, exist_ok=False):
140 """makedirs(path [, mode=0o777][, exist_ok=False])
Guido van Rossum4def7de1998-07-24 20:48:03 +0000141
142 Super-mkdir; create a leaf directory and all intermediate ones.
143 Works like mkdir, except that any intermediate path segment (not
Terry Reedy5a22b652010-12-02 07:05:56 +0000144 just the rightmost) will be created if it does not exist. If the
145 target directory with the same mode as we specified already exists,
146 raises an OSError if exist_ok is False, otherwise no exception is
147 raised. This is recursive.
Guido van Rossum4def7de1998-07-24 20:48:03 +0000148
149 """
150 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000151 if not tail:
152 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000153 if head and tail and not path.exists(head):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000154 try:
Terry Reedy5a22b652010-12-02 07:05:56 +0000155 makedirs(head, mode, exist_ok)
Guido van Rossumb940e112007-01-10 16:19:56 +0000156 except OSError as e:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000157 # be happy if someone already created the path
Christian Heimes45f9af32007-11-27 21:50:00 +0000158 if e.errno != errno.EEXIST:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000159 raise
Andrew M. Kuchling6fccc8a2003-12-23 16:33:28 +0000160 if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists
161 return
Terry Reedy5a22b652010-12-02 07:05:56 +0000162 try:
163 mkdir(name, mode)
164 except OSError as e:
Terry Reedy5a22b652010-12-02 07:05:56 +0000165 if not (e.errno == errno.EEXIST and exist_ok and path.isdir(name) and
166 st.S_IMODE(lstat(name).st_mode) == _get_masked_mode(mode)):
167 raise
Guido van Rossum4def7de1998-07-24 20:48:03 +0000168
169def removedirs(name):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000170 """removedirs(path)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000171
Fredrik Lundh96c1c7a2005-11-12 15:55:04 +0000172 Super-rmdir; remove a leaf directory and all empty intermediate
Guido van Rossum4def7de1998-07-24 20:48:03 +0000173 ones. Works like rmdir except that, if the leaf directory is
174 successfully removed, directories corresponding to rightmost path
Tim Petersc4e09402003-04-25 07:11:48 +0000175 segments will be pruned away until either the whole path is
Guido van Rossum4def7de1998-07-24 20:48:03 +0000176 consumed or an error occurs. Errors during this latter phase are
177 ignored -- they generally mean that a directory was not empty.
178
179 """
180 rmdir(name)
181 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000182 if not tail:
183 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000184 while head and tail:
185 try:
186 rmdir(head)
187 except error:
188 break
189 head, tail = path.split(head)
190
191def renames(old, new):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000192 """renames(old, new)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000193
194 Super-rename; create directories as necessary and delete any left
195 empty. Works like rename, except creation of any intermediate
196 directories needed to make the new pathname good is attempted
197 first. After the rename, directories corresponding to rightmost
198 path segments of the old name will be pruned way until either the
199 whole path is consumed or a nonempty directory is found.
200
201 Note: this function can fail with the new directory structure made
202 if you lack permissions needed to unlink the leaf directory or
203 file.
204
205 """
206 head, tail = path.split(new)
207 if head and tail and not path.exists(head):
208 makedirs(head)
209 rename(old, new)
210 head, tail = path.split(old)
211 if head and tail:
212 try:
213 removedirs(head)
214 except error:
215 pass
216
Skip Montanaro269b83b2001-02-06 01:07:02 +0000217__all__.extend(["makedirs", "removedirs", "renames"])
218
Guido van Rossumd8faa362007-04-27 19:54:29 +0000219def walk(top, topdown=True, onerror=None, followlinks=False):
Tim Petersc4e09402003-04-25 07:11:48 +0000220 """Directory tree generator.
221
222 For each directory in the directory tree rooted at top (including top
223 itself, but excluding '.' and '..'), yields a 3-tuple
224
225 dirpath, dirnames, filenames
226
227 dirpath is a string, the path to the directory. dirnames is a list of
228 the names of the subdirectories in dirpath (excluding '.' and '..').
229 filenames is a list of the names of the non-directory files in dirpath.
230 Note that the names in the lists are just names, with no path components.
231 To get a full path (which begins with top) to a file or directory in
232 dirpath, do os.path.join(dirpath, name).
233
234 If optional arg 'topdown' is true or not specified, the triple for a
235 directory is generated before the triples for any of its subdirectories
236 (directories are generated top down). If topdown is false, the triple
237 for a directory is generated after the triples for all of its
238 subdirectories (directories are generated bottom up).
239
240 When topdown is true, the caller can modify the dirnames list in-place
241 (e.g., via del or slice assignment), and walk will only recurse into the
242 subdirectories whose names remain in dirnames; this can be used to prune
243 the search, or to impose a specific order of visiting. Modifying
244 dirnames when topdown is false is ineffective, since the directories in
245 dirnames have already been generated by the time dirnames itself is
246 generated.
247
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000248 By default errors from the os.listdir() call are ignored. If
249 optional arg 'onerror' is specified, it should be a function; it
250 will be called with one argument, an os.error instance. It can
251 report the error to continue with the walk, or raise the exception
252 to abort the walk. Note that the filename is available as the
253 filename attribute of the exception object.
254
Guido van Rossumd8faa362007-04-27 19:54:29 +0000255 By default, os.walk does not follow symbolic links to subdirectories on
256 systems that support them. In order to get this functionality, set the
257 optional argument 'followlinks' to true.
258
Tim Petersc4e09402003-04-25 07:11:48 +0000259 Caution: if you pass a relative pathname for top, don't change the
260 current working directory between resumptions of walk. walk never
261 changes the current directory, and assumes that the client doesn't
262 either.
263
264 Example:
265
Christian Heimes5d8da202008-05-06 13:58:24 +0000266 import os
Tim Petersc4e09402003-04-25 07:11:48 +0000267 from os.path import join, getsize
Christian Heimes5d8da202008-05-06 13:58:24 +0000268 for root, dirs, files in os.walk('python/Lib/email'):
Neal Norwitz752abd02008-05-13 04:55:24 +0000269 print(root, "consumes", end="")
270 print(sum([getsize(join(root, name)) for name in files]), end="")
271 print("bytes in", len(files), "non-directory files")
Tim Petersc4e09402003-04-25 07:11:48 +0000272 if 'CVS' in dirs:
273 dirs.remove('CVS') # don't visit CVS directories
274 """
275
Benjamin Petersonf6489f92009-11-25 17:46:26 +0000276 islink, join, isdir = path.islink, path.join, path.isdir
Tim Petersc4e09402003-04-25 07:11:48 +0000277
278 # We may not have read permission for top, in which case we can't
Alexandre Vassalotti4e6531e2008-05-09 20:00:17 +0000279 # get a list of the files the directory contains. os.walk
Tim Petersc4e09402003-04-25 07:11:48 +0000280 # always suppressed the exception then, rather than blow up for a
281 # minor reason when (say) a thousand readable directories are still
282 # left to visit. That logic is copied here.
283 try:
284 # Note that listdir and error are globals in this module due
285 # to earlier import-*.
286 names = listdir(top)
Guido van Rossumb940e112007-01-10 16:19:56 +0000287 except error as err:
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000288 if onerror is not None:
289 onerror(err)
Tim Petersc4e09402003-04-25 07:11:48 +0000290 return
291
292 dirs, nondirs = [], []
293 for name in names:
294 if isdir(join(top, name)):
295 dirs.append(name)
296 else:
297 nondirs.append(name)
298
299 if topdown:
300 yield top, dirs, nondirs
301 for name in dirs:
Benjamin Petersonf6489f92009-11-25 17:46:26 +0000302 new_path = join(top, name)
303 if followlinks or not islink(new_path):
304 for x in walk(new_path, topdown, onerror, followlinks):
Tim Petersc4e09402003-04-25 07:11:48 +0000305 yield x
306 if not topdown:
307 yield top, dirs, nondirs
308
309__all__.append("walk")
310
Charles-François Natali7372b062012-02-05 15:15:38 +0100311if _exists("openat"):
312
313 def fwalk(top, topdown=True, onerror=None, followlinks=False):
314 """Directory tree generator.
315
316 This behaves exactly like walk(), except that it yields a 4-tuple
317
318 dirpath, dirnames, filenames, dirfd
319
320 `dirpath`, `dirnames` and `filenames` are identical to walk() output,
321 and `dirfd` is a file descriptor referring to the directory `dirpath`.
322
323 The advantage of walkfd() over walk() is that it's safe against symlink
324 races (when followlinks is False).
325
326 Caution:
327 Since fwalk() yields file descriptors, those are only valid until the
328 next iteration step, so you should dup() them if you want to keep them
329 for a longer period.
330
331 Example:
332
333 import os
334 for root, dirs, files, rootfd in os.fwalk('python/Lib/email'):
335 print(root, "consumes", end="")
336 print(sum([os.fstatat(rootfd, name).st_size for name in files]),
337 end="")
338 print("bytes in", len(files), "non-directory files")
339 if 'CVS' in dirs:
340 dirs.remove('CVS') # don't visit CVS directories
341 """
342 # Note: To guard against symlink races, we use the standard
343 # lstat()/open()/fstat() trick.
344 orig_st = lstat(top)
345 topfd = open(top, O_RDONLY)
346 try:
347 if (followlinks or (st.S_ISDIR(orig_st.st_mode) and
348 _are_same_file(orig_st, fstat(topfd)))):
349 for x in _fwalk(topfd, top, topdown, onerror, followlinks):
350 yield x
351 finally:
352 close(topfd)
353
354 def _fwalk(topfd, toppath, topdown, onerror, followlinks):
355 # Note: This uses O(depth of the directory tree) file descriptors: if
356 # necessary, it can be adapted to only require O(1) FDs, see issue
357 # #13734.
358
359 # whether to follow symlinks
360 flag = 0 if followlinks else AT_SYMLINK_NOFOLLOW
361
Charles-François Natali77940902012-02-06 19:54:48 +0100362 names = flistdir(topfd)
Charles-François Natali7372b062012-02-05 15:15:38 +0100363 dirs, nondirs = [], []
364 for name in names:
365 # Here, we don't use AT_SYMLINK_NOFOLLOW to be consistent with
366 # walk() which reports symlinks to directories as directories. We do
367 # however check for symlinks before recursing into a subdirectory.
368 if st.S_ISDIR(fstatat(topfd, name).st_mode):
369 dirs.append(name)
370 else:
371 nondirs.append(name)
372
373 if topdown:
374 yield toppath, dirs, nondirs, topfd
375
376 for name in dirs:
377 try:
378 orig_st = fstatat(topfd, name, flag)
379 dirfd = openat(topfd, name, O_RDONLY)
380 except error as err:
381 if onerror is not None:
382 onerror(err)
383 return
384 try:
385 if followlinks or _are_same_file(orig_st, fstat(dirfd)):
386 dirpath = path.join(toppath, name)
387 for x in _fwalk(dirfd, dirpath, topdown, onerror, followlinks):
388 yield x
389 finally:
390 close(dirfd)
391
392 if not topdown:
393 yield toppath, dirs, nondirs, topfd
394
395 __all__.append("fwalk")
396
Guido van Rossuma28dab51997-08-29 22:36:47 +0000397# Make sure os.environ exists, at least
398try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000399 environ
Guido van Rossuma28dab51997-08-29 22:36:47 +0000400except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000401 environ = {}
Guido van Rossuma28dab51997-08-29 22:36:47 +0000402
Guido van Rossume65cce51993-11-08 15:05:21 +0000403def execl(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000404 """execl(file, *args)
405
406 Execute the executable file with argument list args, replacing the
407 current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000408 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000409
410def execle(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000411 """execle(file, *args, env)
412
413 Execute the executable file with argument list args and
414 environment env, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000415 env = args[-1]
416 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000417
418def execlp(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000419 """execlp(file, *args)
420
421 Execute the executable file (which is searched for along $PATH)
422 with argument list args, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000423 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000424
Guido van Rossum030afb11995-03-14 17:27:18 +0000425def execlpe(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000426 """execlpe(file, *args, env)
427
428 Execute the executable file (which is searched for along $PATH)
429 with argument list args and environment env, replacing the current
Tim Peters2344fae2001-01-15 00:50:52 +0000430 process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000431 env = args[-1]
432 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000433
Guido van Rossume65cce51993-11-08 15:05:21 +0000434def execvp(file, args):
Matthias Klosea09c54f2010-01-31 16:48:44 +0000435 """execvp(file, args)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000436
437 Execute the executable file (which is searched for along $PATH)
438 with argument list args, replacing the current process.
Thomas Wouters7e474022000-07-16 12:04:32 +0000439 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000440 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000441
442def execvpe(file, args, env):
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000443 """execvpe(file, args, env)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000444
445 Execute the executable file (which is searched for along $PATH)
446 with argument list args and environment env , replacing the
447 current process.
Tim Peters2344fae2001-01-15 00:50:52 +0000448 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000449 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000450
Skip Montanaro269b83b2001-02-06 01:07:02 +0000451__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
452
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000453def _execvpe(file, args, env=None):
454 if env is not None:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000455 exec_func = execve
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000456 argrest = (args, env)
457 else:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000458 exec_func = execv
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000459 argrest = (args,)
460 env = environ
Guido van Rossumaed51d82002-08-05 16:13:24 +0000461
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000462 head, tail = path.split(file)
463 if head:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000464 exec_func(file, *argrest)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000465 return
Guido van Rossume7ba4952007-06-06 23:52:48 +0000466 last_exc = saved_exc = None
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000467 saved_tb = None
Victor Stinnerb745a742010-05-18 17:17:23 +0000468 path_list = get_exec_path(env)
469 if name != 'nt':
470 file = fsencode(file)
471 path_list = map(fsencode, path_list)
472 for dir in path_list:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000473 fullname = path.join(dir, file)
474 try:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000475 exec_func(fullname, *argrest)
Guido van Rossumb940e112007-01-10 16:19:56 +0000476 except error as e:
Guido van Rossume7ba4952007-06-06 23:52:48 +0000477 last_exc = e
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000478 tb = sys.exc_info()[2]
Christian Heimes45f9af32007-11-27 21:50:00 +0000479 if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000480 and saved_exc is None):
481 saved_exc = e
482 saved_tb = tb
483 if saved_exc:
Benjamin Peterson4b068192009-02-20 03:19:25 +0000484 raise saved_exc.with_traceback(saved_tb)
485 raise last_exc.with_traceback(tb)
Guido van Rossumd74fb6b2001-03-02 06:43:49 +0000486
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000487
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000488def get_exec_path(env=None):
489 """Returns the sequence of directories that will be searched for the
490 named executable (similar to a shell) when launching a process.
491
492 *env* must be an environment variable dict or None. If *env* is None,
493 os.environ will be used.
494 """
Victor Stinner273b7662010-11-06 12:59:33 +0000495 # Use a local import instead of a global import to limit the number of
496 # modules loaded at startup: the os module is always loaded at startup by
497 # Python. It may also avoid a bootstrap issue.
Victor Stinner6f35eda2010-10-29 00:38:58 +0000498 import warnings
499
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000500 if env is None:
501 env = environ
Victor Stinnerb745a742010-05-18 17:17:23 +0000502
Victor Stinnerbb4f2182010-11-07 15:43:39 +0000503 # {b'PATH': ...}.get('PATH') and {'PATH': ...}.get(b'PATH') emit a
504 # BytesWarning when using python -b or python -bb: ignore the warning
Victor Stinner273b7662010-11-06 12:59:33 +0000505 with warnings.catch_warnings():
506 warnings.simplefilter("ignore", BytesWarning)
Victor Stinnerb745a742010-05-18 17:17:23 +0000507
Victor Stinnerb745a742010-05-18 17:17:23 +0000508 try:
Victor Stinner273b7662010-11-06 12:59:33 +0000509 path_list = env.get('PATH')
510 except TypeError:
511 path_list = None
Victor Stinnerb745a742010-05-18 17:17:23 +0000512
Victor Stinner273b7662010-11-06 12:59:33 +0000513 if supports_bytes_environ:
514 try:
515 path_listb = env[b'PATH']
516 except (KeyError, TypeError):
517 pass
518 else:
519 if path_list is not None:
520 raise ValueError(
521 "env cannot contain 'PATH' and b'PATH' keys")
522 path_list = path_listb
523
524 if path_list is not None and isinstance(path_list, bytes):
525 path_list = fsdecode(path_list)
Victor Stinnerb745a742010-05-18 17:17:23 +0000526
527 if path_list is None:
528 path_list = defpath
529 return path_list.split(pathsep)
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000530
531
Skip Montanaro289bc052007-08-17 02:30:27 +0000532# Change environ to automatically call putenv(), unsetenv if they exist.
Raymond Hettinger158c9c22011-02-22 00:41:50 +0000533from collections.abc import MutableMapping
Skip Montanaro289bc052007-08-17 02:30:27 +0000534
535class _Environ(MutableMapping):
Victor Stinner84ae1182010-05-06 22:05:07 +0000536 def __init__(self, data, encodekey, decodekey, encodevalue, decodevalue, putenv, unsetenv):
537 self.encodekey = encodekey
538 self.decodekey = decodekey
539 self.encodevalue = encodevalue
540 self.decodevalue = decodevalue
Skip Montanaro289bc052007-08-17 02:30:27 +0000541 self.putenv = putenv
542 self.unsetenv = unsetenv
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000543 self._data = data
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000544
Skip Montanaro289bc052007-08-17 02:30:27 +0000545 def __getitem__(self, key):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000546 value = self._data[self.encodekey(key)]
Victor Stinner84ae1182010-05-06 22:05:07 +0000547 return self.decodevalue(value)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000548
Skip Montanaro289bc052007-08-17 02:30:27 +0000549 def __setitem__(self, key, value):
Victor Stinner84ae1182010-05-06 22:05:07 +0000550 key = self.encodekey(key)
551 value = self.encodevalue(value)
Skip Montanaro289bc052007-08-17 02:30:27 +0000552 self.putenv(key, value)
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000553 self._data[key] = value
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000554
Skip Montanaro289bc052007-08-17 02:30:27 +0000555 def __delitem__(self, key):
Victor Stinner84ae1182010-05-06 22:05:07 +0000556 key = self.encodekey(key)
Skip Montanaro289bc052007-08-17 02:30:27 +0000557 self.unsetenv(key)
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000558 del self._data[key]
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000559
Skip Montanaro289bc052007-08-17 02:30:27 +0000560 def __iter__(self):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000561 for key in self._data:
Victor Stinner84ae1182010-05-06 22:05:07 +0000562 yield self.decodekey(key)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000563
Skip Montanaro289bc052007-08-17 02:30:27 +0000564 def __len__(self):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000565 return len(self._data)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000566
567 def __repr__(self):
Victor Stinnerbed71172010-07-28 21:25:42 +0000568 return 'environ({{{}}})'.format(', '.join(
Victor Stinnerd73c1a32010-07-28 21:23:23 +0000569 ('{!r}: {!r}'.format(self.decodekey(key), self.decodevalue(value))
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000570 for key, value in self._data.items())))
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000571
Skip Montanaro289bc052007-08-17 02:30:27 +0000572 def copy(self):
573 return dict(self)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000574
Skip Montanaro289bc052007-08-17 02:30:27 +0000575 def setdefault(self, key, value):
576 if key not in self:
577 self[key] = value
578 return self[key]
579
580try:
581 _putenv = putenv
582except NameError:
583 _putenv = lambda key, value: None
Martin v. Löwisa90f4382001-03-07 09:05:45 +0000584else:
Skip Montanaro289bc052007-08-17 02:30:27 +0000585 __all__.append("putenv")
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000586
Skip Montanaro289bc052007-08-17 02:30:27 +0000587try:
588 _unsetenv = unsetenv
589except NameError:
590 _unsetenv = lambda key: _putenv(key, "")
591else:
592 __all__.append("unsetenv")
Guido van Rossumc524d952001-10-19 01:31:59 +0000593
Victor Stinner84ae1182010-05-06 22:05:07 +0000594def _createenviron():
595 if name in ('os2', 'nt'):
596 # Where Env Var Names Must Be UPPERCASE
597 def check_str(value):
598 if not isinstance(value, str):
599 raise TypeError("str expected, not %s" % type(value).__name__)
600 return value
601 encode = check_str
602 decode = str
603 def encodekey(key):
604 return encode(key).upper()
605 data = {}
606 for key, value in environ.items():
607 data[encodekey(key)] = value
608 else:
609 # Where Env Var Names Can Be Mixed Case
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000610 encoding = sys.getfilesystemencoding()
Victor Stinner84ae1182010-05-06 22:05:07 +0000611 def encode(value):
612 if not isinstance(value, str):
613 raise TypeError("str expected, not %s" % type(value).__name__)
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000614 return value.encode(encoding, 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000615 def decode(value):
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000616 return value.decode(encoding, 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000617 encodekey = encode
618 data = environ
619 return _Environ(data,
620 encodekey, decode,
621 encode, decode,
622 _putenv, _unsetenv)
Guido van Rossumc524d952001-10-19 01:31:59 +0000623
Victor Stinner84ae1182010-05-06 22:05:07 +0000624# unicode environ
625environ = _createenviron()
626del _createenviron
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000627
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000628
Jack Jansenb11ce9b2003-01-08 16:33:40 +0000629def getenv(key, default=None):
Tim Peters2c60f7a2003-01-29 03:49:43 +0000630 """Get an environment variable, return None if it doesn't exist.
Victor Stinner84ae1182010-05-06 22:05:07 +0000631 The optional second argument can specify an alternate default.
632 key, default and the result are str."""
Tim Peters2c60f7a2003-01-29 03:49:43 +0000633 return environ.get(key, default)
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000634
Victor Stinnerb745a742010-05-18 17:17:23 +0000635supports_bytes_environ = name not in ('os2', 'nt')
636__all__.extend(("getenv", "supports_bytes_environ"))
637
638if supports_bytes_environ:
Victor Stinner84ae1182010-05-06 22:05:07 +0000639 def _check_bytes(value):
640 if not isinstance(value, bytes):
641 raise TypeError("bytes expected, not %s" % type(value).__name__)
642 return value
643
644 # bytes environ
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000645 environb = _Environ(environ._data,
Victor Stinner84ae1182010-05-06 22:05:07 +0000646 _check_bytes, bytes,
647 _check_bytes, bytes,
648 _putenv, _unsetenv)
649 del _check_bytes
650
651 def getenvb(key, default=None):
652 """Get an environment variable, return None if it doesn't exist.
653 The optional second argument can specify an alternate default.
654 key, default and the result are bytes."""
655 return environb.get(key, default)
Victor Stinner70120e22010-07-29 17:19:38 +0000656
657 __all__.extend(("environb", "getenvb"))
Victor Stinner84ae1182010-05-06 22:05:07 +0000658
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000659def _fscodec():
660 encoding = sys.getfilesystemencoding()
661 if encoding == 'mbcs':
Victor Stinnere882aac2010-10-24 21:12:26 +0000662 errors = 'strict'
Victor Stinner313a1202010-06-11 23:56:51 +0000663 else:
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000664 errors = 'surrogateescape'
Victor Stinnere8d51452010-08-19 01:05:19 +0000665
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000666 def fsencode(filename):
667 """
668 Encode filename to the filesystem encoding with 'surrogateescape' error
669 handler, return bytes unchanged. On Windows, use 'strict' error handler if
670 the file system encoding is 'mbcs' (which is the default encoding).
671 """
672 if isinstance(filename, bytes):
673 return filename
674 elif isinstance(filename, str):
675 return filename.encode(encoding, errors)
Victor Stinnere8d51452010-08-19 01:05:19 +0000676 else:
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000677 raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
678
679 def fsdecode(filename):
680 """
681 Decode filename from the filesystem encoding with 'surrogateescape' error
682 handler, return str unchanged. On Windows, use 'strict' error handler if
683 the file system encoding is 'mbcs' (which is the default encoding).
684 """
685 if isinstance(filename, str):
686 return filename
687 elif isinstance(filename, bytes):
688 return filename.decode(encoding, errors)
689 else:
690 raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
691
692 return fsencode, fsdecode
693
694fsencode, fsdecode = _fscodec()
695del _fscodec
Victor Stinner449c4662010-05-08 11:10:09 +0000696
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000697# Supply spawn*() (probably only for Unix)
698if _exists("fork") and not _exists("spawnv") and _exists("execv"):
699
700 P_WAIT = 0
701 P_NOWAIT = P_NOWAITO = 1
702
703 # XXX Should we support P_DETACH? I suppose it could fork()**2
704 # and close the std I/O streams. Also, P_OVERLAY is the same
705 # as execv*()?
706
707 def _spawnvef(mode, file, args, env, func):
708 # Internal helper; func is the exec*() function to use
709 pid = fork()
710 if not pid:
711 # Child
712 try:
713 if env is None:
714 func(file, args)
715 else:
716 func(file, args, env)
717 except:
718 _exit(127)
719 else:
720 # Parent
721 if mode == P_NOWAIT:
722 return pid # Caller is responsible for waiting!
723 while 1:
724 wpid, sts = waitpid(pid, 0)
725 if WIFSTOPPED(sts):
726 continue
727 elif WIFSIGNALED(sts):
728 return -WTERMSIG(sts)
729 elif WIFEXITED(sts):
730 return WEXITSTATUS(sts)
731 else:
Collin Winter828f04a2007-08-31 00:04:24 +0000732 raise error("Not stopped, signaled or exited???")
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000733
734 def spawnv(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000735 """spawnv(mode, file, args) -> integer
736
737Execute file with arguments from args in a subprocess.
738If mode == P_NOWAIT return the pid of the process.
739If mode == P_WAIT return the process's exit code if it exits normally;
Tim Peters2344fae2001-01-15 00:50:52 +0000740otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000741 return _spawnvef(mode, file, args, None, execv)
742
743 def spawnve(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000744 """spawnve(mode, file, args, env) -> integer
745
746Execute file with arguments from args in a subprocess with the
747specified environment.
748If mode == P_NOWAIT return the pid of the process.
749If mode == P_WAIT return the process's exit code if it exits normally;
750otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000751 return _spawnvef(mode, file, args, env, execve)
752
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000753 # Note: spawnvp[e] is't currently supported on Windows
754
755 def spawnvp(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000756 """spawnvp(mode, file, args) -> integer
757
758Execute file (which is looked for along $PATH) with arguments from
759args in a subprocess.
760If mode == P_NOWAIT return the pid of the process.
761If mode == P_WAIT return the process's exit code if it exits normally;
762otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000763 return _spawnvef(mode, file, args, None, execvp)
764
765 def spawnvpe(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000766 """spawnvpe(mode, file, args, env) -> integer
767
768Execute file (which is looked for along $PATH) with arguments from
769args in a subprocess with the supplied environment.
770If mode == P_NOWAIT return the pid of the process.
771If mode == P_WAIT return the process's exit code if it exits normally;
772otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000773 return _spawnvef(mode, file, args, env, execvpe)
774
775if _exists("spawnv"):
776 # These aren't supplied by the basic Windows code
777 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000778
779 def spawnl(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000780 """spawnl(mode, file, *args) -> integer
781
782Execute file with arguments from args in a subprocess.
783If mode == P_NOWAIT return the pid of the process.
784If mode == P_WAIT return the process's exit code if it exits normally;
785otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000786 return spawnv(mode, file, args)
787
788 def spawnle(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000789 """spawnle(mode, file, *args, env) -> integer
790
791Execute file with arguments from args in a subprocess with the
792supplied environment.
793If mode == P_NOWAIT return the pid of the process.
794If mode == P_WAIT return the process's exit code if it exits normally;
795otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000796 env = args[-1]
797 return spawnve(mode, file, args[:-1], env)
798
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000799
800 __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
801
802
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000803if _exists("spawnvp"):
804 # At the moment, Windows doesn't implement spawnvp[e],
805 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000806 def spawnlp(mode, file, *args):
Neal Norwitzb7f68102003-07-02 02:49:33 +0000807 """spawnlp(mode, file, *args) -> integer
Guido van Rossume0cd2912000-04-21 18:35:36 +0000808
809Execute file (which is looked for along $PATH) with arguments from
810args in a subprocess with the supplied environment.
811If mode == P_NOWAIT return the pid of the process.
812If mode == P_WAIT return the process's exit code if it exits normally;
813otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000814 return spawnvp(mode, file, args)
815
816 def spawnlpe(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000817 """spawnlpe(mode, file, *args, env) -> integer
818
819Execute file (which is looked for along $PATH) with arguments from
820args in a subprocess with the supplied environment.
821If mode == P_NOWAIT return the pid of the process.
822If mode == P_WAIT return the process's exit code if it exits normally;
823otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000824 env = args[-1]
825 return spawnvpe(mode, file, args[:-1], env)
Guido van Rossume0cd2912000-04-21 18:35:36 +0000826
827
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000828 __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
Skip Montanaro269b83b2001-02-06 01:07:02 +0000829
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000830import copyreg as _copyreg
Michael W. Hudson0e025302002-03-06 17:11:18 +0000831
832def _make_stat_result(tup, dict):
833 return stat_result(tup, dict)
834
835def _pickle_stat_result(sr):
836 (type, args) = sr.__reduce__()
837 return (_make_stat_result, args)
838
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000839try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000840 _copyreg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000841except NameError: # stat_result may not exist
842 pass
Michael W. Hudson0e025302002-03-06 17:11:18 +0000843
844def _make_statvfs_result(tup, dict):
845 return statvfs_result(tup, dict)
846
847def _pickle_statvfs_result(sr):
848 (type, args) = sr.__reduce__()
849 return (_make_statvfs_result, args)
850
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000851try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000852 _copyreg.pickle(statvfs_result, _pickle_statvfs_result,
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000853 _make_statvfs_result)
Michael W. Hudsone5363b72002-03-15 10:21:59 +0000854except NameError: # statvfs_result may not exist
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000855 pass
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000856
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000857# Supply os.popen()
Antoine Pitrou877766d2011-03-19 17:00:37 +0100858def popen(cmd, mode="r", buffering=-1):
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000859 if not isinstance(cmd, str):
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000860 raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
861 if mode not in ("r", "w"):
862 raise ValueError("invalid mode %r" % mode)
Antoine Pitrou877766d2011-03-19 17:00:37 +0100863 if buffering == 0 or buffering == None:
864 raise ValueError("popen() does not support unbuffered streams")
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000865 import subprocess, io
866 if mode == "r":
867 proc = subprocess.Popen(cmd,
868 shell=True,
869 stdout=subprocess.PIPE,
870 bufsize=buffering)
871 return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
872 else:
873 proc = subprocess.Popen(cmd,
874 shell=True,
875 stdin=subprocess.PIPE,
876 bufsize=buffering)
877 return _wrap_close(io.TextIOWrapper(proc.stdin), proc)
878
879# Helper for popen() -- a proxy for a file whose close waits for the process
880class _wrap_close:
881 def __init__(self, stream, proc):
882 self._stream = stream
883 self._proc = proc
884 def close(self):
885 self._stream.close()
Amaury Forgeot d'Arc97e5f282009-07-11 09:35:13 +0000886 returncode = self._proc.wait()
887 if returncode == 0:
888 return None
889 if name == 'nt':
890 return returncode
891 else:
892 return returncode << 8 # Shift left to match old behavior
Antoine Pitrouac625352009-12-09 00:01:27 +0000893 def __enter__(self):
894 return self
895 def __exit__(self, *args):
896 self.close()
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000897 def __getattr__(self, name):
898 return getattr(self._stream, name)
Thomas Heller476157b2007-09-04 11:27:47 +0000899 def __iter__(self):
900 return iter(self._stream)
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000901
Amaury Forgeot d'Arcbdbddf82008-08-01 00:06:49 +0000902# Supply os.fdopen()
903def fdopen(fd, *args, **kwargs):
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000904 if not isinstance(fd, int):
905 raise TypeError("invalid fd type (%s, expected integer)" % type(fd))
906 import io
Amaury Forgeot d'Arcbdbddf82008-08-01 00:06:49 +0000907 return io.open(fd, *args, **kwargs)