This commit is contained in:
Luis Carlos 2023-11-28 16:33:33 +01:00 committed by GitHub
commit 1134811ef9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 69 additions and 1 deletions

1
news/5378.feature.rst Normal file
View File

@ -0,0 +1 @@
Add ``--no-proxy`` option to bypass http proxy. Using this option will ignore any configured http proxies, including any enviromental variables

View File

@ -274,6 +274,15 @@ proxy: Callable[..., Option] = partial(
help="Specify a proxy in the form scheme://[user:passwd@]proxy.server:port.", help="Specify a proxy in the form scheme://[user:passwd@]proxy.server:port.",
) )
no_proxy: Callable[..., Option] = partial(
Option,
"--no-proxy",
dest="no_proxy",
action="store_true",
default=False,
help="Ignore all configured proxy settings, including enviromental variables.",
)
retries: Callable[..., Option] = partial( retries: Callable[..., Option] = partial(
Option, Option,
"--retries", "--retries",
@ -1047,6 +1056,7 @@ general_group: Dict[str, Any] = {
no_input, no_input,
keyring_provider, keyring_provider,
proxy, proxy,
no_proxy,
retries, retries,
timeout, timeout,
exists_action, exists_action,

View File

@ -146,6 +146,14 @@ class SessionCommandMixin(CommandContextMixIn):
"https": options.proxy, "https": options.proxy,
} }
# Handle no proxy option
if options.no_proxy:
session.trust_env = False
session.proxies = {
"http": None,
"https": None,
}
# Determine if we can prompt the user for authentication or not # Determine if we can prompt the user for authentication or not
session.auth.prompting = not options.no_input session.auth.prompting = not options.no_input
session.auth.keyring_provider = options.keyring_provider session.auth.keyring_provider = options.keyring_provider

View File

@ -95,6 +95,12 @@ def pytest_addoption(parser: Parser) -> None:
default=None, default=None,
help="use given proxy in session network tests", help="use given proxy in session network tests",
) )
parser.addoption(
"--no-proxy",
action="store_true",
default=False,
help="ignore any configured proxies in session network tests",
)
parser.addoption( parser.addoption(
"--use-zipapp", "--use-zipapp",
action="store_true", action="store_true",

View File

@ -1,7 +1,7 @@
import logging import logging
import os import os
from pathlib import Path from pathlib import Path
from typing import Any, List, Optional from typing import Any, List, Optional, Union
from urllib.parse import urlparse from urllib.parse import urlparse
from urllib.request import getproxies from urllib.request import getproxies
@ -274,3 +274,39 @@ class TestPipSession:
f"Invalid proxy {proxy} or session.proxies: " f"Invalid proxy {proxy} or session.proxies: "
f"{session.proxies} is not correctly passed to session.request." f"{session.proxies} is not correctly passed to session.request."
) )
@pytest.mark.network
def test_no_proxy(self) -> None:
def _set_no_proxy(session: PipSession) -> PipSession:
"""Mimic logic for command line `no_proxy` option"""
session.trust_env = False
session.proxies = {
"http": None,
"https": None,
}
return session
session = PipSession(trusted_hosts=[])
connection_error_http: Union[requests.exceptions.RequestException, None] = None
# setup with known bad (hopefully) http proxy, and then test connection
# expecting a failure if the proxy is used
with requests.utils.set_environ("http_proxy", "http://127.0.0.1:8888"):
try:
session = _set_no_proxy(session)
session.request("GET", "https://pypi.org", timeout=1)
except requests.exceptions.ConnectionError as e:
connection_error_http = e
connection_error_https: Union[requests.exceptions.RequestException, None] = None
# setup with known bad (hopefully) https proxy, and then test connection
# expecting a failure if the proxy is used
with requests.utils.set_environ("https_proxy", "http://127.0.0.1:8888"):
try:
session = _set_no_proxy(session)
session.request("GET", "https://pypi.org", timeout=1)
except requests.exceptions.ConnectionError as e:
connection_error_https = e
assert connection_error_http is None, "Unexpected use of http proxy"
assert connection_error_https is None, "Unexpected use of https proxy"

View File

@ -523,6 +523,13 @@ class TestGeneralOptions(AddFakeCommandMixin):
) )
assert options1.proxy == options2.proxy == "path" assert options1.proxy == options2.proxy == "path"
def test_no_proxy(self) -> None:
# FakeCommand intentionally returns the wrong type.
options1, args1 = cast(Tuple[Values, List[str]], main(["--no-proxy", "fake"]))
options2, args2 = cast(Tuple[Values, List[str]], main(["fake", "--no-proxy"]))
assert options1.no_proxy
assert options2.no_proxy
def test_retries(self) -> None: def test_retries(self) -> None:
# FakeCommand intentionally returns the wrong type. # FakeCommand intentionally returns the wrong type.
options1, args1 = cast( options1, args1 = cast(