-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
Description
Bug report
Bug description:
from pathlib import Path
Path("//VBOXSVR/shared-folder").expanduser().resolve()
Raises FileNotFoundError: [WinError 53] The network path was not found: '\\\\VBOXSVR\\shared-folder\\'
.
This appears to be a consequence of this backport:
- [3.9] bpo-43757: Make pathlib use os.path.realpath() to resolve symlinks in a path (GH-25264) #135035 which rewrote the
Path.resolve()
to useos.path.realpath
under the hood - which was a prerequisite for [3.9] gh-135034: Normalize link targets in tarfile, add
os.path.realpath(strict='allow_missing')
(GH-135037) #135084 security fix
By default the FileNotFoundError
should be caught as a descendant of OSError
, but since #135035 it is then also re-raised as it is not on the list of ignored Windows errors.
This passes on Python 3.10+ because 53: ERROR_BAD_NETPATH
is included on the list since #27574:
Lines 659 to 668 in 28937d3
# 53: ERROR_BAD_NETPATH | |
# 65: ERROR_NETWORK_ACCESS_DENIED | |
# 67: ERROR_BAD_NET_NAME (implies remote server unavailable) | |
# 87: ERROR_INVALID_PARAMETER | |
# 123: ERROR_INVALID_NAME | |
# 161: ERROR_BAD_PATHNAME | |
# 1005: ERROR_UNRECOGNIZED_VOLUME | |
# 1920: ERROR_CANT_ACCESS_FILE | |
# 1921: ERROR_CANT_RESOLVE_FILENAME (implies unfollowable symlink) | |
allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 53, 65, 67, 87, 123, 161, 1005, 1920, 1921 |
but it it was not backported to 3.9:
Lines 588 to 596 in 6c97200
# 21: ERROR_NOT_READY (implies drive with no media) | |
# 32: ERROR_SHARING_VIOLATION (probably an NTFS paging file) | |
# 50: ERROR_NOT_SUPPORTED | |
# 67: ERROR_BAD_NET_NAME (implies remote server unavailable) | |
# 87: ERROR_INVALID_PARAMETER | |
# 123: ERROR_INVALID_NAME | |
# 1920: ERROR_CANT_ACCESS_FILE | |
# 1921: ERROR_CANT_RESOLVE_FILENAME (implies unfollowable symlink) | |
allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 67, 87, 123, 1920, 1921 |
And since this code path is now used for Path.resolve()
since #135035 was merged and backported I think that #27574 should be backported to other Python version to preserve old behaviour.
def normalized_uri(root_dir):
"""Attempt to make an LSP rootUri from a ContentsManager root_dir
Special care must be taken around windows paths: the canonical form of
windows drives and UNC paths is lower case
"""
> root_uri = Path(root_dir).expanduser().resolve().as_uri()
C:\Users\runneradmin\miniconda3\envs\test\lib\site-packages\jupyter_lsp\paths.py:16:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = WindowsPath('//VBOXSVR/shared-folder/'), strict = False
def resolve(self, strict=False):
"""
Make the path absolute, resolving all symlinks on the way and also
normalizing it (for example turning slashes into backslashes under
Windows).
"""
def check_eloop(e):
winerror = getattr(e, 'winerror', 0)
if e.errno == ELOOP or winerror == _WINERROR_CANT_RESOLVE_FILENAME:
raise RuntimeError("Symlink loop from %r" % e.filename)
try:
> s = self._accessor.realpath(self, strict=strict)
C:\Users\runneradmin\miniconda3\envs\test\lib\pathlib.py:1140:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
path = '\\\\VBOXSVR\\shared-folder\\'
def realpath(path, *, strict=False):
path = normpath(path)
if isinstance(path, bytes):
prefix = b'\\\\?\\'
unc_prefix = b'\\\\?\\UNC\\'
new_unc_prefix = b'\\\\'
cwd = os.getcwdb()
# bpo-38081: Special case for realpath(b'nul')
if normcase(path) == normcase(os.fsencode(devnull)):
return b'\\\\.\\NUL'
else:
prefix = '\\\\?\\'
unc_prefix = '\\\\?\\UNC\\'
new_unc_prefix = '\\\\'
cwd = os.getcwd()
# bpo-38081: Special case for realpath('nul')
if normcase(path) == normcase(devnull):
return '\\\\.\\NUL'
had_prefix = path.startswith(prefix)
if strict is ALLOW_MISSING:
ignored_error = FileNotFoundError
strict = True
elif strict:
ignored_error = ()
else:
ignored_error = OSError
if not had_prefix and not isabs(path):
path = join(cwd, path)
try:
path = _getfinalpathname(path)
initial_winerror = 0
except ignored_error as ex:
initial_winerror = ex.winerror
> path = _getfinalpathname_nonstrict(path,
ignored_error=ignored_error)
C:\Users\runneradmin\miniconda3\envs\test\lib\ntpath.py:663:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
path = '\\\\VBOXSVR\\shared-folder\\', ignored_error = <class 'OSError'>
def _getfinalpathname_nonstrict(path, ignored_error=OSError):
# These error codes indicate that we should stop resolving the path
# and return the value we currently have.
# 1: ERROR_INVALID_FUNCTION
# 2: ERROR_FILE_NOT_FOUND
# 3: ERROR_DIRECTORY_NOT_FOUND
# 5: ERROR_ACCESS_DENIED
# 21: ERROR_NOT_READY (implies drive with no media)
# 32: ERROR_SHARING_VIOLATION (probably an NTFS paging file)
# 50: ERROR_NOT_SUPPORTED
# 67: ERROR_BAD_NET_NAME (implies remote server unavailable)
# 87: ERROR_INVALID_PARAMETER
# 123: ERROR_INVALID_NAME
# 1920: ERROR_CANT_ACCESS_FILE
# 1921: ERROR_CANT_RESOLVE_FILENAME (implies unfollowable symlink)
allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 67, 87, 123, 1920, 1921
# Non-strict algorithm is to find as much of the target directory
# as we can and join the rest.
tail = ''
while path:
try:
> path = _getfinalpathname(path)
E FileNotFoundError: [WinError 53] The network path was not found: '\\\\VBOXSVR\\shared-folder\\'
CPython versions tested on:
3.9
Operating systems tested on:
Windows