mirror of https://github.com/pypa/pip
Merge pull request #11073 from wimglenn/issue-9330
``pip config`` normalizes names, converting underscores into dashes
This commit is contained in:
commit
bab5bfce50
|
@ -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
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
``pip config`` now normalizes names by converting underscores into dashes.
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue