Skip to content

Commit c5abdda

Browse files
authored
Merge pull request #10186 from uranusjr/new-resolver-file-link-localhost
2 parents e689113 + be89ea5 commit c5abdda

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

news/10162.bugfix.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
New resolver: URL comparison logic now treats ``file://localhost/`` and
2+
``file:///`` as equivalent to conform to RFC 8089.

src/pip/_internal/models/link.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ class _CleanResult(NamedTuple):
260260
def from_link(cls, link: Link) -> "_CleanResult":
261261
parsed = link._parsed_url
262262
netloc = parsed.netloc.rsplit("@", 1)[-1]
263+
# According to RFC 8089, an empty host in file: means localhost.
264+
if parsed.scheme == "file" and not netloc:
265+
netloc = "localhost"
263266
fragment = urllib.parse.parse_qs(parsed.fragment)
264267
if "egg" in fragment:
265268
logger.debug("Ignoring egg= fragment in %s", link)

tests/functional/test_new_resolver.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
import pathlib
23
import sys
34
import textwrap
45

@@ -1962,3 +1963,49 @@ def test_new_resolver_transitively_depends_on_unnamed_local(script):
19621963
certbot_apache="99.99.0.dev0",
19631964
certbot_docs="1",
19641965
)
1966+
1967+
1968+
def _to_uri(path):
1969+
# Something like file:///path/to/package
1970+
return pathlib.Path(path).as_uri()
1971+
1972+
1973+
def _to_localhost_uri(path):
1974+
# Something like file://localhost/path/to/package
1975+
return pathlib.Path(path).as_uri().replace("///", "//localhost/")
1976+
1977+
1978+
@pytest.mark.parametrize(
1979+
"format_dep",
1980+
[
1981+
pytest.param(_to_uri, id="emptyhost"),
1982+
pytest.param(_to_localhost_uri, id="localhost"),
1983+
],
1984+
)
1985+
@pytest.mark.parametrize(
1986+
"format_input",
1987+
[
1988+
pytest.param(lambda path: path, id="path"),
1989+
pytest.param(_to_uri, id="emptyhost"),
1990+
pytest.param(_to_localhost_uri, id="localhost"),
1991+
],
1992+
)
1993+
def test_new_resolver_file_url_normalize(script, format_dep, format_input):
1994+
lib_a = create_test_package_with_setup(
1995+
script,
1996+
name="lib_a",
1997+
version="1",
1998+
)
1999+
lib_b = create_test_package_with_setup(
2000+
script,
2001+
name="lib_b",
2002+
version="1",
2003+
install_requires=[f"lib_a @ {format_dep(lib_a)}"],
2004+
)
2005+
2006+
script.pip(
2007+
"install",
2008+
"--no-cache-dir", "--no-index",
2009+
format_input(lib_a), lib_b,
2010+
)
2011+
script.assert_installed(lib_a="1", lib_b="1")

0 commit comments

Comments
 (0)