pathlib: add analogues to py.path.local's bestrelpath and common
An equivalent for these py.path.local functions is needed for some upcoming py.path -> pathlib conversions.
This commit is contained in:
parent
aa9905d72e
commit
e0d0951945
|
@ -569,3 +569,35 @@ def visit(
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
if entry.is_dir(follow_symlinks=False) and recurse(entry):
|
if entry.is_dir(follow_symlinks=False) and recurse(entry):
|
||||||
yield from visit(entry.path, recurse)
|
yield from visit(entry.path, recurse)
|
||||||
|
|
||||||
|
|
||||||
|
def commonpath(path1: Path, path2: Path) -> Optional[Path]:
|
||||||
|
"""Return the common part shared with the other path, or None if there is
|
||||||
|
no common part."""
|
||||||
|
try:
|
||||||
|
return Path(os.path.commonpath((str(path1), str(path2))))
|
||||||
|
except ValueError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def bestrelpath(directory: Path, dest: Path) -> str:
|
||||||
|
"""Return a string which is a relative path from directory to dest such
|
||||||
|
that directory/bestrelpath == dest.
|
||||||
|
|
||||||
|
If no such path can be determined, returns dest.
|
||||||
|
"""
|
||||||
|
if dest == directory:
|
||||||
|
return os.curdir
|
||||||
|
# Find the longest common directory.
|
||||||
|
base = commonpath(directory, dest)
|
||||||
|
# Can be the case on Windows.
|
||||||
|
if not base:
|
||||||
|
return str(dest)
|
||||||
|
reldirectory = directory.relative_to(base)
|
||||||
|
reldest = dest.relative_to(base)
|
||||||
|
return os.path.join(
|
||||||
|
# Back from directory to base.
|
||||||
|
*([os.pardir] * len(reldirectory.parts)),
|
||||||
|
# Forward from base to dest.
|
||||||
|
*reldest.parts,
|
||||||
|
)
|
||||||
|
|
|
@ -6,6 +6,8 @@ from textwrap import dedent
|
||||||
import py
|
import py
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from _pytest.pathlib import bestrelpath
|
||||||
|
from _pytest.pathlib import commonpath
|
||||||
from _pytest.pathlib import ensure_deletable
|
from _pytest.pathlib import ensure_deletable
|
||||||
from _pytest.pathlib import fnmatch_ex
|
from _pytest.pathlib import fnmatch_ex
|
||||||
from _pytest.pathlib import get_extended_length_path_str
|
from _pytest.pathlib import get_extended_length_path_str
|
||||||
|
@ -381,3 +383,21 @@ def test_suppress_error_removing_lock(tmp_path):
|
||||||
# check now that we can remove the lock file in normal circumstances
|
# check now that we can remove the lock file in normal circumstances
|
||||||
assert ensure_deletable(path, consider_lock_dead_if_created_before=mtime + 30)
|
assert ensure_deletable(path, consider_lock_dead_if_created_before=mtime + 30)
|
||||||
assert not lock.is_file()
|
assert not lock.is_file()
|
||||||
|
|
||||||
|
|
||||||
|
def test_bestrelpath() -> None:
|
||||||
|
curdir = Path("/foo/bar/baz/path")
|
||||||
|
assert bestrelpath(curdir, curdir) == "."
|
||||||
|
assert bestrelpath(curdir, curdir / "hello" / "world") == "hello" + os.sep + "world"
|
||||||
|
assert bestrelpath(curdir, curdir.parent / "sister") == ".." + os.sep + "sister"
|
||||||
|
assert bestrelpath(curdir, curdir.parent) == ".."
|
||||||
|
assert bestrelpath(curdir, Path("hello")) == "hello"
|
||||||
|
|
||||||
|
|
||||||
|
def test_commonpath() -> None:
|
||||||
|
path = Path("/foo/bar/baz/path")
|
||||||
|
subpath = path / "sampledir"
|
||||||
|
assert commonpath(path, subpath) == path
|
||||||
|
assert commonpath(subpath, path) == path
|
||||||
|
assert commonpath(Path(str(path) + "suffix"), path) == path.parent
|
||||||
|
assert commonpath(path, path.parent.parent) == path.parent.parent
|
||||||
|
|
Loading…
Reference in New Issue