1r"""OS routines for NT or Posix depending on what system we're on. 2 3This exports: 4 - all functions from posix or nt, e.g. unlink, stat, etc. 5 - os.path is either posixpath or ntpath 6 - os.name is either 'posix' or 'nt' 7 - 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 '\\') 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.) 16 17Programs 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""" 23 24#' 25import abc 26import sys 27import stat as st 28 29from _collections_abc import _check_methods 30 31_names = sys.builtin_module_names 32 33# Note: more names are added to __all__ later. 34__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep", 35 "defpath", "name", "path", "devnull", "SEEK_SET", "SEEK_CUR", 36 "SEEK_END", "fsencode", "fsdecode", "get_exec_path", "fdopen", 37 "popen", "extsep"] 38 39def _exists(name): 40 return name in globals() 41 42def _get_exports_list(module): 43 try: 44 return list(module.__all__) 45 except AttributeError: 46 return [n for n in dir(module) if n[0] != '_'] 47 48# Any new dependencies of the os module and/or changes in path separator 49# requires updating importlib as well. 50if 'posix' in _names: 51 name = 'posix' 52 linesep = '\n' 53 from posix import * 54 try: 55 from posix import _exit 56 __all__.append('_exit') 57 except ImportError: 58 pass 59 import posixpath as path 60 61 try: 62 from posix import _have_functions 63 except ImportError: 64 pass 65 66 import posix 67 __all__.extend(_get_exports_list(posix)) 68 del posix 69 70elif 'nt' in _names: 71 name = 'nt' 72 linesep = '\r\n' 73 from nt import * 74 try: 75 from nt import _exit 76 __all__.append('_exit') 77 except ImportError: 78 pass 79 import ntpath as path 80 81 import nt 82 __all__.extend(_get_exports_list(nt)) 83 del nt 84 85 try: 86 from nt import _have_functions 87 except ImportError: 88 pass 89 90else: 91 raise ImportError('no os specific module found') 92 93sys.modules['os.path'] = path 94from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep, 95 devnull) 96 97del _names 98 99 100if _exists("_have_functions"): 101 _globals = globals() 102 def _add(str, fn): 103 if (fn in _globals) and (str in _have_functions): 104 _set.add(_globals[fn]) 105 106 _set = set() 107 _add("HAVE_FACCESSAT", "access") 108 _add("HAVE_FCHMODAT", "chmod") 109 _add("HAVE_FCHOWNAT", "chown") 110 _add("HAVE_FSTATAT", "stat") 111 _add("HAVE_FUTIMESAT", "utime") 112 _add("HAVE_LINKAT", "link") 113 _add("HAVE_MKDIRAT", "mkdir") 114 _add("HAVE_MKFIFOAT", "mkfifo") 115 _add("HAVE_MKNODAT", "mknod") 116 _add("HAVE_OPENAT", "open") 117 _add("HAVE_READLINKAT", "readlink") 118 _add("HAVE_RENAMEAT", "rename") 119 _add("HAVE_SYMLINKAT", "symlink") 120 _add("HAVE_UNLINKAT", "unlink") 121 _add("HAVE_UNLINKAT", "rmdir") 122 _add("HAVE_UTIMENSAT", "utime") 123 supports_dir_fd = _set 124 125 _set = set() 126 _add("HAVE_FACCESSAT", "access") 127 supports_effective_ids = _set 128 129 _set = set() 130 _add("HAVE_FCHDIR", "chdir") 131 _add("HAVE_FCHMOD", "chmod") 132 _add("HAVE_FCHOWN", "chown") 133 _add("HAVE_FDOPENDIR", "listdir") 134 _add("HAVE_FDOPENDIR", "scandir") 135 _add("HAVE_FEXECVE", "execve") 136 _set.add(stat) # fstat always works 137 _add("HAVE_FTRUNCATE", "truncate") 138 _add("HAVE_FUTIMENS", "utime") 139 _add("HAVE_FUTIMES", "utime") 140 _add("HAVE_FPATHCONF", "pathconf") 141 if _exists("statvfs") and _exists("fstatvfs"): # mac os x10.3 142 _add("HAVE_FSTATVFS", "statvfs") 143 supports_fd = _set 144 145 _set = set() 146 _add("HAVE_FACCESSAT", "access") 147 # Some platforms don't support lchmod(). Often the function exists 148 # anyway, as a stub that always returns ENOSUP or perhaps EOPNOTSUPP. 149 # (No, I don't know why that's a good design.) ./configure will detect 150 # this and reject it--so HAVE_LCHMOD still won't be defined on such 151 # platforms. This is Very Helpful. 152 # 153 # However, sometimes platforms without a working lchmod() *do* have 154 # fchmodat(). (Examples: Linux kernel 3.2 with glibc 2.15, 155 # OpenIndiana 3.x.) And fchmodat() has a flag that theoretically makes 156 # it behave like lchmod(). So in theory it would be a suitable 157 # replacement for lchmod(). But when lchmod() doesn't work, fchmodat()'s 158 # flag doesn't work *either*. Sadly ./configure isn't sophisticated 159 # enough to detect this condition--it only determines whether or not 160 # fchmodat() minimally works. 161 # 162 # Therefore we simply ignore fchmodat() when deciding whether or not 163 # os.chmod supports follow_symlinks. Just checking lchmod() is 164 # sufficient. After all--if you have a working fchmodat(), your 165 # lchmod() almost certainly works too. 166 # 167 # _add("HAVE_FCHMODAT", "chmod") 168 _add("HAVE_FCHOWNAT", "chown") 169 _add("HAVE_FSTATAT", "stat") 170 _add("HAVE_LCHFLAGS", "chflags") 171 _add("HAVE_LCHMOD", "chmod") 172 if _exists("lchown"): # mac os x10.3 173 _add("HAVE_LCHOWN", "chown") 174 _add("HAVE_LINKAT", "link") 175 _add("HAVE_LUTIMES", "utime") 176 _add("HAVE_LSTAT", "stat") 177 _add("HAVE_FSTATAT", "stat") 178 _add("HAVE_UTIMENSAT", "utime") 179 _add("MS_WINDOWS", "stat") 180 supports_follow_symlinks = _set 181 182 del _set 183 del _have_functions 184 del _globals 185 del _add 186 187 188# Python uses fixed values for the SEEK_ constants; they are mapped 189# to native constants if necessary in posixmodule.c 190# Other possible SEEK values are directly imported from posixmodule.c 191SEEK_SET = 0 192SEEK_CUR = 1 193SEEK_END = 2 194 195# Super directory utilities. 196# (Inspired by Eric Raymond; the doc strings are mostly his) 197 198def makedirs(name, mode=0o777, exist_ok=False): 199 """makedirs(name [, mode=0o777][, exist_ok=False]) 200 201 Super-mkdir; create a leaf directory and all intermediate ones. Works like 202 mkdir, except that any intermediate path segment (not just the rightmost) 203 will be created if it does not exist. If the target directory already 204 exists, raise an OSError if exist_ok is False. Otherwise no exception is 205 raised. This is recursive. 206 207 """ 208 head, tail = path.split(name) 209 if not tail: 210 head, tail = path.split(head) 211 if head and tail and not path.exists(head): 212 try: 213 makedirs(head, exist_ok=exist_ok) 214 except FileExistsError: 215 # Defeats race condition when another thread created the path 216 pass 217 cdir = curdir 218 if isinstance(tail, bytes): 219 cdir = bytes(curdir, 'ASCII') 220 if tail == cdir: # xxx/newdir/. exists if xxx/newdir exists 221 return 222 try: 223 mkdir(name, mode) 224 except OSError: 225 # Cannot rely on checking for EEXIST, since the operating system 226 # could give priority to other errors like EACCES or EROFS 227 if not exist_ok or not path.isdir(name): 228 raise 229 230def removedirs(name): 231 """removedirs(name) 232 233 Super-rmdir; remove a leaf directory and all empty intermediate 234 ones. Works like rmdir except that, if the leaf directory is 235 successfully removed, directories corresponding to rightmost path 236 segments will be pruned away until either the whole path is 237 consumed or an error occurs. Errors during this latter phase are 238 ignored -- they generally mean that a directory was not empty. 239 240 """ 241 rmdir(name) 242 head, tail = path.split(name) 243 if not tail: 244 head, tail = path.split(head) 245 while head and tail: 246 try: 247 rmdir(head) 248 except OSError: 249 break 250 head, tail = path.split(head) 251 252def renames(old, new): 253 """renames(old, new) 254 255 Super-rename; create directories as necessary and delete any left 256 empty. Works like rename, except creation of any intermediate 257 directories needed to make the new pathname good is attempted 258 first. After the rename, directories corresponding to rightmost 259 path segments of the old name will be pruned until either the 260 whole path is consumed or a nonempty directory is found. 261 262 Note: this function can fail with the new directory structure made 263 if you lack permissions needed to unlink the leaf directory or 264 file. 265 266 """ 267 head, tail = path.split(new) 268 if head and tail and not path.exists(head): 269 makedirs(head) 270 rename(old, new) 271 head, tail = path.split(old) 272 if head and tail: 273 try: 274 removedirs(head) 275 except OSError: 276 pass 277 278__all__.extend(["makedirs", "removedirs", "renames"]) 279 280def walk(top, topdown=True, onerror=None, followlinks=False): 281 """Directory tree generator. 282 283 For each directory in the directory tree rooted at top (including top 284 itself, but excluding '.' and '..'), yields a 3-tuple 285 286 dirpath, dirnames, filenames 287 288 dirpath is a string, the path to the directory. dirnames is a list of 289 the names of the subdirectories in dirpath (excluding '.' and '..'). 290 filenames is a list of the names of the non-directory files in dirpath. 291 Note that the names in the lists are just names, with no path components. 292 To get a full path (which begins with top) to a file or directory in 293 dirpath, do os.path.join(dirpath, name). 294 295 If optional arg 'topdown' is true or not specified, the triple for a 296 directory is generated before the triples for any of its subdirectories 297 (directories are generated top down). If topdown is false, the triple 298 for a directory is generated after the triples for all of its 299 subdirectories (directories are generated bottom up). 300 301 When topdown is true, the caller can modify the dirnames list in-place 302 (e.g., via del or slice assignment), and walk will only recurse into the 303 subdirectories whose names remain in dirnames; this can be used to prune the 304 search, or to impose a specific order of visiting. Modifying dirnames when 305 topdown is false has no effect on the behavior of os.walk(), since the 306 directories in dirnames have already been generated by the time dirnames 307 itself is generated. No matter the value of topdown, the list of 308 subdirectories is retrieved before the tuples for the directory and its 309 subdirectories are generated. 310 311 By default errors from the os.scandir() call are ignored. If 312 optional arg 'onerror' is specified, it should be a function; it 313 will be called with one argument, an OSError instance. It can 314 report the error to continue with the walk, or raise the exception 315 to abort the walk. Note that the filename is available as the 316 filename attribute of the exception object. 317 318 By default, os.walk does not follow symbolic links to subdirectories on 319 systems that support them. In order to get this functionality, set the 320 optional argument 'followlinks' to true. 321 322 Caution: if you pass a relative pathname for top, don't change the 323 current working directory between resumptions of walk. walk never 324 changes the current directory, and assumes that the client doesn't 325 either. 326 327 Example: 328 329 import os 330 from os.path import join, getsize 331 for root, dirs, files in os.walk('python/Lib/email'): 332 print(root, "consumes", end="") 333 print(sum(getsize(join(root, name)) for name in files), end="") 334 print("bytes in", len(files), "non-directory files") 335 if 'CVS' in dirs: 336 dirs.remove('CVS') # don't visit CVS directories 337 338 """ 339 top = fspath(top) 340 dirs = [] 341 nondirs = [] 342 walk_dirs = [] 343 344 # We may not have read permission for top, in which case we can't 345 # get a list of the files the directory contains. os.walk 346 # always suppressed the exception then, rather than blow up for a 347 # minor reason when (say) a thousand readable directories are still 348 # left to visit. That logic is copied here. 349 try: 350 # Note that scandir is global in this module due 351 # to earlier import-*. 352 scandir_it = scandir(top) 353 except OSError as error: 354 if onerror is not None: 355 onerror(error) 356 return 357 358 with scandir_it: 359 while True: 360 try: 361 try: 362 entry = next(scandir_it) 363 except StopIteration: 364 break 365 except OSError as error: 366 if onerror is not None: 367 onerror(error) 368 return 369 370 try: 371 is_dir = entry.is_dir() 372 except OSError: 373 # If is_dir() raises an OSError, consider that the entry is not 374 # a directory, same behaviour than os.path.isdir(). 375 is_dir = False 376 377 if is_dir: 378 dirs.append(entry.name) 379 else: 380 nondirs.append(entry.name) 381 382 if not topdown and is_dir: 383 # Bottom-up: recurse into sub-directory, but exclude symlinks to 384 # directories if followlinks is False 385 if followlinks: 386 walk_into = True 387 else: 388 try: 389 is_symlink = entry.is_symlink() 390 except OSError: 391 # If is_symlink() raises an OSError, consider that the 392 # entry is not a symbolic link, same behaviour than 393 # os.path.islink(). 394 is_symlink = False 395 walk_into = not is_symlink 396 397 if walk_into: 398 walk_dirs.append(entry.path) 399 400 # Yield before recursion if going top down 401 if topdown: 402 yield top, dirs, nondirs 403 404 # Recurse into sub-directories 405 islink, join = path.islink, path.join 406 for dirname in dirs: 407 new_path = join(top, dirname) 408 # Issue #23605: os.path.islink() is used instead of caching 409 # entry.is_symlink() result during the loop on os.scandir() because 410 # the caller can replace the directory entry during the "yield" 411 # above. 412 if followlinks or not islink(new_path): 413 yield from walk(new_path, topdown, onerror, followlinks) 414 else: 415 # Recurse into sub-directories 416 for new_path in walk_dirs: 417 yield from walk(new_path, topdown, onerror, followlinks) 418 # Yield after recursion if going bottom up 419 yield top, dirs, nondirs 420 421__all__.append("walk") 422 423if {open, stat} <= supports_dir_fd and {scandir, stat} <= supports_fd: 424 425 def fwalk(top=".", topdown=True, onerror=None, *, follow_symlinks=False, dir_fd=None): 426 """Directory tree generator. 427 428 This behaves exactly like walk(), except that it yields a 4-tuple 429 430 dirpath, dirnames, filenames, dirfd 431 432 `dirpath`, `dirnames` and `filenames` are identical to walk() output, 433 and `dirfd` is a file descriptor referring to the directory `dirpath`. 434 435 The advantage of fwalk() over walk() is that it's safe against symlink 436 races (when follow_symlinks is False). 437 438 If dir_fd is not None, it should be a file descriptor open to a directory, 439 and top should be relative; top will then be relative to that directory. 440 (dir_fd is always supported for fwalk.) 441 442 Caution: 443 Since fwalk() yields file descriptors, those are only valid until the 444 next iteration step, so you should dup() them if you want to keep them 445 for a longer period. 446 447 Example: 448 449 import os 450 for root, dirs, files, rootfd in os.fwalk('python/Lib/email'): 451 print(root, "consumes", end="") 452 print(sum(os.stat(name, dir_fd=rootfd).st_size for name in files), 453 end="") 454 print("bytes in", len(files), "non-directory files") 455 if 'CVS' in dirs: 456 dirs.remove('CVS') # don't visit CVS directories 457 """ 458 if not isinstance(top, int) or not hasattr(top, '__index__'): 459 top = fspath(top) 460 # Note: To guard against symlink races, we use the standard 461 # lstat()/open()/fstat() trick. 462 if not follow_symlinks: 463 orig_st = stat(top, follow_symlinks=False, dir_fd=dir_fd) 464 topfd = open(top, O_RDONLY, dir_fd=dir_fd) 465 try: 466 if (follow_symlinks or (st.S_ISDIR(orig_st.st_mode) and 467 path.samestat(orig_st, stat(topfd)))): 468 yield from _fwalk(topfd, top, isinstance(top, bytes), 469 topdown, onerror, follow_symlinks) 470 finally: 471 close(topfd) 472 473 def _fwalk(topfd, toppath, isbytes, topdown, onerror, follow_symlinks): 474 # Note: This uses O(depth of the directory tree) file descriptors: if 475 # necessary, it can be adapted to only require O(1) FDs, see issue 476 # #13734. 477 478 scandir_it = scandir(topfd) 479 dirs = [] 480 nondirs = [] 481 entries = None if topdown or follow_symlinks else [] 482 for entry in scandir_it: 483 name = entry.name 484 if isbytes: 485 name = fsencode(name) 486 try: 487 if entry.is_dir(): 488 dirs.append(name) 489 if entries is not None: 490 entries.append(entry) 491 else: 492 nondirs.append(name) 493 except OSError: 494 try: 495 # Add dangling symlinks, ignore disappeared files 496 if entry.is_symlink(): 497 nondirs.append(name) 498 except OSError: 499 pass 500 501 if topdown: 502 yield toppath, dirs, nondirs, topfd 503 504 for name in dirs if entries is None else zip(dirs, entries): 505 try: 506 if not follow_symlinks: 507 if topdown: 508 orig_st = stat(name, dir_fd=topfd, follow_symlinks=False) 509 else: 510 assert entries is not None 511 name, entry = name 512 orig_st = entry.stat(follow_symlinks=False) 513 dirfd = open(name, O_RDONLY, dir_fd=topfd) 514 except OSError as err: 515 if onerror is not None: 516 onerror(err) 517 continue 518 try: 519 if follow_symlinks or path.samestat(orig_st, stat(dirfd)): 520 dirpath = path.join(toppath, name) 521 yield from _fwalk(dirfd, dirpath, isbytes, 522 topdown, onerror, follow_symlinks) 523 finally: 524 close(dirfd) 525 526 if not topdown: 527 yield toppath, dirs, nondirs, topfd 528 529 __all__.append("fwalk") 530 531def execl(file, *args): 532 """execl(file, *args) 533 534 Execute the executable file with argument list args, replacing the 535 current process. """ 536 execv(file, args) 537 538def execle(file, *args): 539 """execle(file, *args, env) 540 541 Execute the executable file with argument list args and 542 environment env, replacing the current process. """ 543 env = args[-1] 544 execve(file, args[:-1], env) 545 546def execlp(file, *args): 547 """execlp(file, *args) 548 549 Execute the executable file (which is searched for along $PATH) 550 with argument list args, replacing the current process. """ 551 execvp(file, args) 552 553def execlpe(file, *args): 554 """execlpe(file, *args, env) 555 556 Execute the executable file (which is searched for along $PATH) 557 with argument list args and environment env, replacing the current 558 process. """ 559 env = args[-1] 560 execvpe(file, args[:-1], env) 561 562def execvp(file, args): 563 """execvp(file, args) 564 565 Execute the executable file (which is searched for along $PATH) 566 with argument list args, replacing the current process. 567 args may be a list or tuple of strings. """ 568 _execvpe(file, args) 569 570def execvpe(file, args, env): 571 """execvpe(file, args, env) 572 573 Execute the executable file (which is searched for along $PATH) 574 with argument list args and environment env, replacing the 575 current process. 576 args may be a list or tuple of strings. """ 577 _execvpe(file, args, env) 578 579__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"]) 580 581def _execvpe(file, args, env=None): 582 if env is not None: 583 exec_func = execve 584 argrest = (args, env) 585 else: 586 exec_func = execv 587 argrest = (args,) 588 env = environ 589 590 if path.dirname(file): 591 exec_func(file, *argrest) 592 return 593 saved_exc = None 594 path_list = get_exec_path(env) 595 if name != 'nt': 596 file = fsencode(file) 597 path_list = map(fsencode, path_list) 598 for dir in path_list: 599 fullname = path.join(dir, file) 600 try: 601 exec_func(fullname, *argrest) 602 except (FileNotFoundError, NotADirectoryError) as e: 603 last_exc = e 604 except OSError as e: 605 last_exc = e 606 if saved_exc is None: 607 saved_exc = e 608 if saved_exc is not None: 609 raise saved_exc 610 raise last_exc 611 612 613def get_exec_path(env=None): 614 """Returns the sequence of directories that will be searched for the 615 named executable (similar to a shell) when launching a process. 616 617 *env* must be an environment variable dict or None. If *env* is None, 618 os.environ will be used. 619 """ 620 # Use a local import instead of a global import to limit the number of 621 # modules loaded at startup: the os module is always loaded at startup by 622 # Python. It may also avoid a bootstrap issue. 623 import warnings 624 625 if env is None: 626 env = environ 627 628 # {b'PATH': ...}.get('PATH') and {'PATH': ...}.get(b'PATH') emit a 629 # BytesWarning when using python -b or python -bb: ignore the warning 630 with warnings.catch_warnings(): 631 warnings.simplefilter("ignore", BytesWarning) 632 633 try: 634 path_list = env.get('PATH') 635 except TypeError: 636 path_list = None 637 638 if supports_bytes_environ: 639 try: 640 path_listb = env[b'PATH'] 641 except (KeyError, TypeError): 642 pass 643 else: 644 if path_list is not None: 645 raise ValueError( 646 "env cannot contain 'PATH' and b'PATH' keys") 647 path_list = path_listb 648 649 if path_list is not None and isinstance(path_list, bytes): 650 path_list = fsdecode(path_list) 651 652 if path_list is None: 653 path_list = defpath 654 return path_list.split(pathsep) 655 656 657# Change environ to automatically call putenv(), unsetenv if they exist. 658from _collections_abc import MutableMapping 659 660class _Environ(MutableMapping): 661 def __init__(self, data, encodekey, decodekey, encodevalue, decodevalue, putenv, unsetenv): 662 self.encodekey = encodekey 663 self.decodekey = decodekey 664 self.encodevalue = encodevalue 665 self.decodevalue = decodevalue 666 self.putenv = putenv 667 self.unsetenv = unsetenv 668 self._data = data 669 670 def __getitem__(self, key): 671 try: 672 value = self._data[self.encodekey(key)] 673 except KeyError: 674 # raise KeyError with the original key value 675 raise KeyError(key) from None 676 return self.decodevalue(value) 677 678 def __setitem__(self, key, value): 679 key = self.encodekey(key) 680 value = self.encodevalue(value) 681 self.putenv(key, value) 682 self._data[key] = value 683 684 def __delitem__(self, key): 685 encodedkey = self.encodekey(key) 686 self.unsetenv(encodedkey) 687 try: 688 del self._data[encodedkey] 689 except KeyError: 690 # raise KeyError with the original key value 691 raise KeyError(key) from None 692 693 def __iter__(self): 694 # list() from dict object is an atomic operation 695 keys = list(self._data) 696 for key in keys: 697 yield self.decodekey(key) 698 699 def __len__(self): 700 return len(self._data) 701 702 def __repr__(self): 703 return 'environ({{{}}})'.format(', '.join( 704 ('{!r}: {!r}'.format(self.decodekey(key), self.decodevalue(value)) 705 for key, value in self._data.items()))) 706 707 def copy(self): 708 return dict(self) 709 710 def setdefault(self, key, value): 711 if key not in self: 712 self[key] = value 713 return self[key] 714 715try: 716 _putenv = putenv 717except NameError: 718 _putenv = lambda key, value: None 719else: 720 if "putenv" not in __all__: 721 __all__.append("putenv") 722 723try: 724 _unsetenv = unsetenv 725except NameError: 726 _unsetenv = lambda key: _putenv(key, "") 727else: 728 if "unsetenv" not in __all__: 729 __all__.append("unsetenv") 730 731def _createenviron(): 732 if name == 'nt': 733 # Where Env Var Names Must Be UPPERCASE 734 def check_str(value): 735 if not isinstance(value, str): 736 raise TypeError("str expected, not %s" % type(value).__name__) 737 return value 738 encode = check_str 739 decode = str 740 def encodekey(key): 741 return encode(key).upper() 742 data = {} 743 for key, value in environ.items(): 744 data[encodekey(key)] = value 745 else: 746 # Where Env Var Names Can Be Mixed Case 747 encoding = sys.getfilesystemencoding() 748 def encode(value): 749 if not isinstance(value, str): 750 raise TypeError("str expected, not %s" % type(value).__name__) 751 return value.encode(encoding, 'surrogateescape') 752 def decode(value): 753 return value.decode(encoding, 'surrogateescape') 754 encodekey = encode 755 data = environ 756 return _Environ(data, 757 encodekey, decode, 758 encode, decode, 759 _putenv, _unsetenv) 760 761# unicode environ 762environ = _createenviron() 763del _createenviron 764 765 766def getenv(key, default=None): 767 """Get an environment variable, return None if it doesn't exist. 768 The optional second argument can specify an alternate default. 769 key, default and the result are str.""" 770 return environ.get(key, default) 771 772supports_bytes_environ = (name != 'nt') 773__all__.extend(("getenv", "supports_bytes_environ")) 774 775if supports_bytes_environ: 776 def _check_bytes(value): 777 if not isinstance(value, bytes): 778 raise TypeError("bytes expected, not %s" % type(value).__name__) 779 return value 780 781 # bytes environ 782 environb = _Environ(environ._data, 783 _check_bytes, bytes, 784 _check_bytes, bytes, 785 _putenv, _unsetenv) 786 del _check_bytes 787 788 def getenvb(key, default=None): 789 """Get an environment variable, return None if it doesn't exist. 790 The optional second argument can specify an alternate default. 791 key, default and the result are bytes.""" 792 return environb.get(key, default) 793 794 __all__.extend(("environb", "getenvb")) 795 796def _fscodec(): 797 encoding = sys.getfilesystemencoding() 798 errors = sys.getfilesystemencodeerrors() 799 800 def fsencode(filename): 801 """Encode filename (an os.PathLike, bytes, or str) to the filesystem 802 encoding with 'surrogateescape' error handler, return bytes unchanged. 803 On Windows, use 'strict' error handler if the file system encoding is 804 'mbcs' (which is the default encoding). 805 """ 806 filename = fspath(filename) # Does type-checking of `filename`. 807 if isinstance(filename, str): 808 return filename.encode(encoding, errors) 809 else: 810 return filename 811 812 def fsdecode(filename): 813 """Decode filename (an os.PathLike, bytes, or str) from the filesystem 814 encoding with 'surrogateescape' error handler, return str unchanged. On 815 Windows, use 'strict' error handler if the file system encoding is 816 'mbcs' (which is the default encoding). 817 """ 818 filename = fspath(filename) # Does type-checking of `filename`. 819 if isinstance(filename, bytes): 820 return filename.decode(encoding, errors) 821 else: 822 return filename 823 824 return fsencode, fsdecode 825 826fsencode, fsdecode = _fscodec() 827del _fscodec 828 829# Supply spawn*() (probably only for Unix) 830if _exists("fork") and not _exists("spawnv") and _exists("execv"): 831 832 P_WAIT = 0 833 P_NOWAIT = P_NOWAITO = 1 834 835 __all__.extend(["P_WAIT", "P_NOWAIT", "P_NOWAITO"]) 836 837 # XXX Should we support P_DETACH? I suppose it could fork()**2 838 # and close the std I/O streams. Also, P_OVERLAY is the same 839 # as execv*()? 840 841 def _spawnvef(mode, file, args, env, func): 842 # Internal helper; func is the exec*() function to use 843 if not isinstance(args, (tuple, list)): 844 raise TypeError('argv must be a tuple or a list') 845 if not args or not args[0]: 846 raise ValueError('argv first element cannot be empty') 847 pid = fork() 848 if not pid: 849 # Child 850 try: 851 if env is None: 852 func(file, args) 853 else: 854 func(file, args, env) 855 except: 856 _exit(127) 857 else: 858 # Parent 859 if mode == P_NOWAIT: 860 return pid # Caller is responsible for waiting! 861 while 1: 862 wpid, sts = waitpid(pid, 0) 863 if WIFSTOPPED(sts): 864 continue 865 elif WIFSIGNALED(sts): 866 return -WTERMSIG(sts) 867 elif WIFEXITED(sts): 868 return WEXITSTATUS(sts) 869 else: 870 raise OSError("Not stopped, signaled or exited???") 871 872 def spawnv(mode, file, args): 873 """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; 878otherwise return -SIG, where SIG is the signal that killed it. """ 879 return _spawnvef(mode, file, args, None, execv) 880 881 def spawnve(mode, file, args, env): 882 """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. """ 889 return _spawnvef(mode, file, args, env, execve) 890 891 # Note: spawnvp[e] isn't currently supported on Windows 892 893 def spawnvp(mode, file, args): 894 """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. """ 901 return _spawnvef(mode, file, args, None, execvp) 902 903 def spawnvpe(mode, file, args, env): 904 """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. """ 911 return _spawnvef(mode, file, args, env, execvpe) 912 913 914 __all__.extend(["spawnv", "spawnve", "spawnvp", "spawnvpe"]) 915 916 917if _exists("spawnv"): 918 # These aren't supplied by the basic Windows code 919 # but can be easily implemented in Python 920 921 def spawnl(mode, file, *args): 922 """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. """ 928 return spawnv(mode, file, args) 929 930 def spawnle(mode, file, *args): 931 """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. """ 938 env = args[-1] 939 return spawnve(mode, file, args[:-1], env) 940 941 942 __all__.extend(["spawnl", "spawnle"]) 943 944 945if _exists("spawnvp"): 946 # At the moment, Windows doesn't implement spawnvp[e], 947 # so it won't have spawnlp[e] either. 948 def spawnlp(mode, file, *args): 949 """spawnlp(mode, file, *args) -> integer 950 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. """ 956 return spawnvp(mode, file, args) 957 958 def spawnlpe(mode, file, *args): 959 """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. """ 966 env = args[-1] 967 return spawnvpe(mode, file, args[:-1], env) 968 969 970 __all__.extend(["spawnlp", "spawnlpe"]) 971 972 973# Supply os.popen() 974def popen(cmd, mode="r", buffering=-1): 975 if not isinstance(cmd, str): 976 raise TypeError("invalid cmd type (%s, expected string)" % type(cmd)) 977 if mode not in ("r", "w"): 978 raise ValueError("invalid mode %r" % mode) 979 if buffering == 0 or buffering is None: 980 raise ValueError("popen() does not support unbuffered streams") 981 import subprocess, io 982 if mode == "r": 983 proc = subprocess.Popen(cmd, 984 shell=True, 985 stdout=subprocess.PIPE, 986 bufsize=buffering) 987 return _wrap_close(io.TextIOWrapper(proc.stdout), proc) 988 else: 989 proc = subprocess.Popen(cmd, 990 shell=True, 991 stdin=subprocess.PIPE, 992 bufsize=buffering) 993 return _wrap_close(io.TextIOWrapper(proc.stdin), proc) 994 995# Helper for popen() -- a proxy for a file whose close waits for the process 996class _wrap_close: 997 def __init__(self, stream, proc): 998 self._stream = stream 999 self._proc = proc 1000 def close(self): 1001 self._stream.close() 1002 returncode = self._proc.wait() 1003 if returncode == 0: 1004 return None 1005 if name == 'nt': 1006 return returncode 1007 else: 1008 return returncode << 8 # Shift left to match old behavior 1009 def __enter__(self): 1010 return self 1011 def __exit__(self, *args): 1012 self.close() 1013 def __getattr__(self, name): 1014 return getattr(self._stream, name) 1015 def __iter__(self): 1016 return iter(self._stream) 1017 1018# Supply os.fdopen() 1019def fdopen(fd, *args, **kwargs): 1020 if not isinstance(fd, int): 1021 raise TypeError("invalid fd type (%s, expected integer)" % type(fd)) 1022 import io 1023 return io.open(fd, *args, **kwargs) 1024 1025 1026# For testing purposes, make sure the function is available when the C 1027# implementation exists. 1028def _fspath(path): 1029 """Return the path representation of a path-like object. 1030 1031 If str or bytes is passed in, it is returned unchanged. Otherwise the 1032 os.PathLike interface is used to get the path representation. If the 1033 path representation is not str or bytes, TypeError is raised. If the 1034 provided path is not str, bytes, or os.PathLike, TypeError is raised. 1035 """ 1036 if isinstance(path, (str, bytes)): 1037 return path 1038 1039 # Work from the object's type to match method resolution of other magic 1040 # methods. 1041 path_type = type(path) 1042 try: 1043 path_repr = path_type.__fspath__(path) 1044 except AttributeError: 1045 if hasattr(path_type, '__fspath__'): 1046 raise 1047 else: 1048 raise TypeError("expected str, bytes or os.PathLike object, " 1049 "not " + path_type.__name__) 1050 if isinstance(path_repr, (str, bytes)): 1051 return path_repr 1052 else: 1053 raise TypeError("expected {}.__fspath__() to return str or bytes, " 1054 "not {}".format(path_type.__name__, 1055 type(path_repr).__name__)) 1056 1057# If there is no C implementation, make the pure Python version the 1058# implementation as transparently as possible. 1059if not _exists('fspath'): 1060 fspath = _fspath 1061 fspath.__name__ = "fspath" 1062 1063 1064class PathLike(abc.ABC): 1065 1066 """Abstract base class for implementing the file system path protocol.""" 1067 1068 @abc.abstractmethod 1069 def __fspath__(self): 1070 """Return the file system path representation of the object.""" 1071 raise NotImplementedError 1072 1073 @classmethod 1074 def __subclasshook__(cls, subclass): 1075 if cls is PathLike: 1076 return _check_methods(subclass, '__fspath__') 1077 return NotImplemented 1078 1079 1080if name == 'nt': 1081 class _AddedDllDirectory: 1082 def __init__(self, path, cookie, remove_dll_directory): 1083 self.path = path 1084 self._cookie = cookie 1085 self._remove_dll_directory = remove_dll_directory 1086 def close(self): 1087 self._remove_dll_directory(self._cookie) 1088 self.path = None 1089 def __enter__(self): 1090 return self 1091 def __exit__(self, *args): 1092 self.close() 1093 def __repr__(self): 1094 if self.path: 1095 return "<AddedDllDirectory({!r})>".format(self.path) 1096 return "<AddedDllDirectory()>" 1097 1098 def add_dll_directory(path): 1099 """Add a path to the DLL search path. 1100 1101 This search path is used when resolving dependencies for imported 1102 extension modules (the module itself is resolved through sys.path), 1103 and also by ctypes. 1104 1105 Remove the directory by calling close() on the returned object or 1106 using it in a with statement. 1107 """ 1108 import nt 1109 cookie = nt._add_dll_directory(path) 1110 return _AddedDllDirectory( 1111 path, 1112 cookie, 1113 nt._remove_dll_directory 1114 ) 1115