Skip to content

Commit 4117dc7

Browse files
authored
Always remove authority section when cleaning local URL path (#13510)
pathname2url() generates a URL with an authority section on Windows (all versions) and non-Windows (3.12+ for paths beginning //, 3.14+ for paths beginning /). We need to strip this prefix in order to return a URL path rather than a complete URL.
1 parent 2e21934 commit 4117dc7

File tree

4 files changed

+9
-47
lines changed

4 files changed

+9
-47
lines changed

news/13510.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix normalization of local link on Windows in newer Python versions.

src/pip/_internal/models/link.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import os
77
import posixpath
88
import re
9-
import sys
109
import urllib.parse
1110
from collections.abc import Mapping
1211
from dataclasses import dataclass
@@ -133,8 +132,8 @@ def _clean_file_url_path(part: str) -> str:
133132
# exist, the colon should be quoted. We rely on urllib.request
134133
# to do the right thing here.
135134
ret = urllib.request.pathname2url(urllib.request.url2pathname(part))
136-
if sys.version_info >= (3, 14):
137-
# https://discuss.python.org/t/pathname2url-changes-in-python-3-14-breaking-pip-tests/97091
135+
if ret.startswith("///"):
136+
# Remove any URL authority section, leaving only the URL path.
138137
ret = ret.removeprefix("//")
139138
return ret
140139

tests/lib/__init__.py

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
from io import BytesIO, StringIO
1717
from textwrap import dedent
1818
from typing import Any, AnyStr, Callable, Literal, Protocol, Union, cast
19-
from urllib.parse import urlparse, urlunparse
2019
from urllib.request import pathname2url
2120
from zipfile import ZipFile
2221

@@ -1370,25 +1369,9 @@ def __call__(
13701369
# Accommodations for Windows path and URL changes in recent Python releases
13711370
# -------------------------------------------------------------------------
13721371

1373-
# versions containing fix/backport from https://github.com/python/cpython/pull/113563
1374-
# which changed the behavior of `urllib.parse.urlun{parse,split}`
1375-
url = "////path/to/file"
1376-
has_new_urlun_behavior = url == urlunparse(urlparse(url))
1377-
1378-
# the above change seems to only impact tests on Windows, so just add skips for that
1379-
skip_needs_new_urlun_behavior_win = pytest.mark.skipif(
1380-
sys.platform != "win32" or not has_new_urlun_behavior,
1381-
reason="testing windows behavior for newer CPython",
1382-
)
1383-
1384-
skip_needs_old_urlun_behavior_win = pytest.mark.skipif(
1385-
sys.platform != "win32" or has_new_urlun_behavior,
1386-
reason="testing windows behavior for older CPython",
1387-
)
1388-
13891372
# Trailing slashes are now preserved on Windows, matching POSIX behaviour.
13901373
# BPO: https://github.com/python/cpython/issues/126212
1391-
does_pathname2url_preserve_trailing_slash = pathname2url("C:/foo/").endswith("/")
1374+
does_pathname2url_preserve_trailing_slash = pathname2url("C:\\foo\\").endswith("/")
13921375
skip_needs_new_pathname2url_trailing_slash_behavior_win = pytest.mark.skipif(
13931376
sys.platform != "win32" or not does_pathname2url_preserve_trailing_slash,
13941377
reason="testing windows (pathname2url) behavior for newer CPython",

tests/unit/test_collector.py

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,7 @@
4242
TestData,
4343
make_test_link_collector,
4444
skip_needs_new_pathname2url_trailing_slash_behavior_win,
45-
skip_needs_new_urlun_behavior_win,
4645
skip_needs_old_pathname2url_trailing_slash_behavior_win,
47-
skip_needs_old_urlun_behavior_win,
4846
)
4947

5048
ACCEPT = ", ".join(
@@ -309,7 +307,7 @@ def test_clean_url_path(path: str, expected: str, is_local_path: bool) -> None:
309307
# Test a VCS path with a Windows drive letter and revision.
310308
pytest.param(
311309
"/T:/with space/[email protected]",
312-
"///T:/with%20space/[email protected]",
310+
"/T:/with%20space/[email protected]",
313311
marks=pytest.mark.skipif("sys.platform != 'win32'"),
314312
),
315313
# Test a VCS path with a Windows drive letter and revision,
@@ -393,26 +391,12 @@ def test_clean_url_path_with_local_path(path: str, expected: str) -> None:
393391
pytest.param(
394392
"file:///T:/path/with spaces/",
395393
"file:///T:/path/with%20spaces",
396-
marks=[
397-
skip_needs_old_urlun_behavior_win,
398-
skip_needs_old_pathname2url_trailing_slash_behavior_win,
399-
],
400-
),
401-
pytest.param(
402-
"file:///T:/path/with spaces/",
403-
"file://///T:/path/with%20spaces",
404-
marks=[
405-
skip_needs_new_urlun_behavior_win,
406-
skip_needs_old_pathname2url_trailing_slash_behavior_win,
407-
],
394+
marks=skip_needs_old_pathname2url_trailing_slash_behavior_win,
408395
),
409396
pytest.param(
410397
"file:///T:/path/with spaces/",
411-
"file://///T:/path/with%20spaces/",
412-
marks=[
413-
skip_needs_new_urlun_behavior_win,
414-
skip_needs_new_pathname2url_trailing_slash_behavior_win,
415-
],
398+
"file:///T:/path/with%20spaces/",
399+
marks=skip_needs_new_pathname2url_trailing_slash_behavior_win,
416400
),
417401
# URL with Windows drive letter, running on non-windows
418402
# platform. The `:` after the drive should be quoted.
@@ -425,12 +409,7 @@ def test_clean_url_path_with_local_path(path: str, expected: str) -> None:
425409
pytest.param(
426410
"git+file:///T:/with space/[email protected]#egg=my-package-1.0",
427411
"git+file:///T:/with%20space/[email protected]#egg=my-package-1.0",
428-
marks=skip_needs_old_urlun_behavior_win,
429-
),
430-
pytest.param(
431-
"git+file:///T:/with space/[email protected]#egg=my-package-1.0",
432-
"git+file://///T:/with%20space/[email protected]#egg=my-package-1.0",
433-
marks=skip_needs_new_urlun_behavior_win,
412+
marks=pytest.mark.skipif("sys.platform != 'win32'"),
434413
),
435414
# Test a VCS URL with a Windows drive letter and revision,
436415
# running on non-windows platform.

0 commit comments

Comments
 (0)