msg416336 - (view) |
Author: Jan Bronicki (John15321) |
Date: 2022-03-30 11:01 |
The `//` path should be equivalent to `/`, and in some ways, it does behave like that in pathlib. But in the `relative_to` method on a `Path` object, 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 ```python 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 '/' ``` |
|
|
msg416342 - (view) |
Author: Oleg Iarygin (arhadthedev) * |
Date: 2022-03-30 11:58 |
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. |
|
|
msg416348 - (view) |
Author: Oleg Iarygin (arhadthedev) * |
Date: 2022-03-30 12:24 |
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." |
|
|
msg416351 - (view) |
Author: Oleg Iarygin (arhadthedev) * |
Date: 2022-03-30 12:37 |
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. |
|
|
msg416352 - (view) |
Author: Jan Bronicki (John15321) |
Date: 2022-03-30 12:44 |
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 absolutes |
|
|
msg416355 - (view) |
Author: Oleg Iarygin (arhadthedev) * |
Date: 2022-03-30 13:23 |
> But 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 `/Video` on a computer named `Library`. |
|
|
msg416356 - (view) |
Author: Jan Bronicki (John15321) |
Date: 2022-03-30 13:51 |
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? |
|
|
msg416489 - (view) |
Author: Eryk Sun (eryksun) *  |
Date: 2022-04-01 14:26 |
> 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() False realpath() is also broken for this case in 3.9 under MSYS2: >>> os.path.realpath(p) '/localhost/C$/temp' |
|
|