]> granicus.if.org Git - python/commitdiff
Fix #19546: onfigparser exceptions expose implementation details. Patch by Claudiu...
authorŁukasz Langa <lukasz@langa.pl>
Thu, 4 Sep 2014 08:36:33 +0000 (01:36 -0700)
committerŁukasz Langa <lukasz@langa.pl>
Thu, 4 Sep 2014 08:36:33 +0000 (01:36 -0700)
Lib/configparser.py
Lib/test/test_configparser.py
Misc/NEWS

index 4ee8307613c9c81aecd6f5453b00f31c3bee8e48..5843b0fc035531ce5e65cc036de98439d314ba1f 100644 (file)
@@ -410,7 +410,7 @@ class BasicInterpolation(Interpolation):
                     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 @@ class ExtendedInterpolation(Interpolation):
                             "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 @@ class LegacyInterpolation(Interpolation):
                     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 @@ class RawConfigParser(MutableMapping):
         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 @@ class RawConfigParser(MutableMapping):
             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 @@ class RawConfigParser(MutableMapping):
             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:
index 742b12b4a8a5126e83cbf0b90ac565df2ec3aafc..b43950191c73d6b2e877fe76f6e16110d4c46cbe 100644 (file)
@@ -1763,6 +1763,58 @@ class InlineCommentStrippingTestCase(unittest.TestCase):
         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()
index 8117cbe0b8b53f2766a28683fe5d6a9c06759870..8a6b82341b3d7401be6419d303d5061efbfccd35 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -129,6 +129,10 @@ Core and Builtins
 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.