1
r"""OS routines for Mac, NT, or Posix depending on what system we're on.
4
- 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'.
7
- 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 '\\')
10
- os.extsep is the extension separator (always '.')
11
- os.altsep is the alternate pathname separator (None or '/')
12
- os.pathsep is the component separator used in $PATH etc
13
- os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
14
- os.defpath is the default search path for executables
15
- os.devnull is the file path of the null device ('/dev/null', etc.)
17
Programs that import and use 'os' stand a better chance of being
18
portable between different platforms. Of course, they must then
19
only use functions that are defined by all platforms (e.g., unlink
20
and opendir), and leave all pathname manipulation to os.path
21
(e.g., split and join).
28
_names = sys.builtin_module_names
30
# Note: more names are added to __all__ later.
31
__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
32
"defpath", "name", "path", "devnull",
33
"SEEK_SET", "SEEK_CUR", "SEEK_END"]
35
def _get_exports_list(module):
37
return list(module.__all__)
38
except AttributeError:
39
return [n for n in dir(module) if n[0] != '_']
46
from posix import _exit
49
import posixpath as path
52
__all__.extend(_get_exports_list(posix))
66
__all__.extend(_get_exports_list(nt))
77
if sys.version.find('EMX GCC') == -1:
80
import os2emxpath as path
81
from _emx_link import link
84
__all__.extend(_get_exports_list(os2))
95
# We can use the standard Windows path.
99
__all__.extend(_get_exports_list(ce))
103
raise ImportError('no os specific module found')
105
sys.modules['os.path'] = path
106
from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
111
# Python uses fixed values for the SEEK_ constants; they are mapped
112
# to native constants if necessary in posixmodule.c
119
# Super directory utilities.
120
# (Inspired by Eric Raymond; the doc strings are mostly his)
122
def makedirs(name, mode=0o777):
123
"""makedirs(path [, mode=0o777])
125
Super-mkdir; create a leaf directory and all intermediate ones.
126
Works like mkdir, except that any intermediate path segment (not
127
just the rightmost) will be created if it does not exist. This is
131
head, tail = path.split(name)
133
head, tail = path.split(head)
134
if head and tail and not path.exists(head):
138
# be happy if someone already created the path
139
if e.errno != errno.EEXIST:
141
if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists
145
def removedirs(name):
148
Super-rmdir; remove a leaf directory and all empty intermediate
149
ones. Works like rmdir except that, if the leaf directory is
150
successfully removed, directories corresponding to rightmost path
151
segments will be pruned away until either the whole path is
152
consumed or an error occurs. Errors during this latter phase are
153
ignored -- they generally mean that a directory was not empty.
157
head, tail = path.split(name)
159
head, tail = path.split(head)
165
head, tail = path.split(head)
167
def renames(old, new):
170
Super-rename; create directories as necessary and delete any left
171
empty. Works like rename, except creation of any intermediate
172
directories needed to make the new pathname good is attempted
173
first. After the rename, directories corresponding to rightmost
174
path segments of the old name will be pruned way until either the
175
whole path is consumed or a nonempty directory is found.
177
Note: this function can fail with the new directory structure made
178
if you lack permissions needed to unlink the leaf directory or
182
head, tail = path.split(new)
183
if head and tail and not path.exists(head):
186
head, tail = path.split(old)
193
__all__.extend(["makedirs", "removedirs", "renames"])
195
def walk(top, topdown=True, onerror=None, followlinks=False):
196
"""Directory tree generator.
198
For each directory in the directory tree rooted at top (including top
199
itself, but excluding '.' and '..'), yields a 3-tuple
201
dirpath, dirnames, filenames
203
dirpath is a string, the path to the directory. dirnames is a list of
204
the names of the subdirectories in dirpath (excluding '.' and '..').
205
filenames is a list of the names of the non-directory files in dirpath.
206
Note that the names in the lists are just names, with no path components.
207
To get a full path (which begins with top) to a file or directory in
208
dirpath, do os.path.join(dirpath, name).
210
If optional arg 'topdown' is true or not specified, the triple for a
211
directory is generated before the triples for any of its subdirectories
212
(directories are generated top down). If topdown is false, the triple
213
for a directory is generated after the triples for all of its
214
subdirectories (directories are generated bottom up).
216
When topdown is true, the caller can modify the dirnames list in-place
217
(e.g., via del or slice assignment), and walk will only recurse into the
218
subdirectories whose names remain in dirnames; this can be used to prune
219
the search, or to impose a specific order of visiting. Modifying
220
dirnames when topdown is false is ineffective, since the directories in
221
dirnames have already been generated by the time dirnames itself is
224
By default errors from the os.listdir() call are ignored. If
225
optional arg 'onerror' is specified, it should be a function; it
226
will be called with one argument, an os.error instance. It can
227
report the error to continue with the walk, or raise the exception
228
to abort the walk. Note that the filename is available as the
229
filename attribute of the exception object.
231
By default, os.walk does not follow symbolic links to subdirectories on
232
systems that support them. In order to get this functionality, set the
233
optional argument 'followlinks' to true.
235
Caution: if you pass a relative pathname for top, don't change the
236
current working directory between resumptions of walk. walk never
237
changes the current directory, and assumes that the client doesn't
243
from os.path import join, getsize
244
for root, dirs, files in os.walk('python/Lib/email'):
245
print(root, "consumes", end="")
246
print(sum([getsize(join(root, name)) for name in files]), end="")
247
print("bytes in", len(files), "non-directory files")
249
dirs.remove('CVS') # don't visit CVS directories
252
from os.path import join, isdir, islink
254
# We may not have read permission for top, in which case we can't
255
# get a list of the files the directory contains. os.walk
256
# always suppressed the exception then, rather than blow up for a
257
# minor reason when (say) a thousand readable directories are still
258
# left to visit. That logic is copied here.
260
# Note that listdir and error are globals in this module due
261
# to earlier import-*.
264
if onerror is not None:
268
dirs, nondirs = [], []
270
if isdir(join(top, name)):
276
yield top, dirs, nondirs
278
path = join(top, name)
279
if followlinks or not islink(path):
280
for x in walk(path, topdown, onerror, followlinks):
283
yield top, dirs, nondirs
285
__all__.append("walk")
287
# Make sure os.environ exists, at least
293
def execl(file, *args):
294
"""execl(file, *args)
296
Execute the executable file with argument list args, replacing the
300
def execle(file, *args):
301
"""execle(file, *args, env)
303
Execute the executable file with argument list args and
304
environment env, replacing the current process. """
306
execve(file, args[:-1], env)
308
def execlp(file, *args):
309
"""execlp(file, *args)
311
Execute the executable file (which is searched for along $PATH)
312
with argument list args, replacing the current process. """
315
def execlpe(file, *args):
316
"""execlpe(file, *args, env)
318
Execute the executable file (which is searched for along $PATH)
319
with argument list args and environment env, replacing the current
322
execvpe(file, args[:-1], env)
324
def execvp(file, args):
327
Execute the executable file (which is searched for along $PATH)
328
with argument list args, replacing the current process.
329
args may be a list or tuple of strings. """
332
def execvpe(file, args, env):
333
"""execvpe(file, args, env)
335
Execute the executable file (which is searched for along $PATH)
336
with argument list args and environment env , replacing the
338
args may be a list or tuple of strings. """
339
_execvpe(file, args, env)
341
__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
343
def _execvpe(file, args, env=None):
346
argrest = (args, env)
352
head, tail = path.split(file)
357
envpath = env['PATH']
360
PATH = envpath.split(pathsep)
361
last_exc = saved_exc = None
364
fullname = path.join(dir, file)
366
func(fullname, *argrest)
369
tb = sys.exc_info()[2]
370
if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR
371
and saved_exc is None):
375
raise saved_exc.with_traceback(saved_tb)
376
raise last_exc.with_traceback(tb)
379
# Change environ to automatically call putenv(), unsetenv if they exist.
380
from _abcoll import MutableMapping # Can't use collections (bootstrap)
382
class _Environ(MutableMapping):
383
def __init__(self, environ, keymap, putenv, unsetenv):
386
self.unsetenv = unsetenv
387
self.data = data = {}
388
for key, value in environ.items():
389
data[keymap(key)] = str(value)
390
def __getitem__(self, key):
391
return self.data[self.keymap(key)]
392
def __setitem__(self, key, value):
394
self.putenv(key, value)
395
self.data[self.keymap(key)] = value
396
def __delitem__(self, key):
398
del self.data[self.keymap(key)]
400
for key in self.data:
403
return len(self.data)
406
def setdefault(self, key, value):
414
_putenv = lambda key, value: None
416
__all__.append("putenv")
421
_unsetenv = lambda key: _putenv(key, "")
423
__all__.append("unsetenv")
425
if name in ('os2', 'nt'): # Where Env Var Names Must Be UPPERCASE
426
_keymap = lambda key: str(key.upper())
427
else: # Where Env Var Names Can Be Mixed Case
428
_keymap = lambda key: str(key)
430
environ = _Environ(environ, _keymap, _putenv, _unsetenv)
433
def getenv(key, default=None):
434
"""Get an environment variable, return None if it doesn't exist.
435
The optional second argument can specify an alternate default."""
436
return environ.get(key, default)
437
__all__.append("getenv")
446
# Supply spawn*() (probably only for Unix)
447
if _exists("fork") and not _exists("spawnv") and _exists("execv"):
450
P_NOWAIT = P_NOWAITO = 1
452
# XXX Should we support P_DETACH? I suppose it could fork()**2
453
# and close the std I/O streams. Also, P_OVERLAY is the same
456
def _spawnvef(mode, file, args, env, func):
457
# Internal helper; func is the exec*() function to use
465
func(file, args, env)
471
return pid # Caller is responsible for waiting!
473
wpid, sts = waitpid(pid, 0)
476
elif WIFSIGNALED(sts):
477
return -WTERMSIG(sts)
479
return WEXITSTATUS(sts)
481
raise error("Not stopped, signaled or exited???")
483
def spawnv(mode, file, args):
484
"""spawnv(mode, file, args) -> integer
486
Execute file with arguments from args in a subprocess.
487
If mode == P_NOWAIT return the pid of the process.
488
If mode == P_WAIT return the process's exit code if it exits normally;
489
otherwise return -SIG, where SIG is the signal that killed it. """
490
return _spawnvef(mode, file, args, None, execv)
492
def spawnve(mode, file, args, env):
493
"""spawnve(mode, file, args, env) -> integer
495
Execute file with arguments from args in a subprocess with the
496
specified environment.
497
If mode == P_NOWAIT return the pid of the process.
498
If mode == P_WAIT return the process's exit code if it exits normally;
499
otherwise return -SIG, where SIG is the signal that killed it. """
500
return _spawnvef(mode, file, args, env, execve)
502
# Note: spawnvp[e] is't currently supported on Windows
504
def spawnvp(mode, file, args):
505
"""spawnvp(mode, file, args) -> integer
507
Execute file (which is looked for along $PATH) with arguments from
508
args in a subprocess.
509
If mode == P_NOWAIT return the pid of the process.
510
If mode == P_WAIT return the process's exit code if it exits normally;
511
otherwise return -SIG, where SIG is the signal that killed it. """
512
return _spawnvef(mode, file, args, None, execvp)
514
def spawnvpe(mode, file, args, env):
515
"""spawnvpe(mode, file, args, env) -> integer
517
Execute file (which is looked for along $PATH) with arguments from
518
args in a subprocess with the supplied environment.
519
If mode == P_NOWAIT return the pid of the process.
520
If mode == P_WAIT return the process's exit code if it exits normally;
521
otherwise return -SIG, where SIG is the signal that killed it. """
522
return _spawnvef(mode, file, args, env, execvpe)
524
if _exists("spawnv"):
525
# These aren't supplied by the basic Windows code
526
# but can be easily implemented in Python
528
def spawnl(mode, file, *args):
529
"""spawnl(mode, file, *args) -> integer
531
Execute file with arguments from args in a subprocess.
532
If mode == P_NOWAIT return the pid of the process.
533
If mode == P_WAIT return the process's exit code if it exits normally;
534
otherwise return -SIG, where SIG is the signal that killed it. """
535
return spawnv(mode, file, args)
537
def spawnle(mode, file, *args):
538
"""spawnle(mode, file, *args, env) -> integer
540
Execute file with arguments from args in a subprocess with the
541
supplied environment.
542
If mode == P_NOWAIT return the pid of the process.
543
If mode == P_WAIT return the process's exit code if it exits normally;
544
otherwise return -SIG, where SIG is the signal that killed it. """
546
return spawnve(mode, file, args[:-1], env)
549
__all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
552
if _exists("spawnvp"):
553
# At the moment, Windows doesn't implement spawnvp[e],
554
# so it won't have spawnlp[e] either.
555
def spawnlp(mode, file, *args):
556
"""spawnlp(mode, file, *args) -> integer
558
Execute file (which is looked for along $PATH) with arguments from
559
args in a subprocess with the supplied environment.
560
If mode == P_NOWAIT return the pid of the process.
561
If mode == P_WAIT return the process's exit code if it exits normally;
562
otherwise return -SIG, where SIG is the signal that killed it. """
563
return spawnvp(mode, file, args)
565
def spawnlpe(mode, file, *args):
566
"""spawnlpe(mode, file, *args, env) -> integer
568
Execute file (which is looked for along $PATH) with arguments from
569
args in a subprocess with the supplied environment.
570
If mode == P_NOWAIT return the pid of the process.
571
If mode == P_WAIT return the process's exit code if it exits normally;
572
otherwise return -SIG, where SIG is the signal that killed it. """
574
return spawnvpe(mode, file, args[:-1], env)
577
__all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
579
import copyreg as _copyreg
581
def _make_stat_result(tup, dict):
582
return stat_result(tup, dict)
584
def _pickle_stat_result(sr):
585
(type, args) = sr.__reduce__()
586
return (_make_stat_result, args)
589
_copyreg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
590
except NameError: # stat_result may not exist
593
def _make_statvfs_result(tup, dict):
594
return statvfs_result(tup, dict)
596
def _pickle_statvfs_result(sr):
597
(type, args) = sr.__reduce__()
598
return (_make_statvfs_result, args)
601
_copyreg.pickle(statvfs_result, _pickle_statvfs_result,
602
_make_statvfs_result)
603
except NameError: # statvfs_result may not exist
606
if not _exists("urandom"):
610
Return a string of n random bytes suitable for cryptographic use.
614
_urandomfd = open("/dev/urandom", O_RDONLY)
615
except (OSError, IOError):
616
raise NotImplementedError("/dev/urandom (or equivalent) not found")
619
bs += read(_urandomfd, n - len(bs))
624
def popen(cmd, mode="r", buffering=None):
625
if not isinstance(cmd, str):
626
raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
627
if mode not in ("r", "w"):
628
raise ValueError("invalid mode %r" % mode)
629
import subprocess, io
631
proc = subprocess.Popen(cmd,
633
stdout=subprocess.PIPE,
635
return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
637
proc = subprocess.Popen(cmd,
639
stdin=subprocess.PIPE,
641
return _wrap_close(io.TextIOWrapper(proc.stdin), proc)
643
# Helper for popen() -- a proxy for a file whose close waits for the process
645
def __init__(self, stream, proc):
646
self._stream = stream
650
return self._proc.wait() << 8 # Shift left to match old behavior
651
def __getattr__(self, name):
652
return getattr(self._stream, name)
654
return iter(self._stream)
657
def fdopen(fd, *args, **kwargs):
658
if not isinstance(fd, int):
659
raise TypeError("invalid fd type (%s, expected integer)" % type(fd))
661
return io.open(fd, *args, **kwargs)