Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6554887

Browse files
committed
Issue #11089: Fix performance issue limiting the use of ConfigParser()
with large config files.
1 parent 9f1ab85 commit 6554887

2 files changed

Lines changed: 41 additions & 4 deletions

File tree

Lib/configparser.py

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
"""
8989

9090
try:
91-
from collections import OrderedDict as _default_dict
91+
from collections import Mapping, OrderedDict as _default_dict
9292
except ImportError:
9393
# fallback for setup.py which hasn't yet built _collections
9494
_default_dict = dict
@@ -515,6 +515,38 @@ def _read(self, fp, fpname):
515515
if e:
516516
raise e
517517

518+
class _Chainmap(Mapping):
519+
"""Combine multiple mappings for successive lookups.
520+
521+
For example, to emulate Python's normal lookup sequence:
522+
523+
import __builtin__
524+
pylookup = _Chainmap(locals(), globals(), vars(__builtin__))
525+
"""
526+
527+
def __init__(self, *maps):
528+
self.maps = maps
529+
530+
def __getitem__(self, key):
531+
for mapping in self.maps:
532+
try:
533+
return mapping[key]
534+
except KeyError:
535+
pass
536+
raise KeyError(key)
537+
538+
def __iter__(self):
539+
seen = set()
540+
for mapping in self.maps:
541+
s = set(mapping) - seen
542+
for elem in s:
543+
yield elem
544+
seen.update(s)
545+
546+
def __len__(self):
547+
s = set()
548+
s.update(*self.maps)
549+
return len(s)
518550

519551
class ConfigParser(RawConfigParser):
520552

@@ -530,16 +562,18 @@ def get(self, section, option, raw=False, vars=None):
530562
531563
The section DEFAULT is special.
532564
"""
533-
d = self._defaults.copy()
565+
sectiondict = {}
534566
try:
535-
d.update(self._sections[section])
567+
sectiondict = self._sections[section]
536568
except KeyError:
537569
if section != DEFAULTSECT:
538570
raise NoSectionError(section)
539571
# Update with the entry specific variables
572+
vardict = {}
540573
if vars:
541574
for key, value in vars.items():
542-
d[self.optionxform(key)] = value
575+
vardict[self.optionxform(key)] = value
576+
d = _Chainmap(vardict, sectiondict, self._defaults)
543577
option = self.optionxform(option)
544578
try:
545579
value = d[option]

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ Core and Builtins
3737
Library
3838
-------
3939

40+
- Issue #11089: Fix performance issue limiting the use of ConfigParser()
41+
with large config files.
42+
4043
- Issue #8275: Fix passing of callback arguments with ctypes under Win64.
4144
Patch by Stan Mihai.
4245

0 commit comments

Comments
 (0)