From 3a15e010916f3fd40a37b4458ad9a35696241f0b Mon Sep 17 00:00:00 2001 From: Judah Rand <17158624+judahrand@users.noreply.github.com> Date: Thu, 10 Nov 2022 19:15:07 +0000 Subject: [PATCH] Get the tests passing again --- src/pip/_internal/network/auth.py | 17 ++++++++++++++--- tests/unit/test_network_auth.py | 25 +++++++++++++++++-------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/pip/_internal/network/auth.py b/src/pip/_internal/network/auth.py index bda61534705..99fd9977c75 100644 --- a/src/pip/_internal/network/auth.py +++ b/src/pip/_internal/network/auth.py @@ -28,6 +28,8 @@ logger = getLogger(__name__) +KEYRING_DISABLED = False + class Credentials(NamedTuple): url: str @@ -174,11 +176,20 @@ def get_keyring_auth(url: Optional[str], username: Optional[str]) -> Optional[Au return None keyring = get_keyring_provider() - # Do nothin if keyring is not available - if keyring is None: + # Do nothing if keyring is not available + global KEYRING_DISABLED + if keyring is None or KEYRING_DISABLED: return None - return keyring.get_auth_info(url, username) + try: + return keyring.get_auth_info(url, username) + except Exception as exc: + logger.warning( + "Keyring is skipped due to an exception: %s", + str(exc), + ) + KEYRING_DISABLED = True + return None class MultiDomainBasicAuth(AuthBase): diff --git a/tests/unit/test_network_auth.py b/tests/unit/test_network_auth.py index 5c0e5746281..03d39c452a2 100644 --- a/tests/unit/test_network_auth.py +++ b/tests/unit/test_network_auth.py @@ -1,5 +1,6 @@ import functools -from typing import Any, List, Optional, Tuple +import sys +from typing import Any, Iterable, List, Optional, Tuple import pytest @@ -8,6 +9,14 @@ from tests.lib.requests_mocks import MockConnection, MockRequest, MockResponse +@pytest.fixture(scope="function", autouse=True) +def reset_keyring() -> Iterable[None]: + yield None + # Reset the state of the module between tests + pip._internal.network.auth.KEYRING_DISABLED = False + pip._internal.network.auth.get_keyring_provider.cache_clear() + + @pytest.mark.parametrize( ["input_url", "url", "username", "password"], [ @@ -138,7 +147,7 @@ def test_keyring_get_password( expect: Tuple[Optional[str], Optional[str]], ) -> None: keyring = KeyringModuleV1() - monkeypatch.setattr("pip._internal.network.auth.keyring", keyring) + monkeypatch.setitem(sys.modules, "keyring", keyring) # type: ignore[misc] auth = MultiDomainBasicAuth(index_urls=["http://example.com/path2"]) actual = auth._get_new_credentials(url, allow_netrc=False, allow_keyring=True) @@ -147,7 +156,7 @@ def test_keyring_get_password( def test_keyring_get_password_after_prompt(monkeypatch: pytest.MonkeyPatch) -> None: keyring = KeyringModuleV1() - monkeypatch.setattr("pip._internal.network.auth.keyring", keyring) + monkeypatch.setitem(sys.modules, "keyring", keyring) # type: ignore[misc] auth = MultiDomainBasicAuth() def ask_input(prompt: str) -> str: @@ -163,7 +172,7 @@ def test_keyring_get_password_after_prompt_when_none( monkeypatch: pytest.MonkeyPatch, ) -> None: keyring = KeyringModuleV1() - monkeypatch.setattr("pip._internal.network.auth.keyring", keyring) + monkeypatch.setitem(sys.modules, "keyring", keyring) # type: ignore[misc] auth = MultiDomainBasicAuth() def ask_input(prompt: str) -> str: @@ -184,7 +193,7 @@ def test_keyring_get_password_username_in_index( monkeypatch: pytest.MonkeyPatch, ) -> None: keyring = KeyringModuleV1() - monkeypatch.setattr("pip._internal.network.auth.keyring", keyring) + monkeypatch.setitem(sys.modules, "keyring", keyring) # type: ignore[misc] auth = MultiDomainBasicAuth(index_urls=["http://user@example.com/path2"]) get = functools.partial( auth._get_new_credentials, allow_netrc=False, allow_keyring=True @@ -217,7 +226,7 @@ def test_keyring_set_password( expect_save: bool, ) -> None: keyring = KeyringModuleV1() - monkeypatch.setattr("pip._internal.network.auth.keyring", keyring) + monkeypatch.setitem(sys.modules, "keyring", keyring) # type: ignore[misc] auth = MultiDomainBasicAuth(prompting=True) monkeypatch.setattr(auth, "_get_url_and_credentials", lambda u: (u, None, None)) monkeypatch.setattr(auth, "_prompt_for_password", lambda *a: creds) @@ -293,7 +302,7 @@ def get_credential(self, system: str, username: str) -> Optional[Credential]: def test_keyring_get_credential( monkeypatch: pytest.MonkeyPatch, url: str, expect: str ) -> None: - monkeypatch.setattr(pip._internal.network.auth, "keyring", KeyringModuleV2()) + monkeypatch.setitem(sys.modules, "keyring", KeyringModuleV2()) # type: ignore[misc] auth = MultiDomainBasicAuth(index_urls=["http://example.com/path2"]) assert ( @@ -314,7 +323,7 @@ def get_credential(self, system: str, username: str) -> None: def test_broken_keyring_disables_keyring(monkeypatch: pytest.MonkeyPatch) -> None: keyring_broken = KeyringModuleBroken() - monkeypatch.setattr(pip._internal.network.auth, "keyring", keyring_broken) + monkeypatch.setitem(sys.modules, "keyring", keyring_broken) # type: ignore[misc] auth = MultiDomainBasicAuth(index_urls=["http://example.com/"])