[issue39090] Document various options for getting the absolute path from pathlib.Path objects

New submission from Brett Cannon <brett@python.org>: The question on how best to get an absolute path from a pathlib.Path object keeps coming up (see https://bugs.python.org/issue29688, https://discuss.python.org/t/add-absolute-name-to-pathlib-path/2882/, and https://discuss.python.org/t/pathlib-absolute-vs-resolve/2573 as examples). As pointed out across those posts, getting the absolute path is surprisingly subtle and varied depending on your needs. As such we should probably add a section somewhere in the pathlib docs explaining the various ways and why you would choose one over the other. ---------- assignee: docs@python components: Documentation messages: 358638 nosy: brett.cannon, docs@python priority: normal severity: normal stage: needs patch status: open title: Document various options for getting the absolute path from pathlib.Path objects type: enhancement _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue39090> _______________________________________

Chris Barker <Chris.Barker@noaa.gov> added the comment: Yes Please! I'd offer to help, but I really don't get the intricacies involved. I will offer to proofread and copy-edit though, if that's helpful. And I note that coincidentally, just in the last week, I needed to make an absolute path from a Path, and it took me far too long to figure out that .resolve() would do it for me. Then I needed to do it again three days later, and it again took a while -- "resolve" is simply not mnemonic for me, and I'm guessing a lot of people have the same issue. And I didn't find .absolute(), cause it's not documented. I see in issue #29688 that there are reasons for that, but I'll make a plea: Please document .absolute(), even if those docs say something like "may not work in all circumstances, not well tested". Alternatively, if it's decided that folks should just use .resolve() in all cases anyway, then make .absolute() an alias for .resolve(). Or if that's not a good option, then at least put some prominent notes in resolve() so people will find it. Also -- I needed to read the resolve() docs carefully (and then test) to see if it was what I wanted - which I know, is what this issue is about. In short -- I understand that this is a complex issue, but making an absolute path is a pretty common use case, and we've had os.path.abspath() for decades, so there should be one obvious way to do it, and it should be easily discoverable. NOTE: even if there is no one to do the work of properly testing .absolute() at this point, it would b nice to at least decide now what the long term goal is -- will there be an absolute() or is resolve() all we really need? ---------- nosy: +ChrisBarker _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue39090> _______________________________________

Change by Josh Holland <anowlcalledjosh@gmail.com>: ---------- nosy: +anowlcalledjosh _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue39090> _______________________________________

Paul Moore <p.f.moore@gmail.com> added the comment:
In short -- I understand that this is a complex issue, but making an absolute path is a pretty common use case, and we've had os.path.abspath() for decades, so there should be one obvious way to do it, and it should be easily discoverable.
+1 on this. Given that (as far as I can tell from the various discussions) `resolve` works fine as long as the file exists, maybe the key distinction to make is whether you have an existing file or not. (More subtle questions like UNC path vs drive letter, mentioned on the Discourse thread, are probably things that we can defer to a "more advanced cases" discussion in the docs). ---------- nosy: +paul.moore _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue39090> _______________________________________

Floris Lambrechts <florisla@gmail.com> added the comment: I've written an "Absolute paths" section based on the knowledge I found in the various threads. Any review is appreciated. https://github.com/florisla/cpython/tree/pathlib-chapter-absolute-paths With some related documentation changes: https://github.com/florisla/cpython/tree/absolute-path-related-improvements ---------- nosy: +florisla _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue39090> _______________________________________

Paul Moore <p.f.moore@gmail.com> added the comment: You've provided links to your branches, but not to the specific text you're proposing to add. Can you link to a diff or something that shows what you've added more precisely? ---------- _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue39090> _______________________________________

Floris Lambrechts <florisla@gmail.com> added the comment: This is the new chapter: https://github.com/florisla/cpython/commit/c146ad3d086fe9e401284c12fc670ea4f... ---------- _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue39090> _______________________________________

Vedran Čačić <vedgar@gmail.com> added the comment: If we want something mnemonic, I'm sure nothing beats __abs__. (Hey, we have __truediv__ already!;) ---------- nosy: +veky _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue39090> _______________________________________

Floris Lambrechts <florisla@gmail.com> added the comment: @ChrisBarker, Could you review the proposed addition to the documentation? https://github.com/florisla/cpython/commit/c146ad3d086fe9e401284c12fc670ea4f... ---------- _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue39090> _______________________________________

Floris Lambrechts <florisla@gmail.com> added the comment: (sorry, didn't see the GitHub comments before... I'll process those first.) ---------- _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue39090> _______________________________________

Floris Lambrechts <florisla@gmail.com> added the comment: Based on the feedback received in GitHub here: https://github.com/florisla/cpython/commit/c146ad3d086fe9e401284c12fc670ea4f... I made a new revision of the 'Absolute paths' chapter here: https://github.com/florisla/cpython/blob/pathlib-chapter-absolute-paths-2/Do... Further feedback is welcome. Changes: * Be more 'in your face' about Path.resolve() being the recommended approach. * Add separate section on Windows considerations * Explain difference between Path.resolve() and os.path.isabs() w.r.t. checking for drive. * Refer to 'mapped share' instead of 'mapped network share'. * Explain replacement of substitute drive with final path. * Mention os.path.abspath's upcasing of drive letter in case of a path missing a root. * Mention different handling of junctions versus symlinks w.r.t. relative parts. For brevity, I've kept the wording on substitute drive and handling of junctions very short. For the same reason I did not not include eryksun's (interesting!) info on why mapped and substitute drives are non-canonical. Not mentioning Path.resolve()'s behavior w.r.t. non-existing files since that's documented in resolve() itself. ---------- _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue39090> _______________________________________

Not mentioning Path.resolve()'s behavior w.r.t. non-existing files since
John Hennig <jhen@gmx.net> added the comment: @Floris: that's documented in resolve() itself. I don't see it mentioned in the documentation of `resolve()`, or anywhere else in the docs, that on Windows (but not on other platforms) `resolve()` does *not* resolve a relative path to an absolute path if the file does not exist. As opposed to `absolute()`, which works as expected on any platform. Linux: ``` Python 3.6.9 (default, Oct 8 2020, 12:12:24) [GCC 8.4.0] on linux Type "help", "copyright", "credits" or "license" for more information.
from pathlib import Path file = Path('new.txt') file.exists() False file.resolve() PosixPath('/home/user/new.txt')
Windows:
Python 3.9.2 (tags/v3.9.2:1a79785, Feb 19 2021, 13:44:55) [MSC v.1928 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information.
from pathlib import Path file = Path('new.txt') file.exists() False file.resolve() WindowsPath('new.txt') file.absolute() WindowsPath('d:/home/new.txt') file.touch() file.resolve() WindowsPath('D:/home/new.txt') file.unlink() file.resolve() WindowsPath('new.txt')
----------
nosy: +John-Hennig
_______________________________________
Python tracker <report@bugs.python.org>
<https://bugs.python.org/issue39090>
_______________________________________

Change by 4-launchpad-kalvdans-no-ip-org <launchpad@kalvdans.no-ip.org>: ---------- nosy: +4-launchpad-kalvdans-no-ip-org _______________________________________ Python tracker <report@bugs.python.org> <https://bugs.python.org/issue39090> _______________________________________
participants (8)
-
4-launchpad-kalvdans-no-ip-org
-
Brett Cannon
-
Chris Barker
-
Floris Lambrechts
-
John Hennig
-
Josh Holland
-
Paul Moore
-
Vedran Čačić