Merge pull request #11073 from wimglenn/issue-9330

``pip config`` normalizes names, converting underscores into dashes
This commit is contained in:
Pradyun Gedam 2022-05-04 08:39:33 +01:00 committed by GitHub
commit bab5bfce50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 8 deletions

View File

@ -88,7 +88,7 @@ The contents of this file are reStructuredText formatted text that
will be used as the content of the news file entry. You do not need to
reference the issue or PR numbers in the entry, since ``towncrier``
will automatically add a reference to all of the affected issues when
rendering the NEWS file.
rendering the NEWS file. There must be a newline at the end of the file.
In order to maintain a consistent style in the ``NEWS.rst`` file, it is
preferred to keep the news entry to the point, in sentence case, shorter than

1
news/9330.bugfix.rst Normal file
View File

@ -0,0 +1 @@
``pip config`` now normalizes names by converting underscores into dashes.

View File

@ -142,13 +142,19 @@ class Configuration:
def get_value(self, key: str) -> Any:
"""Get a value from the configuration."""
orig_key = key
key = _normalize_name(key)
try:
return self._dictionary[key]
except KeyError:
raise ConfigurationError(f"No such key - {key}")
# disassembling triggers a more useful error message than simply
# "No such key" in the case that the key isn't in the form command.option
_disassemble_key(key)
raise ConfigurationError(f"No such key - {orig_key}")
def set_value(self, key: str, value: Any) -> None:
"""Modify a value in the configuration."""
key = _normalize_name(key)
self._ensure_have_load_only()
assert self.load_only
@ -167,11 +173,13 @@ class Configuration:
def unset_value(self, key: str) -> None:
"""Unset a value in the configuration."""
orig_key = key
key = _normalize_name(key)
self._ensure_have_load_only()
assert self.load_only
if key not in self._config[self.load_only]:
raise ConfigurationError(f"No such key - {key}")
raise ConfigurationError(f"No such key - {orig_key}")
fname, parser = self._get_parser_to_modify()

View File

@ -1,6 +1,7 @@
"""Tests for all things related to the configuration
"""
import re
from unittest.mock import MagicMock
import pytest
@ -87,6 +88,25 @@ class TestConfigurationLoading(ConfigurationMixin):
err.value
)
def test_no_such_key_error_message_no_command(self) -> None:
self.configuration.load_only = kinds.GLOBAL
self.configuration.load()
expected_msg = (
"Key does not contain dot separated section and key. "
"Perhaps you wanted to use 'global.index-url' instead?"
)
pat = f"^{re.escape(expected_msg)}$"
with pytest.raises(ConfigurationError, match=pat):
self.configuration.get_value("index-url")
def test_no_such_key_error_message_missing_option(self) -> None:
self.configuration.load_only = kinds.GLOBAL
self.configuration.load()
expected_msg = "No such key - global.index-url"
pat = f"^{re.escape(expected_msg)}$"
with pytest.raises(ConfigurationError, match=pat):
self.configuration.get_value("global.index-url")
class TestConfigurationPrecedence(ConfigurationMixin):
# Tests for methods to that determine the order of precedence of
@ -185,12 +205,8 @@ class TestConfigurationModification(ConfigurationMixin):
def test_no_specific_given_modification(self) -> None:
self.configuration.load()
try:
with pytest.raises(ConfigurationError):
self.configuration.set_value("test.hello", "10")
except ConfigurationError:
pass
else:
assert False, "Should have raised an error."
def test_site_modification(self) -> None:
self.configuration.load_only = kinds.SITE
@ -241,3 +257,16 @@ class TestConfigurationModification(ConfigurationMixin):
# get the path to user config file
assert mymock.call_count == 1
assert mymock.call_args[0][0] == (get_configuration_files()[kinds.GLOBAL][-1])
def test_normalization(self) -> None:
# underscores and dashes can be used interchangeably.
# internally, underscores get converted into dashes before reading/writing file
self.configuration.load_only = kinds.GLOBAL
self.configuration.load()
self.configuration.set_value("global.index_url", "example.org")
assert self.configuration.get_value("global.index_url") == "example.org"
assert self.configuration.get_value("global.index-url") == "example.org"
self.configuration.unset_value("global.index-url")
pat = r"^No such key - global\.index-url$"
with pytest.raises(ConfigurationError, match=pat):
self.configuration.get_value("global.index-url")