Commit bd6c0795 authored by Michael Foord's avatar Michael Foord

Issue #4686 - add .args to exceptions in the configparsermodule

parent 4d4d1ce7
...@@ -142,6 +142,7 @@ class NoSectionError(Error): ...@@ -142,6 +142,7 @@ class NoSectionError(Error):
def __init__(self, section): def __init__(self, section):
Error.__init__(self, 'No section: %r' % (section,)) Error.__init__(self, 'No section: %r' % (section,))
self.section = section self.section = section
self.args = (section, )
class DuplicateSectionError(Error): class DuplicateSectionError(Error):
"""Raised when a section is multiply-created.""" """Raised when a section is multiply-created."""
...@@ -149,6 +150,7 @@ class DuplicateSectionError(Error): ...@@ -149,6 +150,7 @@ class DuplicateSectionError(Error):
def __init__(self, section): def __init__(self, section):
Error.__init__(self, "Section %r already exists" % section) Error.__init__(self, "Section %r already exists" % section)
self.section = section self.section = section
self.args = (section, )
class NoOptionError(Error): class NoOptionError(Error):
"""A requested option was not found.""" """A requested option was not found."""
...@@ -158,6 +160,7 @@ class NoOptionError(Error): ...@@ -158,6 +160,7 @@ class NoOptionError(Error):
(option, section)) (option, section))
self.option = option self.option = option
self.section = section self.section = section
self.args = (option, section)
class InterpolationError(Error): class InterpolationError(Error):
"""Base class for interpolation-related exceptions.""" """Base class for interpolation-related exceptions."""
...@@ -166,6 +169,7 @@ class InterpolationError(Error): ...@@ -166,6 +169,7 @@ class InterpolationError(Error):
Error.__init__(self, msg) Error.__init__(self, msg)
self.option = option self.option = option
self.section = section self.section = section
self.args = (option, section, msg)
class InterpolationMissingOptionError(InterpolationError): class InterpolationMissingOptionError(InterpolationError):
"""A string substitution required a setting which was not available.""" """A string substitution required a setting which was not available."""
...@@ -179,6 +183,7 @@ class InterpolationMissingOptionError(InterpolationError): ...@@ -179,6 +183,7 @@ class InterpolationMissingOptionError(InterpolationError):
% (section, option, reference, rawval)) % (section, option, reference, rawval))
InterpolationError.__init__(self, option, section, msg) InterpolationError.__init__(self, option, section, msg)
self.reference = reference self.reference = reference
self.args = (option, section, rawval, reference)
class InterpolationSyntaxError(InterpolationError): class InterpolationSyntaxError(InterpolationError):
"""Raised when the source text into which substitutions are made """Raised when the source text into which substitutions are made
...@@ -194,6 +199,7 @@ class InterpolationDepthError(InterpolationError): ...@@ -194,6 +199,7 @@ class InterpolationDepthError(InterpolationError):
"\trawval : %s\n" "\trawval : %s\n"
% (section, option, rawval)) % (section, option, rawval))
InterpolationError.__init__(self, option, section, msg) InterpolationError.__init__(self, option, section, msg)
self.args = (option, section, rawval)
class ParsingError(Error): class ParsingError(Error):
"""Raised when a configuration file does not follow legal syntax.""" """Raised when a configuration file does not follow legal syntax."""
...@@ -202,6 +208,7 @@ class ParsingError(Error): ...@@ -202,6 +208,7 @@ class ParsingError(Error):
Error.__init__(self, 'File contains parsing errors: %s' % filename) Error.__init__(self, 'File contains parsing errors: %s' % filename)
self.filename = filename self.filename = filename
self.errors = [] self.errors = []
self.args = (filename, )
def append(self, lineno, line): def append(self, lineno, line):
self.errors.append((lineno, line)) self.errors.append((lineno, line))
...@@ -218,7 +225,7 @@ class MissingSectionHeaderError(ParsingError): ...@@ -218,7 +225,7 @@ class MissingSectionHeaderError(ParsingError):
self.filename = filename self.filename = filename
self.lineno = lineno self.lineno = lineno
self.line = line self.line = line
self.args = (filename, lineno, line)
class RawConfigParser: class RawConfigParser:
def __init__(self, defaults=None, dict_type=_default_dict, def __init__(self, defaults=None, dict_type=_default_dict,
......
...@@ -107,8 +107,9 @@ class TestCaseBase(unittest.TestCase): ...@@ -107,8 +107,9 @@ class TestCaseBase(unittest.TestCase):
"remove_option() failed to report non-existence of option" "remove_option() failed to report non-existence of option"
" that was removed") " that was removed")
self.assertRaises(configparser.NoSectionError, with self.assertRaises(configparser.NoSectionError) as cm:
cf.remove_option, 'No Such Section', 'foo') cf.remove_option('No Such Section', 'foo')
self.assertEqual(cm.exception.args, ('No Such Section',))
eq(cf.get('Long Line', 'foo'), eq(cf.get('Long Line', 'foo'),
'this line is much, much longer than my editor\nlikes it.') 'this line is much, much longer than my editor\nlikes it.')
...@@ -160,20 +161,24 @@ class TestCaseBase(unittest.TestCase): ...@@ -160,20 +161,24 @@ class TestCaseBase(unittest.TestCase):
def test_parse_errors(self): def test_parse_errors(self):
self.newconfig() self.newconfig()
self.parse_error(configparser.ParsingError, e = self.parse_error(configparser.ParsingError,
"[Foo]\n extra-spaces: splat\n") "[Foo]\n extra-spaces: splat\n")
self.assertEqual(e.args, ('<???>',))
self.parse_error(configparser.ParsingError, self.parse_error(configparser.ParsingError,
"[Foo]\n extra-spaces= splat\n") "[Foo]\n extra-spaces= splat\n")
self.parse_error(configparser.ParsingError, self.parse_error(configparser.ParsingError,
"[Foo]\n:value-without-option-name\n") "[Foo]\n:value-without-option-name\n")
self.parse_error(configparser.ParsingError, self.parse_error(configparser.ParsingError,
"[Foo]\n=value-without-option-name\n") "[Foo]\n=value-without-option-name\n")
self.parse_error(configparser.MissingSectionHeaderError, e = self.parse_error(configparser.MissingSectionHeaderError,
"No Section!\n") "No Section!\n")
self.assertEqual(e.args, ('<???>', 1, "No Section!\n"))
def parse_error(self, exc, src): def parse_error(self, exc, src):
sio = io.StringIO(src) sio = io.StringIO(src)
self.assertRaises(exc, self.cf.readfp, sio) with self.assertRaises(exc) as cm:
self.cf.readfp(sio)
return cm.exception
def test_query_errors(self): def test_query_errors(self):
cf = self.newconfig() cf = self.newconfig()
...@@ -181,13 +186,15 @@ class TestCaseBase(unittest.TestCase): ...@@ -181,13 +186,15 @@ class TestCaseBase(unittest.TestCase):
"new ConfigParser should have no defined sections") "new ConfigParser should have no defined sections")
self.assertFalse(cf.has_section("Foo"), self.assertFalse(cf.has_section("Foo"),
"new ConfigParser should have no acknowledged sections") "new ConfigParser should have no acknowledged sections")
self.assertRaises(configparser.NoSectionError, with self.assertRaises(configparser.NoSectionError) as cm:
cf.options, "Foo") cf.options("Foo")
self.assertRaises(configparser.NoSectionError, with self.assertRaises(configparser.NoSectionError) as cm:
cf.set, "foo", "bar", "value") cf.set("foo", "bar", "value")
self.get_error(configparser.NoSectionError, "foo", "bar") e = self.get_error(configparser.NoSectionError, "foo", "bar")
self.assertEqual(e.args, ("foo",))
cf.add_section("foo") cf.add_section("foo")
self.get_error(configparser.NoOptionError, "foo", "bar") e = self.get_error(configparser.NoOptionError, "foo", "bar")
self.assertEqual(e.args, ("bar", "foo"))
def get_error(self, exc, section, option): def get_error(self, exc, section, option):
try: try:
...@@ -226,8 +233,9 @@ class TestCaseBase(unittest.TestCase): ...@@ -226,8 +233,9 @@ class TestCaseBase(unittest.TestCase):
def test_weird_errors(self): def test_weird_errors(self):
cf = self.newconfig() cf = self.newconfig()
cf.add_section("Foo") cf.add_section("Foo")
self.assertRaises(configparser.DuplicateSectionError, with self.assertRaises(configparser.DuplicateSectionError) as cm:
cf.add_section, "Foo") cf.add_section("Foo")
self.assertEqual(cm.exception.args, ("Foo",))
def test_write(self): def test_write(self):
config_string = ( config_string = (
...@@ -346,6 +354,11 @@ class ConfigParserTestCase(TestCaseBase): ...@@ -346,6 +354,11 @@ class ConfigParserTestCase(TestCaseBase):
config_class = configparser.ConfigParser config_class = configparser.ConfigParser
def test_interpolation(self): def test_interpolation(self):
rawval = {
configparser.ConfigParser: "something %(with11)s "\
"lots of interpolation (11 steps)",
configparser.SafeConfigParser: "%(with1)s",
}
cf = self.get_interpolation_config() cf = self.get_interpolation_config()
eq = self.assertEqual eq = self.assertEqual
eq(cf.get("Foo", "getname"), "Foo") eq(cf.get("Foo", "getname"), "Foo")
...@@ -354,15 +367,22 @@ class ConfigParserTestCase(TestCaseBase): ...@@ -354,15 +367,22 @@ class ConfigParserTestCase(TestCaseBase):
"something with lots of interpolation (9 steps)") "something with lots of interpolation (9 steps)")
eq(cf.get("Foo", "bar10"), eq(cf.get("Foo", "bar10"),
"something with lots of interpolation (10 steps)") "something with lots of interpolation (10 steps)")
self.get_error(configparser.InterpolationDepthError, "Foo", "bar11") e = self.get_error(configparser.InterpolationDepthError, "Foo", "bar11")
self.assertEqual(e.args, ("bar11", "Foo", rawval[self.config_class]))
def test_interpolation_missing_value(self): def test_interpolation_missing_value(self):
rawval = {
configparser.ConfigParser: '%(reference)s',
configparser.SafeConfigParser: '',
}
self.get_interpolation_config() self.get_interpolation_config()
e = self.get_error(configparser.InterpolationError, e = self.get_error(configparser.InterpolationMissingOptionError,
"Interpolation Error", "name") "Interpolation Error", "name")
self.assertEqual(e.reference, "reference") self.assertEqual(e.reference, "reference")
self.assertEqual(e.section, "Interpolation Error") self.assertEqual(e.section, "Interpolation Error")
self.assertEqual(e.option, "name") self.assertEqual(e.option, "name")
self.assertEqual(e.args, ('name', 'Interpolation Error',
rawval[self.config_class], 'reference'))
def test_items(self): def test_items(self):
self.check_items_config([('default', '<default>'), self.check_items_config([('default', '<default>'),
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
################################################################## ##################################################################
[project attributes] [project attributes]
proj.directory-list = [{'dirloc': loc('..'), proj.directory-list = [{'dirloc': loc('..'),
'excludes': (), 'excludes': [u'Lib/__pycache__'],
'filter': '*', 'filter': '*',
'include_hidden': False, 'include_hidden': False,
'recursive': True, 'recursive': True,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment