Pārlūkot izejas kodu

Support python3 in dulwich.patch.

Jelmer Vernooij 10 gadi atpakaļ
vecāks
revīzija
1df48b6b92
2 mainītis faili ar 144 papildinājumiem un 144 dzēšanām
  1. 33 29
      dulwich/patch.py
  2. 111 115
      dulwich/tests/test_patch.py

+ 33 - 29
dulwich/patch.py

@@ -79,7 +79,7 @@ def get_summary(commit):
     return commit.message.splitlines()[0].replace(" ", "-")
 
 
-def unified_diff(a, b, fromfile='', tofile='', n=3):
+def unified_diff(a, b, fromfile, tofile, n=3):
     """difflib.unified_diff that doesn't write any dates or trailing spaces.
 
     Based on the same function in Python2.6.5-rc2's difflib.py
@@ -87,26 +87,27 @@ def unified_diff(a, b, fromfile='', tofile='', n=3):
     started = False
     for group in SequenceMatcher(None, a, b).get_grouped_opcodes(n):
         if not started:
-            yield '--- %s\n' % fromfile
-            yield '+++ %s\n' % tofile
+            yield b'--- ' + fromfile + b'\n'
+            yield b'+++ ' + tofile + b'\n'
             started = True
         i1, i2, j1, j2 = group[0][1], group[-1][2], group[0][3], group[-1][4]
-        yield "@@ -%d,%d +%d,%d @@\n" % (i1+1, i2-i1, j1+1, j2-j1)
+        sizes = "@@ -%d,%d +%d,%d @@\n" % (i1+1, i2-i1, j1+1, j2-j1)
+        yield sizes.encode('ascii')
         for tag, i1, i2, j1, j2 in group:
             if tag == 'equal':
                 for line in a[i1:i2]:
-                    yield ' ' + line
+                    yield b' ' + line
                 continue
             if tag == 'replace' or tag == 'delete':
                 for line in a[i1:i2]:
-                    if not line[-1] == '\n':
-                        line += '\n\\ No newline at end of file\n'
-                    yield '-' + line
+                    if not line[-1:] == b'\n':
+                        line += b'\n\\ No newline at end of file\n'
+                    yield b'-' + line
             if tag == 'replace' or tag == 'insert':
                 for line in b[j1:j2]:
-                    if not line[-1] == '\n':
-                        line += '\n\\ No newline at end of file\n'
-                    yield '+' + line
+                    if not line[-1:] == b'\n':
+                        line += b'\n\\ No newline at end of file\n'
+                    yield b'+' + line
 
 
 def is_binary(content):
@@ -114,21 +115,21 @@ def is_binary(content):
 
     :param content: Bytestring to check for binary content
     """
-    return '\0' in content[:FIRST_FEW_BYTES]
+    return b'\0' in content[:FIRST_FEW_BYTES]
 
 
 def shortid(hexsha):
     if hexsha is None:
-        return "0" * 7
+        return b"0" * 7
     else:
         return hexsha[:7]
 
 
 def patch_filename(p, root):
     if p is None:
-        return "/dev/null"
+        return b"/dev/null"
     else:
-        return root + "/" + p
+        return root + b"/" + p
 
 
 def write_object_diff(f, store, old_file, new_file, diff_binary=False):
@@ -145,13 +146,13 @@ def write_object_diff(f, store, old_file, new_file, diff_binary=False):
     """
     (old_path, old_mode, old_id) = old_file
     (new_path, new_mode, new_id) = new_file
-    old_path = patch_filename(old_path, "a")
-    new_path = patch_filename(new_path, "b")
+    old_path = patch_filename(old_path, b"a")
+    new_path = patch_filename(new_path, b"b")
     def content(mode, hexsha):
         if hexsha is None:
-            return ''
+            return b''
         elif S_ISGITLINK(mode):
-            return "Submodule commit " + hexsha + "\n"
+            return b"Submodule commit " + hexsha + b"\n"
         else:
             return store[hexsha].data
 
@@ -165,12 +166,13 @@ def write_object_diff(f, store, old_file, new_file, diff_binary=False):
     old_content = content(old_mode, old_id)
     new_content = content(new_mode, new_id)
     if not diff_binary and (is_binary(old_content) or is_binary(new_content)):
-        f.write("Binary files %s and %s differ\n" % (old_path, new_path))
+        f.write(b"Binary files " + old_path + b" and " + new_path + b" differ\n")
     else:
         f.writelines(unified_diff(lines(old_content), lines(new_content),
             old_path, new_path))
 
 
+# TODO(jelmer): Support writing unicode, rather than bytes.
 def gen_diff_header(paths, modes, shas):
     """Write a blob diff header.
 
@@ -181,20 +183,21 @@ def gen_diff_header(paths, modes, shas):
     (old_path, new_path) = paths
     (old_mode, new_mode) = modes
     (old_sha, new_sha) = shas
-    yield "diff --git %s %s\n" % (old_path, new_path)
+    yield b"diff --git " + old_path + b" " + new_path + b"\n"
     if old_mode != new_mode:
         if new_mode is not None:
             if old_mode is not None:
-                yield "old mode %o\n" % old_mode
-            yield "new mode %o\n" % new_mode
+                yield ("old mode %o\n" % old_mode).encode('ascii')
+            yield ("new mode %o\n" % new_mode).encode('ascii')
         else:
-            yield "deleted mode %o\n" % old_mode
-    yield "index " + shortid(old_sha) + ".." + shortid(new_sha)
+            yield ("deleted mode %o\n" % old_mode).encode('ascii')
+    yield b"index " + shortid(old_sha) + b".." + shortid(new_sha)
     if new_mode is not None:
-        yield " %o" % new_mode
-    yield "\n"
+        yield (" %o" % new_mode).encode('ascii')
+    yield b"\n"
 
 
+# TODO(jelmer): Support writing unicode, rather than bytes.
 def write_blob_diff(f, old_file, new_file):
     """Write blob diff.
 
@@ -206,8 +209,8 @@ def write_blob_diff(f, old_file, new_file):
     """
     (old_path, old_mode, old_blob) = old_file
     (new_path, new_mode, new_blob) = new_file
-    old_path = patch_filename(old_path, "a")
-    new_path = patch_filename(new_path, "b")
+    old_path = patch_filename(old_path, b"a")
+    new_path = patch_filename(new_path, b"b")
     def lines(blob):
         if blob is not None:
             return blob.data.splitlines(True)
@@ -222,6 +225,7 @@ def write_blob_diff(f, old_file, new_file):
         old_path, new_path))
 
 
+# TODO(jelmer): Support writing unicode, rather than bytes.
 def write_tree_diff(f, store, old_tree, new_tree, diff_binary=False):
     """Write tree diff.
 

+ 111 - 115
dulwich/tests/test_patch.py

@@ -41,9 +41,6 @@ from dulwich.tests import (
     SkipTest,
     TestCase,
     )
-from dulwich.tests.utils import (
-    skipIfPY3,
-    )
 
 
 class WriteCommitPatchTests(TestCase):
@@ -234,7 +231,6 @@ More help   : https://help.launchpad.net/ListHelp
         self.assertEqual(None, version)
 
 
-@skipIfPY3
 class DiffTests(TestCase):
     """Tests for write_blob_diff and write_tree_diff."""
 
@@ -243,14 +239,14 @@ class DiffTests(TestCase):
         write_blob_diff(f, (b"foo.txt", 0o644, Blob.from_string(b"old\nsame\n")),
                            (b"bar.txt", 0o644, Blob.from_string(b"new\nsame\n")))
         self.assertEqual([
-            "diff --git a/foo.txt b/bar.txt",
-            "index 3b0f961..a116b51 644",
-            "--- a/foo.txt",
-            "+++ b/bar.txt",
-            "@@ -1,2 +1,2 @@",
-            "-old",
-            "+new",
-            " same"
+            b"diff --git a/foo.txt b/bar.txt",
+            b"index 3b0f961..a116b51 644",
+            b"--- a/foo.txt",
+            b"+++ b/bar.txt",
+            b"@@ -1,2 +1,2 @@",
+            b"-old",
+            b"+new",
+            b" same"
             ], f.getvalue().splitlines())
 
     def test_blob_add(self):
@@ -258,14 +254,14 @@ class DiffTests(TestCase):
         write_blob_diff(f, (None, None, None),
                            (b"bar.txt", 0o644, Blob.from_string(b"new\nsame\n")))
         self.assertEqual([
-            'diff --git /dev/null b/bar.txt',
-             'new mode 644',
-             'index 0000000..a116b51 644',
-             '--- /dev/null',
-             '+++ b/bar.txt',
-             '@@ -1,0 +1,2 @@',
-             '+new',
-             '+same'
+             b'diff --git /dev/null b/bar.txt',
+             b'new mode 644',
+             b'index 0000000..a116b51 644',
+             b'--- /dev/null',
+             b'+++ b/bar.txt',
+             b'@@ -1,0 +1,2 @@',
+             b'+new',
+             b'+same'
             ], f.getvalue().splitlines())
 
     def test_blob_remove(self):
@@ -273,14 +269,14 @@ class DiffTests(TestCase):
         write_blob_diff(f, (b"bar.txt", 0o644, Blob.from_string(b"new\nsame\n")),
                            (None, None, None))
         self.assertEqual([
-            'diff --git a/bar.txt /dev/null',
-            'deleted mode 644',
-            'index a116b51..0000000',
-            '--- a/bar.txt',
-            '+++ /dev/null',
-            '@@ -1,2 +1,0 @@',
-            '-new',
-            '-same'
+            b'diff --git a/bar.txt /dev/null',
+            b'deleted mode 644',
+            b'index a116b51..0000000',
+            b'--- a/bar.txt',
+            b'+++ /dev/null',
+            b'@@ -1,2 +1,0 @@',
+            b'-new',
+            b'-same'
             ], f.getvalue().splitlines())
 
     def test_tree_diff(self):
@@ -303,28 +299,28 @@ class DiffTests(TestCase):
             tree1, tree2, added, removed, changed1, changed2, unchanged]])
         write_tree_diff(f, store, tree1.id, tree2.id)
         self.assertEqual([
-            'diff --git /dev/null b/added.txt',
-            'new mode 644',
-            'index 0000000..76d4bb8 644',
-            '--- /dev/null',
-            '+++ b/added.txt',
-            '@@ -1,0 +1,1 @@',
-            '+add',
-            'diff --git a/changed.txt b/changed.txt',
-            'index bf84e48..1be2436 644',
-            '--- a/changed.txt',
-            '+++ b/changed.txt',
-            '@@ -1,2 +1,2 @@',
-            ' unchanged',
-            '-removed',
-            '+added',
-            'diff --git a/removed.txt /dev/null',
-            'deleted mode 644',
-            'index 2c3f0b3..0000000',
-            '--- a/removed.txt',
-            '+++ /dev/null',
-            '@@ -1,1 +1,0 @@',
-            '-removed',
+            b'diff --git /dev/null b/added.txt',
+            b'new mode 644',
+            b'index 0000000..76d4bb8 644',
+            b'--- /dev/null',
+            b'+++ b/added.txt',
+            b'@@ -1,0 +1,1 @@',
+            b'+add',
+            b'diff --git a/changed.txt b/changed.txt',
+            b'index bf84e48..1be2436 644',
+            b'--- a/changed.txt',
+            b'+++ b/changed.txt',
+            b'@@ -1,2 +1,2 @@',
+            b' unchanged',
+            b'-removed',
+            b'+added',
+            b'diff --git a/removed.txt /dev/null',
+            b'deleted mode 644',
+            b'index 2c3f0b3..0000000',
+            b'--- a/removed.txt',
+            b'+++ /dev/null',
+            b'@@ -1,1 +1,0 @@',
+            b'-removed',
             ], f.getvalue().splitlines())
 
     def test_tree_diff_submodule(self):
@@ -339,13 +335,13 @@ class DiffTests(TestCase):
         store.add_objects([(o, None) for o in [tree1, tree2]])
         write_tree_diff(f, store, tree1.id, tree2.id)
         self.assertEqual([
-            'diff --git a/asubmodule b/asubmodule',
-            'index 06d0bdd..cc97564 160000',
-            '--- a/asubmodule',
-            '+++ b/asubmodule',
-            '@@ -1,1 +1,1 @@',
-            '-Submodule commit 06d0bdd9e2e20377b3180e4986b14c8549b393e4',
-            '+Submodule commit cc975646af69f279396d4d5e1379ac6af80ee637',
+            b'diff --git a/asubmodule b/asubmodule',
+            b'index 06d0bdd..cc97564 160000',
+            b'--- a/asubmodule',
+            b'+++ b/asubmodule',
+            b'@@ -1,1 +1,1 @@',
+            b'-Submodule commit 06d0bdd9e2e20377b3180e4986b14c8549b393e4',
+            b'+Submodule commit cc975646af69f279396d4d5e1379ac6af80ee637',
             ], f.getvalue().splitlines())
 
     def test_object_diff_blob(self):
@@ -357,14 +353,14 @@ class DiffTests(TestCase):
         write_object_diff(f, store, (b"foo.txt", 0o644, b1.id),
                                     (b"bar.txt", 0o644, b2.id))
         self.assertEqual([
-            "diff --git a/foo.txt b/bar.txt",
-            "index 3b0f961..a116b51 644",
-            "--- a/foo.txt",
-            "+++ b/bar.txt",
-            "@@ -1,2 +1,2 @@",
-            "-old",
-            "+new",
-            " same"
+            b"diff --git a/foo.txt b/bar.txt",
+            b"index 3b0f961..a116b51 644",
+            b"--- a/foo.txt",
+            b"+++ b/bar.txt",
+            b"@@ -1,2 +1,2 @@",
+            b"-old",
+            b"+new",
+            b" same"
             ], f.getvalue().splitlines())
 
     def test_object_diff_add_blob(self):
@@ -373,16 +369,16 @@ class DiffTests(TestCase):
         b2 = Blob.from_string(b"new\nsame\n")
         store.add_object(b2)
         write_object_diff(f, store, (None, None, None),
-                                    ("bar.txt", 0o644, b2.id))
+                                    (b"bar.txt", 0o644, b2.id))
         self.assertEqual([
-            'diff --git /dev/null b/bar.txt',
-             'new mode 644',
-             'index 0000000..a116b51 644',
-             '--- /dev/null',
-             '+++ b/bar.txt',
-             '@@ -1,0 +1,2 @@',
-             '+new',
-             '+same'
+             b'diff --git /dev/null b/bar.txt',
+             b'new mode 644',
+             b'index 0000000..a116b51 644',
+             b'--- /dev/null',
+             b'+++ b/bar.txt',
+             b'@@ -1,0 +1,2 @@',
+             b'+new',
+             b'+same'
             ], f.getvalue().splitlines())
 
     def test_object_diff_remove_blob(self):
@@ -393,14 +389,14 @@ class DiffTests(TestCase):
         write_object_diff(f, store, (b"bar.txt", 0o644, b1.id),
                                     (None, None, None))
         self.assertEqual([
-            'diff --git a/bar.txt /dev/null',
-            'deleted mode 644',
-            'index a116b51..0000000',
-            '--- a/bar.txt',
-            '+++ /dev/null',
-            '@@ -1,2 +1,0 @@',
-            '-new',
-            '-same'
+            b'diff --git a/bar.txt /dev/null',
+            b'deleted mode 644',
+            b'index a116b51..0000000',
+            b'--- a/bar.txt',
+            b'+++ /dev/null',
+            b'@@ -1,2 +1,0 @@',
+            b'-new',
+            b'-same'
             ], f.getvalue().splitlines())
 
     def test_object_diff_bin_blob_force(self):
@@ -417,18 +413,18 @@ class DiffTests(TestCase):
         write_object_diff(f, store, (b'foo.png', 0o644, b1.id),
                                     (b'bar.png', 0o644, b2.id), diff_binary=True)
         self.assertEqual([
-            'diff --git a/foo.png b/bar.png',
-            'index f73e47d..06364b7 644',
-            '--- a/foo.png',
-            '+++ b/bar.png',
-            '@@ -1,4 +1,4 @@',
-            ' \x89PNG',
-            ' \x1a',
-            ' \x00\x00\x00',
-            '-IHDR\x00\x00\x01\xd5\x00\x00\x00\x9f\x08\x04\x00\x00\x00\x05\x04\x8b',
-            '\\ No newline at end of file',
-            '+IHDR\x00\x00\x01\xd5\x00\x00\x00\x9f\x08\x03\x00\x00\x00\x98\xd3\xb3',
-            '\\ No newline at end of file'
+            b'diff --git a/foo.png b/bar.png',
+            b'index f73e47d..06364b7 644',
+            b'--- a/foo.png',
+            b'+++ b/bar.png',
+            b'@@ -1,4 +1,4 @@',
+            b' \x89PNG',
+            b' \x1a',
+            b' \x00\x00\x00',
+            b'-IHDR\x00\x00\x01\xd5\x00\x00\x00\x9f\x08\x04\x00\x00\x00\x05\x04\x8b',
+            b'\\ No newline at end of file',
+            b'+IHDR\x00\x00\x01\xd5\x00\x00\x00\x9f\x08\x03\x00\x00\x00\x98\xd3\xb3',
+            b'\\ No newline at end of file'
             ], f.getvalue().splitlines())
 
     def test_object_diff_bin_blob(self):
@@ -445,9 +441,9 @@ class DiffTests(TestCase):
         write_object_diff(f, store, (b'foo.png', 0o644, b1.id),
                                     (b'bar.png', 0o644, b2.id))
         self.assertEqual([
-            'diff --git a/foo.png b/bar.png',
-            'index f73e47d..06364b7 644',
-            'Binary files a/foo.png and b/bar.png differ'
+            b'diff --git a/foo.png b/bar.png',
+            b'index f73e47d..06364b7 644',
+            b'Binary files a/foo.png and b/bar.png differ'
             ], f.getvalue().splitlines())
 
     def test_object_diff_add_bin_blob(self):
@@ -460,10 +456,10 @@ class DiffTests(TestCase):
         write_object_diff(f, store, (None, None, None),
                                     (b'bar.png', 0o644, b2.id))
         self.assertEqual([
-            'diff --git /dev/null b/bar.png',
-            'new mode 644',
-            'index 0000000..06364b7 644',
-            'Binary files /dev/null and b/bar.png differ'
+            b'diff --git /dev/null b/bar.png',
+            b'new mode 644',
+            b'index 0000000..06364b7 644',
+            b'Binary files /dev/null and b/bar.png differ'
             ], f.getvalue().splitlines())
 
     def test_object_diff_remove_bin_blob(self):
@@ -476,10 +472,10 @@ class DiffTests(TestCase):
         write_object_diff(f, store, (b'foo.png', 0o644, b1.id),
                                     (None, None, None))
         self.assertEqual([
-            'diff --git a/foo.png /dev/null',
-            'deleted mode 644',
-            'index f73e47d..0000000',
-            'Binary files a/foo.png and /dev/null differ'
+            b'diff --git a/foo.png /dev/null',
+            b'deleted mode 644',
+            b'index f73e47d..0000000',
+            b'Binary files a/foo.png and /dev/null differ'
             ], f.getvalue().splitlines())
 
     def test_object_diff_kind_change(self):
@@ -490,14 +486,14 @@ class DiffTests(TestCase):
         write_object_diff(f, store, (b"bar.txt", 0o644, b1.id),
             (b"bar.txt", 0o160000, b"06d0bdd9e2e20377b3180e4986b14c8549b393e4"))
         self.assertEqual([
-            'diff --git a/bar.txt b/bar.txt',
-            'old mode 644',
-            'new mode 160000',
-            'index a116b51..06d0bdd 160000',
-            '--- a/bar.txt',
-            '+++ b/bar.txt',
-            '@@ -1,2 +1,1 @@',
-            '-new',
-            '-same',
-            '+Submodule commit 06d0bdd9e2e20377b3180e4986b14c8549b393e4',
+            b'diff --git a/bar.txt b/bar.txt',
+            b'old mode 644',
+            b'new mode 160000',
+            b'index a116b51..06d0bdd 160000',
+            b'--- a/bar.txt',
+            b'+++ b/bar.txt',
+            b'@@ -1,2 +1,1 @@',
+            b'-new',
+            b'-same',
+            b'+Submodule commit 06d0bdd9e2e20377b3180e4986b14c8549b393e4',
             ], f.getvalue().splitlines())