浏览代码

Fix section parsing.

Jelmer Vernooij 13 年之前
父节点
当前提交
f73b1e6c6c
共有 2 个文件被更改,包括 36 次插入5 次删除
  1. 16 5
      dulwich/config.py
  2. 20 0
      dulwich/tests/test_config.py

+ 16 - 5
dulwich/config.py

@@ -63,9 +63,14 @@ class Config(object):
 class ConfigDict(Config):
     """Git configuration stored in a dictionary."""
 
-    def __init__(self):
+    def __init__(self, values=None):
         """Create a new ConfigDict."""
-        self._values = {}
+        if values is None:
+            values = {}
+        self._values = values
+
+    def __repr__(self):
+        return "%s(%r)" % (self.__class__.__name__, self._values)
 
     def __eq__(self, other):
         return (
@@ -144,13 +149,19 @@ class ConfigFile(ConfigDict):
         for lineno, line in enumerate(f.readlines()):
             line = line.lstrip()
             if setting is None:
+                if line.strip() == "":
+                    continue
                 if line[0] == "[" and line.rstrip()[-1] == "]":
                     key = line.strip()
                     pts = key[1:-1].split(" ", 1)
                     if len(pts) == 2:
-                        if pts[1][0] != "\"" or pts[1][-1] != "\"":
-                            raise ValueError(pts[1])
-                        section = (pts[0], pts[1][1:-1])
+                        if pts[1][0] == "\"":
+                            if pts[1][-1] != "\"":
+                                raise ValueError(
+                                    "Invalid subsection " + pts[1])
+                            else:
+                                pts[1] = pts[1][1:-1]
+                        section = (pts[0], pts[1])
                     else:
                         section = (pts[0], None)
                     ret._values[section[0]] = {section[1]: {}}

+ 20 - 0
dulwich/tests/test_config.py

@@ -46,6 +46,18 @@ class ConfigFileTests(TestCase):
         cf = self.from_file("")
         self.assertEquals(ConfigFile(), cf)
 
+    def test_empty_line_before_section(self):
+        cf = self.from_file("\n[section]\n")
+        self.assertEquals(ConfigFile({"section": {None: {}}}), cf)
+
+    def test_comment_before_section(self):
+        cf = self.from_file("# foo\n[section]\n")
+        self.assertEquals(ConfigFile(), cf)
+
+    def test_comment_after_section(self):
+        cf = self.from_file("[section] # foo\n")
+        self.assertEquals(ConfigFile(), cf)
+
     def test_from_file_section(self):
         cf = self.from_file("[core]\nfoo = bar\n")
         self.assertEquals("bar", cf.get("core.foo"))
@@ -68,6 +80,14 @@ class ConfigFileTests(TestCase):
         cf = self.from_file("[branch \"foo\"]\nfoo = bar\n")
         self.assertEquals("bar", cf.get("branch.foo.foo"))
 
+    def test_from_file_subsection_invalid(self):
+        self.assertRaises(ValueError,
+            self.from_file, "[branch \"foo]\nfoo = bar\n")
+
+    def test_from_file_subsection_not_quoted(self):
+        cf = self.from_file("[branch foo]\nfoo = bar\n")
+        self.assertEquals("bar", cf.get("branch.foo.foo"))
+
     def test_write_to_file_empty(self):
         c = ConfigFile()
         f = StringIO()