PyXR

c:\python24\lib \ test \ test_cfgparser.py



0001 import ConfigParser
0002 import StringIO
0003 import unittest
0004 
0005 from test import test_support
0006 
0007 
0008 class TestCaseBase(unittest.TestCase):
0009     def newconfig(self, defaults=None):
0010         if defaults is None:
0011             self.cf = self.config_class()
0012         else:
0013             self.cf = self.config_class(defaults)
0014         return self.cf
0015 
0016     def fromstring(self, string, defaults=None):
0017         cf = self.newconfig(defaults)
0018         sio = StringIO.StringIO(string)
0019         cf.readfp(sio)
0020         return cf
0021 
0022     def test_basic(self):
0023         cf = self.fromstring(
0024             "[Foo Bar]\n"
0025             "foo=bar\n"
0026             "[Spacey Bar]\n"
0027             "foo = bar\n"
0028             "[Commented Bar]\n"
0029             "foo: bar ; comment\n"
0030             "[Long Line]\n"
0031             "foo: this line is much, much longer than my editor\n"
0032             "   likes it.\n"
0033             "[Section\\with$weird%characters[\t]\n"
0034             "[Internationalized Stuff]\n"
0035             "foo[bg]: Bulgarian\n"
0036             "foo=Default\n"
0037             "foo[en]=English\n"
0038             "foo[de]=Deutsch\n"
0039             "[Spaces]\n"
0040             "key with spaces : value\n"
0041             "another with spaces = splat!\n"
0042             )
0043         L = cf.sections()
0044         L.sort()
0045         eq = self.assertEqual
0046         eq(L, [r'Commented Bar',
0047                r'Foo Bar',
0048                r'Internationalized Stuff',
0049                r'Long Line',
0050                r'Section\with$weird%characters[' '\t',
0051                r'Spaces',
0052                r'Spacey Bar',
0053                ])
0054 
0055         # The use of spaces in the section names serves as a
0056         # regression test for SourceForge bug #583248:
0057         # http://www.python.org/sf/583248
0058         eq(cf.get('Foo Bar', 'foo'), 'bar')
0059         eq(cf.get('Spacey Bar', 'foo'), 'bar')
0060         eq(cf.get('Commented Bar', 'foo'), 'bar')
0061         eq(cf.get('Spaces', 'key with spaces'), 'value')
0062         eq(cf.get('Spaces', 'another with spaces'), 'splat!')
0063 
0064         self.failIf('__name__' in cf.options("Foo Bar"),
0065                     '__name__ "option" should not be exposed by the API!')
0066 
0067         # Make sure the right things happen for remove_option();
0068         # added to include check for SourceForge bug #123324:
0069         self.failUnless(cf.remove_option('Foo Bar', 'foo'),
0070                         "remove_option() failed to report existance of option")
0071         self.failIf(cf.has_option('Foo Bar', 'foo'),
0072                     "remove_option() failed to remove option")
0073         self.failIf(cf.remove_option('Foo Bar', 'foo'),
0074                     "remove_option() failed to report non-existance of option"
0075                     " that was removed")
0076 
0077         self.assertRaises(ConfigParser.NoSectionError,
0078                           cf.remove_option, 'No Such Section', 'foo')
0079 
0080         eq(cf.get('Long Line', 'foo'),
0081            'this line is much, much longer than my editor\nlikes it.')
0082 
0083     def test_case_sensitivity(self):
0084         cf = self.newconfig()
0085         cf.add_section("A")
0086         cf.add_section("a")
0087         L = cf.sections()
0088         L.sort()
0089         eq = self.assertEqual
0090         eq(L, ["A", "a"])
0091         cf.set("a", "B", "value")
0092         eq(cf.options("a"), ["b"])
0093         eq(cf.get("a", "b"), "value",
0094            "could not locate option, expecting case-insensitive option names")
0095         self.failUnless(cf.has_option("a", "b"))
0096         cf.set("A", "A-B", "A-B value")
0097         for opt in ("a-b", "A-b", "a-B", "A-B"):
0098             self.failUnless(
0099                 cf.has_option("A", opt),
0100                 "has_option() returned false for option which should exist")
0101         eq(cf.options("A"), ["a-b"])
0102         eq(cf.options("a"), ["b"])
0103         cf.remove_option("a", "B")
0104         eq(cf.options("a"), [])
0105 
0106         # SF bug #432369:
0107         cf = self.fromstring(
0108             "[MySection]\nOption: first line\n\tsecond line\n")
0109         eq(cf.options("MySection"), ["option"])
0110         eq(cf.get("MySection", "Option"), "first line\nsecond line")
0111 
0112         # SF bug #561822:
0113         cf = self.fromstring("[section]\nnekey=nevalue\n",
0114                              defaults={"key":"value"})
0115         self.failUnless(cf.has_option("section", "Key"))
0116 
0117 
0118     def test_default_case_sensitivity(self):
0119         cf = self.newconfig({"foo": "Bar"})
0120         self.assertEqual(
0121             cf.get("DEFAULT", "Foo"), "Bar",
0122             "could not locate option, expecting case-insensitive option names")
0123         cf = self.newconfig({"Foo": "Bar"})
0124         self.assertEqual(
0125             cf.get("DEFAULT", "Foo"), "Bar",
0126             "could not locate option, expecting case-insensitive defaults")
0127 
0128     def test_parse_errors(self):
0129         self.newconfig()
0130         self.parse_error(ConfigParser.ParsingError,
0131                          "[Foo]\n  extra-spaces: splat\n")
0132         self.parse_error(ConfigParser.ParsingError,
0133                          "[Foo]\n  extra-spaces= splat\n")
0134         self.parse_error(ConfigParser.ParsingError,
0135                          "[Foo]\noption-without-value\n")
0136         self.parse_error(ConfigParser.ParsingError,
0137                          "[Foo]\n:value-without-option-name\n")
0138         self.parse_error(ConfigParser.ParsingError,
0139                          "[Foo]\n=value-without-option-name\n")
0140         self.parse_error(ConfigParser.MissingSectionHeaderError,
0141                          "No Section!\n")
0142 
0143     def parse_error(self, exc, src):
0144         sio = StringIO.StringIO(src)
0145         self.assertRaises(exc, self.cf.readfp, sio)
0146 
0147     def test_query_errors(self):
0148         cf = self.newconfig()
0149         self.assertEqual(cf.sections(), [],
0150                          "new ConfigParser should have no defined sections")
0151         self.failIf(cf.has_section("Foo"),
0152                     "new ConfigParser should have no acknowledged sections")
0153         self.assertRaises(ConfigParser.NoSectionError,
0154                           cf.options, "Foo")
0155         self.assertRaises(ConfigParser.NoSectionError,
0156                           cf.set, "foo", "bar", "value")
0157         self.get_error(ConfigParser.NoSectionError, "foo", "bar")
0158         cf.add_section("foo")
0159         self.get_error(ConfigParser.NoOptionError, "foo", "bar")
0160 
0161     def get_error(self, exc, section, option):
0162         try:
0163             self.cf.get(section, option)
0164         except exc, e:
0165             return e
0166         else:
0167             self.fail("expected exception type %s.%s"
0168                       % (exc.__module__, exc.__name__))
0169 
0170     def test_boolean(self):
0171         cf = self.fromstring(
0172             "[BOOLTEST]\n"
0173             "T1=1\n"
0174             "T2=TRUE\n"
0175             "T3=True\n"
0176             "T4=oN\n"
0177             "T5=yes\n"
0178             "F1=0\n"
0179             "F2=FALSE\n"
0180             "F3=False\n"
0181             "F4=oFF\n"
0182             "F5=nO\n"
0183             "E1=2\n"
0184             "E2=foo\n"
0185             "E3=-1\n"
0186             "E4=0.1\n"
0187             "E5=FALSE AND MORE"
0188             )
0189         for x in range(1, 5):
0190             self.failUnless(cf.getboolean('BOOLTEST', 't%d' % x))
0191             self.failIf(cf.getboolean('BOOLTEST', 'f%d' % x))
0192             self.assertRaises(ValueError,
0193                               cf.getboolean, 'BOOLTEST', 'e%d' % x)
0194 
0195     def test_weird_errors(self):
0196         cf = self.newconfig()
0197         cf.add_section("Foo")
0198         self.assertRaises(ConfigParser.DuplicateSectionError,
0199                           cf.add_section, "Foo")
0200 
0201     def test_write(self):
0202         cf = self.fromstring(
0203             "[Long Line]\n"
0204             "foo: this line is much, much longer than my editor\n"
0205             "   likes it.\n"
0206             "[DEFAULT]\n"
0207             "foo: another very\n"
0208             " long line"
0209             )
0210         output = StringIO.StringIO()
0211         cf.write(output)
0212         self.assertEqual(
0213             output.getvalue(),
0214             "[DEFAULT]\n"
0215             "foo = another very\n"
0216             "\tlong line\n"
0217             "\n"
0218             "[Long Line]\n"
0219             "foo = this line is much, much longer than my editor\n"
0220             "\tlikes it.\n"
0221             "\n"
0222             )
0223 
0224     def test_set_string_types(self):
0225         cf = self.fromstring("[sect]\n"
0226                              "option1=foo\n")
0227         # Check that we don't get an exception when setting values in
0228         # an existing section using strings:
0229         class mystr(str):
0230             pass
0231         cf.set("sect", "option1", "splat")
0232         cf.set("sect", "option1", mystr("splat"))
0233         cf.set("sect", "option2", "splat")
0234         cf.set("sect", "option2", mystr("splat"))
0235         try:
0236             unicode
0237         except NameError:
0238             pass
0239         else:
0240             cf.set("sect", "option1", unicode("splat"))
0241             cf.set("sect", "option2", unicode("splat"))
0242 
0243     def test_read_returns_file_list(self):
0244         file1 = test_support.findfile("cfgparser.1")
0245         # check when we pass a mix of readable and non-readable files:
0246         cf = self.newconfig()
0247         parsed_files = cf.read([file1, "nonexistant-file"])
0248         self.assertEqual(parsed_files, [file1])
0249         self.assertEqual(cf.get("Foo Bar", "foo"), "newbar")
0250         # check when we pass only a filename:
0251         cf = self.newconfig()
0252         parsed_files = cf.read(file1)
0253         self.assertEqual(parsed_files, [file1])
0254         self.assertEqual(cf.get("Foo Bar", "foo"), "newbar")
0255         # check when we pass only missing files:
0256         cf = self.newconfig()
0257         parsed_files = cf.read(["nonexistant-file"])
0258         self.assertEqual(parsed_files, [])
0259         # check when we pass no files:
0260         cf = self.newconfig()
0261         parsed_files = cf.read([])
0262         self.assertEqual(parsed_files, [])
0263 
0264     # shared by subclasses
0265     def get_interpolation_config(self):
0266         return self.fromstring(
0267             "[Foo]\n"
0268             "bar=something %(with1)s interpolation (1 step)\n"
0269             "bar9=something %(with9)s lots of interpolation (9 steps)\n"
0270             "bar10=something %(with10)s lots of interpolation (10 steps)\n"
0271             "bar11=something %(with11)s lots of interpolation (11 steps)\n"
0272             "with11=%(with10)s\n"
0273             "with10=%(with9)s\n"
0274             "with9=%(with8)s\n"
0275             "with8=%(With7)s\n"
0276             "with7=%(WITH6)s\n"
0277             "with6=%(with5)s\n"
0278             "With5=%(with4)s\n"
0279             "WITH4=%(with3)s\n"
0280             "with3=%(with2)s\n"
0281             "with2=%(with1)s\n"
0282             "with1=with\n"
0283             "\n"
0284             "[Mutual Recursion]\n"
0285             "foo=%(bar)s\n"
0286             "bar=%(foo)s\n"
0287             "\n"
0288             "[Interpolation Error]\n"
0289             "name=%(reference)s\n",
0290             # no definition for 'reference'
0291             defaults={"getname": "%(__name__)s"})
0292 
0293     def check_items_config(self, expected):
0294         cf = self.fromstring(
0295             "[section]\n"
0296             "name = value\n"
0297             "key: |%(name)s| \n"
0298             "getdefault: |%(default)s|\n"
0299             "getname: |%(__name__)s|",
0300             defaults={"default": "<default>"})
0301         L = list(cf.items("section"))
0302         L.sort()
0303         self.assertEqual(L, expected)
0304 
0305 
0306 class ConfigParserTestCase(TestCaseBase):
0307     config_class = ConfigParser.ConfigParser
0308 
0309     def test_interpolation(self):
0310         cf = self.get_interpolation_config()
0311         eq = self.assertEqual
0312         eq(cf.get("Foo", "getname"), "Foo")
0313         eq(cf.get("Foo", "bar"), "something with interpolation (1 step)")
0314         eq(cf.get("Foo", "bar9"),
0315            "something with lots of interpolation (9 steps)")
0316         eq(cf.get("Foo", "bar10"),
0317            "something with lots of interpolation (10 steps)")
0318         self.get_error(ConfigParser.InterpolationDepthError, "Foo", "bar11")
0319 
0320     def test_interpolation_missing_value(self):
0321         cf = self.get_interpolation_config()
0322         e = self.get_error(ConfigParser.InterpolationError,
0323                            "Interpolation Error", "name")
0324         self.assertEqual(e.reference, "reference")
0325         self.assertEqual(e.section, "Interpolation Error")
0326         self.assertEqual(e.option, "name")
0327 
0328     def test_items(self):
0329         self.check_items_config([('default', '<default>'),
0330                                  ('getdefault', '|<default>|'),
0331                                  ('getname', '|section|'),
0332                                  ('key', '|value|'),
0333                                  ('name', 'value')])
0334 
0335     def test_set_nonstring_types(self):
0336         cf = self.newconfig()
0337         cf.add_section('non-string')
0338         cf.set('non-string', 'int', 1)
0339         cf.set('non-string', 'list', [0, 1, 1, 2, 3, 5, 8, 13, '%('])
0340         cf.set('non-string', 'dict', {'pi': 3.14159, '%(': 1,
0341                                       '%(list)': '%(list)'})
0342         cf.set('non-string', 'string_with_interpolation', '%(list)s')
0343         self.assertEqual(cf.get('non-string', 'int', raw=True), 1)
0344         self.assertRaises(TypeError, cf.get, 'non-string', 'int')
0345         self.assertEqual(cf.get('non-string', 'list', raw=True),
0346                          [0, 1, 1, 2, 3, 5, 8, 13, '%('])
0347         self.assertRaises(TypeError, cf.get, 'non-string', 'list')
0348         self.assertEqual(cf.get('non-string', 'dict', raw=True),
0349                          {'pi': 3.14159, '%(': 1, '%(list)': '%(list)'})
0350         self.assertRaises(TypeError, cf.get, 'non-string', 'dict')
0351         self.assertEqual(cf.get('non-string', 'string_with_interpolation',
0352                                 raw=True), '%(list)s')
0353         self.assertRaises(ValueError, cf.get, 'non-string',
0354                           'string_with_interpolation', raw=False)
0355 
0356 
0357 class RawConfigParserTestCase(TestCaseBase):
0358     config_class = ConfigParser.RawConfigParser
0359 
0360     def test_interpolation(self):
0361         cf = self.get_interpolation_config()
0362         eq = self.assertEqual
0363         eq(cf.get("Foo", "getname"), "%(__name__)s")
0364         eq(cf.get("Foo", "bar"),
0365            "something %(with1)s interpolation (1 step)")
0366         eq(cf.get("Foo", "bar9"),
0367            "something %(with9)s lots of interpolation (9 steps)")
0368         eq(cf.get("Foo", "bar10"),
0369            "something %(with10)s lots of interpolation (10 steps)")
0370         eq(cf.get("Foo", "bar11"),
0371            "something %(with11)s lots of interpolation (11 steps)")
0372 
0373     def test_items(self):
0374         self.check_items_config([('default', '<default>'),
0375                                  ('getdefault', '|%(default)s|'),
0376                                  ('getname', '|%(__name__)s|'),
0377                                  ('key', '|%(name)s|'),
0378                                  ('name', 'value')])
0379 
0380     def test_set_nonstring_types(self):
0381         cf = self.newconfig()
0382         cf.add_section('non-string')
0383         cf.set('non-string', 'int', 1)
0384         cf.set('non-string', 'list', [0, 1, 1, 2, 3, 5, 8, 13])
0385         cf.set('non-string', 'dict', {'pi': 3.14159})
0386         self.assertEqual(cf.get('non-string', 'int'), 1)
0387         self.assertEqual(cf.get('non-string', 'list'),
0388                          [0, 1, 1, 2, 3, 5, 8, 13])
0389         self.assertEqual(cf.get('non-string', 'dict'), {'pi': 3.14159})
0390 
0391 
0392 class SafeConfigParserTestCase(ConfigParserTestCase):
0393     config_class = ConfigParser.SafeConfigParser
0394 
0395     def test_safe_interpolation(self):
0396         # See http://www.python.org/sf/511737
0397         cf = self.fromstring("[section]\n"
0398                              "option1=xxx\n"
0399                              "option2=%(option1)s/xxx\n"
0400                              "ok=%(option1)s/%%s\n"
0401                              "not_ok=%(option2)s/%%s")
0402         self.assertEqual(cf.get("section", "ok"), "xxx/%s")
0403         self.assertEqual(cf.get("section", "not_ok"), "xxx/xxx/%s")
0404 
0405     def test_set_nonstring_types(self):
0406         cf = self.fromstring("[sect]\n"
0407                              "option1=foo\n")
0408         # Check that we get a TypeError when setting non-string values
0409         # in an existing section:
0410         self.assertRaises(TypeError, cf.set, "sect", "option1", 1)
0411         self.assertRaises(TypeError, cf.set, "sect", "option1", 1.0)
0412         self.assertRaises(TypeError, cf.set, "sect", "option1", object())
0413         self.assertRaises(TypeError, cf.set, "sect", "option2", 1)
0414         self.assertRaises(TypeError, cf.set, "sect", "option2", 1.0)
0415         self.assertRaises(TypeError, cf.set, "sect", "option2", object())
0416 
0417 
0418 def test_main():
0419     test_support.run_unittest(
0420         ConfigParserTestCase,
0421         RawConfigParserTestCase,
0422         SafeConfigParserTestCase
0423     )
0424 
0425 if __name__ == "__main__":
0426     test_main()
0427 

Generated by PyXR 0.9.4
SourceForge.net Logo