blob: 2c7d9548646c1bf91c070470a5756d86f06a4d14 [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
Guido van Rossum4def7de1998-07-24 20:48:03 +0000129# Super directory utilities.
130# (Inspired by Eric Raymond; the doc strings are mostly his)
131
Terry Reedy5a22b652010-12-02 07:05:56 +0000132def makedirs(name, mode=0o777, exist_ok=False):
133 """makedirs(path [, mode=0o777][, exist_ok=False])
Guido van Rossum4def7de1998-07-24 20:48:03 +0000134
135 Super-mkdir; create a leaf directory and all intermediate ones.
136 Works like mkdir, except that any intermediate path segment (not
Terry Reedy5a22b652010-12-02 07:05:56 +0000137 just the rightmost) will be created if it does not exist. If the
138 target directory with the same mode as we specified already exists,
139 raises an OSError if exist_ok is False, otherwise no exception is
140 raised. This is recursive.
Guido van Rossum4def7de1998-07-24 20:48:03 +0000141
142 """
143 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000144 if not tail:
145 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000146 if head and tail and not path.exists(head):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000147 try:
Terry Reedy5a22b652010-12-02 07:05:56 +0000148 makedirs(head, mode, exist_ok)
Guido van Rossumb940e112007-01-10 16:19:56 +0000149 except OSError as e:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000150 # be happy if someone already created the path
Christian Heimes45f9af32007-11-27 21:50:00 +0000151 if e.errno != errno.EEXIST:
Thomas Wouters89f507f2006-12-13 04:49:30 +0000152 raise
Andrew M. Kuchling6fccc8a2003-12-23 16:33:28 +0000153 if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists
154 return
Terry Reedy5a22b652010-12-02 07:05:56 +0000155 try:
156 mkdir(name, mode)
157 except OSError as e:
Terry Reedy5a22b652010-12-02 07:05:56 +0000158 if not (e.errno == errno.EEXIST and exist_ok and path.isdir(name) and
159 st.S_IMODE(lstat(name).st_mode) == _get_masked_mode(mode)):
160 raise
Guido van Rossum4def7de1998-07-24 20:48:03 +0000161
162def removedirs(name):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000163 """removedirs(path)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000164
Fredrik Lundh96c1c7a2005-11-12 15:55:04 +0000165 Super-rmdir; remove a leaf directory and all empty intermediate
Guido van Rossum4def7de1998-07-24 20:48:03 +0000166 ones. Works like rmdir except that, if the leaf directory is
167 successfully removed, directories corresponding to rightmost path
Tim Petersc4e09402003-04-25 07:11:48 +0000168 segments will be pruned away until either the whole path is
Guido van Rossum4def7de1998-07-24 20:48:03 +0000169 consumed or an error occurs. Errors during this latter phase are
170 ignored -- they generally mean that a directory was not empty.
171
172 """
173 rmdir(name)
174 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000175 if not tail:
176 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000177 while head and tail:
178 try:
179 rmdir(head)
180 except error:
181 break
182 head, tail = path.split(head)
183
184def renames(old, new):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000185 """renames(old, new)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000186
187 Super-rename; create directories as necessary and delete any left
188 empty. Works like rename, except creation of any intermediate
189 directories needed to make the new pathname good is attempted
190 first. After the rename, directories corresponding to rightmost
191 path segments of the old name will be pruned way until either the
192 whole path is consumed or a nonempty directory is found.
193
194 Note: this function can fail with the new directory structure made
195 if you lack permissions needed to unlink the leaf directory or
196 file.
197
198 """
199 head, tail = path.split(new)
200 if head and tail and not path.exists(head):
201 makedirs(head)
202 rename(old, new)
203 head, tail = path.split(old)
204 if head and tail:
205 try:
206 removedirs(head)
207 except error:
208 pass
209
Skip Montanaro269b83b2001-02-06 01:07:02 +0000210__all__.extend(["makedirs", "removedirs", "renames"])
211
Guido van Rossumd8faa362007-04-27 19:54:29 +0000212def walk(top, topdown=True, onerror=None, followlinks=False):
Tim Petersc4e09402003-04-25 07:11:48 +0000213 """Directory tree generator.
214
215 For each directory in the directory tree rooted at top (including top
216 itself, but excluding '.' and '..'), yields a 3-tuple
217
218 dirpath, dirnames, filenames
219
220 dirpath is a string, the path to the directory. dirnames is a list of
221 the names of the subdirectories in dirpath (excluding '.' and '..').
222 filenames is a list of the names of the non-directory files in dirpath.
223 Note that the names in the lists are just names, with no path components.
224 To get a full path (which begins with top) to a file or directory in
225 dirpath, do os.path.join(dirpath, name).
226
227 If optional arg 'topdown' is true or not specified, the triple for a
228 directory is generated before the triples for any of its subdirectories
229 (directories are generated top down). If topdown is false, the triple
230 for a directory is generated after the triples for all of its
231 subdirectories (directories are generated bottom up).
232
233 When topdown is true, the caller can modify the dirnames list in-place
234 (e.g., via del or slice assignment), and walk will only recurse into the
235 subdirectories whose names remain in dirnames; this can be used to prune
236 the search, or to impose a specific order of visiting. Modifying
237 dirnames when topdown is false is ineffective, since the directories in
238 dirnames have already been generated by the time dirnames itself is
239 generated.
240
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000241 By default errors from the os.listdir() call are ignored. If
242 optional arg 'onerror' is specified, it should be a function; it
243 will be called with one argument, an os.error instance. It can
244 report the error to continue with the walk, or raise the exception
245 to abort the walk. Note that the filename is available as the
246 filename attribute of the exception object.
247
Guido van Rossumd8faa362007-04-27 19:54:29 +0000248 By default, os.walk does not follow symbolic links to subdirectories on
249 systems that support them. In order to get this functionality, set the
250 optional argument 'followlinks' to true.
251
Tim Petersc4e09402003-04-25 07:11:48 +0000252 Caution: if you pass a relative pathname for top, don't change the
253 current working directory between resumptions of walk. walk never
254 changes the current directory, and assumes that the client doesn't
255 either.
256
257 Example:
258
Christian Heimes5d8da202008-05-06 13:58:24 +0000259 import os
Tim Petersc4e09402003-04-25 07:11:48 +0000260 from os.path import join, getsize
Christian Heimes5d8da202008-05-06 13:58:24 +0000261 for root, dirs, files in os.walk('python/Lib/email'):
Neal Norwitz752abd02008-05-13 04:55:24 +0000262 print(root, "consumes", end="")
263 print(sum([getsize(join(root, name)) for name in files]), end="")
264 print("bytes in", len(files), "non-directory files")
Tim Petersc4e09402003-04-25 07:11:48 +0000265 if 'CVS' in dirs:
266 dirs.remove('CVS') # don't visit CVS directories
267 """
268
Benjamin Petersonf6489f92009-11-25 17:46:26 +0000269 islink, join, isdir = path.islink, path.join, path.isdir
Tim Petersc4e09402003-04-25 07:11:48 +0000270
271 # We may not have read permission for top, in which case we can't
Alexandre Vassalotti4e6531e2008-05-09 20:00:17 +0000272 # get a list of the files the directory contains. os.walk
Tim Petersc4e09402003-04-25 07:11:48 +0000273 # always suppressed the exception then, rather than blow up for a
274 # minor reason when (say) a thousand readable directories are still
275 # left to visit. That logic is copied here.
276 try:
277 # Note that listdir and error are globals in this module due
278 # to earlier import-*.
279 names = listdir(top)
Guido van Rossumb940e112007-01-10 16:19:56 +0000280 except error as err:
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000281 if onerror is not None:
282 onerror(err)
Tim Petersc4e09402003-04-25 07:11:48 +0000283 return
284
285 dirs, nondirs = [], []
286 for name in names:
287 if isdir(join(top, name)):
288 dirs.append(name)
289 else:
290 nondirs.append(name)
291
292 if topdown:
293 yield top, dirs, nondirs
294 for name in dirs:
Benjamin Petersonf6489f92009-11-25 17:46:26 +0000295 new_path = join(top, name)
296 if followlinks or not islink(new_path):
297 for x in walk(new_path, topdown, onerror, followlinks):
Tim Petersc4e09402003-04-25 07:11:48 +0000298 yield x
299 if not topdown:
300 yield top, dirs, nondirs
301
302__all__.append("walk")
303
Charles-François Natali7372b062012-02-05 15:15:38 +0100304if _exists("openat"):
305
306 def fwalk(top, topdown=True, onerror=None, followlinks=False):
307 """Directory tree generator.
308
309 This behaves exactly like walk(), except that it yields a 4-tuple
310
311 dirpath, dirnames, filenames, dirfd
312
313 `dirpath`, `dirnames` and `filenames` are identical to walk() output,
314 and `dirfd` is a file descriptor referring to the directory `dirpath`.
315
316 The advantage of walkfd() over walk() is that it's safe against symlink
317 races (when followlinks is False).
318
319 Caution:
320 Since fwalk() yields file descriptors, those are only valid until the
321 next iteration step, so you should dup() them if you want to keep them
322 for a longer period.
323
324 Example:
325
326 import os
327 for root, dirs, files, rootfd in os.fwalk('python/Lib/email'):
328 print(root, "consumes", end="")
329 print(sum([os.fstatat(rootfd, name).st_size for name in files]),
330 end="")
331 print("bytes in", len(files), "non-directory files")
332 if 'CVS' in dirs:
333 dirs.remove('CVS') # don't visit CVS directories
334 """
335 # Note: To guard against symlink races, we use the standard
336 # lstat()/open()/fstat() trick.
337 orig_st = lstat(top)
338 topfd = open(top, O_RDONLY)
339 try:
340 if (followlinks or (st.S_ISDIR(orig_st.st_mode) and
Charles-François Natali84c0ca02012-04-22 15:55:43 +0200341 path.samestat(orig_st, fstat(topfd)))):
Charles-François Natali7372b062012-02-05 15:15:38 +0100342 for x in _fwalk(topfd, top, topdown, onerror, followlinks):
343 yield x
344 finally:
345 close(topfd)
346
347 def _fwalk(topfd, toppath, topdown, onerror, followlinks):
348 # Note: This uses O(depth of the directory tree) file descriptors: if
349 # necessary, it can be adapted to only require O(1) FDs, see issue
350 # #13734.
351
352 # whether to follow symlinks
353 flag = 0 if followlinks else AT_SYMLINK_NOFOLLOW
354
Charles-François Natali77940902012-02-06 19:54:48 +0100355 names = flistdir(topfd)
Charles-François Natali7372b062012-02-05 15:15:38 +0100356 dirs, nondirs = [], []
357 for name in names:
358 # Here, we don't use AT_SYMLINK_NOFOLLOW to be consistent with
359 # walk() which reports symlinks to directories as directories. We do
360 # however check for symlinks before recursing into a subdirectory.
361 if st.S_ISDIR(fstatat(topfd, name).st_mode):
362 dirs.append(name)
363 else:
364 nondirs.append(name)
365
366 if topdown:
367 yield toppath, dirs, nondirs, topfd
368
369 for name in dirs:
370 try:
371 orig_st = fstatat(topfd, name, flag)
372 dirfd = openat(topfd, name, O_RDONLY)
373 except error as err:
374 if onerror is not None:
375 onerror(err)
376 return
377 try:
Charles-François Natali84c0ca02012-04-22 15:55:43 +0200378 if followlinks or path.samestat(orig_st, fstat(dirfd)):
Charles-François Natali7372b062012-02-05 15:15:38 +0100379 dirpath = path.join(toppath, name)
380 for x in _fwalk(dirfd, dirpath, topdown, onerror, followlinks):
381 yield x
382 finally:
383 close(dirfd)
384
385 if not topdown:
386 yield toppath, dirs, nondirs, topfd
387
388 __all__.append("fwalk")
389
Guido van Rossuma28dab51997-08-29 22:36:47 +0000390# Make sure os.environ exists, at least
391try:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000392 environ
Guido van Rossuma28dab51997-08-29 22:36:47 +0000393except NameError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000394 environ = {}
Guido van Rossuma28dab51997-08-29 22:36:47 +0000395
Guido van Rossume65cce51993-11-08 15:05:21 +0000396def execl(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000397 """execl(file, *args)
398
399 Execute the executable file with argument list args, replacing the
400 current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000401 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000402
403def execle(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000404 """execle(file, *args, env)
405
406 Execute the executable file with argument list args and
407 environment env, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000408 env = args[-1]
409 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000410
411def execlp(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000412 """execlp(file, *args)
413
414 Execute the executable file (which is searched for along $PATH)
415 with argument list args, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000416 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000417
Guido van Rossum030afb11995-03-14 17:27:18 +0000418def execlpe(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000419 """execlpe(file, *args, env)
420
421 Execute the executable file (which is searched for along $PATH)
422 with argument list args and environment env, replacing the current
Tim Peters2344fae2001-01-15 00:50:52 +0000423 process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000424 env = args[-1]
425 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000426
Guido van Rossume65cce51993-11-08 15:05:21 +0000427def execvp(file, args):
Matthias Klosea09c54f2010-01-31 16:48:44 +0000428 """execvp(file, args)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000429
430 Execute the executable file (which is searched for along $PATH)
431 with argument list args, replacing the current process.
Thomas Wouters7e474022000-07-16 12:04:32 +0000432 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000433 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000434
435def execvpe(file, args, env):
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000436 """execvpe(file, args, env)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000437
438 Execute the executable file (which is searched for along $PATH)
439 with argument list args and environment env , replacing the
440 current process.
Tim Peters2344fae2001-01-15 00:50:52 +0000441 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000442 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000443
Skip Montanaro269b83b2001-02-06 01:07:02 +0000444__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
445
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000446def _execvpe(file, args, env=None):
447 if env is not None:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000448 exec_func = execve
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000449 argrest = (args, env)
450 else:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000451 exec_func = execv
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000452 argrest = (args,)
453 env = environ
Guido van Rossumaed51d82002-08-05 16:13:24 +0000454
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000455 head, tail = path.split(file)
456 if head:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000457 exec_func(file, *argrest)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000458 return
Guido van Rossume7ba4952007-06-06 23:52:48 +0000459 last_exc = saved_exc = None
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000460 saved_tb = None
Victor Stinnerb745a742010-05-18 17:17:23 +0000461 path_list = get_exec_path(env)
462 if name != 'nt':
463 file = fsencode(file)
464 path_list = map(fsencode, path_list)
465 for dir in path_list:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000466 fullname = path.join(dir, file)
467 try:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000468 exec_func(fullname, *argrest)
Guido van Rossumb940e112007-01-10 16:19:56 +0000469 except error as e:
Guido van Rossume7ba4952007-06-06 23:52:48 +0000470 last_exc = e
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000471 tb = sys.exc_info()[2]
Christian Heimes45f9af32007-11-27 21:50:00 +0000472 if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000473 and saved_exc is None):
474 saved_exc = e
475 saved_tb = tb
476 if saved_exc:
Benjamin Peterson4b068192009-02-20 03:19:25 +0000477 raise saved_exc.with_traceback(saved_tb)
478 raise last_exc.with_traceback(tb)
Guido van Rossumd74fb6b2001-03-02 06:43:49 +0000479
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000480
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000481def get_exec_path(env=None):
482 """Returns the sequence of directories that will be searched for the
483 named executable (similar to a shell) when launching a process.
484
485 *env* must be an environment variable dict or None. If *env* is None,
486 os.environ will be used.
487 """
Victor Stinner273b7662010-11-06 12:59:33 +0000488 # Use a local import instead of a global import to limit the number of
489 # modules loaded at startup: the os module is always loaded at startup by
490 # Python. It may also avoid a bootstrap issue.
Victor Stinner6f35eda2010-10-29 00:38:58 +0000491 import warnings
492
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000493 if env is None:
494 env = environ
Victor Stinnerb745a742010-05-18 17:17:23 +0000495
Victor Stinnerbb4f2182010-11-07 15:43:39 +0000496 # {b'PATH': ...}.get('PATH') and {'PATH': ...}.get(b'PATH') emit a
497 # BytesWarning when using python -b or python -bb: ignore the warning
Victor Stinner273b7662010-11-06 12:59:33 +0000498 with warnings.catch_warnings():
499 warnings.simplefilter("ignore", BytesWarning)
Victor Stinnerb745a742010-05-18 17:17:23 +0000500
Victor Stinnerb745a742010-05-18 17:17:23 +0000501 try:
Victor Stinner273b7662010-11-06 12:59:33 +0000502 path_list = env.get('PATH')
503 except TypeError:
504 path_list = None
Victor Stinnerb745a742010-05-18 17:17:23 +0000505
Victor Stinner273b7662010-11-06 12:59:33 +0000506 if supports_bytes_environ:
507 try:
508 path_listb = env[b'PATH']
509 except (KeyError, TypeError):
510 pass
511 else:
512 if path_list is not None:
513 raise ValueError(
514 "env cannot contain 'PATH' and b'PATH' keys")
515 path_list = path_listb
516
517 if path_list is not None and isinstance(path_list, bytes):
518 path_list = fsdecode(path_list)
Victor Stinnerb745a742010-05-18 17:17:23 +0000519
520 if path_list is None:
521 path_list = defpath
522 return path_list.split(pathsep)
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000523
524
Skip Montanaro289bc052007-08-17 02:30:27 +0000525# Change environ to automatically call putenv(), unsetenv if they exist.
Raymond Hettinger158c9c22011-02-22 00:41:50 +0000526from collections.abc import MutableMapping
Skip Montanaro289bc052007-08-17 02:30:27 +0000527
528class _Environ(MutableMapping):
Victor Stinner84ae1182010-05-06 22:05:07 +0000529 def __init__(self, data, encodekey, decodekey, encodevalue, decodevalue, putenv, unsetenv):
530 self.encodekey = encodekey
531 self.decodekey = decodekey
532 self.encodevalue = encodevalue
533 self.decodevalue = decodevalue
Skip Montanaro289bc052007-08-17 02:30:27 +0000534 self.putenv = putenv
535 self.unsetenv = unsetenv
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000536 self._data = data
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000537
Skip Montanaro289bc052007-08-17 02:30:27 +0000538 def __getitem__(self, key):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000539 value = self._data[self.encodekey(key)]
Victor Stinner84ae1182010-05-06 22:05:07 +0000540 return self.decodevalue(value)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000541
Skip Montanaro289bc052007-08-17 02:30:27 +0000542 def __setitem__(self, key, value):
Victor Stinner84ae1182010-05-06 22:05:07 +0000543 key = self.encodekey(key)
544 value = self.encodevalue(value)
Skip Montanaro289bc052007-08-17 02:30:27 +0000545 self.putenv(key, value)
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000546 self._data[key] = value
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000547
Skip Montanaro289bc052007-08-17 02:30:27 +0000548 def __delitem__(self, key):
Victor Stinner84ae1182010-05-06 22:05:07 +0000549 key = self.encodekey(key)
Skip Montanaro289bc052007-08-17 02:30:27 +0000550 self.unsetenv(key)
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000551 del self._data[key]
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000552
Skip Montanaro289bc052007-08-17 02:30:27 +0000553 def __iter__(self):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000554 for key in self._data:
Victor Stinner84ae1182010-05-06 22:05:07 +0000555 yield self.decodekey(key)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000556
Skip Montanaro289bc052007-08-17 02:30:27 +0000557 def __len__(self):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000558 return len(self._data)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000559
560 def __repr__(self):
Victor Stinnerbed71172010-07-28 21:25:42 +0000561 return 'environ({{{}}})'.format(', '.join(
Victor Stinnerd73c1a32010-07-28 21:23:23 +0000562 ('{!r}: {!r}'.format(self.decodekey(key), self.decodevalue(value))
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000563 for key, value in self._data.items())))
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000564
Skip Montanaro289bc052007-08-17 02:30:27 +0000565 def copy(self):
566 return dict(self)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000567
Skip Montanaro289bc052007-08-17 02:30:27 +0000568 def setdefault(self, key, value):
569 if key not in self:
570 self[key] = value
571 return self[key]
572
573try:
574 _putenv = putenv
575except NameError:
576 _putenv = lambda key, value: None
Martin v. Löwisa90f4382001-03-07 09:05:45 +0000577else:
Skip Montanaro289bc052007-08-17 02:30:27 +0000578 __all__.append("putenv")
Guido van Rossum3b8e20d1996-07-24 00:55:17 +0000579
Skip Montanaro289bc052007-08-17 02:30:27 +0000580try:
581 _unsetenv = unsetenv
582except NameError:
583 _unsetenv = lambda key: _putenv(key, "")
584else:
585 __all__.append("unsetenv")
Guido van Rossumc524d952001-10-19 01:31:59 +0000586
Victor Stinner84ae1182010-05-06 22:05:07 +0000587def _createenviron():
588 if name in ('os2', 'nt'):
589 # Where Env Var Names Must Be UPPERCASE
590 def check_str(value):
591 if not isinstance(value, str):
592 raise TypeError("str expected, not %s" % type(value).__name__)
593 return value
594 encode = check_str
595 decode = str
596 def encodekey(key):
597 return encode(key).upper()
598 data = {}
599 for key, value in environ.items():
600 data[encodekey(key)] = value
601 else:
602 # Where Env Var Names Can Be Mixed Case
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000603 encoding = sys.getfilesystemencoding()
Victor Stinner84ae1182010-05-06 22:05:07 +0000604 def encode(value):
605 if not isinstance(value, str):
606 raise TypeError("str expected, not %s" % type(value).__name__)
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000607 return value.encode(encoding, 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000608 def decode(value):
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000609 return value.decode(encoding, 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000610 encodekey = encode
611 data = environ
612 return _Environ(data,
613 encodekey, decode,
614 encode, decode,
615 _putenv, _unsetenv)
Guido van Rossumc524d952001-10-19 01:31:59 +0000616
Victor Stinner84ae1182010-05-06 22:05:07 +0000617# unicode environ
618environ = _createenviron()
619del _createenviron
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000620
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000621
Jack Jansenb11ce9b2003-01-08 16:33:40 +0000622def getenv(key, default=None):
Tim Peters2c60f7a2003-01-29 03:49:43 +0000623 """Get an environment variable, return None if it doesn't exist.
Victor Stinner84ae1182010-05-06 22:05:07 +0000624 The optional second argument can specify an alternate default.
625 key, default and the result are str."""
Tim Peters2c60f7a2003-01-29 03:49:43 +0000626 return environ.get(key, default)
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000627
Victor Stinnerb745a742010-05-18 17:17:23 +0000628supports_bytes_environ = name not in ('os2', 'nt')
629__all__.extend(("getenv", "supports_bytes_environ"))
630
631if supports_bytes_environ:
Victor Stinner84ae1182010-05-06 22:05:07 +0000632 def _check_bytes(value):
633 if not isinstance(value, bytes):
634 raise TypeError("bytes expected, not %s" % type(value).__name__)
635 return value
636
637 # bytes environ
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000638 environb = _Environ(environ._data,
Victor Stinner84ae1182010-05-06 22:05:07 +0000639 _check_bytes, bytes,
640 _check_bytes, bytes,
641 _putenv, _unsetenv)
642 del _check_bytes
643
644 def getenvb(key, default=None):
645 """Get an environment variable, return None if it doesn't exist.
646 The optional second argument can specify an alternate default.
647 key, default and the result are bytes."""
648 return environb.get(key, default)
Victor Stinner70120e22010-07-29 17:19:38 +0000649
650 __all__.extend(("environb", "getenvb"))
Victor Stinner84ae1182010-05-06 22:05:07 +0000651
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000652def _fscodec():
653 encoding = sys.getfilesystemencoding()
654 if encoding == 'mbcs':
Victor Stinnere882aac2010-10-24 21:12:26 +0000655 errors = 'strict'
Victor Stinner313a1202010-06-11 23:56:51 +0000656 else:
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000657 errors = 'surrogateescape'
Victor Stinnere8d51452010-08-19 01:05:19 +0000658
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000659 def fsencode(filename):
660 """
661 Encode filename to the filesystem encoding with 'surrogateescape' error
662 handler, return bytes unchanged. On Windows, use 'strict' error handler if
663 the file system encoding is 'mbcs' (which is the default encoding).
664 """
665 if isinstance(filename, bytes):
666 return filename
667 elif isinstance(filename, str):
668 return filename.encode(encoding, errors)
Victor Stinnere8d51452010-08-19 01:05:19 +0000669 else:
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000670 raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
671
672 def fsdecode(filename):
673 """
674 Decode filename from the filesystem encoding with 'surrogateescape' error
675 handler, return str unchanged. On Windows, use 'strict' error handler if
676 the file system encoding is 'mbcs' (which is the default encoding).
677 """
678 if isinstance(filename, str):
679 return filename
680 elif isinstance(filename, bytes):
681 return filename.decode(encoding, errors)
682 else:
683 raise TypeError("expect bytes or str, not %s" % type(filename).__name__)
684
685 return fsencode, fsdecode
686
687fsencode, fsdecode = _fscodec()
688del _fscodec
Victor Stinner449c4662010-05-08 11:10:09 +0000689
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000690# Supply spawn*() (probably only for Unix)
691if _exists("fork") and not _exists("spawnv") and _exists("execv"):
692
693 P_WAIT = 0
694 P_NOWAIT = P_NOWAITO = 1
695
696 # XXX Should we support P_DETACH? I suppose it could fork()**2
697 # and close the std I/O streams. Also, P_OVERLAY is the same
698 # as execv*()?
699
700 def _spawnvef(mode, file, args, env, func):
701 # Internal helper; func is the exec*() function to use
702 pid = fork()
703 if not pid:
704 # Child
705 try:
706 if env is None:
707 func(file, args)
708 else:
709 func(file, args, env)
710 except:
711 _exit(127)
712 else:
713 # Parent
714 if mode == P_NOWAIT:
715 return pid # Caller is responsible for waiting!
716 while 1:
717 wpid, sts = waitpid(pid, 0)
718 if WIFSTOPPED(sts):
719 continue
720 elif WIFSIGNALED(sts):
721 return -WTERMSIG(sts)
722 elif WIFEXITED(sts):
723 return WEXITSTATUS(sts)
724 else:
Collin Winter828f04a2007-08-31 00:04:24 +0000725 raise error("Not stopped, signaled or exited???")
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000726
727 def spawnv(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000728 """spawnv(mode, file, args) -> integer
729
730Execute file with arguments from args in a subprocess.
731If mode == P_NOWAIT return the pid of the process.
732If mode == P_WAIT return the process's exit code if it exits normally;
Tim Peters2344fae2001-01-15 00:50:52 +0000733otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000734 return _spawnvef(mode, file, args, None, execv)
735
736 def spawnve(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000737 """spawnve(mode, file, args, env) -> integer
738
739Execute file with arguments from args in a subprocess with the
740specified environment.
741If mode == P_NOWAIT return the pid of the process.
742If mode == P_WAIT return the process's exit code if it exits normally;
743otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000744 return _spawnvef(mode, file, args, env, execve)
745
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000746 # Note: spawnvp[e] is't currently supported on Windows
747
748 def spawnvp(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000749 """spawnvp(mode, file, args) -> integer
750
751Execute file (which is looked for along $PATH) with arguments from
752args in a subprocess.
753If mode == P_NOWAIT return the pid of the process.
754If mode == P_WAIT return the process's exit code if it exits normally;
755otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000756 return _spawnvef(mode, file, args, None, execvp)
757
758 def spawnvpe(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000759 """spawnvpe(mode, file, args, env) -> integer
760
761Execute file (which is looked for along $PATH) with arguments from
762args in a subprocess with the supplied environment.
763If mode == P_NOWAIT return the pid of the process.
764If mode == P_WAIT return the process's exit code if it exits normally;
765otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000766 return _spawnvef(mode, file, args, env, execvpe)
767
768if _exists("spawnv"):
769 # These aren't supplied by the basic Windows code
770 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000771
772 def spawnl(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000773 """spawnl(mode, file, *args) -> integer
774
775Execute file with arguments from args in a subprocess.
776If mode == P_NOWAIT return the pid of the process.
777If mode == P_WAIT return the process's exit code if it exits normally;
778otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000779 return spawnv(mode, file, args)
780
781 def spawnle(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000782 """spawnle(mode, file, *args, env) -> integer
783
784Execute file with arguments from args in a subprocess with the
785supplied environment.
786If mode == P_NOWAIT return the pid of the process.
787If mode == P_WAIT return the process's exit code if it exits normally;
788otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000789 env = args[-1]
790 return spawnve(mode, file, args[:-1], env)
791
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000792
793 __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
794
795
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000796if _exists("spawnvp"):
797 # At the moment, Windows doesn't implement spawnvp[e],
798 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000799 def spawnlp(mode, file, *args):
Neal Norwitzb7f68102003-07-02 02:49:33 +0000800 """spawnlp(mode, file, *args) -> integer
Guido van Rossume0cd2912000-04-21 18:35:36 +0000801
802Execute file (which is looked for along $PATH) with arguments from
803args in a subprocess with the supplied environment.
804If mode == P_NOWAIT return the pid of the process.
805If mode == P_WAIT return the process's exit code if it exits normally;
806otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000807 return spawnvp(mode, file, args)
808
809 def spawnlpe(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000810 """spawnlpe(mode, file, *args, env) -> integer
811
812Execute file (which is looked for along $PATH) with arguments from
813args in a subprocess with the supplied environment.
814If mode == P_NOWAIT return the pid of the process.
815If mode == P_WAIT return the process's exit code if it exits normally;
816otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000817 env = args[-1]
818 return spawnvpe(mode, file, args[:-1], env)
Guido van Rossume0cd2912000-04-21 18:35:36 +0000819
820
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000821 __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
Skip Montanaro269b83b2001-02-06 01:07:02 +0000822
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000823import copyreg as _copyreg
Michael W. Hudson0e025302002-03-06 17:11:18 +0000824
825def _make_stat_result(tup, dict):
826 return stat_result(tup, dict)
827
828def _pickle_stat_result(sr):
829 (type, args) = sr.__reduce__()
830 return (_make_stat_result, args)
831
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000832try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000833 _copyreg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000834except NameError: # stat_result may not exist
835 pass
Michael W. Hudson0e025302002-03-06 17:11:18 +0000836
837def _make_statvfs_result(tup, dict):
838 return statvfs_result(tup, dict)
839
840def _pickle_statvfs_result(sr):
841 (type, args) = sr.__reduce__()
842 return (_make_statvfs_result, args)
843
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000844try:
Alexandre Vassalottif7fa63d2008-05-11 08:55:36 +0000845 _copyreg.pickle(statvfs_result, _pickle_statvfs_result,
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000846 _make_statvfs_result)
Michael W. Hudsone5363b72002-03-15 10:21:59 +0000847except NameError: # statvfs_result may not exist
Michael W. Hudsonce00b732002-03-15 10:18:58 +0000848 pass
Martin v. Löwisdc3883f2004-08-29 15:46:35 +0000849
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000850# Supply os.popen()
Antoine Pitrou877766d2011-03-19 17:00:37 +0100851def popen(cmd, mode="r", buffering=-1):
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000852 if not isinstance(cmd, str):
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000853 raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
854 if mode not in ("r", "w"):
855 raise ValueError("invalid mode %r" % mode)
Antoine Pitrou877766d2011-03-19 17:00:37 +0100856 if buffering == 0 or buffering == None:
857 raise ValueError("popen() does not support unbuffered streams")
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000858 import subprocess, io
859 if mode == "r":
860 proc = subprocess.Popen(cmd,
861 shell=True,
862 stdout=subprocess.PIPE,
863 bufsize=buffering)
864 return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
865 else:
866 proc = subprocess.Popen(cmd,
867 shell=True,
868 stdin=subprocess.PIPE,
869 bufsize=buffering)
870 return _wrap_close(io.TextIOWrapper(proc.stdin), proc)
871
872# Helper for popen() -- a proxy for a file whose close waits for the process
873class _wrap_close:
874 def __init__(self, stream, proc):
875 self._stream = stream
876 self._proc = proc
877 def close(self):
878 self._stream.close()
Amaury Forgeot d'Arc97e5f282009-07-11 09:35:13 +0000879 returncode = self._proc.wait()
880 if returncode == 0:
881 return None
882 if name == 'nt':
883 return returncode
884 else:
885 return returncode << 8 # Shift left to match old behavior
Antoine Pitrouac625352009-12-09 00:01:27 +0000886 def __enter__(self):
887 return self
888 def __exit__(self, *args):
889 self.close()
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000890 def __getattr__(self, name):
891 return getattr(self._stream, name)
Thomas Heller476157b2007-09-04 11:27:47 +0000892 def __iter__(self):
893 return iter(self._stream)
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000894
Amaury Forgeot d'Arcbdbddf82008-08-01 00:06:49 +0000895# Supply os.fdopen()
896def fdopen(fd, *args, **kwargs):
Guido van Rossumc2f93dc2007-05-24 00:50:02 +0000897 if not isinstance(fd, int):
898 raise TypeError("invalid fd type (%s, expected integer)" % type(fd))
899 import io
Amaury Forgeot d'Arcbdbddf82008-08-01 00:06:49 +0000900 return io.open(fd, *args, **kwargs)