14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport ConfigParser
24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport StringIO
34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport os
44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport unittest
54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport UserDict
64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfrom test import test_support
84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass SortedDict(UserDict.UserDict):
114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def items(self):
124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        result = self.data.items()
134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        result.sort()
144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return result
154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def keys(self):
174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        result = self.data.keys()
184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        result.sort()
194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return result
204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def values(self):
224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # XXX never used?
234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        result = self.items()
244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return [i[1] for i in result]
254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def iteritems(self): return iter(self.items())
274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def iterkeys(self): return iter(self.keys())
284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    __iter__ = iterkeys
294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def itervalues(self): return iter(self.values())
304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass TestCaseBase(unittest.TestCase):
334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    allow_no_value = False
344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def newconfig(self, defaults=None):
364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if defaults is None:
374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.cf = self.config_class(allow_no_value=self.allow_no_value)
384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.cf = self.config_class(defaults,
404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                        allow_no_value=self.allow_no_value)
414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.cf
424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def fromstring(self, string, defaults=None):
444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.newconfig(defaults)
454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        sio = StringIO.StringIO(string)
464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.readfp(sio)
474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return cf
484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_basic(self):
504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        config_string = (
514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[Foo Bar]\n"
524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "foo=bar\n"
534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[Spacey Bar]\n"
544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "foo = bar\n"
554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[Commented Bar]\n"
564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "foo: bar ; comment\n"
574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[Long Line]\n"
584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "foo: this line is much, much longer than my editor\n"
594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "   likes it.\n"
604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[Section\\with$weird%characters[\t]\n"
614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[Internationalized Stuff]\n"
624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "foo[bg]: Bulgarian\n"
634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "foo=Default\n"
644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "foo[en]=English\n"
654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "foo[de]=Deutsch\n"
664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[Spaces]\n"
674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "key with spaces : value\n"
684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "another with spaces = splat!\n"
694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            )
704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if self.allow_no_value:
714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            config_string += (
724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "[NoValue]\n"
734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "option-without-value\n"
744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                )
754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.fromstring(config_string)
774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        L = cf.sections()
784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        L.sort()
794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        E = [r'Commented Bar',
804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm             r'Foo Bar',
814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm             r'Internationalized Stuff',
824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm             r'Long Line',
834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm             r'Section\with$weird%characters[' '\t',
844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm             r'Spaces',
854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm             r'Spacey Bar',
864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm             ]
874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if self.allow_no_value:
884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            E.append(r'NoValue')
894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        E.sort()
904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq = self.assertEqual
914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(L, E)
924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # The use of spaces in the section names serves as a
944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # regression test for SourceForge bug #583248:
954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # http://www.python.org/sf/583248
964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get('Foo Bar', 'foo'), 'bar')
974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get('Spacey Bar', 'foo'), 'bar')
984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get('Commented Bar', 'foo'), 'bar')
994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get('Spaces', 'key with spaces'), 'value')
1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get('Spaces', 'another with spaces'), 'splat!')
1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if self.allow_no_value:
1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            eq(cf.get('NoValue', 'option-without-value'), None)
1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertNotIn('__name__', cf.options("Foo Bar"),
1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         '__name__ "option" should not be exposed by the API!')
1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Make sure the right things happen for remove_option();
1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # added to include check for SourceForge bug #123324:
1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(cf.remove_option('Foo Bar', 'foo'),
1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "remove_option() failed to report existence of option")
1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(cf.has_option('Foo Bar', 'foo'),
1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "remove_option() failed to remove option")
1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(cf.remove_option('Foo Bar', 'foo'),
1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "remove_option() failed to report non-existence of option"
1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    " that was removed")
1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ConfigParser.NoSectionError,
1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          cf.remove_option, 'No Such Section', 'foo')
1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get('Long Line', 'foo'),
1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           'this line is much, much longer than my editor\nlikes it.')
1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_case_sensitivity(self):
1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.newconfig()
1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.add_section("A")
1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.add_section("a")
1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        L = cf.sections()
1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        L.sort()
1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq = self.assertEqual
1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(L, ["A", "a"])
1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.set("a", "B", "value")
1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.options("a"), ["b"])
1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get("a", "b"), "value",
1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           "could not locate option, expecting case-insensitive option names")
1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(cf.has_option("a", "b"))
1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.set("A", "A-B", "A-B value")
1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for opt in ("a-b", "A-b", "a-B", "A-B"):
1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(
1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                cf.has_option("A", opt),
1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "has_option() returned false for option which should exist")
1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.options("A"), ["a-b"])
1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.options("a"), ["b"])
1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.remove_option("a", "B")
1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.options("a"), [])
1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # SF bug #432369:
1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.fromstring(
1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[MySection]\nOption: first line\n\tsecond line\n")
1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.options("MySection"), ["option"])
1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get("MySection", "Option"), "first line\nsecond line")
1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # SF bug #561822:
1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.fromstring("[section]\nnekey=nevalue\n",
1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             defaults={"key":"value"})
1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertTrue(cf.has_option("section", "Key"))
1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_default_case_sensitivity(self):
1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.newconfig({"foo": "Bar"})
1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(
1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            cf.get("DEFAULT", "Foo"), "Bar",
1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "could not locate option, expecting case-insensitive option names")
1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.newconfig({"Foo": "Bar"})
1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(
1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            cf.get("DEFAULT", "Foo"), "Bar",
1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "could not locate option, expecting case-insensitive defaults")
1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_parse_errors(self):
1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.newconfig()
1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.parse_error(ConfigParser.ParsingError,
1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "[Foo]\n  extra-spaces: splat\n")
1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.parse_error(ConfigParser.ParsingError,
1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "[Foo]\n  extra-spaces= splat\n")
1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.parse_error(ConfigParser.ParsingError,
1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "[Foo]\n:value-without-option-name\n")
1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.parse_error(ConfigParser.ParsingError,
1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "[Foo]\n=value-without-option-name\n")
1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.parse_error(ConfigParser.MissingSectionHeaderError,
1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "No Section!\n")
1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def parse_error(self, exc, src):
1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        sio = StringIO.StringIO(src)
1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(exc, self.cf.readfp, sio)
1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_query_errors(self):
1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.newconfig()
1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf.sections(), [],
1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "new ConfigParser should have no defined sections")
1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertFalse(cf.has_section("Foo"),
1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "new ConfigParser should have no acknowledged "
1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "sections")
1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ConfigParser.NoSectionError,
1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          cf.options, "Foo")
1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ConfigParser.NoSectionError,
1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          cf.set, "foo", "bar", "value")
1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.get_error(ConfigParser.NoSectionError, "foo", "bar")
1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.add_section("foo")
1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.get_error(ConfigParser.NoOptionError, "foo", "bar")
1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def get_error(self, exc, section, option):
2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        try:
2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.cf.get(section, option)
2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        except exc, e:
2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return e
2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.fail("expected exception type %s.%s"
2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      % (exc.__module__, exc.__name__))
2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_boolean(self):
2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.fromstring(
2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[BOOLTEST]\n"
2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "T1=1\n"
2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "T2=TRUE\n"
2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "T3=True\n"
2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "T4=oN\n"
2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "T5=yes\n"
2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "F1=0\n"
2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "F2=FALSE\n"
2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "F3=False\n"
2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "F4=oFF\n"
2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "F5=nO\n"
2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "E1=2\n"
2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "E2=foo\n"
2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "E3=-1\n"
2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "E4=0.1\n"
2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "E5=FALSE AND MORE"
2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            )
2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for x in range(1, 5):
2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertTrue(cf.getboolean('BOOLTEST', 't%d' % x))
2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertFalse(cf.getboolean('BOOLTEST', 'f%d' % x))
2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            self.assertRaises(ValueError,
2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                              cf.getboolean, 'BOOLTEST', 'e%d' % x)
2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_weird_errors(self):
2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.newconfig()
2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.add_section("Foo")
2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ConfigParser.DuplicateSectionError,
2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          cf.add_section, "Foo")
2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_write(self):
2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        config_string = (
2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[Long Line]\n"
2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "foo: this line is much, much longer than my editor\n"
2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "   likes it.\n"
2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[DEFAULT]\n"
2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "foo: another very\n"
2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            " long line\n"
2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            )
2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if self.allow_no_value:
2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            config_string += (
2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[Valueless]\n"
2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "option-without-value\n"
2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            )
2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.fromstring(config_string)
2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        output = StringIO.StringIO()
2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.write(output)
2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        expect_string = (
2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[DEFAULT]\n"
2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "foo = another very\n"
2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "\tlong line\n"
2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "\n"
2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[Long Line]\n"
2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "foo = this line is much, much longer than my editor\n"
2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "\tlikes it.\n"
2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "\n"
2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            )
2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if self.allow_no_value:
2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            expect_string += (
2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "[Valueless]\n"
2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "option-without-value\n"
2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "\n"
2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                )
2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(output.getvalue(), expect_string)
2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_set_string_types(self):
2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.fromstring("[sect]\n"
2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             "option1=foo\n")
2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Check that we don't get an exception when setting values in
2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # an existing section using strings:
2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        class mystr(str):
2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.set("sect", "option1", "splat")
2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.set("sect", "option1", mystr("splat"))
2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.set("sect", "option2", "splat")
2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.set("sect", "option2", mystr("splat"))
2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        try:
2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            unicode
2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        except NameError:
2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pass
2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else:
2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            cf.set("sect", "option1", unicode("splat"))
2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            cf.set("sect", "option2", unicode("splat"))
2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_read_returns_file_list(self):
2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        file1 = test_support.findfile("cfgparser.1")
2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # check when we pass a mix of readable and non-readable files:
2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.newconfig()
2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        parsed_files = cf.read([file1, "nonexistent-file"])
3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(parsed_files, [file1])
3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf.get("Foo Bar", "foo"), "newbar")
3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # check when we pass only a filename:
3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.newconfig()
3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        parsed_files = cf.read(file1)
3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(parsed_files, [file1])
3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf.get("Foo Bar", "foo"), "newbar")
3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # check when we pass only missing files:
3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.newconfig()
3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        parsed_files = cf.read(["nonexistent-file"])
3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(parsed_files, [])
3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # check when we pass no files:
3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.newconfig()
3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        parsed_files = cf.read([])
3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(parsed_files, [])
3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    # shared by subclasses
3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def get_interpolation_config(self):
3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.fromstring(
3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[Foo]\n"
3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "bar=something %(with1)s interpolation (1 step)\n"
3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "bar9=something %(with9)s lots of interpolation (9 steps)\n"
3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "bar10=something %(with10)s lots of interpolation (10 steps)\n"
3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "bar11=something %(with11)s lots of interpolation (11 steps)\n"
3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "with11=%(with10)s\n"
3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "with10=%(with9)s\n"
3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "with9=%(with8)s\n"
3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "with8=%(With7)s\n"
3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "with7=%(WITH6)s\n"
3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "with6=%(with5)s\n"
3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "With5=%(with4)s\n"
3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "WITH4=%(with3)s\n"
3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "with3=%(with2)s\n"
3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "with2=%(with1)s\n"
3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "with1=with\n"
3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "\n"
3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[Mutual Recursion]\n"
3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "foo=%(bar)s\n"
3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "bar=%(foo)s\n"
3394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "\n"
3404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[Interpolation Error]\n"
3414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "name=%(reference)s\n",
3424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            # no definition for 'reference'
3434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            defaults={"getname": "%(__name__)s"})
3444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def check_items_config(self, expected):
3464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.fromstring(
3474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "[section]\n"
3484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "name = value\n"
3494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "key: |%(name)s| \n"
3504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "getdefault: |%(default)s|\n"
3514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "getname: |%(__name__)s|",
3524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            defaults={"default": "<default>"})
3534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        L = list(cf.items("section"))
3544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        L.sort()
3554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(L, expected)
3564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass ConfigParserTestCase(TestCaseBase):
3594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    config_class = ConfigParser.ConfigParser
3604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    allow_no_value = True
3614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_interpolation(self):
3634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        rawval = {
3644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ConfigParser.ConfigParser: ("something %(with11)s "
3654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                        "lots of interpolation (11 steps)"),
3664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            ConfigParser.SafeConfigParser: "%(with1)s",
3674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
3684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.get_interpolation_config()
3694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq = self.assertEqual
3704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get("Foo", "getname"), "Foo")
3714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get("Foo", "bar"), "something with interpolation (1 step)")
3724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get("Foo", "bar9"),
3734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           "something with lots of interpolation (9 steps)")
3744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get("Foo", "bar10"),
3754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           "something with lots of interpolation (10 steps)")
3764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.get_error(ConfigParser.InterpolationDepthError, "Foo", "bar11")
3774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_interpolation_missing_value(self):
3794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.get_interpolation_config()
3804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        e = self.get_error(ConfigParser.InterpolationError,
3814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           "Interpolation Error", "name")
3824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(e.reference, "reference")
3834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(e.section, "Interpolation Error")
3844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(e.option, "name")
3854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_items(self):
3874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.check_items_config([('default', '<default>'),
3884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                 ('getdefault', '|<default>|'),
3894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                 ('getname', '|section|'),
3904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                 ('key', '|value|'),
3914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                 ('name', 'value')])
3924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_set_nonstring_types(self):
3944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.newconfig()
3954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.add_section('non-string')
3964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.set('non-string', 'int', 1)
3974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.set('non-string', 'list', [0, 1, 1, 2, 3, 5, 8, 13, '%('])
3984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.set('non-string', 'dict', {'pi': 3.14159, '%(': 1,
3994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                      '%(list)': '%(list)'})
4004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.set('non-string', 'string_with_interpolation', '%(list)s')
4014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.set('non-string', 'no-value')
4024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf.get('non-string', 'int', raw=True), 1)
4034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, cf.get, 'non-string', 'int')
4044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf.get('non-string', 'list', raw=True),
4054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         [0, 1, 1, 2, 3, 5, 8, 13, '%('])
4064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, cf.get, 'non-string', 'list')
4074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf.get('non-string', 'dict', raw=True),
4084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         {'pi': 3.14159, '%(': 1, '%(list)': '%(list)'})
4094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, cf.get, 'non-string', 'dict')
4104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf.get('non-string', 'string_with_interpolation',
4114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                raw=True), '%(list)s')
4124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ValueError, cf.get, 'non-string',
4134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          'string_with_interpolation', raw=False)
4144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf.get('non-string', 'no-value'), None)
4154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass MultilineValuesTestCase(TestCaseBase):
4174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    config_class = ConfigParser.ConfigParser
4184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    wonderful_spam = ("I'm having spam spam spam spam "
4194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      "spam spam spam beaked beans spam "
4204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      "spam spam and spam!").replace(' ', '\t\n')
4214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def setUp(self):
4234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.newconfig()
4244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for i in range(100):
4254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            s = 'section{}'.format(i)
4264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            cf.add_section(s)
4274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            for j in range(10):
4284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                cf.set(s, 'lovely_spam{}'.format(j), self.wonderful_spam)
4294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        with open(test_support.TESTFN, 'w') as f:
4304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            cf.write(f)
4314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def tearDown(self):
4334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        os.unlink(test_support.TESTFN)
4344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_dominating_multiline_values(self):
4364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # we're reading from file because this is where the code changed
4374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # during performance updates in Python 3.2
4384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf_from_file = self.newconfig()
4394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        with open(test_support.TESTFN) as f:
4404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            cf_from_file.readfp(f)
4414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf_from_file.get('section8', 'lovely_spam4'),
4424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         self.wonderful_spam.replace('\t\n', '\n'))
4434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass RawConfigParserTestCase(TestCaseBase):
4454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    config_class = ConfigParser.RawConfigParser
4464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_interpolation(self):
4484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.get_interpolation_config()
4494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq = self.assertEqual
4504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get("Foo", "getname"), "%(__name__)s")
4514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get("Foo", "bar"),
4524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           "something %(with1)s interpolation (1 step)")
4534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get("Foo", "bar9"),
4544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           "something %(with9)s lots of interpolation (9 steps)")
4554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get("Foo", "bar10"),
4564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           "something %(with10)s lots of interpolation (10 steps)")
4574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        eq(cf.get("Foo", "bar11"),
4584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           "something %(with11)s lots of interpolation (11 steps)")
4594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_items(self):
4614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.check_items_config([('default', '<default>'),
4624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                 ('getdefault', '|%(default)s|'),
4634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                 ('getname', '|%(__name__)s|'),
4644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                 ('key', '|%(name)s|'),
4654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                 ('name', 'value')])
4664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_set_nonstring_types(self):
4684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.newconfig()
4694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.add_section('non-string')
4704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.set('non-string', 'int', 1)
4714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.set('non-string', 'list', [0, 1, 1, 2, 3, 5, 8, 13])
4724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.set('non-string', 'dict', {'pi': 3.14159})
4734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf.get('non-string', 'int'), 1)
4744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf.get('non-string', 'list'),
4754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         [0, 1, 1, 2, 3, 5, 8, 13])
4764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf.get('non-string', 'dict'), {'pi': 3.14159})
4774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass SafeConfigParserTestCase(ConfigParserTestCase):
4804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    config_class = ConfigParser.SafeConfigParser
4814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_safe_interpolation(self):
4834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # See http://www.python.org/sf/511737
4844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.fromstring("[section]\n"
4854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             "option1=xxx\n"
4864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             "option2=%(option1)s/xxx\n"
4874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             "ok=%(option1)s/%%s\n"
4884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             "not_ok=%(option2)s/%%s")
4894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf.get("section", "ok"), "xxx/%s")
4904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf.get("section", "not_ok"), "xxx/xxx/%s")
4914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_set_malformatted_interpolation(self):
4934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.fromstring("[sect]\n"
4944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             "option1=foo\n")
4954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf.get('sect', "option1"), "foo")
4974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ValueError, cf.set, "sect", "option1", "%foo")
4994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ValueError, cf.set, "sect", "option1", "foo%")
5004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ValueError, cf.set, "sect", "option1", "f%oo")
5014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf.get('sect', "option1"), "foo")
5034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # bug #5741: double percents are *not* malformed
5054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf.set("sect", "option2", "foo%%bar")
5064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(cf.get("sect", "option2"), "foo%bar")
5074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_set_nonstring_types(self):
5094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.fromstring("[sect]\n"
5104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                             "option1=foo\n")
5114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # Check that we get a TypeError when setting non-string values
5124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # in an existing section:
5134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, cf.set, "sect", "option1", 1)
5144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, cf.set, "sect", "option1", 1.0)
5154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, cf.set, "sect", "option1", object())
5164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, cf.set, "sect", "option2", 1)
5174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, cf.set, "sect", "option2", 1.0)
5184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(TypeError, cf.set, "sect", "option2", object())
5194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_add_section_default_1(self):
5214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.newconfig()
5224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ValueError, cf.add_section, "default")
5234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_add_section_default_2(self):
5254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cf = self.newconfig()
5264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertRaises(ValueError, cf.add_section, "DEFAULT")
5274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass SafeConfigParserTestCaseNoValue(SafeConfigParserTestCase):
5304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    allow_no_value = True
5314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass Issue7005TestCase(unittest.TestCase):
5344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    """Test output when None is set() as a value and allow_no_value == False.
5354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    http://bugs.python.org/issue7005
5374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    """
5394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    expected_output = "[section]\noption = None\n\n"
5414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def prepare(self, config_class):
5434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        # This is the default, but that's the point.
5444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cp = config_class(allow_no_value=False)
5454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cp.add_section("section")
5464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cp.set("section", "option", None)
5474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        sio = StringIO.StringIO()
5484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        cp.write(sio)
5494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return sio.getvalue()
5504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_none_as_value_stringified(self):
5524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        output = self.prepare(ConfigParser.ConfigParser)
5534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(output, self.expected_output)
5544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_none_as_value_stringified_raw(self):
5564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        output = self.prepare(ConfigParser.RawConfigParser)
5574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(output, self.expected_output)
5584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmclass SortedTestCase(RawConfigParserTestCase):
5614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def newconfig(self, defaults=None):
5624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.cf = self.config_class(defaults=defaults, dict_type=SortedDict)
5634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return self.cf
5644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    def test_sorted(self):
5664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.fromstring("[b]\n"
5674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "o4=1\n"
5684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "o3=2\n"
5694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "o2=3\n"
5704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "o1=4\n"
5714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "[a]\n"
5724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "k=v\n")
5734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        output = StringIO.StringIO()
5744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.cf.write(output)
5754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        self.assertEqual(output.getvalue(),
5764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "[a]\n"
5774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "k = v\n\n"
5784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "[b]\n"
5794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "o1 = 4\n"
5804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "o2 = 3\n"
5814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "o3 = 2\n"
5824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "o4 = 1\n\n")
5834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdef test_main():
5864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    test_support.run_unittest(
5874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ConfigParserTestCase,
5884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        MultilineValuesTestCase,
5894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        RawConfigParserTestCase,
5904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        SafeConfigParserTestCase,
5914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        SafeConfigParserTestCaseNoValue,
5924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        SortedTestCase,
5934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Issue7005TestCase,
5944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        )
5954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmif __name__ == "__main__":
5984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    test_main()
599