diff options
author | Raymond Hettinger <python@rcn.com> | 2011-02-02 21:35:48 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2011-02-02 21:35:48 (GMT) |
commit | 65548873cfdef1fbd99a71e84a81283558342d64 (patch) | |
tree | 6d236a45c12552e357c46f18d7669dbbffd9c40b /Lib | |
parent | 9f1ab8530c20d38f66afbc55cf96d144681464f8 (diff) | |
download | cpython-65548873cfdef1fbd99a71e84a81283558342d64.zip cpython-65548873cfdef1fbd99a71e84a81283558342d64.tar.gz cpython-65548873cfdef1fbd99a71e84a81283558342d64.tar.bz2 |
Issue #11089: Fix performance issue limiting the use of ConfigParser()
with large config files.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/configparser.py | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/Lib/configparser.py b/Lib/configparser.py index 14ddd85..edd3ac3 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -88,7 +88,7 @@ ConfigParser -- responsible for parsing a list of """ try: - from collections import OrderedDict as _default_dict + from collections import Mapping, OrderedDict as _default_dict except ImportError: # fallback for setup.py which hasn't yet built _collections _default_dict = dict @@ -515,6 +515,38 @@ class RawConfigParser: if e: raise e +class _Chainmap(Mapping): + """Combine multiple mappings for successive lookups. + + For example, to emulate Python's normal lookup sequence: + + import __builtin__ + pylookup = _Chainmap(locals(), globals(), vars(__builtin__)) + """ + + def __init__(self, *maps): + self.maps = maps + + def __getitem__(self, key): + for mapping in self.maps: + try: + return mapping[key] + except KeyError: + pass + raise KeyError(key) + + def __iter__(self): + seen = set() + for mapping in self.maps: + s = set(mapping) - seen + for elem in s: + yield elem + seen.update(s) + + def __len__(self): + s = set() + s.update(*self.maps) + return len(s) class ConfigParser(RawConfigParser): @@ -530,16 +562,18 @@ class ConfigParser(RawConfigParser): The section DEFAULT is special. """ - d = self._defaults.copy() + sectiondict = {} try: - d.update(self._sections[section]) + sectiondict = self._sections[section] except KeyError: if section != DEFAULTSECT: raise NoSectionError(section) # Update with the entry specific variables + vardict = {} if vars: for key, value in vars.items(): - d[self.optionxform(key)] = value + vardict[self.optionxform(key)] = value + d = _Chainmap(vardict, sectiondict, self._defaults) option = self.optionxform(option) try: value = d[option] |