mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-02 07:18:25 +01:00
path_info: don't forget to override as_posix method
Unlike original implementation [1] that uses `str()` we actually need to use `fspath`, because we've overriden `__str__` method to return relative paths, which will break original `as_posix`. [1] https://github.com/python/cpython/blob/v3.7.0/Lib/pathlib.py#L692 Fixes #2483 Signed-off-by: Ruslan Kuprieiev <[email protected]>
This commit is contained in:
+9
-4
@@ -36,6 +36,15 @@ class PathInfo(pathlib.PurePath):
|
||||
def from_posix(cls, s):
|
||||
return cls(PosixPathInfo(s))
|
||||
|
||||
def as_posix(self):
|
||||
f = self._flavour
|
||||
# Unlike original implementation [1] that uses `str()` we actually need
|
||||
# to use `fspath`, because we've overriden `__str__` method to return
|
||||
# relative paths, which will break original `as_posix`.
|
||||
#
|
||||
# [1] https://github.com/python/cpython/blob/v3.7.0/Lib/pathlib.py#L692
|
||||
return self.fspath.replace(f.sep, "/")
|
||||
|
||||
def __str__(self):
|
||||
path = self.__fspath__()
|
||||
return relpath(path)
|
||||
@@ -94,10 +103,6 @@ class PathInfo(pathlib.PurePath):
|
||||
def with_name(self, name):
|
||||
return pathlib.PurePath.with_name(self, name.encode(fs_encoding))
|
||||
|
||||
def as_posix(self):
|
||||
f = self._flavour
|
||||
return str(self).replace(f.sep, "/")
|
||||
|
||||
|
||||
class WindowsPathInfo(PathInfo, pathlib.PureWindowsPath):
|
||||
pass
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import pytest
|
||||
import copy
|
||||
|
||||
from dvc.path_info import URLInfo, CloudURLInfo
|
||||
from dvc.utils.compat import pathlib
|
||||
from dvc.path_info import PathInfo, URLInfo, CloudURLInfo
|
||||
|
||||
|
||||
TEST_DEPTH = len(pathlib.Path(__file__).parents) + 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize("cls", [URLInfo, CloudURLInfo])
|
||||
@@ -42,3 +46,32 @@ def test_url_info_deepcopy(cls):
|
||||
u1 = cls("ssh://[email protected]:/test1/test2/test3")
|
||||
u2 = copy.deepcopy(u1)
|
||||
assert u1 == u2
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"path, as_posix, osname",
|
||||
[
|
||||
("/some/abs/path", "/some/abs/path", "posix"),
|
||||
("some/rel/path", "some/rel/path", "posix"),
|
||||
("../some/rel/path", "../some/rel/path", "posix"),
|
||||
("windows\\relpath", "windows/relpath", "nt"),
|
||||
("..\\windows\\rel\\path", "../windows/rel/path", "nt"),
|
||||
# These ones are to test that no matter how layered this relpath is,
|
||||
# we don't accidentally round it over. E.g. how
|
||||
#
|
||||
# import os
|
||||
# os.chdir("/")
|
||||
# os.path.relpath("../../path")
|
||||
#
|
||||
# results in "path".
|
||||
("\\".join([".."] * TEST_DEPTH), "/".join([".."] * TEST_DEPTH), "nt"),
|
||||
(
|
||||
"/".join([".."] * TEST_DEPTH),
|
||||
"/".join([".."] * TEST_DEPTH),
|
||||
"posix",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_path_info_as_posix(mocker, path, as_posix, osname):
|
||||
mocker.patch("os.name", osname)
|
||||
assert PathInfo(path).as_posix() == as_posix
|
||||
|
||||
Reference in New Issue
Block a user