From fffd5ac422f2bf7a55175149e221c08986472072 Mon Sep 17 00:00:00 2001 From: Thiago Date: Fri, 11 Mar 2022 16:04:21 +0100 Subject: [PATCH] Pass the session's proxies property to request (#10680) --- news/9691.bugfix.rst | 1 + src/pip/_internal/network/session.py | 2 ++ tests/conftest.py | 11 ++++++++++ tests/unit/test_network_session.py | 33 +++++++++++++++++++++++++++- 4 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 news/9691.bugfix.rst diff --git a/news/9691.bugfix.rst b/news/9691.bugfix.rst new file mode 100644 index 00000000000..6a07d49c83a --- /dev/null +++ b/news/9691.bugfix.rst @@ -0,0 +1 @@ +Fix pip install issues using a proxy due to an inconsistency in how Requests is currently handling variable precedence in session. diff --git a/src/pip/_internal/network/session.py b/src/pip/_internal/network/session.py index cbe743ba6a1..e06ac2d3ee1 100644 --- a/src/pip/_internal/network/session.py +++ b/src/pip/_internal/network/session.py @@ -449,6 +449,8 @@ def is_secure_origin(self, location: Link) -> bool: def request(self, method: str, url: str, *args: Any, **kwargs: Any) -> Response: # Allow setting a default timeout on a session kwargs.setdefault("timeout", self.timeout) + # Allow setting a default proxies on a session + kwargs.setdefault("proxies", self.proxies) # Dispatch the actual request return super().request(method, url, *args, **kwargs) diff --git a/tests/conftest.py b/tests/conftest.py index b084d3f9927..04b1b6e7058 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -70,6 +70,12 @@ def pytest_addoption(parser: Parser) -> None: default=False, help="run 'pip search' tests", ) + parser.addoption( + "--proxy", + action="store", + default=None, + help="use given proxy in session network tests", + ) def pytest_collection_modifyitems(config: Config, items: List[pytest.Item]) -> None: @@ -628,3 +634,8 @@ def utc() -> Iterator[None]: tzset() yield tzset() + + +@pytest.fixture +def proxy(request: pytest.FixtureRequest) -> str: + return request.config.getoption("proxy") diff --git a/tests/unit/test_network_session.py b/tests/unit/test_network_session.py index f16843abfb1..18eb9539f7f 100644 --- a/tests/unit/test_network_session.py +++ b/tests/unit/test_network_session.py @@ -1,7 +1,10 @@ import logging -from typing import Any, List +from typing import Any, List, Optional +from urllib.parse import urlparse +from urllib.request import getproxies import pytest +from pip._vendor import requests from pip import __version__ from pip._internal.models.link import Link @@ -242,3 +245,31 @@ def warning(self, *args: Any, **kwargs: Any) -> None: actual_level, actual_message = log_records[0] assert actual_level == "WARNING" assert "is not a trusted or secure host" in actual_message + + @pytest.mark.network + def test_proxy(self, proxy: Optional[str]) -> None: + session = PipSession(trusted_hosts=[]) + + if not proxy: + # if user didn't pass --proxy then try to get it from the system. + env_proxy = getproxies().get("http", None) + proxy = urlparse(env_proxy).netloc if env_proxy else None + + if proxy: + # set proxy scheme to session.proxies + session.proxies = { + "http": f"{proxy}", + "https": f"{proxy}", + "ftp": f"{proxy}", + } + + connection_error = None + try: + session.request("GET", "https://pypi.org", timeout=1) + except requests.exceptions.ConnectionError as e: + connection_error = e + + assert connection_error is None, ( + f"Invalid proxy {proxy} or session.proxies: " + f"{session.proxies} is not correctly passed to session.request." + )