Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace captured_output() and get_url_scheme() with stdlib alternatives #12639

Merged
merged 4 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/c678d9e3-4844-4298-a46c-80768b38f652.trivial.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Replace ``captured_output()`` and ``get_url_scheme()`` with stdlib alternatives.
4 changes: 1 addition & 3 deletions src/pip/_internal/req/req_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
from pip._internal.exceptions import InstallationError, RequirementsFileParseError
from pip._internal.models.search_scope import SearchScope
from pip._internal.utils.encoding import auto_decode
from pip._internal.utils.urls import get_url_scheme

if TYPE_CHECKING:
from pip._internal.index.package_finder import PackageFinder
Expand Down Expand Up @@ -533,8 +532,7 @@ def get_file_content(url: str, session: "PipSession") -> Tuple[str, str]:
:param url: File path or url.
:param session: PipSession instance.
"""
scheme = get_url_scheme(url)

scheme = urllib.parse.urlsplit(url).scheme
# Pip has special support for file:// URLs (LocalFSAdapter).
if scheme in ["http", "https", "file"]:
# Delay importing heavy network modules until absolutely necessary.
Expand Down
29 changes: 6 additions & 23 deletions src/pip/_internal/utils/misc.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import contextlib
import errno
import getpass
import hashlib
Expand All @@ -11,6 +10,7 @@
import sys
import sysconfig
import urllib.parse
from contextlib import redirect_stderr, redirect_stdout
from dataclasses import dataclass
from functools import partial
from io import StringIO
Expand Down Expand Up @@ -400,38 +400,21 @@ def encoding(self) -> str: # type: ignore
return self.orig_stream.encoding


@contextlib.contextmanager
def captured_output(stream_name: str) -> Generator[StreamWrapper, None, None]:
"""Return a context manager used by captured_stdout/stdin/stderr
that temporarily replaces the sys stream *stream_name* with a StringIO.

Taken from Lib/support/__init__.py in the CPython repo.
"""
orig_stdout = getattr(sys, stream_name)
setattr(sys, stream_name, StreamWrapper.from_stream(orig_stdout))
try:
yield getattr(sys, stream_name)
finally:
setattr(sys, stream_name, orig_stdout)


def captured_stdout() -> ContextManager[StreamWrapper]:
"""Capture the output of sys.stdout:
ichard26 marked this conversation as resolved.
Show resolved Hide resolved

with captured_stdout() as stdout:
print('hello')
self.assertEqual(stdout.getvalue(), 'hello\n')

Taken from Lib/support/__init__.py in the CPython repo.
with captured_stdout() as stdout:
print('hello')
self.assertEqual(stdout.getvalue(), 'hello\n')
"""
return captured_output("stdout")
return redirect_stdout(StreamWrapper.from_stream(sys.stdout))


def captured_stderr() -> ContextManager[StreamWrapper]:
"""
See captured_stdout().
"""
return captured_output("stderr")
return redirect_stderr(StreamWrapper.from_stream(sys.stderr))


# Simulates an enum
Expand Down
7 changes: 0 additions & 7 deletions src/pip/_internal/utils/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,10 @@
import string
import urllib.parse
import urllib.request
from typing import Optional

from .compat import WINDOWS


def get_url_scheme(url: str) -> Optional[str]:
if ":" not in url:
return None
return url.split(":", 1)[0].lower()


def path_to_url(path: str) -> str:
"""
Convert a path to a file: URL. The path will be made absolute and have
Expand Down
5 changes: 2 additions & 3 deletions src/pip/_internal/vcs/versioncontrol.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
format_command_args,
make_command,
)
from pip._internal.utils.urls import get_url_scheme

__all__ = ["vcs"]

Expand All @@ -52,8 +51,8 @@ def is_url(name: str) -> bool:
"""
Return true if the name looks like a URL.
"""
scheme = get_url_scheme(name)
if scheme is None:
scheme = urllib.parse.urlsplit(name).scheme
if not scheme:
return False
return scheme in ["http", "https", "file", "ftp"] + vcs.all_schemes

Expand Down
16 changes: 1 addition & 15 deletions tests/unit/test_urls.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,10 @@
import os
import sys
import urllib.request
from typing import Optional

import pytest

from pip._internal.utils.urls import get_url_scheme, path_to_url, url_to_path


@pytest.mark.parametrize(
"url,expected",
[
("http://localhost:8080/", "http"),
("file:c:/path/to/file", "file"),
("file:/dev/null", "file"),
("", None),
],
)
def test_get_url_scheme(url: str, expected: Optional[str]) -> None:
assert get_url_scheme(url) == expected
from pip._internal.utils.urls import path_to_url, url_to_path


@pytest.mark.skipif("sys.platform == 'win32'")
Expand Down
Loading