diff --git a/news/3931.bugfix.rst b/news/3931.bugfix.rst new file mode 100644 index 00000000000..0ebb9e495e6 --- /dev/null +++ b/news/3931.bugfix.rst @@ -0,0 +1 @@ +Prefer credentials from the URL over the previously-obtained credentials from URLs of the same domain, so it is possible to use different credentials on the same index server for different ``--extra-index-url`` options. diff --git a/src/pip/_internal/network/auth.py b/src/pip/_internal/network/auth.py index bd54a5cba99..819687bae18 100644 --- a/src/pip/_internal/network/auth.py +++ b/src/pip/_internal/network/auth.py @@ -170,13 +170,12 @@ def _get_url_and_credentials(self, original_url): """ url, netloc, _ = split_auth_netloc_from_url(original_url) - # Use any stored credentials that we have for this netloc - username, password = self.passwords.get(netloc, (None, None)) + # Try to get credentials from original url + username, password = self._get_new_credentials(original_url) + # If credentials not found, use any stored credentials for this netloc if username is None and password is None: - # No stored credentials. Acquire new credentials without prompting - # the user. (e.g. from netrc, keyring, or the URL itself) - username, password = self._get_new_credentials(original_url) + username, password = self.passwords.get(netloc, (None, None)) if username is not None or password is not None: # Convert the username and password if they're None, so that diff --git a/tests/unit/test_network_auth.py b/tests/unit/test_network_auth.py index 44c739d864f..ce528d0ac11 100644 --- a/tests/unit/test_network_auth.py +++ b/tests/unit/test_network_auth.py @@ -47,11 +47,29 @@ def test_get_credentials_parses_correctly(input_url, url, username, password): ) -def test_get_credentials_uses_cached_credentials(): +def test_get_credentials_not_to_uses_cached_credentials(): auth = MultiDomainBasicAuth() auth.passwords['example.com'] = ('user', 'pass') got = auth._get_url_and_credentials("http://foo:bar@example.com/path") + expected = ('http://example.com/path', 'foo', 'bar') + assert got == expected + + +def test_get_credentials_not_to_uses_cached_credentials_only_username(): + auth = MultiDomainBasicAuth() + auth.passwords['example.com'] = ('user', 'pass') + + got = auth._get_url_and_credentials("http://foo@example.com/path") + expected = ('http://example.com/path', 'foo', '') + assert got == expected + + +def test_get_credentials_uses_cached_credentials(): + auth = MultiDomainBasicAuth() + auth.passwords['example.com'] = ('user', 'pass') + + got = auth._get_url_and_credentials("http://example.com/path") expected = ('http://example.com/path', 'user', 'pass') assert got == expected