blob: 05e9c32c5a71177781f2916202078ef0ddb7ed86 [file] [log] [blame]
Ned Deily5c867012014-06-26 23:40:06 -07001r"""OS routines for 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:
Larry Hastings10108a72016-09-05 15:11:23 -07004 - all functions from posix or nt, e.g. unlink, stat, etc.
Alexandre Vassalottieca20b62008-05-16 02:54:33 +00005 - os.path is either posixpath or ntpath
Larry Hastings10108a72016-09-05 15:11:23 -07006 - os.name is either 'posix' or 'nt'
Ned Deilybf090e32016-10-01 21:12:35 -04007 - os.curdir is a string representing the current directory (always '.')
8 - os.pardir is a string representing the parent directory (always '..')
9 - os.sep is the (or a most common) pathname separator ('/' 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#'
Ethan Furman958b3e42016-06-04 12:49:35 -070025import abc
Serhiy Storchaka81108372017-09-26 00:55:55 +030026import sys
Charles-François Natali7372b062012-02-05 15:15:38 +010027import stat as st
Guido van Rossuma28dab51997-08-29 22:36:47 +000028
Bar Hareleae87e32019-12-22 11:57:27 +020029from _collections_abc import _check_methods
30
Guido van Rossum48b069a2020-04-07 09:50:06 -070031GenericAlias = type(list[int])
32
Guido van Rossuma28dab51997-08-29 22:36:47 +000033_names = sys.builtin_module_names
34
Tim Petersc4e09402003-04-25 07:11:48 +000035# Note: more names are added to __all__ later.
Brett Cannon13962fc2008-08-18 01:45:29 +000036__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
Petri Lehtinen3bc37f22012-05-23 21:36:16 +030037 "defpath", "name", "path", "devnull", "SEEK_SET", "SEEK_CUR",
38 "SEEK_END", "fsencode", "fsdecode", "get_exec_path", "fdopen",
pxinwre1e3c2d2020-12-16 05:20:07 +080039 "extsep"]
Skip Montanaro269b83b2001-02-06 01:07:02 +000040
Charles-François Natali7372b062012-02-05 15:15:38 +010041def _exists(name):
42 return name in globals()
43
Skip Montanaro269b83b2001-02-06 01:07:02 +000044def _get_exports_list(module):
45 try:
46 return list(module.__all__)
47 except AttributeError:
48 return [n for n in dir(module) if n[0] != '_']
49
Brett Cannonfd074152012-04-14 14:10:13 -040050# Any new dependencies of the os module and/or changes in path separator
51# requires updating importlib as well.
Guido van Rossuma28dab51997-08-29 22:36:47 +000052if 'posix' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000053 name = 'posix'
Guido van Rossume9387ea1998-05-22 15:26:04 +000054 linesep = '\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000055 from posix import *
56 try:
57 from posix import _exit
Petri Lehtinen3bc37f22012-05-23 21:36:16 +030058 __all__.append('_exit')
Brett Cannoncd171c82013-07-04 17:43:24 -040059 except ImportError:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000060 pass
Skip Montanaro117910d2003-02-14 19:35:31 +000061 import posixpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000062
Larry Hastings9cf065c2012-06-22 16:30:09 -070063 try:
64 from posix import _have_functions
Brett Cannoncd171c82013-07-04 17:43:24 -040065 except ImportError:
Larry Hastings9cf065c2012-06-22 16:30:09 -070066 pass
Skip Montanaro269b83b2001-02-06 01:07:02 +000067
Yury Selivanov97e2e062014-09-26 12:33:06 -040068 import posix
69 __all__.extend(_get_exports_list(posix))
70 del posix
71
Guido van Rossuma28dab51997-08-29 22:36:47 +000072elif 'nt' in _names:
Guido van Rossum61de0ac1997-12-05 21:24:30 +000073 name = 'nt'
Guido van Rossume9387ea1998-05-22 15:26:04 +000074 linesep = '\r\n'
Guido van Rossum61de0ac1997-12-05 21:24:30 +000075 from nt import *
Tim Peters6757c1e2003-01-08 21:20:57 +000076 try:
77 from nt import _exit
Petri Lehtinen3bc37f22012-05-23 21:36:16 +030078 __all__.append('_exit')
Brett Cannoncd171c82013-07-04 17:43:24 -040079 except ImportError:
Tim Peters6757c1e2003-01-08 21:20:57 +000080 pass
Skip Montanaro117910d2003-02-14 19:35:31 +000081 import ntpath as path
Tim Petersf2715e02003-02-19 02:35:07 +000082
Skip Montanaro269b83b2001-02-06 01:07:02 +000083 import nt
84 __all__.extend(_get_exports_list(nt))
85 del nt
86
Larry Hastings9cf065c2012-06-22 16:30:09 -070087 try:
88 from nt import _have_functions
Brett Cannoncd171c82013-07-04 17:43:24 -040089 except ImportError:
Larry Hastings9cf065c2012-06-22 16:30:09 -070090 pass
91
Guido van Rossum2979b011994-08-01 11:18:30 +000092else:
Brett Cannoncd171c82013-07-04 17:43:24 -040093 raise ImportError('no os specific module found')
Guido van Rossume65cce51993-11-08 15:05:21 +000094
Skip Montanaro117910d2003-02-14 19:35:31 +000095sys.modules['os.path'] = path
Georg Brandled5b9b32008-12-05 07:45:54 +000096from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
97 devnull)
Skip Montanaro269b83b2001-02-06 01:07:02 +000098
Guido van Rossuma28dab51997-08-29 22:36:47 +000099del _names
100
Larry Hastings9cf065c2012-06-22 16:30:09 -0700101
102if _exists("_have_functions"):
103 _globals = globals()
104 def _add(str, fn):
105 if (fn in _globals) and (str in _have_functions):
106 _set.add(_globals[fn])
107
108 _set = set()
109 _add("HAVE_FACCESSAT", "access")
110 _add("HAVE_FCHMODAT", "chmod")
111 _add("HAVE_FCHOWNAT", "chown")
112 _add("HAVE_FSTATAT", "stat")
113 _add("HAVE_FUTIMESAT", "utime")
114 _add("HAVE_LINKAT", "link")
115 _add("HAVE_MKDIRAT", "mkdir")
116 _add("HAVE_MKFIFOAT", "mkfifo")
117 _add("HAVE_MKNODAT", "mknod")
118 _add("HAVE_OPENAT", "open")
119 _add("HAVE_READLINKAT", "readlink")
120 _add("HAVE_RENAMEAT", "rename")
121 _add("HAVE_SYMLINKAT", "symlink")
122 _add("HAVE_UNLINKAT", "unlink")
Larry Hastingsb698d8e2012-06-23 16:55:07 -0700123 _add("HAVE_UNLINKAT", "rmdir")
Larry Hastings9cf065c2012-06-22 16:30:09 -0700124 _add("HAVE_UTIMENSAT", "utime")
125 supports_dir_fd = _set
126
127 _set = set()
128 _add("HAVE_FACCESSAT", "access")
129 supports_effective_ids = _set
130
131 _set = set()
132 _add("HAVE_FCHDIR", "chdir")
133 _add("HAVE_FCHMOD", "chmod")
134 _add("HAVE_FCHOWN", "chown")
135 _add("HAVE_FDOPENDIR", "listdir")
Serhiy Storchakaea720fe2017-03-30 09:12:31 +0300136 _add("HAVE_FDOPENDIR", "scandir")
Larry Hastings9cf065c2012-06-22 16:30:09 -0700137 _add("HAVE_FEXECVE", "execve")
138 _set.add(stat) # fstat always works
Georg Brandl306336b2012-06-24 12:55:33 +0200139 _add("HAVE_FTRUNCATE", "truncate")
Larry Hastings9cf065c2012-06-22 16:30:09 -0700140 _add("HAVE_FUTIMENS", "utime")
141 _add("HAVE_FUTIMES", "utime")
Georg Brandl306336b2012-06-24 12:55:33 +0200142 _add("HAVE_FPATHCONF", "pathconf")
Larry Hastings9cf065c2012-06-22 16:30:09 -0700143 if _exists("statvfs") and _exists("fstatvfs"): # mac os x10.3
144 _add("HAVE_FSTATVFS", "statvfs")
145 supports_fd = _set
146
147 _set = set()
148 _add("HAVE_FACCESSAT", "access")
Larry Hastingsdbbc0c82012-06-22 19:50:21 -0700149 # Some platforms don't support lchmod(). Often the function exists
150 # anyway, as a stub that always returns ENOSUP or perhaps EOPNOTSUPP.
151 # (No, I don't know why that's a good design.) ./configure will detect
152 # this and reject it--so HAVE_LCHMOD still won't be defined on such
153 # platforms. This is Very Helpful.
154 #
155 # However, sometimes platforms without a working lchmod() *do* have
156 # fchmodat(). (Examples: Linux kernel 3.2 with glibc 2.15,
157 # OpenIndiana 3.x.) And fchmodat() has a flag that theoretically makes
158 # it behave like lchmod(). So in theory it would be a suitable
159 # replacement for lchmod(). But when lchmod() doesn't work, fchmodat()'s
160 # flag doesn't work *either*. Sadly ./configure isn't sophisticated
161 # enough to detect this condition--it only determines whether or not
162 # fchmodat() minimally works.
163 #
164 # Therefore we simply ignore fchmodat() when deciding whether or not
165 # os.chmod supports follow_symlinks. Just checking lchmod() is
166 # sufficient. After all--if you have a working fchmodat(), your
167 # lchmod() almost certainly works too.
168 #
169 # _add("HAVE_FCHMODAT", "chmod")
Larry Hastings9cf065c2012-06-22 16:30:09 -0700170 _add("HAVE_FCHOWNAT", "chown")
171 _add("HAVE_FSTATAT", "stat")
172 _add("HAVE_LCHFLAGS", "chflags")
173 _add("HAVE_LCHMOD", "chmod")
174 if _exists("lchown"): # mac os x10.3
175 _add("HAVE_LCHOWN", "chown")
176 _add("HAVE_LINKAT", "link")
177 _add("HAVE_LUTIMES", "utime")
178 _add("HAVE_LSTAT", "stat")
179 _add("HAVE_FSTATAT", "stat")
180 _add("HAVE_UTIMENSAT", "utime")
181 _add("MS_WINDOWS", "stat")
182 supports_follow_symlinks = _set
183
Larry Hastings9cf065c2012-06-22 16:30:09 -0700184 del _set
185 del _have_functions
186 del _globals
187 del _add
188
189
Martin v. Löwis22b457e2005-01-16 08:40:58 +0000190# Python uses fixed values for the SEEK_ constants; they are mapped
191# to native constants if necessary in posixmodule.c
Jesus Cea94363612012-06-22 18:32:07 +0200192# Other possible SEEK values are directly imported from posixmodule.c
Martin v. Löwis22b457e2005-01-16 08:40:58 +0000193SEEK_SET = 0
194SEEK_CUR = 1
195SEEK_END = 2
196
Guido van Rossum4def7de1998-07-24 20:48:03 +0000197# Super directory utilities.
198# (Inspired by Eric Raymond; the doc strings are mostly his)
199
Terry Reedy5a22b652010-12-02 07:05:56 +0000200def makedirs(name, mode=0o777, exist_ok=False):
Zachary Warea22ae212014-03-20 09:42:01 -0500201 """makedirs(name [, mode=0o777][, exist_ok=False])
Guido van Rossum4def7de1998-07-24 20:48:03 +0000202
Benjamin Petersonee5f1c12014-04-01 19:13:18 -0400203 Super-mkdir; create a leaf directory and all intermediate ones. Works like
204 mkdir, except that any intermediate path segment (not just the rightmost)
205 will be created if it does not exist. If the target directory already
206 exists, raise an OSError if exist_ok is False. Otherwise no exception is
Terry Reedy5a22b652010-12-02 07:05:56 +0000207 raised. This is recursive.
Guido van Rossum4def7de1998-07-24 20:48:03 +0000208
209 """
210 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000211 if not tail:
212 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000213 if head and tail and not path.exists(head):
Thomas Wouters89f507f2006-12-13 04:49:30 +0000214 try:
Serhiy Storchakae304e332017-03-24 13:27:42 +0200215 makedirs(head, exist_ok=exist_ok)
Giampaolo Rodola'0166a282013-02-12 15:14:17 +0100216 except FileExistsError:
Martin Pantera82642f2015-11-19 04:48:44 +0000217 # Defeats race condition when another thread created the path
Giampaolo Rodola'0166a282013-02-12 15:14:17 +0100218 pass
Serhiy Storchaka4ab23bf2013-01-08 11:32:58 +0200219 cdir = curdir
220 if isinstance(tail, bytes):
221 cdir = bytes(curdir, 'ASCII')
222 if tail == cdir: # xxx/newdir/. exists if xxx/newdir exists
Andrew M. Kuchling6fccc8a2003-12-23 16:33:28 +0000223 return
Terry Reedy5a22b652010-12-02 07:05:56 +0000224 try:
225 mkdir(name, mode)
Martin Pantera82642f2015-11-19 04:48:44 +0000226 except OSError:
227 # Cannot rely on checking for EEXIST, since the operating system
228 # could give priority to other errors like EACCES or EROFS
229 if not exist_ok or not path.isdir(name):
Terry Reedy5a22b652010-12-02 07:05:56 +0000230 raise
Guido van Rossum4def7de1998-07-24 20:48:03 +0000231
232def removedirs(name):
Zachary Warea22ae212014-03-20 09:42:01 -0500233 """removedirs(name)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000234
Fredrik Lundh96c1c7a2005-11-12 15:55:04 +0000235 Super-rmdir; remove a leaf directory and all empty intermediate
Guido van Rossum4def7de1998-07-24 20:48:03 +0000236 ones. Works like rmdir except that, if the leaf directory is
237 successfully removed, directories corresponding to rightmost path
Tim Petersc4e09402003-04-25 07:11:48 +0000238 segments will be pruned away until either the whole path is
Guido van Rossum4def7de1998-07-24 20:48:03 +0000239 consumed or an error occurs. Errors during this latter phase are
240 ignored -- they generally mean that a directory was not empty.
241
242 """
243 rmdir(name)
244 head, tail = path.split(name)
Fred Drake9f2550f2000-07-25 15:16:40 +0000245 if not tail:
246 head, tail = path.split(head)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000247 while head and tail:
248 try:
249 rmdir(head)
Andrew Svetlov2552bc02012-12-24 21:47:24 +0200250 except OSError:
Guido van Rossum4def7de1998-07-24 20:48:03 +0000251 break
252 head, tail = path.split(head)
253
254def renames(old, new):
Fred Drakecadb9eb2002-07-02 21:28:04 +0000255 """renames(old, new)
Guido van Rossum4def7de1998-07-24 20:48:03 +0000256
257 Super-rename; create directories as necessary and delete any left
258 empty. Works like rename, except creation of any intermediate
259 directories needed to make the new pathname good is attempted
260 first. After the rename, directories corresponding to rightmost
Benjamin Peterson52a3b742015-04-13 20:24:10 -0400261 path segments of the old name will be pruned until either the
Guido van Rossum4def7de1998-07-24 20:48:03 +0000262 whole path is consumed or a nonempty directory is found.
263
264 Note: this function can fail with the new directory structure made
265 if you lack permissions needed to unlink the leaf directory or
266 file.
267
268 """
269 head, tail = path.split(new)
270 if head and tail and not path.exists(head):
271 makedirs(head)
272 rename(old, new)
273 head, tail = path.split(old)
274 if head and tail:
275 try:
276 removedirs(head)
Andrew Svetlov8b33dd82012-12-24 19:58:48 +0200277 except OSError:
Guido van Rossum4def7de1998-07-24 20:48:03 +0000278 pass
279
Skip Montanaro269b83b2001-02-06 01:07:02 +0000280__all__.extend(["makedirs", "removedirs", "renames"])
281
Guido van Rossumd8faa362007-04-27 19:54:29 +0000282def walk(top, topdown=True, onerror=None, followlinks=False):
Tim Petersc4e09402003-04-25 07:11:48 +0000283 """Directory tree generator.
284
285 For each directory in the directory tree rooted at top (including top
286 itself, but excluding '.' and '..'), yields a 3-tuple
287
288 dirpath, dirnames, filenames
289
290 dirpath is a string, the path to the directory. dirnames is a list of
291 the names of the subdirectories in dirpath (excluding '.' and '..').
292 filenames is a list of the names of the non-directory files in dirpath.
293 Note that the names in the lists are just names, with no path components.
294 To get a full path (which begins with top) to a file or directory in
295 dirpath, do os.path.join(dirpath, name).
296
297 If optional arg 'topdown' is true or not specified, the triple for a
298 directory is generated before the triples for any of its subdirectories
299 (directories are generated top down). If topdown is false, the triple
300 for a directory is generated after the triples for all of its
301 subdirectories (directories are generated bottom up).
302
303 When topdown is true, the caller can modify the dirnames list in-place
304 (e.g., via del or slice assignment), and walk will only recurse into the
Benjamin Petersone58e0c72014-06-15 20:51:12 -0700305 subdirectories whose names remain in dirnames; this can be used to prune the
306 search, or to impose a specific order of visiting. Modifying dirnames when
Bernt Røskar Brenna734f1202019-09-10 14:43:58 +0200307 topdown is false has no effect on the behavior of os.walk(), since the
308 directories in dirnames have already been generated by the time dirnames
309 itself is generated. No matter the value of topdown, the list of
310 subdirectories is retrieved before the tuples for the directory and its
311 subdirectories are generated.
Tim Petersc4e09402003-04-25 07:11:48 +0000312
Victor Stinner524a5ba2015-03-10 13:20:34 +0100313 By default errors from the os.scandir() call are ignored. If
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000314 optional arg 'onerror' is specified, it should be a function; it
Andrew Svetlovad28c7f2012-12-18 22:02:39 +0200315 will be called with one argument, an OSError instance. It can
Guido van Rossumbf1bef82003-05-13 18:01:19 +0000316 report the error to continue with the walk, or raise the exception
317 to abort the walk. Note that the filename is available as the
318 filename attribute of the exception object.
319
Guido van Rossumd8faa362007-04-27 19:54:29 +0000320 By default, os.walk does not follow symbolic links to subdirectories on
321 systems that support them. In order to get this functionality, set the
322 optional argument 'followlinks' to true.
323
Tim Petersc4e09402003-04-25 07:11:48 +0000324 Caution: if you pass a relative pathname for top, don't change the
325 current working directory between resumptions of walk. walk never
326 changes the current directory, and assumes that the client doesn't
327 either.
328
329 Example:
330
Christian Heimes5d8da202008-05-06 13:58:24 +0000331 import os
Tim Petersc4e09402003-04-25 07:11:48 +0000332 from os.path import join, getsize
Christian Heimes5d8da202008-05-06 13:58:24 +0000333 for root, dirs, files in os.walk('python/Lib/email'):
Neal Norwitz752abd02008-05-13 04:55:24 +0000334 print(root, "consumes", end="")
Recursing3ce3dea2018-12-23 04:48:14 +0100335 print(sum(getsize(join(root, name)) for name in files), end="")
Neal Norwitz752abd02008-05-13 04:55:24 +0000336 print("bytes in", len(files), "non-directory files")
Tim Petersc4e09402003-04-25 07:11:48 +0000337 if 'CVS' in dirs:
338 dirs.remove('CVS') # don't visit CVS directories
Benjamin Petersone58e0c72014-06-15 20:51:12 -0700339
Tim Petersc4e09402003-04-25 07:11:48 +0000340 """
Serhiy Storchakaf4f445b2020-02-12 12:11:34 +0200341 sys.audit("os.walk", top, topdown, onerror, followlinks)
342 return _walk(fspath(top), topdown, onerror, followlinks)
343
344def _walk(top, topdown, onerror, followlinks):
Victor Stinner524a5ba2015-03-10 13:20:34 +0100345 dirs = []
346 nondirs = []
Serhiy Storchaka7c90a822016-02-11 13:31:00 +0200347 walk_dirs = []
Tim Petersc4e09402003-04-25 07:11:48 +0000348
349 # We may not have read permission for top, in which case we can't
Alexandre Vassalotti4e6531e2008-05-09 20:00:17 +0000350 # get a list of the files the directory contains. os.walk
Tim Petersc4e09402003-04-25 07:11:48 +0000351 # always suppressed the exception then, rather than blow up for a
352 # minor reason when (say) a thousand readable directories are still
353 # left to visit. That logic is copied here.
354 try:
Serhiy Storchaka3ae41552016-10-05 23:17:10 +0300355 # Note that scandir is global in this module due
356 # to earlier import-*.
357 scandir_it = scandir(top)
Victor Stinner7fea9742015-03-18 11:29:47 +0100358 except OSError as error:
359 if onerror is not None:
360 onerror(error)
361 return
362
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +0200363 with scandir_it:
364 while True:
Victor Stinner524a5ba2015-03-10 13:20:34 +0100365 try:
Victor Stinner524a5ba2015-03-10 13:20:34 +0100366 try:
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +0200367 entry = next(scandir_it)
368 except StopIteration:
369 break
370 except OSError as error:
371 if onerror is not None:
372 onerror(error)
373 return
Victor Stinner7fea9742015-03-18 11:29:47 +0100374
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +0200375 try:
376 is_dir = entry.is_dir()
377 except OSError:
378 # If is_dir() raises an OSError, consider that the entry is not
379 # a directory, same behaviour than os.path.isdir().
380 is_dir = False
381
382 if is_dir:
383 dirs.append(entry.name)
384 else:
385 nondirs.append(entry.name)
386
387 if not topdown and is_dir:
388 # Bottom-up: recurse into sub-directory, but exclude symlinks to
389 # directories if followlinks is False
390 if followlinks:
391 walk_into = True
392 else:
393 try:
394 is_symlink = entry.is_symlink()
395 except OSError:
396 # If is_symlink() raises an OSError, consider that the
397 # entry is not a symbolic link, same behaviour than
398 # os.path.islink().
399 is_symlink = False
400 walk_into = not is_symlink
401
402 if walk_into:
Serhiy Storchaka7c90a822016-02-11 13:31:00 +0200403 walk_dirs.append(entry.path)
Tim Petersc4e09402003-04-25 07:11:48 +0000404
Victor Stinner524a5ba2015-03-10 13:20:34 +0100405 # Yield before recursion if going top down
Tim Petersc4e09402003-04-25 07:11:48 +0000406 if topdown:
407 yield top, dirs, nondirs
Victor Stinner524a5ba2015-03-10 13:20:34 +0100408
Victor Stinner7fea9742015-03-18 11:29:47 +0100409 # Recurse into sub-directories
410 islink, join = path.islink, path.join
Serhiy Storchaka5f6a0b42016-02-08 16:23:28 +0200411 for dirname in dirs:
412 new_path = join(top, dirname)
Victor Stinner7fea9742015-03-18 11:29:47 +0100413 # Issue #23605: os.path.islink() is used instead of caching
414 # entry.is_symlink() result during the loop on os.scandir() because
415 # the caller can replace the directory entry during the "yield"
416 # above.
417 if followlinks or not islink(new_path):
Serhiy Storchakaf4f445b2020-02-12 12:11:34 +0200418 yield from _walk(new_path, topdown, onerror, followlinks)
Victor Stinner7fea9742015-03-18 11:29:47 +0100419 else:
Serhiy Storchaka7c90a822016-02-11 13:31:00 +0200420 # Recurse into sub-directories
421 for new_path in walk_dirs:
Serhiy Storchakaf4f445b2020-02-12 12:11:34 +0200422 yield from _walk(new_path, topdown, onerror, followlinks)
Victor Stinner7fea9742015-03-18 11:29:47 +0100423 # Yield after recursion if going bottom up
Tim Petersc4e09402003-04-25 07:11:48 +0000424 yield top, dirs, nondirs
425
426__all__.append("walk")
427
Serhiy Storchakaea720fe2017-03-30 09:12:31 +0300428if {open, stat} <= supports_dir_fd and {scandir, stat} <= supports_fd:
Charles-François Natali7372b062012-02-05 15:15:38 +0100429
Larry Hastingsb4038062012-07-15 10:57:38 -0700430 def fwalk(top=".", topdown=True, onerror=None, *, follow_symlinks=False, dir_fd=None):
Charles-François Natali7372b062012-02-05 15:15:38 +0100431 """Directory tree generator.
432
433 This behaves exactly like walk(), except that it yields a 4-tuple
434
435 dirpath, dirnames, filenames, dirfd
436
437 `dirpath`, `dirnames` and `filenames` are identical to walk() output,
438 and `dirfd` is a file descriptor referring to the directory `dirpath`.
439
Larry Hastingsc48fe982012-06-25 04:49:05 -0700440 The advantage of fwalk() over walk() is that it's safe against symlink
Larry Hastingsb4038062012-07-15 10:57:38 -0700441 races (when follow_symlinks is False).
Charles-François Natali7372b062012-02-05 15:15:38 +0100442
Larry Hastingsc48fe982012-06-25 04:49:05 -0700443 If dir_fd is not None, it should be a file descriptor open to a directory,
444 and top should be relative; top will then be relative to that directory.
445 (dir_fd is always supported for fwalk.)
446
Charles-François Natali7372b062012-02-05 15:15:38 +0100447 Caution:
448 Since fwalk() yields file descriptors, those are only valid until the
449 next iteration step, so you should dup() them if you want to keep them
450 for a longer period.
451
452 Example:
453
454 import os
455 for root, dirs, files, rootfd in os.fwalk('python/Lib/email'):
456 print(root, "consumes", end="")
Recursing3ce3dea2018-12-23 04:48:14 +0100457 print(sum(os.stat(name, dir_fd=rootfd).st_size for name in files),
Charles-François Natali7372b062012-02-05 15:15:38 +0100458 end="")
459 print("bytes in", len(files), "non-directory files")
460 if 'CVS' in dirs:
461 dirs.remove('CVS') # don't visit CVS directories
462 """
Serhiy Storchakaf4f445b2020-02-12 12:11:34 +0200463 sys.audit("os.fwalk", top, topdown, onerror, follow_symlinks, dir_fd)
Brett Cannon3f9183b2016-08-26 14:44:48 -0700464 if not isinstance(top, int) or not hasattr(top, '__index__'):
465 top = fspath(top)
Charles-François Natali7372b062012-02-05 15:15:38 +0100466 # Note: To guard against symlink races, we use the standard
467 # lstat()/open()/fstat() trick.
Serhiy Storchakaea720fe2017-03-30 09:12:31 +0300468 if not follow_symlinks:
469 orig_st = stat(top, follow_symlinks=False, dir_fd=dir_fd)
Larry Hastingsc48fe982012-06-25 04:49:05 -0700470 topfd = open(top, O_RDONLY, dir_fd=dir_fd)
Charles-François Natali7372b062012-02-05 15:15:38 +0100471 try:
Larry Hastingsb4038062012-07-15 10:57:38 -0700472 if (follow_symlinks or (st.S_ISDIR(orig_st.st_mode) and
473 path.samestat(orig_st, stat(topfd)))):
Serhiy Storchaka8f6b3442017-03-07 14:33:21 +0200474 yield from _fwalk(topfd, top, isinstance(top, bytes),
475 topdown, onerror, follow_symlinks)
Charles-François Natali7372b062012-02-05 15:15:38 +0100476 finally:
477 close(topfd)
478
Serhiy Storchaka8f6b3442017-03-07 14:33:21 +0200479 def _fwalk(topfd, toppath, isbytes, topdown, onerror, follow_symlinks):
Charles-François Natali7372b062012-02-05 15:15:38 +0100480 # Note: This uses O(depth of the directory tree) file descriptors: if
481 # necessary, it can be adapted to only require O(1) FDs, see issue
482 # #13734.
483
Serhiy Storchakaea720fe2017-03-30 09:12:31 +0300484 scandir_it = scandir(topfd)
485 dirs = []
486 nondirs = []
487 entries = None if topdown or follow_symlinks else []
488 for entry in scandir_it:
489 name = entry.name
490 if isbytes:
491 name = fsencode(name)
Hynek Schlawack66bfcc12012-05-15 16:32:21 +0200492 try:
Serhiy Storchakaea720fe2017-03-30 09:12:31 +0300493 if entry.is_dir():
Hynek Schlawack66bfcc12012-05-15 16:32:21 +0200494 dirs.append(name)
Serhiy Storchakaea720fe2017-03-30 09:12:31 +0300495 if entries is not None:
496 entries.append(entry)
Hynek Schlawack66bfcc12012-05-15 16:32:21 +0200497 else:
498 nondirs.append(name)
Serhiy Storchaka42babab2016-10-25 14:28:38 +0300499 except OSError:
Hynek Schlawack66bfcc12012-05-15 16:32:21 +0200500 try:
501 # Add dangling symlinks, ignore disappeared files
Serhiy Storchakaea720fe2017-03-30 09:12:31 +0300502 if entry.is_symlink():
Hynek Schlawack66bfcc12012-05-15 16:32:21 +0200503 nondirs.append(name)
Serhiy Storchaka42babab2016-10-25 14:28:38 +0300504 except OSError:
Serhiy Storchakaea720fe2017-03-30 09:12:31 +0300505 pass
Charles-François Natali7372b062012-02-05 15:15:38 +0100506
507 if topdown:
508 yield toppath, dirs, nondirs, topfd
509
Serhiy Storchakaea720fe2017-03-30 09:12:31 +0300510 for name in dirs if entries is None else zip(dirs, entries):
Charles-François Natali7372b062012-02-05 15:15:38 +0100511 try:
Serhiy Storchakaea720fe2017-03-30 09:12:31 +0300512 if not follow_symlinks:
513 if topdown:
514 orig_st = stat(name, dir_fd=topfd, follow_symlinks=False)
515 else:
516 assert entries is not None
517 name, entry = name
518 orig_st = entry.stat(follow_symlinks=False)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700519 dirfd = open(name, O_RDONLY, dir_fd=topfd)
Andrew Svetlov8b33dd82012-12-24 19:58:48 +0200520 except OSError as err:
Charles-François Natali7372b062012-02-05 15:15:38 +0100521 if onerror is not None:
522 onerror(err)
Serhiy Storchaka0bddc9e2015-12-23 00:08:24 +0200523 continue
Charles-François Natali7372b062012-02-05 15:15:38 +0100524 try:
Larry Hastingsb4038062012-07-15 10:57:38 -0700525 if follow_symlinks or path.samestat(orig_st, stat(dirfd)):
Charles-François Natali7372b062012-02-05 15:15:38 +0100526 dirpath = path.join(toppath, name)
Serhiy Storchaka8f6b3442017-03-07 14:33:21 +0200527 yield from _fwalk(dirfd, dirpath, isbytes,
528 topdown, onerror, follow_symlinks)
Charles-François Natali7372b062012-02-05 15:15:38 +0100529 finally:
530 close(dirfd)
531
532 if not topdown:
533 yield toppath, dirs, nondirs, topfd
534
535 __all__.append("fwalk")
536
Guido van Rossume65cce51993-11-08 15:05:21 +0000537def execl(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000538 """execl(file, *args)
539
540 Execute the executable file with argument list args, replacing the
541 current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000542 execv(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000543
544def execle(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000545 """execle(file, *args, env)
546
547 Execute the executable file with argument list args and
548 environment env, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000549 env = args[-1]
550 execve(file, args[:-1], env)
Guido van Rossume65cce51993-11-08 15:05:21 +0000551
552def execlp(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000553 """execlp(file, *args)
554
555 Execute the executable file (which is searched for along $PATH)
556 with argument list args, replacing the current process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000557 execvp(file, args)
Guido van Rossume65cce51993-11-08 15:05:21 +0000558
Guido van Rossum030afb11995-03-14 17:27:18 +0000559def execlpe(file, *args):
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000560 """execlpe(file, *args, env)
561
562 Execute the executable file (which is searched for along $PATH)
563 with argument list args and environment env, replacing the current
Tim Peters2344fae2001-01-15 00:50:52 +0000564 process. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000565 env = args[-1]
566 execvpe(file, args[:-1], env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000567
Guido van Rossume65cce51993-11-08 15:05:21 +0000568def execvp(file, args):
Matthias Klosea09c54f2010-01-31 16:48:44 +0000569 """execvp(file, args)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000570
571 Execute the executable file (which is searched for along $PATH)
572 with argument list args, replacing the current process.
Thomas Wouters7e474022000-07-16 12:04:32 +0000573 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000574 _execvpe(file, args)
Guido van Rossum030afb11995-03-14 17:27:18 +0000575
576def execvpe(file, args, env):
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000577 """execvpe(file, args, env)
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000578
579 Execute the executable file (which is searched for along $PATH)
Hasan Ramezanifb6807b2019-09-09 17:58:21 +0200580 with argument list args and environment env, replacing the
Guido van Rossum7da3cc52000-04-25 10:53:22 +0000581 current process.
Tim Peters2344fae2001-01-15 00:50:52 +0000582 args may be a list or tuple of strings. """
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000583 _execvpe(file, args, env)
Guido van Rossum030afb11995-03-14 17:27:18 +0000584
Skip Montanaro269b83b2001-02-06 01:07:02 +0000585__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
586
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000587def _execvpe(file, args, env=None):
588 if env is not None:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000589 exec_func = execve
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000590 argrest = (args, env)
591 else:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000592 exec_func = execv
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000593 argrest = (args,)
594 env = environ
Guido van Rossumaed51d82002-08-05 16:13:24 +0000595
Serhiy Storchaka81108372017-09-26 00:55:55 +0300596 if path.dirname(file):
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000597 exec_func(file, *argrest)
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000598 return
Serhiy Storchaka81108372017-09-26 00:55:55 +0300599 saved_exc = None
Victor Stinnerb745a742010-05-18 17:17:23 +0000600 path_list = get_exec_path(env)
601 if name != 'nt':
602 file = fsencode(file)
603 path_list = map(fsencode, path_list)
604 for dir in path_list:
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000605 fullname = path.join(dir, file)
606 try:
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000607 exec_func(fullname, *argrest)
Serhiy Storchaka81108372017-09-26 00:55:55 +0300608 except (FileNotFoundError, NotADirectoryError) as e:
609 last_exc = e
Andrew Svetlov8b33dd82012-12-24 19:58:48 +0200610 except OSError as e:
Guido van Rossume7ba4952007-06-06 23:52:48 +0000611 last_exc = e
Serhiy Storchaka81108372017-09-26 00:55:55 +0300612 if saved_exc is None:
Guido van Rossum683c0fe2002-09-03 16:36:17 +0000613 saved_exc = e
Serhiy Storchaka81108372017-09-26 00:55:55 +0300614 if saved_exc is not None:
615 raise saved_exc
616 raise last_exc
Guido van Rossumd74fb6b2001-03-02 06:43:49 +0000617
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000618
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000619def get_exec_path(env=None):
620 """Returns the sequence of directories that will be searched for the
621 named executable (similar to a shell) when launching a process.
622
623 *env* must be an environment variable dict or None. If *env* is None,
624 os.environ will be used.
625 """
Victor Stinner273b7662010-11-06 12:59:33 +0000626 # Use a local import instead of a global import to limit the number of
627 # modules loaded at startup: the os module is always loaded at startup by
628 # Python. It may also avoid a bootstrap issue.
Victor Stinner6f35eda2010-10-29 00:38:58 +0000629 import warnings
630
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000631 if env is None:
632 env = environ
Victor Stinnerb745a742010-05-18 17:17:23 +0000633
Victor Stinnerbb4f2182010-11-07 15:43:39 +0000634 # {b'PATH': ...}.get('PATH') and {'PATH': ...}.get(b'PATH') emit a
635 # BytesWarning when using python -b or python -bb: ignore the warning
Victor Stinner273b7662010-11-06 12:59:33 +0000636 with warnings.catch_warnings():
637 warnings.simplefilter("ignore", BytesWarning)
Victor Stinnerb745a742010-05-18 17:17:23 +0000638
Victor Stinnerb745a742010-05-18 17:17:23 +0000639 try:
Victor Stinner273b7662010-11-06 12:59:33 +0000640 path_list = env.get('PATH')
641 except TypeError:
642 path_list = None
Victor Stinnerb745a742010-05-18 17:17:23 +0000643
Victor Stinner273b7662010-11-06 12:59:33 +0000644 if supports_bytes_environ:
645 try:
646 path_listb = env[b'PATH']
647 except (KeyError, TypeError):
648 pass
649 else:
650 if path_list is not None:
651 raise ValueError(
652 "env cannot contain 'PATH' and b'PATH' keys")
653 path_list = path_listb
654
655 if path_list is not None and isinstance(path_list, bytes):
656 path_list = fsdecode(path_list)
Victor Stinnerb745a742010-05-18 17:17:23 +0000657
658 if path_list is None:
659 path_list = defpath
660 return path_list.split(pathsep)
Gregory P. Smithb6e8c7e2010-02-27 07:22:22 +0000661
662
Victor Stinnerb8d12622020-01-24 14:05:48 +0100663# Change environ to automatically call putenv() and unsetenv()
Charles Burklandd648ef12020-03-13 09:04:43 -0700664from _collections_abc import MutableMapping, Mapping
Skip Montanaro289bc052007-08-17 02:30:27 +0000665
666class _Environ(MutableMapping):
Victor Stinnerb8d12622020-01-24 14:05:48 +0100667 def __init__(self, data, encodekey, decodekey, encodevalue, decodevalue):
Victor Stinner84ae1182010-05-06 22:05:07 +0000668 self.encodekey = encodekey
669 self.decodekey = decodekey
670 self.encodevalue = encodevalue
671 self.decodevalue = decodevalue
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000672 self._data = data
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000673
Skip Montanaro289bc052007-08-17 02:30:27 +0000674 def __getitem__(self, key):
Victor Stinner6d101392013-04-14 16:35:04 +0200675 try:
676 value = self._data[self.encodekey(key)]
677 except KeyError:
678 # raise KeyError with the original key value
Victor Stinner0c2dd0c2013-08-23 19:19:15 +0200679 raise KeyError(key) from None
Victor Stinner84ae1182010-05-06 22:05:07 +0000680 return self.decodevalue(value)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000681
Skip Montanaro289bc052007-08-17 02:30:27 +0000682 def __setitem__(self, key, value):
Victor Stinner84ae1182010-05-06 22:05:07 +0000683 key = self.encodekey(key)
684 value = self.encodevalue(value)
Victor Stinnerb8d12622020-01-24 14:05:48 +0100685 putenv(key, value)
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000686 self._data[key] = value
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000687
Skip Montanaro289bc052007-08-17 02:30:27 +0000688 def __delitem__(self, key):
Victor Stinner6d101392013-04-14 16:35:04 +0200689 encodedkey = self.encodekey(key)
Victor Stinnerb8d12622020-01-24 14:05:48 +0100690 unsetenv(encodedkey)
Victor Stinner6d101392013-04-14 16:35:04 +0200691 try:
692 del self._data[encodedkey]
693 except KeyError:
694 # raise KeyError with the original key value
Victor Stinner0c2dd0c2013-08-23 19:19:15 +0200695 raise KeyError(key) from None
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000696
Skip Montanaro289bc052007-08-17 02:30:27 +0000697 def __iter__(self):
Osvaldo Santana Neto8a8d2852017-07-01 14:34:45 -0300698 # list() from dict object is an atomic operation
699 keys = list(self._data)
700 for key in keys:
Victor Stinner84ae1182010-05-06 22:05:07 +0000701 yield self.decodekey(key)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000702
Skip Montanaro289bc052007-08-17 02:30:27 +0000703 def __len__(self):
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000704 return len(self._data)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000705
706 def __repr__(self):
Victor Stinnerbed71172010-07-28 21:25:42 +0000707 return 'environ({{{}}})'.format(', '.join(
Victor Stinnerd73c1a32010-07-28 21:23:23 +0000708 ('{!r}: {!r}'.format(self.decodekey(key), self.decodevalue(value))
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000709 for key, value in self._data.items())))
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000710
Skip Montanaro289bc052007-08-17 02:30:27 +0000711 def copy(self):
712 return dict(self)
Ezio Melotti19e4acf2010-02-22 15:59:01 +0000713
Skip Montanaro289bc052007-08-17 02:30:27 +0000714 def setdefault(self, key, value):
715 if key not in self:
716 self[key] = value
717 return self[key]
718
Charles Burklandd648ef12020-03-13 09:04:43 -0700719 def __ior__(self, other):
720 self.update(other)
721 return self
722
723 def __or__(self, other):
724 if not isinstance(other, Mapping):
725 return NotImplemented
726 new = dict(self)
727 new.update(other)
728 return new
729
730 def __ror__(self, other):
731 if not isinstance(other, Mapping):
732 return NotImplemented
733 new = dict(other)
734 new.update(self)
735 return new
736
Victor Stinner84ae1182010-05-06 22:05:07 +0000737def _createenviron():
Jesus Cea4791a242012-10-05 03:15:39 +0200738 if name == 'nt':
Victor Stinner84ae1182010-05-06 22:05:07 +0000739 # Where Env Var Names Must Be UPPERCASE
740 def check_str(value):
741 if not isinstance(value, str):
742 raise TypeError("str expected, not %s" % type(value).__name__)
743 return value
744 encode = check_str
745 decode = str
746 def encodekey(key):
747 return encode(key).upper()
748 data = {}
749 for key, value in environ.items():
750 data[encodekey(key)] = value
751 else:
752 # Where Env Var Names Can Be Mixed Case
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000753 encoding = sys.getfilesystemencoding()
Victor Stinner84ae1182010-05-06 22:05:07 +0000754 def encode(value):
755 if not isinstance(value, str):
756 raise TypeError("str expected, not %s" % type(value).__name__)
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000757 return value.encode(encoding, 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000758 def decode(value):
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000759 return value.decode(encoding, 'surrogateescape')
Victor Stinner84ae1182010-05-06 22:05:07 +0000760 encodekey = encode
761 data = environ
762 return _Environ(data,
763 encodekey, decode,
Victor Stinnerb8d12622020-01-24 14:05:48 +0100764 encode, decode)
Guido van Rossumc524d952001-10-19 01:31:59 +0000765
Victor Stinner84ae1182010-05-06 22:05:07 +0000766# unicode environ
767environ = _createenviron()
768del _createenviron
Guido van Rossum61de0ac1997-12-05 21:24:30 +0000769
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000770
Jack Jansenb11ce9b2003-01-08 16:33:40 +0000771def getenv(key, default=None):
Tim Peters2c60f7a2003-01-29 03:49:43 +0000772 """Get an environment variable, return None if it doesn't exist.
Victor Stinner84ae1182010-05-06 22:05:07 +0000773 The optional second argument can specify an alternate default.
774 key, default and the result are str."""
Tim Peters2c60f7a2003-01-29 03:49:43 +0000775 return environ.get(key, default)
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000776
Jesus Cea4791a242012-10-05 03:15:39 +0200777supports_bytes_environ = (name != 'nt')
Victor Stinnerb745a742010-05-18 17:17:23 +0000778__all__.extend(("getenv", "supports_bytes_environ"))
779
780if supports_bytes_environ:
Victor Stinner84ae1182010-05-06 22:05:07 +0000781 def _check_bytes(value):
782 if not isinstance(value, bytes):
783 raise TypeError("bytes expected, not %s" % type(value).__name__)
784 return value
785
786 # bytes environ
Victor Stinner3d75d0c2010-09-10 22:18:16 +0000787 environb = _Environ(environ._data,
Victor Stinner84ae1182010-05-06 22:05:07 +0000788 _check_bytes, bytes,
Victor Stinnerb8d12622020-01-24 14:05:48 +0100789 _check_bytes, bytes)
Victor Stinner84ae1182010-05-06 22:05:07 +0000790 del _check_bytes
791
792 def getenvb(key, default=None):
793 """Get an environment variable, return None if it doesn't exist.
794 The optional second argument can specify an alternate default.
795 key, default and the result are bytes."""
796 return environb.get(key, default)
Victor Stinner70120e22010-07-29 17:19:38 +0000797
798 __all__.extend(("environb", "getenvb"))
Victor Stinner84ae1182010-05-06 22:05:07 +0000799
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000800def _fscodec():
801 encoding = sys.getfilesystemencoding()
Steve Dowercc16be82016-09-08 10:35:16 -0700802 errors = sys.getfilesystemencodeerrors()
Victor Stinnere8d51452010-08-19 01:05:19 +0000803
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000804 def fsencode(filename):
Brett Cannon5f74ebc2016-06-09 14:29:25 -0700805 """Encode filename (an os.PathLike, bytes, or str) to the filesystem
Ethan Furmanc1cbeed2016-06-04 10:19:27 -0700806 encoding with 'surrogateescape' error handler, return bytes unchanged.
807 On Windows, use 'strict' error handler if the file system encoding is
808 'mbcs' (which is the default encoding).
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000809 """
Brett Cannonc78ca1e2016-06-24 12:03:43 -0700810 filename = fspath(filename) # Does type-checking of `filename`.
811 if isinstance(filename, str):
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000812 return filename.encode(encoding, errors)
Victor Stinnere8d51452010-08-19 01:05:19 +0000813 else:
Brett Cannonc78ca1e2016-06-24 12:03:43 -0700814 return filename
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000815
816 def fsdecode(filename):
Brett Cannon5f74ebc2016-06-09 14:29:25 -0700817 """Decode filename (an os.PathLike, bytes, or str) from the filesystem
Ethan Furmanc1cbeed2016-06-04 10:19:27 -0700818 encoding with 'surrogateescape' error handler, return str unchanged. On
819 Windows, use 'strict' error handler if the file system encoding is
820 'mbcs' (which is the default encoding).
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000821 """
Brett Cannonc78ca1e2016-06-24 12:03:43 -0700822 filename = fspath(filename) # Does type-checking of `filename`.
823 if isinstance(filename, bytes):
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000824 return filename.decode(encoding, errors)
825 else:
Brett Cannonc78ca1e2016-06-24 12:03:43 -0700826 return filename
Victor Stinnerdf6d6cb2010-10-24 20:32:26 +0000827
828 return fsencode, fsdecode
829
830fsencode, fsdecode = _fscodec()
831del _fscodec
Victor Stinner449c4662010-05-08 11:10:09 +0000832
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000833# Supply spawn*() (probably only for Unix)
834if _exists("fork") and not _exists("spawnv") and _exists("execv"):
835
836 P_WAIT = 0
837 P_NOWAIT = P_NOWAITO = 1
838
Petri Lehtinen3bc37f22012-05-23 21:36:16 +0300839 __all__.extend(["P_WAIT", "P_NOWAIT", "P_NOWAITO"])
840
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000841 # XXX Should we support P_DETACH? I suppose it could fork()**2
842 # and close the std I/O streams. Also, P_OVERLAY is the same
843 # as execv*()?
844
845 def _spawnvef(mode, file, args, env, func):
846 # Internal helper; func is the exec*() function to use
Steve Dowereccaa062016-11-19 20:11:56 -0800847 if not isinstance(args, (tuple, list)):
848 raise TypeError('argv must be a tuple or a list')
Steve Dowerbb08db42016-11-19 21:14:27 -0800849 if not args or not args[0]:
Steve Dowereccaa062016-11-19 20:11:56 -0800850 raise ValueError('argv first element cannot be empty')
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000851 pid = fork()
852 if not pid:
853 # Child
854 try:
855 if env is None:
856 func(file, args)
857 else:
858 func(file, args, env)
859 except:
860 _exit(127)
861 else:
862 # Parent
863 if mode == P_NOWAIT:
864 return pid # Caller is responsible for waiting!
865 while 1:
866 wpid, sts = waitpid(pid, 0)
867 if WIFSTOPPED(sts):
868 continue
Victor Stinner65a796e2020-04-01 18:49:29 +0200869
870 return waitstatus_to_exitcode(sts)
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000871
872 def spawnv(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000873 """spawnv(mode, file, args) -> integer
874
875Execute file with arguments from args in a subprocess.
876If mode == P_NOWAIT return the pid of the process.
877If mode == P_WAIT return the process's exit code if it exits normally;
Tim Peters2344fae2001-01-15 00:50:52 +0000878otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000879 return _spawnvef(mode, file, args, None, execv)
880
881 def spawnve(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000882 """spawnve(mode, file, args, env) -> integer
883
884Execute file with arguments from args in a subprocess with the
885specified environment.
886If mode == P_NOWAIT return the pid of the process.
887If mode == P_WAIT return the process's exit code if it exits normally;
888otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000889 return _spawnvef(mode, file, args, env, execve)
890
Mike53f7a7c2017-12-14 14:04:53 +0300891 # Note: spawnvp[e] isn't currently supported on Windows
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000892
893 def spawnvp(mode, file, args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000894 """spawnvp(mode, file, args) -> integer
895
896Execute file (which is looked for along $PATH) with arguments from
897args in a subprocess.
898If mode == P_NOWAIT return the pid of the process.
899If mode == P_WAIT return the process's exit code if it exits normally;
900otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000901 return _spawnvef(mode, file, args, None, execvp)
902
903 def spawnvpe(mode, file, args, env):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000904 """spawnvpe(mode, file, args, env) -> integer
905
906Execute file (which is looked for along $PATH) with arguments from
907args in a subprocess with the supplied environment.
908If mode == P_NOWAIT return the pid of the process.
909If mode == P_WAIT return the process's exit code if it exits normally;
910otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000911 return _spawnvef(mode, file, args, env, execvpe)
912
Richard Oudkerkad34ef82013-05-07 14:23:42 +0100913
914 __all__.extend(["spawnv", "spawnve", "spawnvp", "spawnvpe"])
915
916
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000917if _exists("spawnv"):
918 # These aren't supplied by the basic Windows code
919 # but can be easily implemented in Python
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000920
921 def spawnl(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000922 """spawnl(mode, file, *args) -> integer
923
924Execute file with arguments from args in a subprocess.
925If mode == P_NOWAIT return the pid of the process.
926If mode == P_WAIT return the process's exit code if it exits normally;
927otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000928 return spawnv(mode, file, args)
929
930 def spawnle(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000931 """spawnle(mode, file, *args, env) -> integer
932
933Execute file with arguments from args in a subprocess with the
934supplied environment.
935If mode == P_NOWAIT return the pid of the process.
936If mode == P_WAIT return the process's exit code if it exits normally;
937otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000938 env = args[-1]
939 return spawnve(mode, file, args[:-1], env)
940
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000941
Richard Oudkerkad34ef82013-05-07 14:23:42 +0100942 __all__.extend(["spawnl", "spawnle"])
Andrew MacIntyre69e18c92004-04-04 07:11:43 +0000943
944
Guido van Rossumdd7cbbf1999-11-02 20:44:07 +0000945if _exists("spawnvp"):
946 # At the moment, Windows doesn't implement spawnvp[e],
947 # so it won't have spawnlp[e] either.
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000948 def spawnlp(mode, file, *args):
Neal Norwitzb7f68102003-07-02 02:49:33 +0000949 """spawnlp(mode, file, *args) -> integer
Guido van Rossume0cd2912000-04-21 18:35:36 +0000950
951Execute file (which is looked for along $PATH) with arguments from
952args in a subprocess with the supplied environment.
953If mode == P_NOWAIT return the pid of the process.
954If mode == P_WAIT return the process's exit code if it exits normally;
955otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000956 return spawnvp(mode, file, args)
957
958 def spawnlpe(mode, file, *args):
Guido van Rossume0cd2912000-04-21 18:35:36 +0000959 """spawnlpe(mode, file, *args, env) -> integer
960
961Execute file (which is looked for along $PATH) with arguments from
962args in a subprocess with the supplied environment.
963If mode == P_NOWAIT return the pid of the process.
964If mode == P_WAIT return the process's exit code if it exits normally;
965otherwise return -SIG, where SIG is the signal that killed it. """
Guido van Rossum5a2ca931999-11-02 13:27:32 +0000966 env = args[-1]
967 return spawnvpe(mode, file, args[:-1], env)
Guido van Rossume0cd2912000-04-21 18:35:36 +0000968
969
Richard Oudkerkad34ef82013-05-07 14:23:42 +0100970 __all__.extend(["spawnlp", "spawnlpe"])
971
pxinwre1e3c2d2020-12-16 05:20:07 +0800972# VxWorks has no user space shell provided. As a result, running
973# command in a shell can't be supported.
974if sys.platform != 'vxworks':
975 # Supply os.popen()
976 def popen(cmd, mode="r", buffering=-1):
977 if not isinstance(cmd, str):
978 raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
979 if mode not in ("r", "w"):
980 raise ValueError("invalid mode %r" % mode)
981 if buffering == 0 or buffering is None:
982 raise ValueError("popen() does not support unbuffered streams")
983 import subprocess, io
984 if mode == "r":
985 proc = subprocess.Popen(cmd,
986 shell=True,
987 stdout=subprocess.PIPE,
988 bufsize=buffering)
989 return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
Amaury Forgeot d'Arc97e5f282009-07-11 09:35:13 +0000990 else:
pxinwre1e3c2d2020-12-16 05:20:07 +0800991 proc = subprocess.Popen(cmd,
992 shell=True,
993 stdin=subprocess.PIPE,
994 bufsize=buffering)
995 return _wrap_close(io.TextIOWrapper(proc.stdin), proc)
996
997 # Helper for popen() -- a proxy for a file whose close waits for the process
998 class _wrap_close:
999 def __init__(self, stream, proc):
1000 self._stream = stream
1001 self._proc = proc
1002 def close(self):
1003 self._stream.close()
1004 returncode = self._proc.wait()
1005 if returncode == 0:
1006 return None
1007 if name == 'nt':
1008 return returncode
1009 else:
1010 return returncode << 8 # Shift left to match old behavior
1011 def __enter__(self):
1012 return self
1013 def __exit__(self, *args):
1014 self.close()
1015 def __getattr__(self, name):
1016 return getattr(self._stream, name)
1017 def __iter__(self):
1018 return iter(self._stream)
1019
1020 __all__.append("popen")
Guido van Rossumc2f93dc2007-05-24 00:50:02 +00001021
Amaury Forgeot d'Arcbdbddf82008-08-01 00:06:49 +00001022# Supply os.fdopen()
1023def fdopen(fd, *args, **kwargs):
Guido van Rossumc2f93dc2007-05-24 00:50:02 +00001024 if not isinstance(fd, int):
1025 raise TypeError("invalid fd type (%s, expected integer)" % type(fd))
1026 import io
Amaury Forgeot d'Arcbdbddf82008-08-01 00:06:49 +00001027 return io.open(fd, *args, **kwargs)
Ethan Furmancdc08792016-06-02 15:06:09 -07001028
Brett Cannonc78ca1e2016-06-24 12:03:43 -07001029
1030# For testing purposes, make sure the function is available when the C
1031# implementation exists.
1032def _fspath(path):
1033 """Return the path representation of a path-like object.
1034
1035 If str or bytes is passed in, it is returned unchanged. Otherwise the
1036 os.PathLike interface is used to get the path representation. If the
1037 path representation is not str or bytes, TypeError is raised. If the
1038 provided path is not str, bytes, or os.PathLike, TypeError is raised.
1039 """
1040 if isinstance(path, (str, bytes)):
1041 return path
1042
1043 # Work from the object's type to match method resolution of other magic
1044 # methods.
1045 path_type = type(path)
1046 try:
1047 path_repr = path_type.__fspath__(path)
1048 except AttributeError:
1049 if hasattr(path_type, '__fspath__'):
1050 raise
1051 else:
1052 raise TypeError("expected str, bytes or os.PathLike object, "
1053 "not " + path_type.__name__)
1054 if isinstance(path_repr, (str, bytes)):
1055 return path_repr
1056 else:
1057 raise TypeError("expected {}.__fspath__() to return str or bytes, "
1058 "not {}".format(path_type.__name__,
1059 type(path_repr).__name__))
1060
1061# If there is no C implementation, make the pure Python version the
1062# implementation as transparently as possible.
Ethan Furman410ef8e2016-06-04 12:06:26 -07001063if not _exists('fspath'):
Brett Cannonc78ca1e2016-06-24 12:03:43 -07001064 fspath = _fspath
1065 fspath.__name__ = "fspath"
Ethan Furmancdc08792016-06-02 15:06:09 -07001066
Ethan Furman958b3e42016-06-04 12:49:35 -07001067
1068class PathLike(abc.ABC):
Brett Cannon5f74ebc2016-06-09 14:29:25 -07001069
1070 """Abstract base class for implementing the file system path protocol."""
1071
Ethan Furman958b3e42016-06-04 12:49:35 -07001072 @abc.abstractmethod
1073 def __fspath__(self):
Brett Cannon5f74ebc2016-06-09 14:29:25 -07001074 """Return the file system path representation of the object."""
Ethan Furman958b3e42016-06-04 12:49:35 -07001075 raise NotImplementedError
1076
1077 @classmethod
1078 def __subclasshook__(cls, subclass):
Bar Hareleae87e32019-12-22 11:57:27 +02001079 if cls is PathLike:
1080 return _check_methods(subclass, '__fspath__')
1081 return NotImplemented
Steve Dower2438cdf2019-03-29 16:37:16 -07001082
Guido van Rossum48b069a2020-04-07 09:50:06 -07001083 __class_getitem__ = classmethod(GenericAlias)
Batuhan Taşkaya526606b2019-12-08 23:31:15 +03001084
Steve Dower2438cdf2019-03-29 16:37:16 -07001085
1086if name == 'nt':
1087 class _AddedDllDirectory:
1088 def __init__(self, path, cookie, remove_dll_directory):
1089 self.path = path
1090 self._cookie = cookie
1091 self._remove_dll_directory = remove_dll_directory
1092 def close(self):
1093 self._remove_dll_directory(self._cookie)
1094 self.path = None
1095 def __enter__(self):
1096 return self
1097 def __exit__(self, *args):
1098 self.close()
1099 def __repr__(self):
1100 if self.path:
1101 return "<AddedDllDirectory({!r})>".format(self.path)
1102 return "<AddedDllDirectory()>"
1103
1104 def add_dll_directory(path):
1105 """Add a path to the DLL search path.
1106
1107 This search path is used when resolving dependencies for imported
1108 extension modules (the module itself is resolved through sys.path),
1109 and also by ctypes.
1110
1111 Remove the directory by calling close() on the returned object or
1112 using it in a with statement.
1113 """
1114 import nt
1115 cookie = nt._add_dll_directory(path)
1116 return _AddedDllDirectory(
1117 path,
1118 cookie,
1119 nt._remove_dll_directory
1120 )