diff options
author | 박문식 <mooonsik.park@gmail.com> | 2023-10-05 14:49:07 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-05 14:49:07 (GMT) |
commit | d33aa18f15de482a01988aabc75907328e1f9c9f (patch) | |
tree | 16b6448d4cfd56a4f5723950aa1bb108b0b644f2 /Lib/ntpath.py | |
parent | 2cb62c6437fa07e08b4778f7ab9baa5f16ac01f2 (diff) | |
download | cpython-d33aa18f15de482a01988aabc75907328e1f9c9f.zip cpython-d33aa18f15de482a01988aabc75907328e1f9c9f.tar.gz cpython-d33aa18f15de482a01988aabc75907328e1f9c9f.tar.bz2 |
gh-82367: Use `FindFirstFile` Win32 API in `ntpath.realpath()` (GH-110298)
* Use `FindFirstFile` Win32 API to fix a bug where `ntpath.realpath()`
breaks out of traversing a series of paths where a (handled)
`ERROR_ACCESS_DENIED` or `ERROR_SHARING_VIOLATION` occurs.
* Update docs to reflect that `ntpath.realpath()` eliminates MS-DOS
style names.
Diffstat (limited to 'Lib/ntpath.py')
-rw-r--r-- | Lib/ntpath.py | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/Lib/ntpath.py b/Lib/ntpath.py index df3402d..3061a4a 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -23,7 +23,6 @@ import stat import genericpath from genericpath import * - __all__ = ["normcase","isabs","join","splitdrive","splitroot","split","splitext", "basename","dirname","commonprefix","getsize","getmtime", "getatime","getctime", "islink","exists","lexists","isdir","isfile", @@ -601,7 +600,7 @@ else: # use native Windows method on Windows return _abspath_fallback(path) try: - from nt import _getfinalpathname, readlink as _nt_readlink + from nt import _findfirstfile, _getfinalpathname, readlink as _nt_readlink except ImportError: # realpath is a no-op on systems without _getfinalpathname support. realpath = abspath @@ -688,10 +687,15 @@ else: except OSError: # If we fail to readlink(), let's keep traversing pass - path, name = split(path) - # TODO (bpo-38186): Request the real file name from the directory - # entry using FindFirstFileW. For now, we will return the path - # as best we have it + # If we get these errors, try to get the real name of the file without accessing it. + if ex.winerror in (1, 5, 32, 50, 87, 1920, 1921): + try: + name = _findfirstfile(path) + path, _ = split(path) + except OSError: + path, name = split(path) + else: + path, name = split(path) if path and not name: return path + tail tail = join(name, tail) if tail else name |