Skip to content

Commit 14b5170

Browse files
committed
Correctly assign configuration to origin files with pip config
1 parent 3c0147a commit 14b5170

File tree

4 files changed

+69
-28
lines changed

4 files changed

+69
-28
lines changed

news/12099.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This change will fix incorrect output of the ``pip config debug`` command.

src/pip/_internal/cli/parser.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -185,23 +185,38 @@ def _get_ordered_configuration_items(
185185
section_items: Dict[str, List[Tuple[str, Any]]] = {
186186
name: [] for name in override_order
187187
}
188-
for section_key, val in self.config.items():
189-
# ignore empty values
190-
if not val:
191-
logger.debug(
192-
"Ignoring configuration key '%s' as it's value is empty.",
193-
section_key,
194-
)
195-
continue
196188

197-
section, key = section_key.split(".", 1)
198-
if section in override_order:
199-
section_items[section].append((key, val))
189+
for key, value in self.config.items():
190+
if not isinstance(value, dict):
191+
# ignore empty values
192+
if not value:
193+
logger.debug(
194+
"Ignoring configuration key '%s' as it's value is empty.",
195+
key,
196+
)
197+
continue
200198

201-
# Yield each group in their override order
202-
for section in override_order:
203-
for key, val in section_items[section]:
204-
yield key, val
199+
section, key = key.split(".", 1)
200+
if section in override_order:
201+
section_items[section].append((key, value))
202+
else:
203+
for section_key, val in value.items():
204+
# ignore empty values
205+
if not val:
206+
logger.debug(
207+
"Ignoring configuration key '%s' as it's value is empty.",
208+
section_key,
209+
)
210+
continue
211+
212+
section, key = section_key.split(".", 1)
213+
if section in override_order:
214+
section_items[section].append((key, val))
215+
216+
# Yield each group in their override order
217+
for section in override_order:
218+
for key, val in section_items[section]:
219+
yield key, val
205220

206221
def _update_defaults(self, defaults: Dict[str, Any]) -> Dict[str, Any]:
207222
"""Updates the given defaults with values from the config files and

src/pip/_internal/commands/configuration.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,11 @@ def list_values(self, options: Values, args: List[str]) -> None:
172172
self._get_n_args(args, "list", n=0)
173173

174174
for key, value in sorted(self.configuration.items()):
175-
write_output("%s=%r", key, value)
175+
if isinstance(value, dict):
176+
for key, value in sorted(value.items()):
177+
write_output("%s=%r", key, value)
178+
else:
179+
write_output("%s=%r", key, value)
176180

177181
def get_name(self, options: Values, args: List[str]) -> None:
178182
key = self._get_n_args(args, "get [name]", n=1)
@@ -206,13 +210,15 @@ def list_config_values(self, options: Values, args: List[str]) -> None:
206210
file_exists = os.path.exists(fname)
207211
write_output("%s, exists: %r", fname, file_exists)
208212
if file_exists:
209-
self.print_config_file_values(variant)
213+
self.print_config_file_values(variant, fname)
210214

211-
def print_config_file_values(self, variant: Kind) -> None:
215+
def print_config_file_values(self, variant: Kind, fname: str) -> None:
212216
"""Get key-value pairs from the file of a variant"""
213217
for name, value in self.configuration.get_values_in_config(variant).items():
214218
with indent_log():
215-
write_output("%s: %s", name, value)
219+
if name == fname:
220+
for confname, confvalue in value.items():
221+
write_output("%s: %s", confname, confvalue)
216222

217223
def print_env_var_values(self) -> None:
218224
"""Get key-values pairs present as environment variables"""

src/pip/_internal/configuration.py

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def __init__(self, isolated: bool, load_only: Optional[Kind] = None) -> None:
114114
self._parsers: Dict[Kind, List[Tuple[str, RawConfigParser]]] = {
115115
variant: [] for variant in OVERRIDE_ORDER
116116
}
117-
self._config: Dict[Kind, Dict[str, Any]] = {
117+
self._config: Dict[Kind, Dict[str, Dict[str, Any]]] = {
118118
variant: {} for variant in OVERRIDE_ORDER
119119
}
120120
self._modified_parsers: List[Tuple[str, RawConfigParser]] = []
@@ -145,7 +145,14 @@ def get_value(self, key: str) -> Any:
145145
orig_key = key
146146
key = _normalize_name(key)
147147
try:
148-
return self._dictionary[key]
148+
clean_config = {}
149+
for k, value in self._dictionary.items():
150+
if isinstance(value, dict):
151+
for k, v in value.items():
152+
clean_config[k] = v
153+
else:
154+
clean_config[k] = value
155+
return clean_config[key]
149156
except KeyError:
150157
# disassembling triggers a more useful error message than simply
151158
# "No such key" in the case that the key isn't in the form command.option
@@ -168,7 +175,11 @@ def set_value(self, key: str, value: Any) -> None:
168175
parser.add_section(section)
169176
parser.set(section, name, value)
170177

171-
self._config[self.load_only][key] = value
178+
exists = self._config[self.load_only].get(fname)
179+
if not exists:
180+
self._config[self.load_only][fname] = {}
181+
182+
self._config[self.load_only][fname][key] = value
172183
self._mark_as_modified(fname, parser)
173184

174185
def unset_value(self, key: str) -> None:
@@ -178,11 +189,14 @@ def unset_value(self, key: str) -> None:
178189
self._ensure_have_load_only()
179190

180191
assert self.load_only
181-
if key not in self._config[self.load_only]:
182-
raise ConfigurationError(f"No such key - {orig_key}")
183-
184192
fname, parser = self._get_parser_to_modify()
185193

194+
if (
195+
key not in self._config[self.load_only][fname]
196+
and key not in self._config[self.load_only]
197+
):
198+
raise ConfigurationError(f"No such key - {orig_key}")
199+
186200
if parser is not None:
187201
section, name = _disassemble_key(key)
188202
if not (
@@ -197,8 +211,10 @@ def unset_value(self, key: str) -> None:
197211
if not parser.items(section):
198212
parser.remove_section(section)
199213
self._mark_as_modified(fname, parser)
200-
201-
del self._config[self.load_only][key]
214+
try:
215+
del self._config[self.load_only][fname][key]
216+
except KeyError:
217+
del self._config[self.load_only][key]
202218

203219
def save(self) -> None:
204220
"""Save the current in-memory state."""
@@ -270,7 +286,10 @@ def _load_file(self, variant: Kind, fname: str) -> RawConfigParser:
270286

271287
for section in parser.sections():
272288
items = parser.items(section)
273-
self._config[variant].update(self._normalized_keys(section, items))
289+
exists = self._config[variant].get(fname)
290+
if not exists:
291+
self._config[variant][fname] = {}
292+
self._config[variant][fname].update(self._normalized_keys(section, items))
274293

275294
return parser
276295

0 commit comments

Comments
 (0)