[Python-checkins] cpython (merge default -> default): Merge fix for #19546: configparser exceptions leak implementation details

lukasz.langa python-checkins at python.org
Thu Sep 4 10:42:50 CEST 2014


http://hg.python.org/cpython/rev/554ead559f24
changeset:   92333:554ead559f24
parent:      92331:e6cfbc3e2ed9
parent:      92332:2b14665b7bce
user:        Łukasz Langa <lukasz at langa.pl>
date:        Thu Sep 04 01:42:29 2014 -0700
summary:
  Merge fix for #19546: configparser exceptions leak implementation details

files:
  Lib/configparser.py           |  12 ++--
  Lib/test/test_configparser.py |  52 +++++++++++++++++++++++
  Misc/NEWS                     |   4 +
  3 files changed, 62 insertions(+), 6 deletions(-)


diff --git a/Lib/configparser.py b/Lib/configparser.py
--- a/Lib/configparser.py
+++ b/Lib/configparser.py
@@ -410,7 +410,7 @@
                     v = map[var]
                 except KeyError:
                     raise InterpolationMissingOptionError(
-                        option, section, rest, var)
+                        option, section, rest, var) from None
                 if "%" in v:
                     self._interpolate_some(parser, option, accum, v,
                                            section, map, depth + 1)
@@ -482,7 +482,7 @@
                             "More than one ':' found: %r" % (rest,))
                 except (KeyError, NoSectionError, NoOptionError):
                     raise InterpolationMissingOptionError(
-                        option, section, rest, ":".join(path))
+                        option, section, rest, ":".join(path)) from None
                 if "$" in v:
                     self._interpolate_some(parser, opt, accum, v, sect,
                                            dict(parser.items(sect, raw=True)),
@@ -515,7 +515,7 @@
                     value = value % vars
                 except KeyError as e:
                     raise InterpolationMissingOptionError(
-                        option, section, rawval, e.args[0])
+                        option, section, rawval, e.args[0]) from None
             else:
                 break
         if value and "%(" in value:
@@ -647,7 +647,7 @@
         try:
             opts = self._sections[section].copy()
         except KeyError:
-            raise NoSectionError(section)
+            raise NoSectionError(section) from None
         opts.update(self._defaults)
         return list(opts.keys())
 
@@ -876,7 +876,7 @@
             try:
                 sectdict = self._sections[section]
             except KeyError:
-                raise NoSectionError(section)
+                raise NoSectionError(section) from None
         sectdict[self.optionxform(option)] = value
 
     def write(self, fp, space_around_delimiters=True):
@@ -917,7 +917,7 @@
             try:
                 sectdict = self._sections[section]
             except KeyError:
-                raise NoSectionError(section)
+                raise NoSectionError(section) from None
         option = self.optionxform(option)
         existed = option in sectdict
         if existed:
diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py
--- a/Lib/test/test_configparser.py
+++ b/Lib/test/test_configparser.py
@@ -1763,6 +1763,58 @@
         self.assertEqual(s['k2'], 'v2')
         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__':
     unittest.main()
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -129,6 +129,10 @@
 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.
   Initialization of variables and gui setup should be done in main(),
   which is called each time a demo is run, but not on import.

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list