Voice et bot modif

This commit is contained in:
pi 2026-06-16 17:09:34 +00:00
parent 189d56026b
commit 7333a22bcd
10774 changed files with 634644 additions and 933308 deletions

View file

@ -11,14 +11,11 @@ Some terminology:
A single word describing where the configuration key-value pair came from
"""
from __future__ import annotations
import configparser
import locale
import os
import sys
from collections.abc import Iterable
from typing import Any, NewType
from typing import Any, Dict, Iterable, List, NewType, Optional, Tuple
from pip._internal.exceptions import (
ConfigurationError,
@ -53,11 +50,12 @@ logger = getLogger(__name__)
def _normalize_name(name: str) -> str:
"""Make a name consistent regardless of source (environment or file)"""
name = name.lower().replace("_", "-")
name = name.removeprefix("--") # only prefer long opts
if name.startswith("--"):
name = name[2:] # only prefer long opts
return name
def _disassemble_key(name: str) -> list[str]:
def _disassemble_key(name: str) -> List[str]:
if "." not in name:
error_message = (
"Key does not contain dot separated section and key. "
@ -67,7 +65,7 @@ def _disassemble_key(name: str) -> list[str]:
return name.split(".", 1)
def get_configuration_files() -> dict[Kind, list[str]]:
def get_configuration_files() -> Dict[Kind, List[str]]:
global_config_files = [
os.path.join(path, CONFIG_BASENAME) for path in appdirs.site_config_dirs("pip")
]
@ -100,7 +98,7 @@ class Configuration:
and the data stored is also nice.
"""
def __init__(self, isolated: bool, load_only: Kind | None = None) -> None:
def __init__(self, isolated: bool, load_only: Optional[Kind] = None) -> None:
super().__init__()
if load_only is not None and load_only not in VALID_LOAD_ONLY:
@ -113,13 +111,13 @@ class Configuration:
self.load_only = load_only
# Because we keep track of where we got the data from
self._parsers: dict[Kind, list[tuple[str, RawConfigParser]]] = {
self._parsers: Dict[Kind, List[Tuple[str, RawConfigParser]]] = {
variant: [] for variant in OVERRIDE_ORDER
}
self._config: dict[Kind, dict[str, dict[str, Any]]] = {
self._config: Dict[Kind, Dict[str, Any]] = {
variant: {} for variant in OVERRIDE_ORDER
}
self._modified_parsers: list[tuple[str, RawConfigParser]] = []
self._modified_parsers: List[Tuple[str, RawConfigParser]] = []
def load(self) -> None:
"""Loads configuration from configuration files and environment"""
@ -127,7 +125,7 @@ class Configuration:
if not self.isolated:
self._load_environment_vars()
def get_file_to_edit(self) -> str | None:
def get_file_to_edit(self) -> Optional[str]:
"""Returns the file with highest priority in configuration"""
assert self.load_only is not None, "Need to be specified a file to be editing"
@ -136,7 +134,7 @@ class Configuration:
except IndexError:
return None
def items(self) -> Iterable[tuple[str, Any]]:
def items(self) -> Iterable[Tuple[str, Any]]:
"""Returns key-value pairs like dict.items() representing the loaded
configuration
"""
@ -147,10 +145,7 @@ class Configuration:
orig_key = key
key = _normalize_name(key)
try:
clean_config: dict[str, Any] = {}
for file_values in self._dictionary.values():
clean_config.update(file_values)
return clean_config[key]
return self._dictionary[key]
except KeyError:
# 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
@ -173,8 +168,7 @@ class Configuration:
parser.add_section(section)
parser.set(section, name, value)
self._config[self.load_only].setdefault(fname, {})
self._config[self.load_only][fname][key] = value
self._config[self.load_only][key] = value
self._mark_as_modified(fname, parser)
def unset_value(self, key: str) -> None:
@ -184,14 +178,11 @@ class Configuration:
self._ensure_have_load_only()
assert self.load_only
fname, parser = self._get_parser_to_modify()
if (
key not in self._config[self.load_only][fname]
and key not in self._config[self.load_only]
):
if key not in self._config[self.load_only]:
raise ConfigurationError(f"No such key - {orig_key}")
fname, parser = self._get_parser_to_modify()
if parser is not None:
section, name = _disassemble_key(key)
if not (
@ -206,10 +197,8 @@ class Configuration:
if not parser.items(section):
parser.remove_section(section)
self._mark_as_modified(fname, parser)
try:
del self._config[self.load_only][fname][key]
except KeyError:
del self._config[self.load_only][key]
del self._config[self.load_only][key]
def save(self) -> None:
"""Save the current in-memory state."""
@ -241,7 +230,7 @@ class Configuration:
logger.debug("Will be working with %s variant only", self.load_only)
@property
def _dictionary(self) -> dict[str, dict[str, Any]]:
def _dictionary(self) -> Dict[str, Any]:
"""A dictionary representing the loaded configuration."""
# NOTE: Dictionaries are not populated if not loaded. So, conditionals
# are not needed here.
@ -281,8 +270,7 @@ class Configuration:
for section in parser.sections():
items = parser.items(section)
self._config[variant].setdefault(fname, {})
self._config[variant][fname].update(self._normalized_keys(section, items))
self._config[variant].update(self._normalized_keys(section, items))
return parser
@ -309,14 +297,13 @@ class Configuration:
def _load_environment_vars(self) -> None:
"""Loads configuration from environment variables"""
self._config[kinds.ENV_VAR].setdefault(":env:", {})
self._config[kinds.ENV_VAR][":env:"].update(
self._config[kinds.ENV_VAR].update(
self._normalized_keys(":env:", self.get_environ_vars())
)
def _normalized_keys(
self, section: str, items: Iterable[tuple[str, Any]]
) -> dict[str, Any]:
self, section: str, items: Iterable[Tuple[str, Any]]
) -> Dict[str, Any]:
"""Normalizes items to construct a dictionary with normalized keys.
This routine is where the names become keys and are made the same
@ -328,7 +315,7 @@ class Configuration:
normalized[key] = val
return normalized
def get_environ_vars(self) -> Iterable[tuple[str, str]]:
def get_environ_vars(self) -> Iterable[Tuple[str, str]]:
"""Returns a generator with all environmental vars with prefix PIP_"""
for key, val in os.environ.items():
if key.startswith("PIP_"):
@ -337,13 +324,13 @@ class Configuration:
yield name, val
# XXX: This is patched in the tests.
def iter_config_files(self) -> Iterable[tuple[Kind, list[str]]]:
def iter_config_files(self) -> Iterable[Tuple[Kind, List[str]]]:
"""Yields variant and configuration files associated with it.
This should be treated like items of a dictionary. The order
here doesn't affect what gets overridden. That is controlled
by OVERRIDE_ORDER. However this does control the order they are
displayed to the user. It's probably most ergonomic to display
displayed to the user. It's probably most ergononmic to display
things in the same order as OVERRIDE_ORDER
"""
# SMELL: Move the conditions out of this function
@ -369,11 +356,11 @@ class Configuration:
else:
yield kinds.ENV, []
def get_values_in_config(self, variant: Kind) -> dict[str, Any]:
def get_values_in_config(self, variant: Kind) -> Dict[str, Any]:
"""Get values present in a config file"""
return self._config[variant]
def _get_parser_to_modify(self) -> tuple[str, RawConfigParser]:
def _get_parser_to_modify(self) -> Tuple[str, RawConfigParser]:
# Determine which parser to modify
assert self.load_only
parsers = self._parsers[self.load_only]