diff options
| author | Raymond Hettinger <python@rcn.com> | 2011-02-22 01:48:33 (GMT) |
|---|---|---|
| committer | Raymond Hettinger <python@rcn.com> | 2011-02-22 01:48:33 (GMT) |
| commit | 16fe75e4e0bbc6eadb97c199272dd4b7616d8042 (patch) | |
| tree | 9d9d9eaa71faa09f0a3506289a5eadc582e4a92f /Lib/test/test_cfgparser.py | |
| parent | 158c9c26fca16dee2f7a8d89707cf9c149bd04f2 (diff) | |
| download | cpython-16fe75e4e0bbc6eadb97c199272dd4b7616d8042.zip cpython-16fe75e4e0bbc6eadb97c199272dd4b7616d8042.tar.gz cpython-16fe75e4e0bbc6eadb97c199272dd4b7616d8042.tar.bz2 | |
Have the test filename match the module filename.
Diffstat (limited to 'Lib/test/test_cfgparser.py')
| -rw-r--r-- | Lib/test/test_cfgparser.py | 1342 |
1 files changed, 0 insertions, 1342 deletions
diff --git a/Lib/test/test_cfgparser.py b/Lib/test/test_cfgparser.py deleted file mode 100644 index f7d9a26..0000000 --- a/Lib/test/test_cfgparser.py +++ /dev/null @@ -1,1342 +0,0 @@ -import collections -import configparser -import io -import os -import sys -import textwrap -import unittest -import warnings - -from test import support - -class SortedDict(collections.UserDict): - - def items(self): - return sorted(self.data.items()) - - def keys(self): - return sorted(self.data.keys()) - - def values(self): - return [i[1] for i in self.items()] - - def iteritems(self): return iter(self.items()) - def iterkeys(self): return iter(self.keys()) - __iter__ = iterkeys - def itervalues(self): return iter(self.values()) - - -class CfgParserTestCaseClass(unittest.TestCase): - allow_no_value = False - delimiters = ('=', ':') - comment_prefixes = (';', '#') - inline_comment_prefixes = (';', '#') - empty_lines_in_values = True - dict_type = configparser._default_dict - strict = False - default_section = configparser.DEFAULTSECT - interpolation = configparser._UNSET - - def newconfig(self, defaults=None): - arguments = dict( - defaults=defaults, - allow_no_value=self.allow_no_value, - delimiters=self.delimiters, - comment_prefixes=self.comment_prefixes, - inline_comment_prefixes=self.inline_comment_prefixes, - empty_lines_in_values=self.empty_lines_in_values, - dict_type=self.dict_type, - strict=self.strict, - default_section=self.default_section, - interpolation=self.interpolation, - ) - instance = self.config_class(**arguments) - return instance - - def fromstring(self, string, defaults=None): - cf = self.newconfig(defaults) - cf.read_string(string) - return cf - -class BasicTestCase(CfgParserTestCaseClass): - - def basic_test(self, cf): - E = ['Commented Bar', - 'Foo Bar', - 'Internationalized Stuff', - 'Long Line', - 'Section\\with$weird%characters[\t', - 'Spaces', - 'Spacey Bar', - 'Spacey Bar From The Beginning', - 'Types', - ] - - if self.allow_no_value: - E.append('NoValue') - E.sort() - F = [('baz', 'qwe'), ('foo', 'bar3')] - - # API access - L = cf.sections() - L.sort() - eq = self.assertEqual - eq(L, E) - L = cf.items('Spacey Bar From The Beginning') - L.sort() - eq(L, F) - - # mapping access - L = [section for section in cf] - L.sort() - E.append(self.default_section) - E.sort() - eq(L, E) - L = cf['Spacey Bar From The Beginning'].items() - L = sorted(list(L)) - eq(L, F) - L = cf.items() - L = sorted(list(L)) - self.assertEqual(len(L), len(E)) - for name, section in L: - eq(name, section.name) - eq(cf.defaults(), cf[self.default_section]) - - # The use of spaces in the section names serves as a - # regression test for SourceForge bug #583248: - # http://www.python.org/sf/583248 - - # API access - eq(cf.get('Foo Bar', 'foo'), 'bar1') - eq(cf.get('Spacey Bar', 'foo'), 'bar2') - eq(cf.get('Spacey Bar From The Beginning', 'foo'), 'bar3') - eq(cf.get('Spacey Bar From The Beginning', 'baz'), 'qwe') - eq(cf.get('Commented Bar', 'foo'), 'bar4') - eq(cf.get('Commented Bar', 'baz'), 'qwe') - eq(cf.get('Spaces', 'key with spaces'), 'value') - eq(cf.get('Spaces', 'another with spaces'), 'splat!') - eq(cf.getint('Types', 'int'), 42) - eq(cf.get('Types', 'int'), "42") - self.assertAlmostEqual(cf.getfloat('Types', 'float'), 0.44) - eq(cf.get('Types', 'float'), "0.44") - eq(cf.getboolean('Types', 'boolean'), False) - eq(cf.get('Types', '123'), 'strange but acceptable') - if self.allow_no_value: - eq(cf.get('NoValue', 'option-without-value'), None) - - # test vars= and fallback= - eq(cf.get('Foo Bar', 'foo', fallback='baz'), 'bar1') - eq(cf.get('Foo Bar', 'foo', vars={'foo': 'baz'}), 'baz') - with self.assertRaises(configparser.NoSectionError): - cf.get('No Such Foo Bar', 'foo') - with self.assertRaises(configparser.NoOptionError): - cf.get('Foo Bar', 'no-such-foo') - eq(cf.get('No Such Foo Bar', 'foo', fallback='baz'), 'baz') - eq(cf.get('Foo Bar', 'no-such-foo', fallback='baz'), 'baz') - eq(cf.get('Spacey Bar', 'foo', fallback=None), 'bar2') - eq(cf.get('No Such Spacey Bar', 'foo', fallback=None), None) - eq(cf.getint('Types', 'int', fallback=18), 42) - eq(cf.getint('Types', 'no-such-int', fallback=18), 18) - eq(cf.getint('Types', 'no-such-int', fallback="18"), "18") # sic! - with self.assertRaises(configparser.NoOptionError): - cf.getint('Types', 'no-such-int') - self.assertAlmostEqual(cf.getfloat('Types', 'float', - fallback=0.0), 0.44) - self.assertAlmostEqual(cf.getfloat('Types', 'no-such-float', - fallback=0.0), 0.0) - eq(cf.getfloat('Types', 'no-such-float', fallback="0.0"), "0.0") # sic! - with self.assertRaises(configparser.NoOptionError): - cf.getfloat('Types', 'no-such-float') - eq(cf.getboolean('Types', 'boolean', fallback=True), False) - eq(cf.getboolean('Types', 'no-such-boolean', fallback="yes"), - "yes") # sic! - eq(cf.getboolean('Types', 'no-such-boolean', fallback=True), True) - with self.assertRaises(configparser.NoOptionError): - cf.getboolean('Types', 'no-such-boolean') - eq(cf.getboolean('No Such Types', 'boolean', fallback=True), True) - if self.allow_no_value: - eq(cf.get('NoValue', 'option-without-value', fallback=False), None) - eq(cf.get('NoValue', 'no-such-option-without-value', - fallback=False), False) - - # mapping access - eq(cf['Foo Bar']['foo'], 'bar1') - eq(cf['Spacey Bar']['foo'], 'bar2') - section = cf['Spacey Bar From The Beginning'] - eq(section.name, 'Spacey Bar From The Beginning') - self.assertIs(section.parser, cf) - with self.assertRaises(AttributeError): - section.name = 'Name is read-only' - with self.assertRaises(AttributeError): - section.parser = 'Parser is read-only' - eq(section['foo'], 'bar3') - eq(section['baz'], 'qwe') - eq(cf['Commented Bar']['foo'], 'bar4') - eq(cf['Commented Bar']['baz'], 'qwe') - eq(cf['Spaces']['key with spaces'], 'value') - eq(cf['Spaces']['another with spaces'], 'splat!') - eq(cf['Long Line']['foo'], - 'this line is much, much longer than my editor\nlikes it.') - if self.allow_no_value: - eq(cf['NoValue']['option-without-value'], None) - # test vars= and fallback= - eq(cf['Foo Bar'].get('foo', 'baz'), 'bar1') - eq(cf['Foo Bar'].get('foo', fallback='baz'), 'bar1') - eq(cf['Foo Bar'].get('foo', vars={'foo': 'baz'}), 'baz') - with self.assertRaises(KeyError): - cf['No Such Foo Bar']['foo'] - with self.assertRaises(KeyError): - cf['Foo Bar']['no-such-foo'] - with self.assertRaises(KeyError): - cf['No Such Foo Bar'].get('foo', fallback='baz') - eq(cf['Foo Bar'].get('no-such-foo', 'baz'), 'baz') - eq(cf['Foo Bar'].get('no-such-foo', fallback='baz'), 'baz') - eq(cf['Foo Bar'].get('no-such-foo'), None) - eq(cf['Spacey Bar'].get('foo', None), 'bar2') - eq(cf['Spacey Bar'].get('foo', fallback=None), 'bar2') - with self.assertRaises(KeyError): - cf['No Such Spacey Bar'].get('foo', None) - eq(cf['Types'].getint('int', 18), 42) - eq(cf['Types'].getint('int', fallback=18), 42) - eq(cf['Types'].getint('no-such-int', 18), 18) - eq(cf['Types'].getint('no-such-int', fallback=18), 18) - eq(cf['Types'].getint('no-such-int', "18"), "18") # sic! - eq(cf['Types'].getint('no-such-int', fallback="18"), "18") # sic! - eq(cf['Types'].getint('no-such-int'), None) - self.assertAlmostEqual(cf['Types'].getfloat('float', 0.0), 0.44) - self.assertAlmostEqual(cf['Types'].getfloat('float', - fallback=0.0), 0.44) - self.assertAlmostEqual(cf['Types'].getfloat('no-such-float', 0.0), 0.0) - self.assertAlmostEqual(cf['Types'].getfloat('no-such-float', - fallback=0.0), 0.0) - eq(cf['Types'].getfloat('no-such-float', "0.0"), "0.0") # sic! - eq(cf['Types'].getfloat('no-such-float', fallback="0.0"), "0.0") # sic! - eq(cf['Types'].getfloat('no-such-float'), None) - eq(cf['Types'].getboolean('boolean', True), False) - eq(cf['Types'].getboolean('boolean', fallback=True), False) - eq(cf['Types'].getboolean('no-such-boolean', "yes"), "yes") # sic! - eq(cf['Types'].getboolean('no-such-boolean', fallback="yes"), - "yes") # sic! - eq(cf['Types'].getboolean('no-such-boolean', True), True) - eq(cf['Types'].getboolean('no-such-boolean', fallback=True), True) - eq(cf['Types'].getboolean('no-such-boolean'), None) - if self.allow_no_value: - eq(cf['NoValue'].get('option-without-value', False), None) - eq(cf['NoValue'].get('option-without-value', fallback=False), None) - eq(cf['NoValue'].get('no-such-option-without-value', False), False) - eq(cf['NoValue'].get('no-such-option-without-value', - fallback=False), False) - - # Make sure the right things happen for remove_section() and - # remove_option(); added to include check for SourceForge bug #123324. - - cf[self.default_section]['this_value'] = '1' - cf[self.default_section]['that_value'] = '2' - - # API access - self.assertTrue(cf.remove_section('Spaces')) - self.assertFalse(cf.has_option('Spaces', 'key with spaces')) - self.assertFalse(cf.remove_section('Spaces')) - self.assertFalse(cf.remove_section(self.default_section)) - self.assertTrue(cf.remove_option('Foo Bar', 'foo'), - "remove_option() failed to report existence of option") - self.assertFalse(cf.has_option('Foo Bar', 'foo'), - "remove_option() failed to remove option") - self.assertFalse(cf.remove_option('Foo Bar', 'foo'), - "remove_option() failed to report non-existence of option" - " that was removed") - self.assertTrue(cf.has_option('Foo Bar', 'this_value')) - self.assertFalse(cf.remove_option('Foo Bar', 'this_value')) - self.assertTrue(cf.remove_option(self.default_section, 'this_value')) - self.assertFalse(cf.has_option('Foo Bar', 'this_value')) - self.assertFalse(cf.remove_option(self.default_section, 'this_value')) - - with self.assertRaises(configparser.NoSectionError) as cm: - cf.remove_option('No Such Section', 'foo') - self.assertEqual(cm.exception.args, ('No Such Section',)) - - eq(cf.get('Long Line', 'foo'), - 'this line is much, much longer than my editor\nlikes it.') - - # mapping access - del cf['Types'] - self.assertFalse('Types' in cf) - with self.assertRaises(KeyError): - del cf['Types'] - with self.assertRaises(ValueError): - del cf[self.default_section] - del cf['Spacey Bar']['foo'] - self.assertFalse('foo' in cf['Spacey Bar']) - with self.assertRaises(KeyError): - del cf['Spacey Bar']['foo'] - self.assertTrue('that_value' in cf['Spacey Bar']) - with self.assertRaises(KeyError): - del cf['Spacey Bar']['that_value'] - del cf[self.default_section]['that_value'] - self.assertFalse('that_value' in cf['Spacey Bar']) - with self.assertRaises(KeyError): - del cf[self.default_section]['that_value'] - with self.assertRaises(KeyError): - del cf['No Such Section']['foo'] - - # Don't add new asserts below in this method as most of the options - # and sections are now removed. - - def test_basic(self): - config_string = """\ -[Foo Bar] -foo{0[0]}bar1 -[Spacey Bar] -foo {0[0]} bar2 -[Spacey Bar From The Beginning] - foo {0[0]} bar3 - baz {0[0]} qwe -[Commented Bar] -foo{0[1]} bar4 {1[1]} comment -baz{0[0]}qwe {1[0]}another one -[Long Line] -foo{0[1]} this line is much, much longer than my editor - likes it. -[Section\\with$weird%characters[\t] -[Internationalized Stuff] -foo[bg]{0[1]} Bulgarian -foo{0[0]}Default -foo[en]{0[0]}English -foo[de]{0[0]}Deutsch -[Spaces] -key with spaces {0[1]} value -another with spaces {0[0]} splat! -[Types] -int {0[1]} 42 -float {0[0]} 0.44 -boolean {0[0]} NO -123 {0[1]} strange but acceptable -""".format(self.delimiters, self.comment_prefixes) - if self.allow_no_value: - config_string += ( - "[NoValue]\n" - "option-without-value\n" - ) - cf = self.fromstring(config_string) - self.basic_test(cf) - if self.strict: - with self.assertRaises(configparser.DuplicateOptionError): - cf.read_string(textwrap.dedent("""\ - [Duplicate Options Here] - option {0[0]} with a value - option {0[1]} with another value - """.format(self.delimiters))) - with self.assertRaises(configparser.DuplicateSectionError): - cf.read_string(textwrap.dedent("""\ - [And Now For Something] - completely different {0[0]} True - [And Now For Something] - the larch {0[1]} 1 - """.format(self.delimiters))) - else: - cf.read_string(textwrap.dedent("""\ - [Duplicate Options Here] - option {0[0]} with a value - option {0[1]} with another value - """.format(self.delimiters))) - - cf.read_string(textwrap.dedent("""\ - [And Now For Something] - completely different {0[0]} True - [And Now For Something] - the larch {0[1]} 1 - """.format(self.delimiters))) - - def test_basic_from_dict(self): - config = { - "Foo Bar": { - "foo": "bar1", - }, - "Spacey Bar": { - "foo": "bar2", - }, - "Spacey Bar From The Beginning": { - "foo": "bar3", - "baz": "qwe", - }, - "Commented Bar": { - "foo": "bar4", - "baz": "qwe", - }, - "Long Line": { - "foo": "this line is much, much longer than my editor\nlikes " - "it.", - }, - "Section\\with$weird%characters[\t": { - }, - "Internationalized Stuff": { - "foo[bg]": "Bulgarian", - "foo": "Default", - "foo[en]": "English", - "foo[de]": "Deutsch", - }, - "Spaces": { - "key with spaces": "value", - "another with spaces": "splat!", - }, - "Types": { - "int": 42, - "float": 0.44, - "boolean": False, - 123: "strange but acceptable", - }, - } - if self.allow_no_value: - config.update({ - "NoValue": { - "option-without-value": None, - } - }) - cf = self.newconfig() - cf.read_dict(config) - self.basic_test(cf) - if self.strict: - with self.assertRaises(configparser.DuplicateSectionError): - cf.read_dict({ - '1': {'key': 'value'}, - 1: {'key2': 'value2'}, - }) - with self.assertRaises(configparser.DuplicateOptionError): - cf.read_dict({ - "Duplicate Options Here": { - 'option': 'with a value', - 'OPTION': 'with another value', - }, - }) - else: - cf.read_dict({ - 'section': {'key': 'value'}, - 'SECTION': {'key2': 'value2'}, - }) - cf.read_dict({ - "Duplicate Options Here": { - 'option': 'with a value', - 'OPTION': 'with another value', - }, - }) - - def test_case_sensitivity(self): - cf = self.newconfig() - cf.add_section("A") - cf.add_section("a") - cf.add_section("B") - L = cf.sections() - L.sort() - eq = self.assertEqual - eq(L, ["A", "B", "a"]) - cf.set("a", "B", "value") - eq(cf.options("a"), ["b"]) - eq(cf.get("a", "b"), "value", - "could not locate option, expecting case-insensitive option names") - with self.assertRaises(configparser.NoSectionError): - # section names are case-sensitive - cf.set("b", "A", "value") - self.assertTrue(cf.has_option("a", "b")) - self.assertFalse(cf.has_option("b", "b")) - cf.set("A", "A-B", "A-B value") - for opt in ("a-b", "A-b", "a-B", "A-B"): - self.assertTrue( - cf.has_option("A", opt), - "has_option() returned false for option which should exist") - eq(cf.options("A"), ["a-b"]) - eq(cf.options("a"), ["b"]) - cf.remove_option("a", "B") - eq(cf.options("a"), []) - - # SF bug #432369: - cf = self.fromstring( - "[MySection]\nOption{} first line \n\tsecond line \n".format( - self.delimiters[0])) - eq(cf.options("MySection"), ["option"]) - eq(cf.get("MySection", "Option"), "first line\nsecond line") - - # SF bug #561822: - cf = self.fromstring("[section]\n" - "nekey{}nevalue\n".format(self.delimiters[0]), - defaults={"key":"value"}) - self.assertTrue(cf.has_option("section", "Key")) - - - def test_case_sensitivity_mapping_access(self): - cf = self.newconfig() - cf["A"] = {} - cf["a"] = {"B": "value"} - cf["B"] = {} - L = [section for section in cf] - L.sort() - eq = self.assertEqual - elem_eq = self.assertCountEqual - eq(L, sorted(["A", "B", self.default_section, "a"])) - eq(cf["a"].keys(), {"b"}) - eq(cf["a"]["b"], "value", - "could not locate option, expecting case-insensitive option names") - with self.assertRaises(KeyError): - # section names are case-sensitive - cf["b"]["A"] = "value" - self.assertTrue("b" in cf["a"]) - cf["A"]["A-B"] = "A-B value" - for opt in ("a-b", "A-b", "a-B", "A-B"): - self.assertTrue( - opt in cf["A"], - "has_option() returned false for option which should exist") - eq(cf["A"].keys(), {"a-b"}) - eq(cf["a"].keys(), {"b"}) - del cf["a"]["B"] - elem_eq(cf["a"].keys(), {}) - - # SF bug #432369: - cf = self.fromstring( - "[MySection]\nOption{} first line \n\tsecond line \n".format( - self.delimiters[0])) - eq(cf["MySection"].keys(), {"option"}) - eq(cf["MySection"]["Option"], "first line\nsecond line") - - # SF bug #561822: - cf = self.fromstring("[section]\n" - "nekey{}nevalue\n".format(self.delimiters[0]), - defaults={"key":"value"}) - self.assertTrue("Key" in cf["section"]) - - def test_default_case_sensitivity(self): - cf = self.newconfig({"foo": "Bar"}) - self.assertEqual( - cf.get(self.default_section, "Foo"), "Bar", - "could not locate option, expecting case-insensitive option names") - cf = self.newconfig({"Foo": "Bar"}) - self.assertEqual( - cf.get(self.default_section, "Foo"), "Bar", - "could not locate option, expecting case-insensitive defaults") - - def test_parse_errors(self): - cf = self.newconfig() - self.parse_error(cf, configparser.ParsingError, - "[Foo]\n" - "{}val-without-opt-name\n".format(self.delimiters[0])) - self.parse_error(cf, configparser.ParsingError, - "[Foo]\n" - "{}val-without-opt-name\n".format(self.delimiters[1])) - e = self.parse_error(cf, configparser.MissingSectionHeaderError, - "No Section!\n") - self.assertEqual(e.args, ('<???>', 1, "No Section!\n")) - if not self.allow_no_value: - e = self.parse_error(cf, configparser.ParsingError, - "[Foo]\n wrong-indent\n") - self.assertEqual(e.args, ('<???>',)) - # read_file on a real file - tricky = support.findfile("cfgparser.3") - if self.delimiters[0] == '=': - error = configparser.ParsingError - expected = (tricky,) - else: - error = configparser.MissingSectionHeaderError - expected = (tricky, 1, - ' # INI with as many tricky parts as possible\n') - with open(tricky, encoding='utf-8') as f: - e = self.parse_error(cf, error, f) - self.assertEqual(e.args, expected) - - def parse_error(self, cf, exc, src): - if hasattr(src, 'readline'): - sio = src - else: - sio = io.StringIO(src) - with self.assertRaises(exc) as cm: - cf.read_file(sio) - return cm.exception - - def test_query_errors(self): - cf = self.newconfig() - self.assertEqual(cf.sections(), [], - "new ConfigParser should have no defined sections") - self.assertFalse(cf.has_section("Foo"), - "new ConfigParser should have no acknowledged " - "sections") - with self.assertRaises(configparser.NoSectionError): - cf.options("Foo") - with self.assertRaises(configparser.NoSectionError): - cf.set("foo", "bar", "value") - e = self.get_error(cf, configparser.NoSectionError, "foo", "bar") - self.assertEqual(e.args, ("foo",)) - cf.add_section("foo") - e = self.get_error(cf, configparser.NoOptionError, "foo", "bar") - self.assertEqual(e.args, ("bar", "foo")) - - def get_error(self, cf, exc, section, option): - try: - cf.get(section, option) - except exc as e: - return e - else: - self.fail("expected exception type %s.%s" - % (exc.__module__, exc.__name__)) - - def test_boolean(self): - cf = self.fromstring( - "[BOOLTEST]\n" - "T1{equals}1\n" - "T2{equals}TRUE\n" - "T3{equals}True\n" - "T4{equals}oN\n" - "T5{equals}yes\n" - "F1{equals}0\n" - "F2{equals}FALSE\n" - "F3{equals}False\n" - "F4{equals}oFF\n" - "F5{equals}nO\n" - "E1{equals}2\n" - "E2{equals}foo\n" - "E3{equals}-1\n" - "E4{equals}0.1\n" - "E5{equals}FALSE AND MORE".format(equals=self.delimiters[0]) - ) - for x in range(1, 5): - self.assertTrue(cf.getboolean('BOOLTEST', 't%d' % x)) - self.assertFalse(cf.getboolean('BOOLTEST', 'f%d' % x)) - self.assertRaises(ValueError, - cf.getboolean, 'BOOLTEST', 'e%d' % x) - - def test_weird_errors(self): - cf = self.newconfig() - cf.add_section("Foo") - with self.assertRaises(configparser.DuplicateSectionError) as cm: - cf.add_section("Foo") - e = cm.exception - self.assertEqual(str(e), "Section 'Foo' already exists") - self.assertEqual(e.args, ("Foo", None, None)) - - if self.strict: - with self.assertRaises(configparser.DuplicateSectionError) as cm: - cf.read_string(textwrap.dedent("""\ - [Foo] - will this be added{equals}True - [Bar] - what about this{equals}True - [Foo] - oops{equals}this won't - """.format(equals=self.delimiters[0])), source='<foo-bar>') - e = cm.exception - self.assertEqual(str(e), "While reading from <foo-bar> [line 5]: " - "section 'Foo' already exists") - self.assertEqual(e.args, ("Foo", '<foo-bar>', 5)) - - with self.assertRaises(configparser.DuplicateOptionError) as cm: - cf.read_dict({'Bar': {'opt': 'val', 'OPT': 'is really `opt`'}}) - e = cm.exception - self.assertEqual(str(e), "While reading from <dict>: option 'opt' " - "in section 'Bar' already exists") - self.assertEqual(e.args, ("Bar", "opt", "<dict>", None)) - - def test_write(self): - config_string = ( - "[Long Line]\n" - "foo{0[0]} this line is much, much longer than my editor\n" - " likes it.\n" - "[{default_section}]\n" - "foo{0[1]} another very\n" - " long line\n" - "[Long Line - With Comments!]\n" - "test {0[1]} we {comment} can\n" - " also {comment} place\n" - " comments {comment} in\n" - " multiline {comment} values" - "\n".format(self.delimiters, comment=self.comment_prefixes[0], - default_section=self.default_section) - ) - if self.allow_no_value: - config_string += ( - "[Valueless]\n" - "option-without-value\n" - ) - - cf = self.fromstring(config_string) - for space_around_delimiters in (True, False): - output = io.StringIO() - cf.write(output, space_around_delimiters=space_around_delimiters) - delimiter = self.delimiters[0] - if space_around_delimiters: - delimiter = " {} ".format(delimiter) - expect_string = ( - "[{default_section}]\n" - "foo{equals}another very\n" - "\tlong line\n" - "\n" - "[Long Line]\n" - "foo{equals}this line is much, much longer than my editor\n" - "\tlikes it.\n" - "\n" - "[Long Line - With Comments!]\n" - "test{equals}we\n" - "\talso\n" - "\tcomments\n" - "\tmultiline\n" - "\n".format(equals=delimiter, - default_section=self.default_section) - ) - if self.allow_no_value: - expect_string += ( - "[Valueless]\n" - "option-without-value\n" - "\n" - ) - self.assertEqual(output.getvalue(), expect_string) - - def test_set_string_types(self): - cf = self.fromstring("[sect]\n" - "option1{eq}foo\n".format(eq=self.delimiters[0])) - # Check that we don't get an exception when setting values in - # an existing section using strings: - class mystr(str): - pass - cf.set("sect", "option1", "splat") - cf.set("sect", "option1", mystr("splat")) - cf.set("sect", "option2", "splat") - cf.set("sect", "option2", mystr("splat")) - cf.set("sect", "option1", "splat") - cf.set("sect", "option2", "splat") - - def test_read_returns_file_list(self): - if self.delimiters[0] != '=': - # skip reading the file if we're using an incompatible format - return - file1 = support.findfile("cfgparser.1") - # check when we pass a mix of readable and non-readable files: - cf = self.newconfig() - parsed_files = cf.read([file1, "nonexistent-file"]) - self.assertEqual(parsed_files, [file1]) - self.assertEqual(cf.get("Foo Bar", "foo"), "newbar") - # check when we pass only a filename: - cf = self.newconfig() - parsed_files = cf.read(file1) - self.assertEqual(parsed_files, [file1]) - self.assertEqual(cf.get("Foo Bar", "foo"), "newbar") - # check when we pass only missing files: - cf = self.newconfig() - parsed_files = cf.read(["nonexistent-file"]) - self.assertEqual(parsed_files, []) - # check when we pass no files: - cf = self.newconfig() - parsed_files = cf.read([]) - self.assertEqual(parsed_files, []) - - # shared by subclasses - def get_interpolation_config(self): - return self.fromstring( - "[Foo]\n" - "bar{equals}something %(with1)s interpolation (1 step)\n" - "bar9{equals}something %(with9)s lots of interpolation (9 steps)\n" - "bar10{equals}something %(with10)s lots of interpolation (10 steps)\n" - "bar11{equals}something %(with11)s lots of interpolation (11 steps)\n" - "with11{equals}%(with10)s\n" - "with10{equals}%(with9)s\n" - "with9{equals}%(with8)s\n" - "with8{equals}%(With7)s\n" - "with7{equals}%(WITH6)s\n" - "with6{equals}%(with5)s\n" - "With5{equals}%(with4)s\n" - "WITH4{equals}%(with3)s\n" - "with3{equals}%(with2)s\n" - "with2{equals}%(with1)s\n" - "with1{equals}with\n" - "\n" - "[Mutual Recursion]\n" - "foo{equals}%(bar)s\n" - "bar{equals}%(foo)s\n" - "\n" - "[Interpolation Error]\n" - # no definition for 'reference' - "name{equals}%(reference)s\n".format(equals=self.delimiters[0])) - - def check_items_config(self, expected): - cf = self.fromstring(""" - [section] - name {0[0]} %(value)s - key{0[1]} |%(name)s| - getdefault{0[1]} |%(default)s| - """.format(self.delimiters), defaults={"default": "<default>"}) - L = list(cf.items("section", vars={'value': 'value'})) - L.sort() - self.assertEqual(L, expected) - with self.assertRaises(configparser.NoSectionError): - cf.items("no such section") - - -class StrictTestCase(BasicTestCase): - config_class = configparser.RawConfigParser - strict = True - - -class ConfigParserTestCase(BasicTestCase): - config_class = configparser.ConfigParser - - def test_interpolation(self): - cf = self.get_interpolation_config() - eq = self.assertEqual - eq(cf.get("Foo", "bar"), "something with interpolation (1 step)") - eq(cf.get("Foo", "bar9"), - "something with lots of interpolation (9 steps)") - eq(cf.get("Foo", "bar10"), - "something with lots of interpolation (10 steps)") - e = self.get_error(cf, configparser.InterpolationDepthError, "Foo", "bar11") - if self.interpolation == configparser._UNSET: - self.assertEqual(e.args, ("bar11", "Foo", "%(with1)s")) - elif isinstance(self.interpolation, configparser.LegacyInterpolation): - self.assertEqual(e.args, ("bar11", "Foo", - "something %(with11)s lots of interpolation (11 steps)")) - - def test_interpolation_missing_value(self): - cf = self.get_interpolation_config() - e = self.get_error(cf, configparser.InterpolationMissingOptionError, - "Interpolation Error", "name") - self.assertEqual(e.reference, "reference") - self.assertEqual(e.section, "Interpolation Error") - self.assertEqual(e.option, "name") - if self.interpolation == configparser._UNSET: - self.assertEqual(e.args, ('name', 'Interpolation Error', - '', 'reference')) - elif isinstance(self.interpolation, configparser.LegacyInterpolation): - self.assertEqual(e.args, ('name', 'Interpolation Error', - '%(reference)s', 'reference')) - - def test_items(self): - self.check_items_config([('default', '<default>'), - ('getdefault', '|<default>|'), - ('key', '|value|'), - ('name', 'value'), - ('value', 'value')]) - - def test_safe_interpolation(self): - # See http://www.python.org/sf/511737 - cf = self.fromstring("[section]\n" - "option1{eq}xxx\n" - "option2{eq}%(option1)s/xxx\n" - "ok{eq}%(option1)s/%%s\n" - "not_ok{eq}%(option2)s/%%s".format( - eq=self.delimiters[0])) - self.assertEqual(cf.get("section", "ok"), "xxx/%s") - if self.interpolation == configparser._UNSET: - self.assertEqual(cf.get("section", "not_ok"), "xxx/xxx/%s") - elif isinstance(self.interpolation, configparser.LegacyInterpolation): - with self.assertRaises(TypeError): - cf.get("section", "not_ok") - - def test_set_malformatted_interpolation(self): - cf = self.fromstring("[sect]\n" - "option1{eq}foo\n".format(eq=self.delimiters[0])) - - self.assertEqual(cf.get('sect', "option1"), "foo") - - self.assertRaises(ValueError, cf.set, "sect", "option1", "%foo") - self.assertRaises(ValueError, cf.set, "sect", "option1", "foo%") - self.assertRaises(ValueError, cf.set, "sect", "option1", "f%oo") - - self.assertEqual(cf.get('sect', "option1"), "foo") - - # bug #5741: double percents are *not* malformed - cf.set("sect", "option2", "foo%%bar") - self.assertEqual(cf.get("sect", "option2"), "foo%bar") - - def test_set_nonstring_types(self): - cf = self.fromstring("[sect]\n" - "option1{eq}foo\n".format(eq=self.delimiters[0])) - # Check that we get a TypeError when setting non-string values - # in an existing section: - self.assertRaises(TypeError, cf.set, "sect", "option1", 1) - self.assertRaises(TypeError, cf.set, "sect", "option1", 1.0) - self.assertRaises(TypeError, cf.set, "sect", "option1", object()) - self.assertRaises(TypeError, cf.set, "sect", "option2", 1) - self.assertRaises(TypeError, cf.set, "sect", "option2", 1.0) - self.assertRaises(TypeError, cf.set, "sect", "option2", object()) - self.assertRaises(TypeError, cf.set, "sect", 123, "invalid opt name!") - self.assertRaises(TypeError, cf.add_section, 123) - - def test_add_section_default(self): - cf = self.newconfig() - self.assertRaises(ValueError, cf.add_section, self.default_section) - -class ConfigParserTestCaseLegacyInterpolation(ConfigParserTestCase): - config_class = configparser.ConfigParser - interpolation = configparser.LegacyInterpolation() - - def test_set_malformatted_interpolation(self): - cf = self.fromstring("[sect]\n" - "option1{eq}foo\n".format(eq=self.delimiters[0])) - - self.assertEqual(cf.get('sect', "option1"), "foo") - - cf.set("sect", "option1", "%foo") - self.assertEqual(cf.get('sect', "option1"), "%foo") - cf.set("sect", "option1", "foo%") - self.assertEqual(cf.get('sect', "option1"), "foo%") - cf.set("sect", "option1", "f%oo") - self.assertEqual(cf.get('sect', "option1"), "f%oo") - - # bug #5741: double percents are *not* malformed - cf.set("sect", "option2", "foo%%bar") - self.assertEqual(cf.get("sect", "option2"), "foo%%bar") - -class ConfigParserTestCaseNonStandardDelimiters(ConfigParserTestCase): - delimiters = (':=', '$') - comment_prefixes = ('//', '"') - inline_comment_prefixes = ('//', '"') - -class ConfigParserTestCaseNonStandardDefaultSection(ConfigParserTestCase): - default_section = 'general' - -class MultilineValuesTestCase(BasicTestCase): - config_class = configparser.ConfigParser - wonderful_spam = ("I'm having spam spam spam spam " - "spam spam spam beaked beans spam " - "spam spam and spam!").replace(' ', '\t\n') - - def setUp(self): - cf = self.newconfig() - for i in range(100): - s = 'section{}'.format(i) - cf.add_section(s) - for j in range(10): - cf.set(s, 'lovely_spam{}'.format(j), self.wonderful_spam) - with open(support.TESTFN, 'w') as f: - cf.write(f) - - def tearDown(self): - os.unlink(support.TESTFN) - - def test_dominating_multiline_values(self): - # We're reading from file because this is where the code changed - # during performance updates in Python 3.2 - cf_from_file = self.newconfig() - with open(support.TESTFN) as f: - cf_from_file.read_file(f) - self.assertEqual(cf_from_file.get('section8', 'lovely_spam4'), - self.wonderful_spam.replace('\t\n', '\n')) - -class RawConfigParserTestCase(BasicTestCase): - config_class = configparser.RawConfigParser - - def test_interpolation(self): - cf = self.get_interpolation_config() - eq = self.assertEqual - eq(cf.get("Foo", "bar"), - "something %(with1)s interpolation (1 step)") - eq(cf.get("Foo", "bar9"), - "something %(with9)s lots of interpolation (9 steps)") - eq(cf.get("Foo", "bar10"), - "something %(with10)s lots of interpolation (10 steps)") - eq(cf.get("Foo", "bar11"), - "something %(with11)s lots of interpolation (11 steps)") - - def test_items(self): - self.check_items_config([('default', '<default>'), - ('getdefault', '|%(default)s|'), - ('key', '|%(name)s|'), - ('name', '%(value)s'), - ('value', 'value')]) - - def test_set_nonstring_types(self): - cf = self.newconfig() - cf.add_section('non-string') - cf.set('non-string', 'int', 1) - cf.set('non-string', 'list', [0, 1, 1, 2, 3, 5, 8, 13]) - cf.set('non-string', 'dict', {'pi': 3.14159}) - self.assertEqual(cf.get('non-string', 'int'), 1) - self.assertEqual(cf.get('non-string', 'list'), - [0, 1, 1, 2, 3, 5, 8, 13]) - self.assertEqual(cf.get('non-string', 'dict'), {'pi': 3.14159}) - cf.add_section(123) - cf.set(123, 'this is sick', True) - self.assertEqual(cf.get(123, 'this is sick'), True) - if cf._dict.__class__ is configparser._default_dict: - # would not work for SortedDict; only checking for the most common - # default dictionary (OrderedDict) - cf.optionxform = lambda x: x - cf.set('non-string', 1, 1) - self.assertEqual(cf.get('non-string', 1), 1) - -class RawConfigParserTestCaseNonStandardDelimiters(RawConfigParserTestCase): - delimiters = (':=', '$') - comment_prefixes = ('//', '"') - inline_comment_prefixes = ('//', '"') - -class RawConfigParserTestSambaConf(CfgParserTestCaseClass): - config_class = configparser.RawConfigParser - comment_prefixes = ('#', ';', '----') - inline_comment_prefixes = ('//',) - empty_lines_in_values = False - - def test_reading(self): - smbconf = support.findfile("cfgparser.2") - # check when we pass a mix of readable and non-readable files: - cf = self.newconfig() - parsed_files = cf.read([smbconf, "nonexistent-file"], encoding='utf-8') - self.assertEqual(parsed_files, [smbconf]) - sections = ['global', 'homes', 'printers', - 'print$', 'pdf-generator', 'tmp', 'Agustin'] - self.assertEqual(cf.sections(), sections) - self.assertEqual(cf.get("global", "workgroup"), "MDKGROUP") - self.assertEqual(cf.getint("global", "max log size"), 50) - self.assertEqual(cf.get("global", "hosts allow"), "127.") - self.assertEqual(cf.get("tmp", "echo command"), "cat %s; rm %s") - -class ConfigParserTestCaseExtendedInterpolation(BasicTestCase): - config_class = configparser.ConfigParser - interpolation = configparser.ExtendedInterpolation() - default_section = 'common' - - def test_extended_interpolation(self): - cf = self.fromstring(textwrap.dedent(""" - [common] - favourite Beatle = Paul - favourite color = green - - [tom] - favourite band = ${favourite color} day - favourite pope = John ${favourite Beatle} II - sequel = ${favourite pope}I - - [ambv] - favourite Beatle = George - son of Edward VII = ${favourite Beatle} V - son of George V = ${son of Edward VII}I - - [stanley] - favourite Beatle = ${ambv:favourite Beatle} - favourite pope = ${tom:favourite pope} - favourite color = black - favourite state of mind = paranoid - favourite movie = soylent ${common:favourite color} - favourite song = ${favourite color} sabbath - ${favourite state of mind} - """).strip()) - - eq = self.assertEqual - eq(cf['common']['favourite Beatle'], 'Paul') - eq(cf['common']['favourite color'], 'green') - eq(cf['tom']['favourite Beatle'], 'Paul') - eq(cf['tom']['favourite color'], 'green') - eq(cf['tom']['favourite band'], 'green day') - eq(cf['tom']['favourite pope'], 'John Paul II') - eq(cf['tom']['sequel'], 'John Paul III') - eq(cf['ambv']['favourite Beatle'], 'George') - eq(cf['ambv']['favourite color'], 'green') - eq(cf['ambv']['son of Edward VII'], 'George V') - eq(cf['ambv']['son of George V'], 'George VI') - eq(cf['stanley']['favourite Beatle'], 'George') - eq(cf['stanley']['favourite color'], 'black') - eq(cf['stanley']['favourite state of mind'], 'paranoid') - eq(cf['stanley']['favourite movie'], 'soylent green') - eq(cf['stanley']['favourite pope'], 'John Paul II') - eq(cf['stanley']['favourite song'], - 'black sabbath - paranoid') - - def test_endless_loop(self): - cf = self.fromstring(textwrap.dedent(""" - [one for you] - ping = ${one for me:pong} - - [one for me] - pong = ${one for you:ping} - - [selfish] - me = ${me} - """).strip()) - - with self.assertRaises(configparser.InterpolationDepthError): - cf['one for you']['ping'] - with self.assertRaises(configparser.InterpolationDepthError): - cf['selfish']['me'] - - def test_strange_options(self): - cf = self.fromstring(""" - [dollars] - $var = $$value - $var2 = ${$var} - ${sick} = cannot interpolate me - - [interpolated] - $other = ${dollars:$var} - $trying = ${dollars:${sick}} - """) - - self.assertEqual(cf['dollars']['$var'], '$value') - self.assertEqual(cf['interpolated']['$other'], '$value') - self.assertEqual(cf['dollars']['${sick}'], 'cannot interpolate me') - exception_class = configparser.InterpolationMissingOptionError - with self.assertRaises(exception_class) as cm: - cf['interpolated']['$trying'] - self.assertEqual(cm.exception.reference, 'dollars:${sick') - self.assertEqual(cm.exception.args[2], '}') #rawval - - - def test_other_errors(self): - cf = self.fromstring(""" - [interpolation fail] - case1 = ${where's the brace - case2 = ${does_not_exist} - case3 = ${wrong_section:wrong_value} - case4 = ${i:like:colon:characters} - case5 = $100 for Fail No 5! - """) - - with self.assertRaises(configparser.InterpolationSyntaxError): - cf['interpolation fail']['case1'] - with self.assertRaises(configparser.InterpolationMissingOptionError): - cf['interpolation fail']['case2'] - with self.assertRaises(configparser.InterpolationMissingOptionError): - cf['interpolation fail']['case3'] - with self.assertRaises(configparser.InterpolationSyntaxError): - cf['interpolation fail']['case4'] - with self.assertRaises(configparser.InterpolationSyntaxError): - cf['interpolation fail']['case5'] - with self.assertRaises(ValueError): - cf['interpolation fail']['case6'] = "BLACK $ABBATH" - - -class ConfigParserTestCaseNoValue(ConfigParserTestCase): - allow_no_value = True - -class ConfigParserTestCaseTrickyFile(CfgParserTestCaseClass): - config_class = configparser.ConfigParser - delimiters = {'='} - comment_prefixes = {'#'} - allow_no_value = True - - def test_cfgparser_dot_3(self): - tricky = support.findfile("cfgparser.3") - cf = self.newconfig() - self.assertEqual(len(cf.read(tricky, encoding='utf-8')), 1) - self.assertEqual(cf.sections(), ['strange', - 'corruption', - 'yeah, sections can be ' - 'indented as well', - 'another one!', - 'no values here', - 'tricky interpolation', - 'more interpolation']) - self.assertEqual(cf.getint(self.default_section, 'go', - vars={'interpolate': '-1'}), -1) - with self.assertRaises(ValueError): - # no interpolation will happen - cf.getint(self.default_section, 'go', raw=True, - vars={'interpolate': '-1'}) - self.assertEqual(len(cf.get('strange', 'other').split('\n')), 4) - self.assertEqual(len(cf.get('corruption', 'value').split('\n')), 10) - longname = 'yeah, sections can be indented as well' - self.assertFalse(cf.getboolean(longname, 'are they subsections')) - self.assertEqual(cf.get(longname, 'lets use some Unicode'), '片仮名') - self.assertEqual(len(cf.items('another one!')), 5) # 4 in section and - # `go` from DEFAULT - with self.assertRaises(configparser.InterpolationMissingOptionError): - cf.items('no values here') - self.assertEqual(cf.get('tricky interpolation', 'lets'), 'do this') - self.assertEqual(cf.get('tricky interpolation', 'lets'), - cf.get('tricky interpolation', 'go')) - self.assertEqual(cf.get('more interpolation', 'lets'), 'go shopping') - - def test_unicode_failure(self): - tricky = support.findfile("cfgparser.3") - cf = self.newconfig() - with self.assertRaises(UnicodeDecodeError): - cf.read(tricky, encoding='ascii') - - -class Issue7005TestCase(unittest.TestCase): - """Test output when None is set() as a value and allow_no_value == False. - - http://bugs.python.org/issue7005 - - """ - - expected_output = "[section]\noption = None\n\n" - - def prepare(self, config_class): - # This is the default, but that's the point. - cp = config_class(allow_no_value=False) - cp.add_section("section") - cp.set("section", "option", None) - sio = io.StringIO() - cp.write(sio) - return sio.getvalue() - - def test_none_as_value_stringified(self): - cp = configparser.ConfigParser(allow_no_value=False) - cp.add_section("section") - with self.assertRaises(TypeError): - cp.set("section", "option", None) - - def test_none_as_value_stringified_raw(self): - output = self.prepare(configparser.RawConfigParser) - self.assertEqual(output, self.expected_output) - - -class SortedTestCase(RawConfigParserTestCase): - dict_type = SortedDict - - def test_sorted(self): - cf = self.fromstring("[b]\n" - "o4=1\n" - "o3=2\n" - "o2=3\n" - "o1=4\n" - "[a]\n" - "k=v\n") - output = io.StringIO() - cf.write(output) - self.assertEqual(output.getvalue(), - "[a]\n" - "k = v\n\n" - "[b]\n" - "o1 = 4\n" - "o2 = 3\n" - "o3 = 2\n" - "o4 = 1\n\n") - - -class CompatibleTestCase(CfgParserTestCaseClass): - config_class = configparser.RawConfigParser - comment_prefixes = '#;' - inline_comment_prefixes = ';' - - def test_comment_handling(self): - config_string = textwrap.dedent("""\ - [Commented Bar] - baz=qwe ; a comment - foo: bar # not a comment! - # but this is a comment - ; another comment - quirk: this;is not a comment - ; a space must precede an inline comment - """) - cf = self.fromstring(config_string) - self.assertEqual(cf.get('Commented Bar', 'foo'), - 'bar # not a comment!') - self.assertEqual(cf.get('Commented Bar', 'baz'), 'qwe') - self.assertEqual(cf.get('Commented Bar', 'quirk'), - 'this;is not a comment') - -class CopyTestCase(BasicTestCase): - config_class = configparser.ConfigParser - - def fromstring(self, string, defaults=None): - cf = self.newconfig(defaults) - cf.read_string(string) - cf_copy = self.newconfig() - cf_copy.read_dict(cf) - # we have to clean up option duplicates that appeared because of - # the magic DEFAULTSECT behaviour. - for section in cf_copy.values(): - if section.name == self.default_section: - continue - for default, value in cf[self.default_section].items(): - if section[default] == value: - del section[default] - return cf_copy - -class CoverageOneHundredTestCase(unittest.TestCase): - """Covers edge cases in the codebase.""" - - def test_duplicate_option_error(self): - error = configparser.DuplicateOptionError('section', 'option') - self.assertEqual(error.section, 'section') - self.assertEqual(error.option, 'option') - self.assertEqual(error.source, None) - self.assertEqual(error.lineno, None) - self.assertEqual(error.args, ('section', 'option', None, None)) - self.assertEqual(str(error), "Option 'option' in section 'section' " - "already exists") - - def test_interpolation_depth_error(self): - error = configparser.InterpolationDepthError('option', 'section', - 'rawval') - self.assertEqual(error.args, ('option', 'section', 'rawval')) - self.assertEqual(error.option, 'option') - self.assertEqual(error.section, 'section') - - def test_parsing_error(self): - with self.assertRaises(ValueError) as cm: - configparser.ParsingError() - self.assertEqual(str(cm.exception), "Required argument `source' not " - "given.") - with self.assertRaises(ValueError) as cm: - configparser.ParsingError(source='source', filename='filename') - self.assertEqual(str(cm.exception), "Cannot specify both `filename' " - "and `source'. Use `source'.") - error = configparser.ParsingError(filename='source') - self.assertEqual(error.source, 'source') - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always", DeprecationWarning) - self.assertEqual(error.filename, 'source') - error.filename = 'filename' - self.assertEqual(error.source, 'filename') - for warning in w: - self.assertTrue(warning.category is DeprecationWarning) - - def test_interpolation_validation(self): - parser = configparser.ConfigParser() - parser.read_string(""" - [section] - invalid_percent = % - invalid_reference = %(() - invalid_variable = %(does_not_exist)s - """) - with self.assertRaises(configparser.InterpolationSyntaxError) as cm: - parser['section']['invalid_percent'] - self.assertEqual(str(cm.exception), "'%' must be followed by '%' or " - "'(', found: '%'") - with self.assertRaises(configparser.InterpolationSyntaxError) as cm: - parser['section']['invalid_reference'] - self.assertEqual(str(cm.exception), "bad interpolation variable " - "reference '%(()'") - - def test_readfp_deprecation(self): - sio = io.StringIO(""" - [section] - option = value - """) - parser = configparser.ConfigParser() - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always", DeprecationWarning) - parser.readfp(sio, filename='StringIO') - for warning in w: - self.assertTrue(warning.category is DeprecationWarning) - self.assertEqual(len(parser), 2) - self.assertEqual(parser['section']['option'], 'value') - - def test_safeconfigparser_deprecation(self): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always", DeprecationWarning) - parser = configparser.SafeConfigParser() - for warning in w: - self.assertTrue(warning.category is DeprecationWarning) - - def test_sectionproxy_repr(self): - parser = configparser.ConfigParser() - parser.read_string(""" - [section] - key = value - """) - self.assertEqual(repr(parser['section']), '<Section: section>') - -def test_main(): - support.run_unittest( - ConfigParserTestCase, - ConfigParserTestCaseNonStandardDelimiters, - ConfigParserTestCaseNoValue, - ConfigParserTestCaseExtendedInterpolation, - ConfigParserTestCaseLegacyInterpolation, - ConfigParserTestCaseTrickyFile, - MultilineValuesTestCase, - RawConfigParserTestCase, - RawConfigParserTestCaseNonStandardDelimiters, - RawConfigParserTestSambaConf, - SortedTestCase, - Issue7005TestCase, - StrictTestCase, - CompatibleTestCase, - CopyTestCase, - ConfigParserTestCaseNonStandardDefaultSection, - CoverageOneHundredTestCase, - ) |
