|
8 | 8 | import os |
9 | 9 | import stat |
10 | 10 | from genericpath import * |
11 | | -from ntpath import (expanduser, expandvars, isabs, islink, splitdrive, |
| 11 | +from ntpath import (expandvars, isabs, islink, splitdrive, |
12 | 12 | splitext, split) |
13 | 13 |
|
14 | 14 | __all__ = ["normcase","isabs","join","splitdrive","split","splitext", |
@@ -381,3 +381,66 @@ def commonpath(paths): |
381 | 381 | genericpath._check_arg_types('commonpath', *paths) |
382 | 382 | raise |
383 | 383 |
|
| 384 | +# Expand paths beginning with '~' or '~user'. |
| 385 | +# '~' means $HOME; '~user' means that user's home directory. |
| 386 | +# If the path doesn't begin with '~', or if the user or $HOME is unknown, |
| 387 | +# the path is returned unchanged (leaving error reporting to whatever |
| 388 | +# function is called with the expanded path as argument). |
| 389 | +# See also module 'glob' for expansion of *, ? and [...] in pathnames. |
| 390 | +# (A function should also be defined to do full *sh-style environment |
| 391 | +# variable expansion.) |
| 392 | + |
| 393 | +def expanduser(path): |
| 394 | + """Expand ~ and ~user constructs. |
| 395 | +
|
| 396 | + If user or $HOME is unknown, do nothing.""" |
| 397 | + path = os.fspath(path) |
| 398 | + if isinstance(path, bytes): |
| 399 | + seps = b'\\/' |
| 400 | + tilde = b'~' |
| 401 | + else: |
| 402 | + seps = '\\/' |
| 403 | + tilde = '~' |
| 404 | + if not path.startswith(tilde): |
| 405 | + return path |
| 406 | + i, n = 1, len(path) |
| 407 | + while i < n and path[i] not in seps: |
| 408 | + i += 1 |
| 409 | + |
| 410 | + if 'HOME' not in os.environ: |
| 411 | + try: |
| 412 | + import pwd |
| 413 | + except ImportError: |
| 414 | + # pwd module unavailable, return path unchanged |
| 415 | + return path |
| 416 | + try: |
| 417 | + userhome = pwd.getpwuid(os.getuid()).pw_dir |
| 418 | + except KeyError: |
| 419 | + # bpo-10496: if the current user identifier doesn't exist in the |
| 420 | + # password database, return the path unchanged |
| 421 | + return path |
| 422 | + else: |
| 423 | + userhome = os.environ['HOME'] |
| 424 | + |
| 425 | + if i != 1: #~user |
| 426 | + target_user = path[1:i] |
| 427 | + if isinstance(target_user, bytes): |
| 428 | + target_user = os.fsdecode(target_user) |
| 429 | + |
| 430 | + try: |
| 431 | + import pwd |
| 432 | + except ImportError: |
| 433 | + # pwd module unavailable, return path unchanged |
| 434 | + return path |
| 435 | + |
| 436 | + try: |
| 437 | + userhome = pwd.getpwnam(target_user).pw_dir |
| 438 | + except KeyError: |
| 439 | + return path |
| 440 | + |
| 441 | + userhome = join(dirname(userhome), target_user) |
| 442 | + |
| 443 | + if isinstance(path, bytes): |
| 444 | + userhome = os.fsencode(userhome) |
| 445 | + |
| 446 | + return userhome + path[i:] |
0 commit comments