This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Inconsistent/Undocumented behavior with pathlib resolve and absolute on Windows
Type: behavior Stage: resolved
Components: Library (Lib), Windows Versions: Python 3.7
process
Status: closed Resolution: duplicate
Dependencies: Superseder: pathlib.Path.resolve(strict=False) returns relative path on Windows if the entry does not exist
View: 38671
Assigned To: Nosy List: alexjacobson95, eryksun, paul.moore, steve.dower, tim.golden, zach.ware
Priority: normal Keywords:

Created on 2019-05-09 02:17 by alexjacobson95, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (3)
msg341953 - (view) Author: Alex (alexjacobson95) Date: 2019-05-09 02:17
Maybe I am doing something wrong here but:

On Windows 10:
> python --version
Python 3.7.1
> python 
>>> from pathlib import Path
>>> Path("test.py").resolve()
WindowsPath('test.py')
>>> Path("test.py").absolute()  # this is undocumented in https://docs.python.org/3.7/library/pathlib.html
WindowsPath('C:/Users/Name/Desktop/test.py')

On Ubuntu 18.04 LTS:
$ python3.7 --version
Python 3.7.3
$ python3.7
>>> from pathlib import Path
>>> Path("test.py").resolve()
PosixPath('/home/name/test.py')
>>> Path("test.py").absolute()  # same as above undocumented
PosixPath('/home/name/test.py')

Why in Windows does this fail, but not Linux? Why is .absolute() undocumented? I've looked around trying to figure out what the intended behavior is but there is conflicting information.

Resolve seems to not work correctly on Windows. Bug?
msg341970 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2019-05-09 07:18
Windows resolve() is based on ntpath._getfinalpathname, which requires that the file exists and is accessible. resolve() defaults to non-strict behavior, which tries to resolve as much as possible by traversing the path in reverse and trying _getfinalpathname until it succeeds. For this to work reliably, it needs to begin with a fully-qualified path from ntpath._getfullpathname. This is also required in order to correctly resolve paths that have a reserved DOS device name in the final component (e.g. "nul", "nul:", "nul.txt")

Additionally, for an empty path, resolve() returns os.getcwd(). I don't know whether this case occurs in practice, but the working directory has to be resolved in Windows the same as any other path. It's not already resolved.

Also, the non-strict case should be relaxed like the POSIX version. It should continue resolving the path on any OSError, with possibly one exception. The POSIX version raises RuntimeError for a symlink loop. In Windows this case is ERROR_CANT_RESOLVE_FILENAME (1921). For cross-platform compatibility, this should probably be handled by raising the same RuntimeError.
msg389268 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2021-03-22 01:07
The issue with non-strict resolution of relative paths that do not exist is being addressed in bpo-38671. The proposal to support and document the absolute() method is addressed in bpo-29688.
History
Date User Action Args
2022-04-11 14:59:14adminsetgithub: 81041
2021-03-22 01:07:54eryksunsetstatus: open -> closed
superseder: pathlib.Path.resolve(strict=False) returns relative path on Windows if the entry does not exist
messages: + msg389268

resolution: duplicate
stage: resolved
2019-05-09 07:18:30eryksunsetmessages: + msg341970
2019-05-09 02:17:50alexjacobson95create