More installation info. Bump alpha version.
[python/dscho.git] / Lib / os.py
blob721cb7e50e529e9d76ea5e39b3fcfdd814ab857b
1 r"""OS routines for Mac, DOS, NT, or Posix depending on what system we're on.
3 This exports:
4 - all functions from posix, nt, os2, mac, or ce, e.g. unlink, stat, etc.
5 - os.path is one of the modules posixpath, ntpath, or macpath
6 - os.name is 'posix', 'nt', 'os2', 'mac', 'ce' or 'riscos'
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 ('.' or '/')
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
16 Programs that import and use 'os' stand a better chance of being
17 portable between different platforms. Of course, they must then
18 only use functions that are defined by all platforms (e.g., unlink
19 and opendir), and leave all pathname manipulation to os.path
20 (e.g., split and join).
21 """
25 import sys
27 _names = sys.builtin_module_names
29 altsep = None
31 __all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
32 "defpath", "name"]
34 def _get_exports_list(module):
35 try:
36 return list(module.__all__)
37 except AttributeError:
38 return [n for n in dir(module) if n[0] != '_']
40 if 'posix' in _names:
41 name = 'posix'
42 linesep = '\n'
43 curdir = '.'; pardir = '..'; sep = '/'; pathsep = ':'
44 defpath = ':/bin:/usr/bin'
45 from posix import *
46 try:
47 from posix import _exit
48 except ImportError:
49 pass
50 import posixpath
51 path = posixpath
52 del posixpath
54 import posix
55 __all__.extend(_get_exports_list(posix))
56 del posix
58 elif 'nt' in _names:
59 name = 'nt'
60 linesep = '\r\n'
61 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
62 defpath = '.;C:\\bin'
63 from nt import *
64 for i in ['_exit']:
65 try:
66 exec "from nt import " + i
67 except ImportError:
68 pass
69 import ntpath
70 path = ntpath
71 del ntpath
73 import nt
74 __all__.extend(_get_exports_list(nt))
75 del nt
77 elif 'os2' in _names:
78 name = 'os2'
79 linesep = '\r\n'
80 curdir = '.'; pardir = '..'; pathsep = ';'
81 if sys.version.find('EMX GCC') == -1:
82 # standard OS/2 compiler (VACPP or Watcom?)
83 sep = '\\'; altsep = '/'
84 else:
85 # EMX
86 sep = '/'; altsep = '\\'
87 defpath = '.;C:\\bin'
88 from os2 import *
89 try:
90 from os2 import _exit
91 except ImportError:
92 pass
93 if sys.version.find('EMX GCC') == -1:
94 import ntpath
95 path = ntpath
96 del ntpath
97 else:
98 import os2emxpath
99 path = os2emxpath
100 del os2emxpath
102 import os2
103 __all__.extend(_get_exports_list(os2))
104 del os2
106 elif 'mac' in _names:
107 name = 'mac'
108 linesep = '\r'
109 curdir = ':'; pardir = '::'; sep = ':'; pathsep = '\n'
110 defpath = ':'
111 from mac import *
112 try:
113 from mac import _exit
114 except ImportError:
115 pass
116 import macpath
117 path = macpath
118 del macpath
120 import mac
121 __all__.extend(_get_exports_list(mac))
122 del mac
124 elif 'ce' in _names:
125 name = 'ce'
126 linesep = '\r\n'
127 curdir = '.'; pardir = '..'; sep = '\\'; pathsep = ';'
128 defpath = '\\Windows'
129 from ce import *
130 for i in ['_exit']:
131 try:
132 exec "from ce import " + i
133 except ImportError:
134 pass
135 # We can use the standard Windows path.
136 import ntpath
137 path = ntpath
138 del ntpath
140 import ce
141 __all__.extend(_get_exports_list(ce))
142 del ce
144 elif 'riscos' in _names:
145 name = 'riscos'
146 linesep = '\n'
147 curdir = '@'; pardir = '^'; sep = '.'; pathsep = ','
148 defpath = '<Run$Dir>'
149 from riscos import *
150 try:
151 from riscos import _exit
152 except ImportError:
153 pass
154 import riscospath
155 path = riscospath
156 del riscospath
158 import riscos
159 __all__.extend(_get_exports_list(riscos))
160 del riscos
162 else:
163 raise ImportError, 'no os specific module found'
166 if sep=='.':
167 extsep = '/'
168 else:
169 extsep = '.'
171 __all__.append("path")
173 del _names
175 sys.modules['os.path'] = path
179 # Super directory utilities.
180 # (Inspired by Eric Raymond; the doc strings are mostly his)
182 def makedirs(name, mode=0777):
183 """makedirs(path [, mode=0777])
185 Super-mkdir; create a leaf directory and all intermediate ones.
186 Works like mkdir, except that any intermediate path segment (not
187 just the rightmost) will be created if it does not exist. This is
188 recursive.
191 head, tail = path.split(name)
192 if not tail:
193 head, tail = path.split(head)
194 if head and tail and not path.exists(head):
195 makedirs(head, mode)
196 mkdir(name, mode)
198 def removedirs(name):
199 """removedirs(path)
201 Super-rmdir; remove a leaf directory and empty all intermediate
202 ones. Works like rmdir except that, if the leaf directory is
203 successfully removed, directories corresponding to rightmost path
204 segments will be pruned way until either the whole path is
205 consumed or an error occurs. Errors during this latter phase are
206 ignored -- they generally mean that a directory was not empty.
209 rmdir(name)
210 head, tail = path.split(name)
211 if not tail:
212 head, tail = path.split(head)
213 while head and tail:
214 try:
215 rmdir(head)
216 except error:
217 break
218 head, tail = path.split(head)
220 def renames(old, new):
221 """renames(old, new)
223 Super-rename; create directories as necessary and delete any left
224 empty. Works like rename, except creation of any intermediate
225 directories needed to make the new pathname good is attempted
226 first. After the rename, directories corresponding to rightmost
227 path segments of the old name will be pruned way until either the
228 whole path is consumed or a nonempty directory is found.
230 Note: this function can fail with the new directory structure made
231 if you lack permissions needed to unlink the leaf directory or
232 file.
235 head, tail = path.split(new)
236 if head and tail and not path.exists(head):
237 makedirs(head)
238 rename(old, new)
239 head, tail = path.split(old)
240 if head and tail:
241 try:
242 removedirs(head)
243 except error:
244 pass
246 __all__.extend(["makedirs", "removedirs", "renames"])
248 # Make sure os.environ exists, at least
249 try:
250 environ
251 except NameError:
252 environ = {}
254 def execl(file, *args):
255 """execl(file, *args)
257 Execute the executable file with argument list args, replacing the
258 current process. """
259 execv(file, args)
261 def execle(file, *args):
262 """execle(file, *args, env)
264 Execute the executable file with argument list args and
265 environment env, replacing the current process. """
266 env = args[-1]
267 execve(file, args[:-1], env)
269 def execlp(file, *args):
270 """execlp(file, *args)
272 Execute the executable file (which is searched for along $PATH)
273 with argument list args, replacing the current process. """
274 execvp(file, args)
276 def execlpe(file, *args):
277 """execlpe(file, *args, env)
279 Execute the executable file (which is searched for along $PATH)
280 with argument list args and environment env, replacing the current
281 process. """
282 env = args[-1]
283 execvpe(file, args[:-1], env)
285 def execvp(file, args):
286 """execp(file, args)
288 Execute the executable file (which is searched for along $PATH)
289 with argument list args, replacing the current process.
290 args may be a list or tuple of strings. """
291 _execvpe(file, args)
293 def execvpe(file, args, env):
294 """execvpe(file, args, env)
296 Execute the executable file (which is searched for along $PATH)
297 with argument list args and environment env , replacing the
298 current process.
299 args may be a list or tuple of strings. """
300 _execvpe(file, args, env)
302 __all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
304 def _execvpe(file, args, env=None):
305 from errno import ENOENT, ENOTDIR
307 if env is not None:
308 func = execve
309 argrest = (args, env)
310 else:
311 func = execv
312 argrest = (args,)
313 env = environ
315 head, tail = path.split(file)
316 if head:
317 apply(func, (file,) + argrest)
318 return
319 if 'PATH' in env:
320 envpath = env['PATH']
321 else:
322 envpath = defpath
323 PATH = envpath.split(pathsep)
324 saved_exc = None
325 saved_tb = None
326 for dir in PATH:
327 fullname = path.join(dir, file)
328 try:
329 apply(func, (fullname,) + argrest)
330 except error, e:
331 tb = sys.exc_info()[2]
332 if (e.errno != ENOENT and e.errno != ENOTDIR
333 and saved_exc is None):
334 saved_exc = e
335 saved_tb = tb
336 if saved_exc:
337 raise error, saved_exc, saved_tb
338 raise error, e, tb
340 # Change environ to automatically call putenv() if it exists
341 try:
342 # This will fail if there's no putenv
343 putenv
344 except NameError:
345 pass
346 else:
347 import UserDict
349 # Fake unsetenv() for Windows
350 # not sure about os2 here but
351 # I'm guessing they are the same.
353 if name in ('os2', 'nt'):
354 def unsetenv(key):
355 putenv(key, "")
357 if name == "riscos":
358 # On RISC OS, all env access goes through getenv and putenv
359 from riscosenviron import _Environ
360 elif name in ('os2', 'nt'): # Where Env Var Names Must Be UPPERCASE
361 # But we store them as upper case
362 class _Environ(UserDict.IterableUserDict):
363 def __init__(self, environ):
364 UserDict.UserDict.__init__(self)
365 data = self.data
366 for k, v in environ.items():
367 data[k.upper()] = v
368 def __setitem__(self, key, item):
369 putenv(key, item)
370 self.data[key.upper()] = item
371 def __getitem__(self, key):
372 return self.data[key.upper()]
373 try:
374 unsetenv
375 except NameError:
376 def __delitem__(self, key):
377 del self.data[key.upper()]
378 else:
379 def __delitem__(self, key):
380 unsetenv(key)
381 del self.data[key.upper()]
382 def has_key(self, key):
383 return key.upper() in self.data
384 def __contains__(self, key):
385 return key.upper() in self.data
386 def get(self, key, failobj=None):
387 return self.data.get(key.upper(), failobj)
388 def update(self, dict):
389 for k, v in dict.items():
390 self[k] = v
391 def copy(self):
392 return dict(self)
394 else: # Where Env Var Names Can Be Mixed Case
395 class _Environ(UserDict.IterableUserDict):
396 def __init__(self, environ):
397 UserDict.UserDict.__init__(self)
398 self.data = environ
399 def __setitem__(self, key, item):
400 putenv(key, item)
401 self.data[key] = item
402 def update(self, dict):
403 for k, v in dict.items():
404 self[k] = v
405 try:
406 unsetenv
407 except NameError:
408 pass
409 else:
410 def __delitem__(self, key):
411 unsetenv(key)
412 del self.data[key]
413 def copy(self):
414 return dict(self)
417 environ = _Environ(environ)
419 def getenv(key, default=None):
420 """Get an environment variable, return None if it doesn't exist.
421 The optional second argument can specify an alternate default."""
422 return environ.get(key, default)
423 __all__.append("getenv")
425 def _exists(name):
426 try:
427 eval(name)
428 return True
429 except NameError:
430 return False
432 # Supply spawn*() (probably only for Unix)
433 if _exists("fork") and not _exists("spawnv") and _exists("execv"):
435 P_WAIT = 0
436 P_NOWAIT = P_NOWAITO = 1
438 # XXX Should we support P_DETACH? I suppose it could fork()**2
439 # and close the std I/O streams. Also, P_OVERLAY is the same
440 # as execv*()?
442 def _spawnvef(mode, file, args, env, func):
443 # Internal helper; func is the exec*() function to use
444 pid = fork()
445 if not pid:
446 # Child
447 try:
448 if env is None:
449 func(file, args)
450 else:
451 func(file, args, env)
452 except:
453 _exit(127)
454 else:
455 # Parent
456 if mode == P_NOWAIT:
457 return pid # Caller is responsible for waiting!
458 while 1:
459 wpid, sts = waitpid(pid, 0)
460 if WIFSTOPPED(sts):
461 continue
462 elif WIFSIGNALED(sts):
463 return -WTERMSIG(sts)
464 elif WIFEXITED(sts):
465 return WEXITSTATUS(sts)
466 else:
467 raise error, "Not stopped, signaled or exited???"
469 def spawnv(mode, file, args):
470 """spawnv(mode, file, args) -> integer
472 Execute file with arguments from args in a subprocess.
473 If mode == P_NOWAIT return the pid of the process.
474 If mode == P_WAIT return the process's exit code if it exits normally;
475 otherwise return -SIG, where SIG is the signal that killed it. """
476 return _spawnvef(mode, file, args, None, execv)
478 def spawnve(mode, file, args, env):
479 """spawnve(mode, file, args, env) -> integer
481 Execute file with arguments from args in a subprocess with the
482 specified environment.
483 If mode == P_NOWAIT return the pid of the process.
484 If mode == P_WAIT return the process's exit code if it exits normally;
485 otherwise return -SIG, where SIG is the signal that killed it. """
486 return _spawnvef(mode, file, args, env, execve)
488 # Note: spawnvp[e] is't currently supported on Windows
490 def spawnvp(mode, file, args):
491 """spawnvp(mode, file, args) -> integer
493 Execute file (which is looked for along $PATH) with arguments from
494 args in a subprocess.
495 If mode == P_NOWAIT return the pid of the process.
496 If mode == P_WAIT return the process's exit code if it exits normally;
497 otherwise return -SIG, where SIG is the signal that killed it. """
498 return _spawnvef(mode, file, args, None, execvp)
500 def spawnvpe(mode, file, args, env):
501 """spawnvpe(mode, file, args, env) -> integer
503 Execute file (which is looked for along $PATH) with arguments from
504 args in a subprocess with the supplied environment.
505 If mode == P_NOWAIT return the pid of the process.
506 If mode == P_WAIT return the process's exit code if it exits normally;
507 otherwise return -SIG, where SIG is the signal that killed it. """
508 return _spawnvef(mode, file, args, env, execvpe)
510 if _exists("spawnv"):
511 # These aren't supplied by the basic Windows code
512 # but can be easily implemented in Python
514 def spawnl(mode, file, *args):
515 """spawnl(mode, file, *args) -> integer
517 Execute file with arguments from args in a subprocess.
518 If mode == P_NOWAIT return the pid of the process.
519 If mode == P_WAIT return the process's exit code if it exits normally;
520 otherwise return -SIG, where SIG is the signal that killed it. """
521 return spawnv(mode, file, args)
523 def spawnle(mode, file, *args):
524 """spawnle(mode, file, *args, env) -> integer
526 Execute file with arguments from args in a subprocess with the
527 supplied environment.
528 If mode == P_NOWAIT return the pid of the process.
529 If mode == P_WAIT return the process's exit code if it exits normally;
530 otherwise return -SIG, where SIG is the signal that killed it. """
531 env = args[-1]
532 return spawnve(mode, file, args[:-1], env)
534 if _exists("spawnvp"):
535 # At the moment, Windows doesn't implement spawnvp[e],
536 # so it won't have spawnlp[e] either.
537 def spawnlp(mode, file, *args):
538 """spawnlp(mode, file, *args, env) -> integer
540 Execute file (which is looked for along $PATH) with arguments from
541 args in a subprocess with the 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. """
545 return spawnvp(mode, file, args)
547 def spawnlpe(mode, file, *args):
548 """spawnlpe(mode, file, *args, env) -> integer
550 Execute file (which is looked for along $PATH) with arguments from
551 args in a subprocess with the supplied environment.
552 If mode == P_NOWAIT return the pid of the process.
553 If mode == P_WAIT return the process's exit code if it exits normally;
554 otherwise return -SIG, where SIG is the signal that killed it. """
555 env = args[-1]
556 return spawnvpe(mode, file, args[:-1], env)
559 __all__.extend(["spawnlp","spawnlpe","spawnv", "spawnve","spawnvp",
560 "spawnvpe","spawnl","spawnle",])
563 # Supply popen2 etc. (for Unix)
564 if _exists("fork"):
565 if not _exists("popen2"):
566 def popen2(cmd, mode="t", bufsize=-1):
567 import popen2
568 stdout, stdin = popen2.popen2(cmd, bufsize)
569 return stdin, stdout
570 __all__.append("popen2")
572 if not _exists("popen3"):
573 def popen3(cmd, mode="t", bufsize=-1):
574 import popen2
575 stdout, stdin, stderr = popen2.popen3(cmd, bufsize)
576 return stdin, stdout, stderr
577 __all__.append("popen3")
579 if not _exists("popen4"):
580 def popen4(cmd, mode="t", bufsize=-1):
581 import popen2
582 stdout, stdin = popen2.popen4(cmd, bufsize)
583 return stdin, stdout
584 __all__.append("popen4")
586 import copy_reg as _copy_reg
588 def _make_stat_result(tup, dict):
589 return stat_result(tup, dict)
591 def _pickle_stat_result(sr):
592 (type, args) = sr.__reduce__()
593 return (_make_stat_result, args)
595 try:
596 _copy_reg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
597 except NameError: # stat_result may not exist
598 pass
600 def _make_statvfs_result(tup, dict):
601 return statvfs_result(tup, dict)
603 def _pickle_statvfs_result(sr):
604 (type, args) = sr.__reduce__()
605 return (_make_statvfs_result, args)
607 try:
608 _copy_reg.pickle(statvfs_result, _pickle_statvfs_result,
609 _make_statvfs_result)
610 except NameError: # statvfs_result may not exist
611 pass