Repository navigation
pathlib method relative_to doesnt work with // in paths #91317
Description
Activity
The
//path should be equivalent to/, and in some ways, it does behave like that in pathlib. But in therelative_tomethod on aPathobject, it does not work
This is causing our CI pipeline to fail. In the documentation here you can see//being properly processed:https://docs.python.org/3/library/pathlib.html
In [10]: x=Path("/Library/Video") ; x.relative_to(Path("/")) Out[10]: PosixPath('Library/Video') In [11]: x=Path("//Library/Video") ; x.relative_to(Path("/")) --------------------------------------------------------------------------- ValueError Traceback (most recent call last) Input In [11], in <cell line: 1>() ----> 1 x=Path("//Library/Video") ; x.relative_to(Path("/")) File ~/.pyenv/versions/3.8.13/lib/python3.8/pathlib.py:908, in PurePath.relative_to(self, *other) 906 if (root or drv) if n == 0 else cf(abs_parts[:n]) != cf(to_abs_parts): 907 formatted = self._format_parsed_parts(to_drv, to_root, to_parts) --> 908 raise ValueError("{!r} does not start with {!r}" 909 .format(str(self), str(formatted))) 910 return self._from_parsed_parts('', root if n == 1 else '', 911 abs_parts[n:]) ValueError: '//Library/Video' does not start with '/'
- added3.8 (EOL)end of lifeend of lifestdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Mar 30, 2022 I started to investigate and found that a double slash in the beginning cancels any parsing of a path:
>>> Path("//Library/Video")._parts ['\\\\Library\\Video\\']vs
>>> Path("/Library/Video")._parts ['\\', 'Library', 'Video']Investigating further.
As I found out, any path starting with two double slashes is treated as an UNC (network) path:
vvvvvvvvvvvvvvvvvvvv root \\machine\mountpoint\directory\etc\... directory ^^^^^^^^^^^^^^^^^So "/Library/Video" and "/" are directories mounted on your machine while "//Library/Video" is a computer named "Library" with a share named "Video".
However, an error message in Python 3.8 (as a file path suggests) is misleading. In 3.11 it was changed to "'\\Library\Video\' is not in the subpath of '\' OR one path is relative and the other is absolute."
Also, the error message cannot be fixed because for 3.8 only security fixes are accepted since May 2021. For 3.9 and later, the message is already corrected.
But shouldn't it just work with
//as a/? It seems like this is the behavior elsewhere. Sure I get that it cannot be done for 3.8. But the new error message implies that either//is not a subpath of/which it is, or that one is relative and the other is absolute, which is also false because both are absolutesBut shouldn't it just work with
//as a/? It seems like this is the behavior elsewhere.It works elsewhere because empty directory names are impossible so can be dropped. But if
//is placed in the beginning, it gets a special meaning that totally changes the whole path so its plain replacement would give a totally wrong one.Roughly speaking, "//Library/Video" is
/Videoon a computer namedLibrary.Hmm..., I get it, but Im not gonna lie it's pretty confusing given that in other places
//works as a substitute for/. Maybe it should be mentioned in the documentation?Hmm..., I get it, but Im not gonna lie it's pretty confusing given
that in other places//works as a substitute for/. Maybe it
should be mentioned in the documentation?In Linux, the system resolves "//" as just "/". In other POSIX systems, such as Cygwin or MSYS2 (running in Windows), "//" is a UNC path of the form "//server/share/filepath". I would expect resolve() to handle this. For example:
Linux:
>>> p = pathlib.Path('//tmp') >>> p PosixPath('//tmp') >>> p.resolve() PosixPath('/tmp')However, resolve() is broken for a UNC path in 3.9 under MSYS2:
>>> p = pathlib.Path('//localhost/C$/temp') >>> p.exists() True >>> p.resolve() PosixPath('/localhost/C$/temp') >>> p.resolve().exists() Falserealpath() is also broken for this case in 3.9 under MSYS2:
>>> os.path.realpath(p) '/localhost/C$/temp'- added 5 commits that reference this issue
on Jun 10, 2022 - added a commit that references this issue
on Jun 26, 2022
//#32193Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields: