Eryk Sun <eryk...@gmail.com> added the comment:
Here's a concrete implementation of the above discussion. _is_windows = (sys.platform == 'win32') def ismount(path): """Test whether a path is a mount point""" path = os.fspath(path) if isinstance(path, bytes): sep = b'\\' extended_devices = b'\\\\?\\' normal_devices = b'\\\\.\\' global_link = b'GLOBAL' unc_device = b'UNC' else: sep = '\\' extended_devices = '\\\\?\\' normal_devices = '\\\\.\\' global_link = 'GLOBAL' unc_device = 'UNC' # In Windows, require an existing, accessible directory. if _is_windows: if not isdir(path): return False try: s = os.lstat(path) if s.st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT: # isdir() verified the target directory. return True except (OSError, ValueError): return False path = abspath(path) drive, drive_path = splitdrive(path) if not drive: return False # A drive root is a mount point. if drive_path == sep: return True # A root path is not required for a UNC drive. if not drive_path and drive[0] in sep: if not drive.startswith((extended_devices, normal_devices)): return True # Check for \\?\[Global]\UNC. Ignore repeated "Global" links. comps = [c.upper() for c in drive[4:].split(sep)] for c in comps: if c != global_link: break if c == unc_device: return True return False Removing the dependency on GetVolumePathNameW() also eliminates buggy behavior with substitute drives. For example, if substitute drive "W:" maps to r"C:\Windows", GetVolumePathNameW() mistakenly claims r"W:\System32" is a volume mount point. In principle, this implementation also supports "\\?\[Global]\UNC\server\share" mount points on the "UNC" device, but it depends on fixing bpo-37609. The suggested rewrite for the latter issue also includes support for repeated slashes in a UNC drive, e.g. r"\\server\\\share" and r"\\?\\\Global\\\UNC\\\server\\\share" are valid. For POSIX, ntpath._abspath_fallback() has to be fixed to correctly resolve drive-relative paths. For example: def _abspath_fallback(path): """Return the absolute version of a path.""" path = os.fspath(path) if isinstance(path, bytes): sep = b'\\' colon = b':' cwd = os.getcwdb() else: sep = '\\' colon = ':' cwd = os.getcwd() if not isabs(path): # For a drive-relative path, default to the root directory # on the drive if the process working directory is on a # different drive. if path[1:2] == colon and path[:2].upper() != cwd[:2].upper(): path = path[:2] + sep + path[2:] else: path = join(cwd, path) return normpath(path) Since _abspath_fallback() is no longer needed in any version of Windows, maybe it should simply assume that the working drive is "C:" and the working directory on all drives is the root directory. ---------- components: +Library (Lib) dependencies: +support "UNC" device paths in ntpath.splitdrive title: os.path.ismount() returns False for current working drive -> [Windows] require an existing directory and suport junctions in ntpath.ismount() versions: +Python 3.10 -Python 3.7 _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue38948> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com