On Sun, Jan 7, 2018 at 10:51 AM, Albert-Jan Roskam <sjeik_ap...@hotmail.com> wrote: > > On Jan 7, 2018 09:08, Steven D'Aprano <st...@pearwood.info> wrote: >> >> realpath() returns the canonical path of the given filename. It doesn't >> try to locate some actual existing file. > > I always thought that os.path.realpath is the Python equivalent of Linux > realpath/readlink
In POSIX, os.path.realpath resolves a path that contains symlinks by calling os.readlink in a loop until all links are resolved. In Windows, os.path.realpath is an alias for os.path.abspath. This decision predates NTFS support for junctions (2000) and symbolic links (Vista). It's simply the case that no one has gotten around to implementing realpath for Windows. In Windows, os.path.abspath calls os.path._getfullpathname (WinAPI GetFullPathName). Other than resolving the working directory, this is a string transformation to return a canonical, fully-qualified path. It doesn't touch the filesystem. Note that in the case of classic DOS devices, the canonical path is a local-device path (i.e. "\\.\" prefix). For example: >>> print(os.path.abspath('C:/path/to/nul')) \\.\nul > maybe also when it's a hard link - in this case the function actually also > does > something in Windows A hard link shouldn't be resolved to another path by os.path.realpath. It's already a real path. Cross-platform Python 3 code that needs to resolve symbolic links (or junctions) can use pathlib.Path.resolve(). For example: >>> pathlib.Path('C:/Documents and Settings').resolve() WindowsPath('C:/Users') On Windows this relies on os.path._getfinalpathname (WinAPI GetFinalPathNameByHandle). This function returns the final opened filename, so the OS does all of the work to resolve the final path. In non-strict mode pathlib uses a loop to reduce the path when it can't be resolved to an existing file. (There are open issues for edge cases in this code, but it should work as intended with regular files in accessible directories.) For those who are curious, WinAPI GetFinalPathNameByHandle is called with a handle for a File object that's opened via CreateFile. It gets the NT name of the volume (e.g, "\Device\HarddiskVolume1") and the filesystem path (e.g. "\Users"). Then it asks the mount-point manager to map this NT name back to a DOS name such as drive "C:"; or an NTFS volume mountpoint such as "C:\Mount\VolumeName"; or a "Volume{GUID}" name. (In the latter case, Python's _getfinalpathname and pathlib have bugs and need improvement.) _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor