Fix #19546: onfigparser exceptions expose implementation details. Patch by Claudiu Popa.
This commit is contained in:
parent
f29468118b
commit
949053bff2
|
@ -410,7 +410,7 @@ class BasicInterpolation(Interpolation):
|
||||||
v = map[var]
|
v = map[var]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise InterpolationMissingOptionError(
|
raise InterpolationMissingOptionError(
|
||||||
option, section, rest, var)
|
option, section, rest, var) from None
|
||||||
if "%" in v:
|
if "%" in v:
|
||||||
self._interpolate_some(parser, option, accum, v,
|
self._interpolate_some(parser, option, accum, v,
|
||||||
section, map, depth + 1)
|
section, map, depth + 1)
|
||||||
|
@ -482,7 +482,7 @@ class ExtendedInterpolation(Interpolation):
|
||||||
"More than one ':' found: %r" % (rest,))
|
"More than one ':' found: %r" % (rest,))
|
||||||
except (KeyError, NoSectionError, NoOptionError):
|
except (KeyError, NoSectionError, NoOptionError):
|
||||||
raise InterpolationMissingOptionError(
|
raise InterpolationMissingOptionError(
|
||||||
option, section, rest, ":".join(path))
|
option, section, rest, ":".join(path)) from None
|
||||||
if "$" in v:
|
if "$" in v:
|
||||||
self._interpolate_some(parser, opt, accum, v, sect,
|
self._interpolate_some(parser, opt, accum, v, sect,
|
||||||
dict(parser.items(sect, raw=True)),
|
dict(parser.items(sect, raw=True)),
|
||||||
|
@ -515,7 +515,7 @@ class LegacyInterpolation(Interpolation):
|
||||||
value = value % vars
|
value = value % vars
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
raise InterpolationMissingOptionError(
|
raise InterpolationMissingOptionError(
|
||||||
option, section, rawval, e.args[0])
|
option, section, rawval, e.args[0]) from None
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
if value and "%(" in value:
|
if value and "%(" in value:
|
||||||
|
@ -647,7 +647,7 @@ class RawConfigParser(MutableMapping):
|
||||||
try:
|
try:
|
||||||
opts = self._sections[section].copy()
|
opts = self._sections[section].copy()
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise NoSectionError(section)
|
raise NoSectionError(section) from None
|
||||||
opts.update(self._defaults)
|
opts.update(self._defaults)
|
||||||
return list(opts.keys())
|
return list(opts.keys())
|
||||||
|
|
||||||
|
@ -876,7 +876,7 @@ class RawConfigParser(MutableMapping):
|
||||||
try:
|
try:
|
||||||
sectdict = self._sections[section]
|
sectdict = self._sections[section]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise NoSectionError(section)
|
raise NoSectionError(section) from None
|
||||||
sectdict[self.optionxform(option)] = value
|
sectdict[self.optionxform(option)] = value
|
||||||
|
|
||||||
def write(self, fp, space_around_delimiters=True):
|
def write(self, fp, space_around_delimiters=True):
|
||||||
|
@ -917,7 +917,7 @@ class RawConfigParser(MutableMapping):
|
||||||
try:
|
try:
|
||||||
sectdict = self._sections[section]
|
sectdict = self._sections[section]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise NoSectionError(section)
|
raise NoSectionError(section) from None
|
||||||
option = self.optionxform(option)
|
option = self.optionxform(option)
|
||||||
existed = option in sectdict
|
existed = option in sectdict
|
||||||
if existed:
|
if existed:
|
||||||
|
|
|
@ -1763,6 +1763,58 @@ class InlineCommentStrippingTestCase(unittest.TestCase):
|
||||||
self.assertEqual(s['k2'], 'v2')
|
self.assertEqual(s['k2'], 'v2')
|
||||||
self.assertEqual(s['k3'], 'v3;#//still v3# and still v3')
|
self.assertEqual(s['k3'], 'v3;#//still v3# and still v3')
|
||||||
|
|
||||||
|
class ExceptionContextTestCase(unittest.TestCase):
|
||||||
|
""" Test that implementation details doesn't leak
|
||||||
|
through raising exceptions. """
|
||||||
|
|
||||||
|
def test_get_basic_interpolation(self):
|
||||||
|
parser = configparser.ConfigParser()
|
||||||
|
parser.read_string("""
|
||||||
|
[Paths]
|
||||||
|
home_dir: /Users
|
||||||
|
my_dir: %(home_dir1)s/lumberjack
|
||||||
|
my_pictures: %(my_dir)s/Pictures
|
||||||
|
""")
|
||||||
|
cm = self.assertRaises(configparser.InterpolationMissingOptionError)
|
||||||
|
with cm:
|
||||||
|
parser.get('Paths', 'my_dir')
|
||||||
|
self.assertIs(cm.exception.__suppress_context__, True)
|
||||||
|
|
||||||
|
def test_get_extended_interpolation(self):
|
||||||
|
parser = configparser.ConfigParser(
|
||||||
|
interpolation=configparser.ExtendedInterpolation())
|
||||||
|
parser.read_string("""
|
||||||
|
[Paths]
|
||||||
|
home_dir: /Users
|
||||||
|
my_dir: ${home_dir1}/lumberjack
|
||||||
|
my_pictures: ${my_dir}/Pictures
|
||||||
|
""")
|
||||||
|
cm = self.assertRaises(configparser.InterpolationMissingOptionError)
|
||||||
|
with cm:
|
||||||
|
parser.get('Paths', 'my_dir')
|
||||||
|
self.assertIs(cm.exception.__suppress_context__, True)
|
||||||
|
|
||||||
|
def test_missing_options(self):
|
||||||
|
parser = configparser.ConfigParser()
|
||||||
|
parser.read_string("""
|
||||||
|
[Paths]
|
||||||
|
home_dir: /Users
|
||||||
|
""")
|
||||||
|
with self.assertRaises(configparser.NoSectionError) as cm:
|
||||||
|
parser.options('test')
|
||||||
|
self.assertIs(cm.exception.__suppress_context__, True)
|
||||||
|
|
||||||
|
def test_missing_section(self):
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
with self.assertRaises(configparser.NoSectionError) as cm:
|
||||||
|
config.set('Section1', 'an_int', '15')
|
||||||
|
self.assertIs(cm.exception.__suppress_context__, True)
|
||||||
|
|
||||||
|
def test_remove_option(self):
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
with self.assertRaises(configparser.NoSectionError) as cm:
|
||||||
|
config.remove_option('Section1', 'an_int')
|
||||||
|
self.assertIs(cm.exception.__suppress_context__, True)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -129,6 +129,10 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #19546: configparser exceptions no longer expose implementation details.
|
||||||
|
Chained KeyErrors are removed, which leads to cleaner tracebacks. Patch by
|
||||||
|
Claudiu Popa.
|
||||||
|
|
||||||
- Issue #22051: turtledemo no longer reloads examples to re-run them.
|
- Issue #22051: turtledemo no longer reloads examples to re-run them.
|
||||||
Initialization of variables and gui setup should be done in main(),
|
Initialization of variables and gui setup should be done in main(),
|
||||||
which is called each time a demo is run, but not on import.
|
which is called each time a demo is run, but not on import.
|
||||||
|
|
Loading…
Reference in New Issue