Skip to content

Commit 95a824d

Browse files
committed
Move pathlib compatibility code to dedicated module
`piptools._compat.path_compat` is a new module for holding any helpers dedicated to path inspection and manipulations.
1 parent 21e5b23 commit 95a824d

File tree

3 files changed

+40
-29
lines changed

3 files changed

+40
-29
lines changed

piptools/_compat/path_compat.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""
2+
Compatibility helpers for working with paths and ``pathlib`` across platforms
3+
and Python versions.
4+
"""
5+
6+
from __future__ import annotations
7+
8+
import os.path
9+
import pathlib
10+
import sys
11+
12+
13+
def relative_to_walk_up(path: pathlib.Path, start: pathlib.Path) -> pathlib.Path:
14+
"""
15+
Compute a relative path allowing for the input to not be a subpath of the start.
16+
17+
This is a compatibility helper for ``pathlib.Path.relative_to(..., walk_up=True)``
18+
on all Python versions. (``walk_up: bool`` is Python 3.12+)
19+
"""
20+
# prefer `pathlib.Path.relative_to` where available
21+
if sys.version_info >= (3, 12):
22+
return path.relative_to(start, walk_up=True)
23+
24+
str_result = os.path.relpath(path, start=start)
25+
return pathlib.Path(str_result)
26+
27+
28+
def is_path_relative_to(path1: pathlib.Path, path2: pathlib.Path) -> bool:
29+
"""Return True if ``path1`` is relative to ``path2``."""
30+
# TODO: remove this function in favor of Path.is_relative_to()
31+
# when we drop support for Python 3.8
32+
try:
33+
path1.relative_to(path2)
34+
except ValueError:
35+
return False
36+
return True

piptools/_compat/pip_compat.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
from __future__ import annotations
22

33
import optparse
4-
import os.path
54
import pathlib
6-
import sys
75
import urllib.parse
86
from dataclasses import dataclass
97
from typing import TYPE_CHECKING, Callable, Iterable, Iterator, Set, cast
@@ -20,6 +18,8 @@
2018
from pip._internal.req.constructors import install_req_from_parsed_requirement
2119
from pip._vendor.pkg_resources import Requirement
2220

21+
from .path_compat import relative_to_walk_up
22+
2323
# The Distribution interface has changed between pkg_resources and
2424
# importlib.metadata, so this compat layer allows for a consistent access
2525
# pattern. In pip 22.1, importlib.metadata became the default on Python 3.11
@@ -154,7 +154,7 @@ def _relativize_comes_from_location(original_comes_from: str, /) -> str:
154154
return f"{prefix} {file_path.as_posix()}"
155155

156156
# make it relative to the current working dir
157-
suffix = _relative_to_walk_up(file_path, pathlib.Path.cwd()).as_posix()
157+
suffix = relative_to_walk_up(file_path, pathlib.Path.cwd()).as_posix()
158158
return f"{prefix}{space_sep}{suffix}"
159159

160160

@@ -212,18 +212,3 @@ def get_dev_pkgs() -> set[str]:
212212
from pip._internal.commands.freeze import _dev_pkgs
213213

214214
return cast(Set[str], _dev_pkgs())
215-
216-
217-
def _relative_to_walk_up(path: pathlib.Path, start: pathlib.Path) -> pathlib.Path:
218-
"""
219-
Compute a relative path allowing for the input to not be a subpath of the start.
220-
221-
This is a compatibility helper for ``pathlib.Path.relative_to(..., walk_up=True)``
222-
on all Python versions. (``walk_up: bool`` is Python 3.12+)
223-
"""
224-
# prefer `pathlib.Path.relative_to` where available
225-
if sys.version_info >= (3, 12):
226-
return path.relative_to(start, walk_up=True)
227-
228-
str_result = os.path.relpath(path, start=start)
229-
return pathlib.Path(str_result)

piptools/utils.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from pip._vendor.packaging.version import parse as parse_version
3838
from pip._vendor.pkg_resources import get_distribution
3939

40+
from piptools._compat.path_compat import is_path_relative_to
4041
from piptools.locations import DEFAULT_CONFIG_FILE_NAMES
4142
from piptools.subprocess_utils import run_python_snippet
4243

@@ -757,14 +758,3 @@ def _normalize_config_key(key: str) -> str:
757758
def _convert_to_long_option(key: str) -> str:
758759
"""Transform given ``some-key`` into ``--some-key``."""
759760
return "--" + key.lstrip("-").replace("_", "-").lower()
760-
761-
762-
def is_path_relative_to(path1: Path, path2: Path) -> bool:
763-
"""Return True if ``path1`` is relative to ``path2``."""
764-
# TODO: remove this function in favor of Path.is_relative_to()
765-
# when we drop support for Python 3.8
766-
try:
767-
path1.relative_to(path2)
768-
except ValueError:
769-
return False
770-
return True

0 commit comments

Comments
 (0)