mirror of
https://github.com/python/cpython.git
synced 2025-07-31 23:23:11 +00:00
Issue #11089: Fix performance issue limiting the use of ConfigParser()
with large config files.
This commit is contained in:
parent
9f1ab8530c
commit
65548873cf
2 changed files with 41 additions and 4 deletions
|
@ -88,7 +88,7 @@ ConfigParser -- responsible for parsing a list of
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from collections import OrderedDict as _default_dict
|
from collections import Mapping, OrderedDict as _default_dict
|
||||||
except ImportError:
|
except ImportError:
|
||||||
# fallback for setup.py which hasn't yet built _collections
|
# fallback for setup.py which hasn't yet built _collections
|
||||||
_default_dict = dict
|
_default_dict = dict
|
||||||
|
@ -515,6 +515,38 @@ class RawConfigParser:
|
||||||
if e:
|
if e:
|
||||||
raise 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):
|
class ConfigParser(RawConfigParser):
|
||||||
|
|
||||||
|
@ -530,16 +562,18 @@ class ConfigParser(RawConfigParser):
|
||||||
|
|
||||||
The section DEFAULT is special.
|
The section DEFAULT is special.
|
||||||
"""
|
"""
|
||||||
d = self._defaults.copy()
|
sectiondict = {}
|
||||||
try:
|
try:
|
||||||
d.update(self._sections[section])
|
sectiondict = self._sections[section]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
if section != DEFAULTSECT:
|
if section != DEFAULTSECT:
|
||||||
raise NoSectionError(section)
|
raise NoSectionError(section)
|
||||||
# Update with the entry specific variables
|
# Update with the entry specific variables
|
||||||
|
vardict = {}
|
||||||
if vars:
|
if vars:
|
||||||
for key, value in vars.items():
|
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)
|
option = self.optionxform(option)
|
||||||
try:
|
try:
|
||||||
value = d[option]
|
value = d[option]
|
||||||
|
|
|
@ -37,6 +37,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #11089: Fix performance issue limiting the use of ConfigParser()
|
||||||
|
with large config files.
|
||||||
|
|
||||||
- Issue #8275: Fix passing of callback arguments with ctypes under Win64.
|
- Issue #8275: Fix passing of callback arguments with ctypes under Win64.
|
||||||
Patch by Stan Mihai.
|
Patch by Stan Mihai.
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue