diff -r 524a032c8e0f Lib/packaging/tests/test_command_install_data.py --- a/Lib/packaging/tests/test_command_install_data.py Tue Feb 21 22:10:16 2012 +0100 +++ b/Lib/packaging/tests/test_command_install_data.py Wed Feb 22 00:17:45 2012 +0100 @@ -17,13 +17,11 @@ class InstallDataTestCase(support.Tempdi def setUp(self): super(InstallDataTestCase, self).setUp() scheme = _get_default_scheme() - old_items = sysconfig._SCHEMES.items(scheme) + old_sections = sysconfig._SCHEMES._sections.copy() def restore(): - sysconfig._SCHEMES.remove_section(scheme) - sysconfig._SCHEMES.add_section(scheme) - for option, value in old_items: - sysconfig._SCHEMES.set(scheme, option, value) + sysconfig._SCHEMES._sections.clear() + sysconfig._SCHEMES._sections.update(old_sections) self.addCleanup(restore) diff -r 524a032c8e0f Lib/sysconfig.py --- a/Lib/sysconfig.py Tue Feb 21 22:10:16 2012 +0100 +++ b/Lib/sysconfig.py Wed Feb 22 00:17:45 2012 +0100 @@ -1,10 +1,8 @@ """Access to Python's configuration information.""" - import os import re import sys from os.path import pardir, realpath -from configparser import RawConfigParser __all__ = [ 'get_config_h_filename', @@ -20,11 +18,120 @@ __all__ = [ 'parse_config_h', ] +class SectionProxy: + def __init__(self, parser, name): + self._parser = parser + self._name = name + + def __iter__(self): + return iter(self._parser.options(self._name)) + +class _ConfigParser: + """ + configparser.RawConfigParser copy specialized for sysconfig: + - read-only + - use dict + - only support "#" prefix for comments + - only support "=" option name/value separator + - don't use custom exceptions + """ + + 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 Exception("Section %s already exists" % 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): + return list(self._sections[section].keys()) + + def items(self, section): + return self._sections[section].items() + + 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): + self._sections[section][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): + return self._proxies[key] + + def __iter__(self): + return iter(self._sections.keys()) + + def read(self, filename): + with open(filename, encoding="ASCII") as fp: + self._read(fp, filename) + + def _read(self, fp, fpname): + cursect = None # None, or a dictionary + sectname = None + optname = None + lineno = 0 + for lineno, line in enumerate(fp, start=1): + value = line.strip() + if value.startswith('#'): + continue + if not value: + continue + + # is it a section header? + if value.startswith('[') and value.endswith(']'): + sectname = value[1:-1] + if sectname in self._sections: + raise Exception("%s:%s: Section %s already exists" + % (fpname, lineno, sectname)) + else: + cursect = dict() + self._sections[sectname] = cursect + self._proxies[sectname] = SectionProxy(self, sectname) + # So sections can't start with a continuation line + optname = None + # no section header in the file? + elif cursect is None: + raise Exception('%s:%s: File contains no section headers' + % (fpname, lineno)) + # an option line? + else: + optname, optval = value.split('=', 1) + optname = optname.rstrip() + optval = optval.lstrip() + if not optname: + raise ValueError("%s:%s: Empty option name" + % (fpname, lineno)) + optname = optname.rstrip() + if optname in cursect: + raise DuplicateOptionError(sectname, optname, + fpname, lineno) + cursect[optname] = optval + # let's read the configuration file # XXX _CONFIG_DIR will be set by the Makefile later _CONFIG_DIR = os.path.normpath(os.path.dirname(__file__)) _CONFIG_FILE = os.path.join(_CONFIG_DIR, 'sysconfig.cfg') -_SCHEMES = RawConfigParser(dict_type=dict) # Faster than OrderedDict +_SCHEMES = _ConfigParser() _SCHEMES.read(_CONFIG_FILE) _VAR_REPL = re.compile(r'\{([^{]*?)\}') @@ -784,3 +891,4 @@ def _main(): if __name__ == '__main__': _main() +