diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -1,10 +1,217 @@ """Access to Python's configuration information.""" - import os import re import sys from os.path import pardir, realpath -from configparser import RawConfigParser + +import itertools + +class SectionProxy: + def __init__(self, parser, name): + self._parser = parser + self._name = name + + def __getitem__(self, key): + if not self._parser.has_option(self._name, key): + raise KeyError(key) + return self._parser.get(self._name, key) + + def __contains__(self, key): + return self._parser.has_option(self._name, key) + + def __iter__(self): + return iter(self._parser.options(self._name)) + + def get(self, option): + return self._parser.get(self._name, option) + +class _ConfigParser: + """Specialized copy of configparser.RawConfigParser: read-only using dict.""" + + def __init__(self): + self._sections = dict() + self._proxies = dict() + + def sections(self): + return list(self._sections.keys()) + + def add_section(self, section): + if section in self._sections: + raise DuplicateSectionError(section) + self._sections[section] = dict() + self._proxies[section] = SectionProxy(self, section) + + def has_section(self, section): + return section in self._sections + + def options(self, section): + try: + opts = self._sections[section].copy() + except KeyError: + raise NoSectionError(section) + return list(opts.keys()) + + def read(self, filename): + with open(filename) as fp: + self._read(fp, filename) + + def items(self, section): + d = dict() + try: + d.update(self._sections[section]) + except KeyError: + raise NoSectionError(section) + return [(option, d[option]) for option in d.keys()] + + def has_option(self, section, option): + if section not in self._sections: + return False + else: + option = option + return option in self._sections[section] + + def set(self, section, option, value=None): + try: + sectdict = self._sections[section] + except KeyError: + raise NoSectionError(section) + sectdict[option] = value + + def remove_section(self, section): + existed = section in self._sections + if existed: + del self._sections[section] + del self._proxies[section] + return existed + + def __getitem__(self, key): + if not self.has_section(key): + raise KeyError(key) + return self._proxies[key] + + def __setitem__(self, section, keys): + self.remove_section(section) + elements_added = set() + section = str(section) + try: + self.add_section(section) + except (DuplicateSectionError, ValueError): + if section in elements_added: + raise + elements_added.add(section) + for key, value in keys.items(): + key = str(key) + if value is not None: + value = str(value) + if (section, key) in elements_added: + raise DuplicateOptionError(section, key, '') + elements_added.add((section, key)) + self.set(section, key, value) + + def __contains__(self, key): + return self.has_section(key) + + def __iter__(self): + return iter(self._sections.keys()) + + def _read(self, fp, fpname): + elements_added = set() + cursect = None # None, or a dictionary + sectname = None + optname = None + lineno = 0 + indent_level = 0 + optcre = re.compile(r"(?P