Patchwork [2,of,2,manifest-py3] tests: make test-manifest.py portable to Python 3

login
register
mail settings
Submitter Augie Fackler
Date May 29, 2017, 2:29 p.m.
Message ID <50a270f82b7320406bf6.1496068191@imladris.local>
Download mbox | patch
Permalink /patch/21041/
State Accepted
Headers show

Comments

Augie Fackler - May 29, 2017, 2:29 p.m.
# HG changeset patch
# User Augie Fackler <raf@durin42.com>
# Date 1496021489 14400
#      Sun May 28 21:31:29 2017 -0400
# Node ID 50a270f82b7320406bf6baf284838d18ad1017c3
# Parent  5f4c7324c8edd5e82f719bbef6a55ec24560ea2b
tests: make test-manifest.py portable to Python 3

Lots of b prefixes here, and https://bugs.python.org/issue29714 means
that this test is still very broken on Python 3.6 and 3.6.1, but 3.6.2
should things (based on testing using tip of the 3.6 branch from git).

#cleanup-only

Patch

diff --git a/tests/test-manifest.py b/tests/test-manifest.py
--- a/tests/test-manifest.py
+++ b/tests/test-manifest.py
@@ -10,84 +10,84 @@  from mercurial import (
     match as matchmod,
 )
 
-EMTPY_MANIFEST = ''
-EMTPY_MANIFEST_V2 = '\0\n'
+EMTPY_MANIFEST = b''
+EMTPY_MANIFEST_V2 = b'\0\n'
 
-HASH_1 = '1' * 40
+HASH_1 = b'1' * 40
 BIN_HASH_1 = binascii.unhexlify(HASH_1)
-HASH_2 = 'f' * 40
+HASH_2 = b'f' * 40
 BIN_HASH_2 = binascii.unhexlify(HASH_2)
-HASH_3 = '1234567890abcdef0987654321deadbeef0fcafe'
+HASH_3 = b'1234567890abcdef0987654321deadbeef0fcafe'
 BIN_HASH_3 = binascii.unhexlify(HASH_3)
 A_SHORT_MANIFEST = (
-    'bar/baz/qux.py\0%(hash2)s%(flag2)s\n'
-    'foo\0%(hash1)s%(flag1)s\n'
-    ) % {'hash1': HASH_1,
-         'flag1': '',
-         'hash2': HASH_2,
-         'flag2': 'l',
+    b'bar/baz/qux.py\0%(hash2)s%(flag2)s\n'
+    b'foo\0%(hash1)s%(flag1)s\n'
+    ) % {b'hash1': HASH_1,
+         b'flag1': b'',
+         b'hash2': HASH_2,
+         b'flag2': b'l',
          }
 
 # Same data as A_SHORT_MANIFEST
 A_SHORT_MANIFEST_V2 = (
-    '\0\n'
-    '\x00bar/baz/qux.py\0%(flag2)s\n%(hash2)s\n'
-    '\x00foo\0%(flag1)s\n%(hash1)s\n'
-    ) % {'hash1': BIN_HASH_1,
-         'flag1': '',
-         'hash2': BIN_HASH_2,
-         'flag2': 'l',
+    b'\0\n'
+    b'\x00bar/baz/qux.py\0%(flag2)s\n%(hash2)s\n'
+    b'\x00foo\0%(flag1)s\n%(hash1)s\n'
+    ) % {b'hash1': BIN_HASH_1,
+         b'flag1': b'',
+         b'hash2': BIN_HASH_2,
+         b'flag2': b'l',
          }
 
 # Same data as A_SHORT_MANIFEST
 A_METADATA_MANIFEST = (
-    '\0foo\0bar\n'
-    '\x00bar/baz/qux.py\0%(flag2)s\0foo\0bar\n%(hash2)s\n' # flag and metadata
-    '\x00foo\0%(flag1)s\0foo\n%(hash1)s\n' # no flag, but metadata
-    ) % {'hash1': BIN_HASH_1,
-         'flag1': '',
-         'hash2': BIN_HASH_2,
-         'flag2': 'l',
+    b'\0foo\0bar\n'
+    b'\x00bar/baz/qux.py\0%(flag2)s\0foo\0bar\n%(hash2)s\n' # flag and metadata
+    b'\x00foo\0%(flag1)s\0foo\n%(hash1)s\n' # no flag, but metadata
+    ) % {b'hash1': BIN_HASH_1,
+         b'flag1': b'',
+         b'hash2': BIN_HASH_2,
+         b'flag2': b'l',
          }
 
 A_STEM_COMPRESSED_MANIFEST = (
-    '\0\n'
-    '\x00bar/baz/qux.py\0%(flag2)s\n%(hash2)s\n'
-    '\x04qux/foo.py\0%(flag1)s\n%(hash1)s\n' # simple case of 4 stem chars
-    '\x0az.py\0%(flag1)s\n%(hash1)s\n' # tricky newline = 10 stem characters
-    '\x00%(verylongdir)sx/x\0\n%(hash1)s\n'
-    '\xffx/y\0\n%(hash2)s\n' # more than 255 stem chars
-    ) % {'hash1': BIN_HASH_1,
-         'flag1': '',
-         'hash2': BIN_HASH_2,
-         'flag2': 'l',
-         'verylongdir': 255 * 'x',
+    b'\0\n'
+    b'\x00bar/baz/qux.py\0%(flag2)s\n%(hash2)s\n'
+    b'\x04qux/foo.py\0%(flag1)s\n%(hash1)s\n' # simple case of 4 stem chars
+    b'\x0az.py\0%(flag1)s\n%(hash1)s\n' # tricky newline = 10 stem characters
+    b'\x00%(verylongdir)sx/x\0\n%(hash1)s\n'
+    b'\xffx/y\0\n%(hash2)s\n' # more than 255 stem chars
+    ) % {b'hash1': BIN_HASH_1,
+         b'flag1': b'',
+         b'hash2': BIN_HASH_2,
+         b'flag2': b'l',
+         b'verylongdir': 255 * b'x',
          }
 
 A_DEEPER_MANIFEST = (
-    'a/b/c/bar.py\0%(hash3)s%(flag1)s\n'
-    'a/b/c/bar.txt\0%(hash1)s%(flag1)s\n'
-    'a/b/c/foo.py\0%(hash3)s%(flag1)s\n'
-    'a/b/c/foo.txt\0%(hash2)s%(flag2)s\n'
-    'a/b/d/baz.py\0%(hash3)s%(flag1)s\n'
-    'a/b/d/qux.py\0%(hash1)s%(flag2)s\n'
-    'a/b/d/ten.txt\0%(hash3)s%(flag2)s\n'
-    'a/b/dog.py\0%(hash3)s%(flag1)s\n'
-    'a/b/fish.py\0%(hash2)s%(flag1)s\n'
-    'a/c/london.py\0%(hash3)s%(flag2)s\n'
-    'a/c/paper.txt\0%(hash2)s%(flag2)s\n'
-    'a/c/paris.py\0%(hash2)s%(flag1)s\n'
-    'a/d/apple.py\0%(hash3)s%(flag1)s\n'
-    'a/d/pizza.py\0%(hash3)s%(flag2)s\n'
-    'a/green.py\0%(hash1)s%(flag2)s\n'
-    'a/purple.py\0%(hash2)s%(flag1)s\n'
-    'app.py\0%(hash3)s%(flag1)s\n'
-    'readme.txt\0%(hash2)s%(flag1)s\n'
-    ) % {'hash1': HASH_1,
-         'flag1': '',
-         'hash2': HASH_2,
-         'flag2': 'l',
-         'hash3': HASH_3,
+    b'a/b/c/bar.py\0%(hash3)s%(flag1)s\n'
+    b'a/b/c/bar.txt\0%(hash1)s%(flag1)s\n'
+    b'a/b/c/foo.py\0%(hash3)s%(flag1)s\n'
+    b'a/b/c/foo.txt\0%(hash2)s%(flag2)s\n'
+    b'a/b/d/baz.py\0%(hash3)s%(flag1)s\n'
+    b'a/b/d/qux.py\0%(hash1)s%(flag2)s\n'
+    b'a/b/d/ten.txt\0%(hash3)s%(flag2)s\n'
+    b'a/b/dog.py\0%(hash3)s%(flag1)s\n'
+    b'a/b/fish.py\0%(hash2)s%(flag1)s\n'
+    b'a/c/london.py\0%(hash3)s%(flag2)s\n'
+    b'a/c/paper.txt\0%(hash2)s%(flag2)s\n'
+    b'a/c/paris.py\0%(hash2)s%(flag1)s\n'
+    b'a/d/apple.py\0%(hash3)s%(flag1)s\n'
+    b'a/d/pizza.py\0%(hash3)s%(flag2)s\n'
+    b'a/green.py\0%(hash1)s%(flag2)s\n'
+    b'a/purple.py\0%(hash2)s%(flag1)s\n'
+    b'app.py\0%(hash3)s%(flag1)s\n'
+    b'readme.txt\0%(hash2)s%(flag1)s\n'
+    ) % {b'hash1': HASH_1,
+         b'flag1': b'',
+         b'hash2': HASH_2,
+         b'flag2': b'l',
+         b'hash3': HASH_3,
          }
 
 HUGE_MANIFEST_ENTRIES = 200001
@@ -96,11 +96,11 @@  izip = getattr(itertools, 'izip', zip)
 if 'xrange' not in globals():
     xrange = range
 
-A_HUGE_MANIFEST = ''.join(sorted(
-    'file%d\0%s%s\n' % (i, h, f) for i, h, f in
+A_HUGE_MANIFEST = b''.join(sorted(
+    b'file%d\0%s%s\n' % (i, h, f) for i, h, f in
     izip(xrange(200001),
          itertools.cycle((HASH_1, HASH_2)),
-         itertools.cycle(('', 'x', 'l')))))
+         itertools.cycle((b'', b'x', b'l')))))
 
 class basemanifesttests(object):
     def parsemanifest(self, text):
@@ -118,13 +118,13 @@  class basemanifesttests(object):
 
     def testManifest(self):
         m = self.parsemanifest(A_SHORT_MANIFEST)
-        self.assertEqual(['bar/baz/qux.py', 'foo'], list(m))
-        self.assertEqual(BIN_HASH_2, m['bar/baz/qux.py'])
-        self.assertEqual('l', m.flags('bar/baz/qux.py'))
-        self.assertEqual(BIN_HASH_1, m['foo'])
-        self.assertEqual('', m.flags('foo'))
+        self.assertEqual([b'bar/baz/qux.py', b'foo'], list(m))
+        self.assertEqual(BIN_HASH_2, m[b'bar/baz/qux.py'])
+        self.assertEqual(b'l', m.flags(b'bar/baz/qux.py'))
+        self.assertEqual(BIN_HASH_1, m[b'foo'])
+        self.assertEqual(b'', m.flags(b'foo'))
         with self.assertRaises(KeyError):
-            m['wat']
+            m[b'wat']
 
     def testParseManifestV2(self):
         m1 = self.parsemanifest(A_SHORT_MANIFEST)
@@ -139,11 +139,11 @@  class basemanifesttests(object):
 
     def testParseManifestStemCompression(self):
         m = self.parsemanifest(A_STEM_COMPRESSED_MANIFEST)
-        self.assertIn('bar/baz/qux.py', m)
-        self.assertIn('bar/qux/foo.py', m)
-        self.assertIn('bar/qux/foz.py', m)
-        self.assertIn(256 * 'x' + '/x', m)
-        self.assertIn(256 * 'x' + '/y', m)
+        self.assertIn(b'bar/baz/qux.py', m)
+        self.assertIn(b'bar/qux/foo.py', m)
+        self.assertIn(b'bar/qux/foz.py', m)
+        self.assertIn(256 * b'x' + b'/x', m)
+        self.assertIn(256 * b'x' + b'/y', m)
         self.assertEqual(A_STEM_COMPRESSED_MANIFEST, m.text(usemanifestv2=True))
 
     def testTextV2(self):
@@ -155,38 +155,38 @@  class basemanifesttests(object):
         want = BIN_HASH_1
 
         m = self.parsemanifest(EMTPY_MANIFEST)
-        m['a'] = want
-        self.assertIn('a', m)
-        self.assertEqual(want, m['a'])
-        self.assertEqual('a\0' + HASH_1 + '\n', m.text())
+        m[b'a'] = want
+        self.assertIn(b'a', m)
+        self.assertEqual(want, m[b'a'])
+        self.assertEqual(b'a\0' + HASH_1 + b'\n', m.text())
 
         m = self.parsemanifest(A_SHORT_MANIFEST)
-        m['a'] = want
-        self.assertEqual(want, m['a'])
-        self.assertEqual('a\0' + HASH_1 + '\n' + A_SHORT_MANIFEST,
+        m[b'a'] = want
+        self.assertEqual(want, m[b'a'])
+        self.assertEqual(b'a\0' + HASH_1 + b'\n' + A_SHORT_MANIFEST,
                          m.text())
 
     def testSetFlag(self):
-        want = 'x'
+        want = b'x'
 
         m = self.parsemanifest(EMTPY_MANIFEST)
         # first add a file; a file-less flag makes no sense
-        m['a'] = BIN_HASH_1
-        m.setflag('a', want)
-        self.assertEqual(want, m.flags('a'))
-        self.assertEqual('a\0' + HASH_1 + want + '\n', m.text())
+        m[b'a'] = BIN_HASH_1
+        m.setflag(b'a', want)
+        self.assertEqual(want, m.flags(b'a'))
+        self.assertEqual(b'a\0' + HASH_1 + want + b'\n', m.text())
 
         m = self.parsemanifest(A_SHORT_MANIFEST)
         # first add a file; a file-less flag makes no sense
-        m['a'] = BIN_HASH_1
-        m.setflag('a', want)
-        self.assertEqual(want, m.flags('a'))
-        self.assertEqual('a\0' + HASH_1 + want + '\n' + A_SHORT_MANIFEST,
+        m[b'a'] = BIN_HASH_1
+        m.setflag(b'a', want)
+        self.assertEqual(want, m.flags(b'a'))
+        self.assertEqual(b'a\0' + HASH_1 + want + b'\n' + A_SHORT_MANIFEST,
                          m.text())
 
     def testCopy(self):
         m = self.parsemanifest(A_SHORT_MANIFEST)
-        m['a'] = BIN_HASH_1
+        m[b'a'] = BIN_HASH_1
         m2 = m.copy()
         del m
         del m2 # make sure we don't double free() anything
@@ -195,60 +195,60 @@  class basemanifesttests(object):
         unhex = binascii.unhexlify
         h1, h2 = unhex(HASH_1), unhex(HASH_2)
         m = self.parsemanifest(A_SHORT_MANIFEST)
-        m['alpha'] = h1
-        m['beta'] = h2
-        del m['foo']
-        want = 'alpha\0%s\nbar/baz/qux.py\0%sl\nbeta\0%s\n' % (
+        m[b'alpha'] = h1
+        m[b'beta'] = h2
+        del m[b'foo']
+        want = b'alpha\0%s\nbar/baz/qux.py\0%sl\nbeta\0%s\n' % (
             HASH_1, HASH_2, HASH_2)
         self.assertEqual(want, m.text())
         self.assertEqual(3, len(m))
-        self.assertEqual(['alpha', 'bar/baz/qux.py', 'beta'], list(m))
-        self.assertEqual(h1, m['alpha'])
-        self.assertEqual(h2, m['bar/baz/qux.py'])
-        self.assertEqual(h2, m['beta'])
-        self.assertEqual('', m.flags('alpha'))
-        self.assertEqual('l', m.flags('bar/baz/qux.py'))
-        self.assertEqual('', m.flags('beta'))
+        self.assertEqual([b'alpha', b'bar/baz/qux.py', b'beta'], list(m))
+        self.assertEqual(h1, m[b'alpha'])
+        self.assertEqual(h2, m[b'bar/baz/qux.py'])
+        self.assertEqual(h2, m[b'beta'])
+        self.assertEqual(b'', m.flags(b'alpha'))
+        self.assertEqual(b'l', m.flags(b'bar/baz/qux.py'))
+        self.assertEqual(b'', m.flags(b'beta'))
         with self.assertRaises(KeyError):
-            m['foo']
+            m[b'foo']
 
     def testSetGetNodeSuffix(self):
         clean = self.parsemanifest(A_SHORT_MANIFEST)
         m = self.parsemanifest(A_SHORT_MANIFEST)
-        h = m['foo']
-        f = m.flags('foo')
-        want = h + 'a'
+        h = m[b'foo']
+        f = m.flags(b'foo')
+        want = h + b'a'
         # Merge code wants to set 21-byte fake hashes at times
-        m['foo'] = want
-        self.assertEqual(want, m['foo'])
-        self.assertEqual([('bar/baz/qux.py', BIN_HASH_2),
-                          ('foo', BIN_HASH_1 + 'a')],
+        m[b'foo'] = want
+        self.assertEqual(want, m[b'foo'])
+        self.assertEqual([(b'bar/baz/qux.py', BIN_HASH_2),
+                          (b'foo', BIN_HASH_1 + b'a')],
                          list(m.iteritems()))
         # Sometimes it even tries a 22-byte fake hash, but we can
         # return 21 and it'll work out
-        m['foo'] = want + '+'
-        self.assertEqual(want, m['foo'])
+        m[b'foo'] = want + b'+'
+        self.assertEqual(want, m[b'foo'])
         # make sure the suffix survives a copy
-        match = matchmod.match('', '', ['re:foo'])
+        match = matchmod.match(b'', b'', [b're:foo'])
         m2 = m.matches(match)
-        self.assertEqual(want, m2['foo'])
+        self.assertEqual(want, m2[b'foo'])
         self.assertEqual(1, len(m2))
         m2 = m.copy()
-        self.assertEqual(want, m2['foo'])
+        self.assertEqual(want, m2[b'foo'])
         # suffix with iteration
-        self.assertEqual([('bar/baz/qux.py', BIN_HASH_2),
-                          ('foo', want)],
+        self.assertEqual([(b'bar/baz/qux.py', BIN_HASH_2),
+                          (b'foo', want)],
                          list(m.iteritems()))
 
         # shows up in diff
-        self.assertEqual({'foo': ((want, f), (h, ''))}, m.diff(clean))
-        self.assertEqual({'foo': ((h, ''), (want, f))}, clean.diff(m))
+        self.assertEqual({b'foo': ((want, f), (h, b''))}, m.diff(clean))
+        self.assertEqual({b'foo': ((h, b''), (want, f))}, clean.diff(m))
 
     def testMatchException(self):
         m = self.parsemanifest(A_SHORT_MANIFEST)
-        match = matchmod.match('', '', ['re:.*'])
+        match = matchmod.match(b'', b'', [b're:.*'])
         def filt(path):
-            if path == 'foo':
+            if path == b'foo':
                 assert False
             return True
         match.matchfn = filt
@@ -257,73 +257,73 @@  class basemanifesttests(object):
 
     def testRemoveItem(self):
         m = self.parsemanifest(A_SHORT_MANIFEST)
-        del m['foo']
+        del m[b'foo']
         with self.assertRaises(KeyError):
-            m['foo']
+            m[b'foo']
         self.assertEqual(1, len(m))
         self.assertEqual(1, len(list(m)))
         # now restore and make sure everything works right
-        m['foo'] = 'a' * 20
+        m[b'foo'] = b'a' * 20
         self.assertEqual(2, len(m))
         self.assertEqual(2, len(list(m)))
 
     def testManifestDiff(self):
-        MISSING = (None, '')
-        addl = 'z-only-in-left\0' + HASH_1 + '\n'
-        addr = 'z-only-in-right\0' + HASH_2 + 'x\n'
+        MISSING = (None, b'')
+        addl = b'z-only-in-left\0' + HASH_1 + b'\n'
+        addr = b'z-only-in-right\0' + HASH_2 + b'x\n'
         left = self.parsemanifest(
-            A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + 'x') + addl)
+            A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + b'x') + addl)
         right = self.parsemanifest(A_SHORT_MANIFEST + addr)
         want = {
-            'foo': ((BIN_HASH_3, 'x'),
-                    (BIN_HASH_1, '')),
-            'z-only-in-left': ((BIN_HASH_1, ''), MISSING),
-            'z-only-in-right': (MISSING, (BIN_HASH_2, 'x')),
+            b'foo': ((BIN_HASH_3, b'x'),
+                     (BIN_HASH_1, b'')),
+            b'z-only-in-left': ((BIN_HASH_1, b''), MISSING),
+            b'z-only-in-right': (MISSING, (BIN_HASH_2, b'x')),
             }
         self.assertEqual(want, left.diff(right))
 
         want = {
-            'bar/baz/qux.py': (MISSING, (BIN_HASH_2, 'l')),
-            'foo': (MISSING, (BIN_HASH_3, 'x')),
-            'z-only-in-left': (MISSING, (BIN_HASH_1, '')),
+            b'bar/baz/qux.py': (MISSING, (BIN_HASH_2, b'l')),
+            b'foo': (MISSING, (BIN_HASH_3, b'x')),
+            b'z-only-in-left': (MISSING, (BIN_HASH_1, b'')),
             }
         self.assertEqual(want, self.parsemanifest(EMTPY_MANIFEST).diff(left))
 
         want = {
-            'bar/baz/qux.py': ((BIN_HASH_2, 'l'), MISSING),
-            'foo': ((BIN_HASH_3, 'x'), MISSING),
-            'z-only-in-left': ((BIN_HASH_1, ''), MISSING),
+            b'bar/baz/qux.py': ((BIN_HASH_2, b'l'), MISSING),
+            b'foo': ((BIN_HASH_3, b'x'), MISSING),
+            b'z-only-in-left': ((BIN_HASH_1, b''), MISSING),
             }
         self.assertEqual(want, left.diff(self.parsemanifest(EMTPY_MANIFEST)))
         copy = right.copy()
-        del copy['z-only-in-right']
-        del right['foo']
+        del copy[b'z-only-in-right']
+        del right[b'foo']
         want = {
-            'foo': (MISSING, (BIN_HASH_1, '')),
-            'z-only-in-right': ((BIN_HASH_2, 'x'), MISSING),
+            b'foo': (MISSING, (BIN_HASH_1, b'')),
+            b'z-only-in-right': ((BIN_HASH_2, b'x'), MISSING),
             }
         self.assertEqual(want, right.diff(copy))
 
         short = self.parsemanifest(A_SHORT_MANIFEST)
         pruned = short.copy()
-        del pruned['foo']
+        del pruned[b'foo']
         want = {
-            'foo': ((BIN_HASH_1, ''), MISSING),
+            b'foo': ((BIN_HASH_1, b''), MISSING),
             }
         self.assertEqual(want, short.diff(pruned))
         want = {
-            'foo': (MISSING, (BIN_HASH_1, '')),
+            b'foo': (MISSING, (BIN_HASH_1, b'')),
             }
         self.assertEqual(want, pruned.diff(short))
         want = {
-            'bar/baz/qux.py': None,
-            'foo': (MISSING, (BIN_HASH_1, '')),
+            b'bar/baz/qux.py': None,
+            b'foo': (MISSING, (BIN_HASH_1, b'')),
             }
         self.assertEqual(want, pruned.diff(short, clean=True))
 
     def testReversedLines(self):
-        backwards = ''.join(
-            l + '\n' for l in reversed(A_SHORT_MANIFEST.split('\n')) if l)
+        backwards = b''.join(
+            l + b'\n' for l in reversed(A_SHORT_MANIFEST.split(b'\n')) if l)
         try:
             self.parsemanifest(backwards)
             self.fail('Should have raised ValueError')
@@ -332,14 +332,14 @@  class basemanifesttests(object):
 
     def testNoTerminalNewline(self):
         try:
-            self.parsemanifest(A_SHORT_MANIFEST + 'wat')
+            self.parsemanifest(A_SHORT_MANIFEST + b'wat')
             self.fail('Should have raised ValueError')
         except ValueError as v:
             self.assertIn('Manifest did not end in a newline.', str(v))
 
     def testNoNewLineAtAll(self):
         try:
-            self.parsemanifest('wat')
+            self.parsemanifest(b'wat')
             self.fail('Should have raised ValueError')
         except ValueError as v:
             self.assertIn('Manifest did not end in a newline.', str(v))
@@ -355,13 +355,13 @@  class basemanifesttests(object):
         the resulting manifest.'''
         m = self.parsemanifest(A_HUGE_MANIFEST)
 
-        match = matchmod.match('/', '',
-                ['file1', 'file200', 'file300'], exact=True)
+        match = matchmod.match(b'/', b'',
+                [b'file1', b'file200', b'file300'], exact=True)
         m2 = m.matches(match)
 
-        w = ('file1\0%sx\n'
-             'file200\0%sl\n'
-             'file300\0%s\n') % (HASH_2, HASH_1, HASH_1)
+        w = (b'file1\0%sx\n'
+             b'file200\0%sl\n'
+             b'file300\0%s\n') % (HASH_2, HASH_1, HASH_1)
         self.assertEqual(w, m2.text())
 
     def testMatchesNonexistentFile(self):
@@ -370,13 +370,14 @@  class basemanifesttests(object):
         '''
         m = self.parsemanifest(A_DEEPER_MANIFEST)
 
-        match = matchmod.match('/', '',
-                ['a/b/c/bar.txt', 'a/b/d/qux.py', 'readme.txt', 'nonexistent'],
+        match = matchmod.match(b'/', b'',
+                [b'a/b/c/bar.txt', b'a/b/d/qux.py',
+                 b'readme.txt', b'nonexistent'],
                 exact=True)
         m2 = m.matches(match)
 
         self.assertEqual(
-                ['a/b/c/bar.txt', 'a/b/d/qux.py', 'readme.txt'],
+                [b'a/b/c/bar.txt', b'a/b/d/qux.py', b'readme.txt'],
                 m2.keys())
 
     def testMatchesNonexistentDirectory(self):
@@ -384,7 +385,7 @@  class basemanifesttests(object):
         actually exist.'''
         m = self.parsemanifest(A_DEEPER_MANIFEST)
 
-        match = matchmod.match('/', '', ['a/f'], default='relpath')
+        match = matchmod.match(b'/', b'', [b'a/f'], default=b'relpath')
         m2 = m.matches(match)
 
         self.assertEqual([], m2.keys())
@@ -395,7 +396,7 @@  class basemanifesttests(object):
         m = self.parsemanifest(A_HUGE_MANIFEST)
 
         flist = m.keys()[80:300]
-        match = matchmod.match('/', '', flist, exact=True)
+        match = matchmod.match(b'/', b'', flist, exact=True)
         m2 = m.matches(match)
 
         self.assertEqual(flist, m2.keys())
@@ -404,7 +405,7 @@  class basemanifesttests(object):
         '''Tests matches() for what should be a full match.'''
         m = self.parsemanifest(A_DEEPER_MANIFEST)
 
-        match = matchmod.match('/', '', [''])
+        match = matchmod.match(b'/', b'', [b''])
         m2 = m.matches(match)
 
         self.assertEqual(m.keys(), m2.keys())
@@ -414,13 +415,13 @@  class basemanifesttests(object):
         match against all files within said directory.'''
         m = self.parsemanifest(A_DEEPER_MANIFEST)
 
-        match = matchmod.match('/', '', ['a/b'], default='relpath')
+        match = matchmod.match(b'/', b'', [b'a/b'], default=b'relpath')
         m2 = m.matches(match)
 
         self.assertEqual([
-            'a/b/c/bar.py', 'a/b/c/bar.txt', 'a/b/c/foo.py', 'a/b/c/foo.txt',
-            'a/b/d/baz.py', 'a/b/d/qux.py', 'a/b/d/ten.txt', 'a/b/dog.py',
-            'a/b/fish.py'], m2.keys())
+            b'a/b/c/bar.py', b'a/b/c/bar.txt', b'a/b/c/foo.py', b'a/b/c/foo.txt',
+            b'a/b/d/baz.py', b'a/b/d/qux.py', b'a/b/d/ten.txt', b'a/b/dog.py',
+            b'a/b/fish.py'], m2.keys())
 
     def testMatchesExactPath(self):
         '''Tests matches() on an exact match on a directory, which should
@@ -428,7 +429,7 @@  class basemanifesttests(object):
         against a directory.'''
         m = self.parsemanifest(A_DEEPER_MANIFEST)
 
-        match = matchmod.match('/', '', ['a/b'], exact=True)
+        match = matchmod.match(b'/', b'', [b'a/b'], exact=True)
         m2 = m.matches(match)
 
         self.assertEqual([], m2.keys())
@@ -438,24 +439,24 @@  class basemanifesttests(object):
         when not in the root directory.'''
         m = self.parsemanifest(A_DEEPER_MANIFEST)
 
-        match = matchmod.match('/', 'a/b', ['.'], default='relpath')
+        match = matchmod.match(b'/', b'a/b', [b'.'], default=b'relpath')
         m2 = m.matches(match)
 
         self.assertEqual([
-            'a/b/c/bar.py', 'a/b/c/bar.txt', 'a/b/c/foo.py', 'a/b/c/foo.txt',
-            'a/b/d/baz.py', 'a/b/d/qux.py', 'a/b/d/ten.txt', 'a/b/dog.py',
-            'a/b/fish.py'], m2.keys())
+            b'a/b/c/bar.py', b'a/b/c/bar.txt', b'a/b/c/foo.py',
+            b'a/b/c/foo.txt', b'a/b/d/baz.py', b'a/b/d/qux.py',
+            b'a/b/d/ten.txt', b'a/b/dog.py', b'a/b/fish.py'], m2.keys())
 
     def testMatchesWithPattern(self):
         '''Tests matches() for files matching a pattern that reside
         deeper than the specified directory.'''
         m = self.parsemanifest(A_DEEPER_MANIFEST)
 
-        match = matchmod.match('/', '', ['a/b/*/*.txt'])
+        match = matchmod.match(b'/', b'', [b'a/b/*/*.txt'])
         m2 = m.matches(match)
 
         self.assertEqual(
-                ['a/b/c/bar.txt', 'a/b/c/foo.txt', 'a/b/d/ten.txt'],
+                [b'a/b/c/bar.txt', b'a/b/c/foo.txt', b'a/b/d/ten.txt'],
                 m2.keys())
 
 class testmanifestdict(unittest.TestCase, basemanifesttests):
@@ -464,21 +465,22 @@  class testmanifestdict(unittest.TestCase
 
 class testtreemanifest(unittest.TestCase, basemanifesttests):
     def parsemanifest(self, text):
-        return manifestmod.treemanifest('', text)
+        return manifestmod.treemanifest(b'', text)
 
     def testWalkSubtrees(self):
         m = self.parsemanifest(A_DEEPER_MANIFEST)
 
         dirs = [s._dir for s in m.walksubtrees()]
         self.assertEqual(
-            sorted(['', 'a/', 'a/c/', 'a/d/', 'a/b/', 'a/b/c/', 'a/b/d/']),
+            sorted([
+                b'', b'a/', b'a/c/', b'a/d/', b'a/b/', b'a/b/c/', b'a/b/d/']),
             sorted(dirs)
         )
 
-        match = matchmod.match('/', '', ['path:a/b/'])
+        match = matchmod.match(b'/', b'', [b'path:a/b/'])
         dirs = [s._dir for s in m.walksubtrees(matcher=match)]
         self.assertEqual(
-            sorted(['a/b/', 'a/b/c/', 'a/b/d/']),
+            sorted([b'a/b/', b'a/b/c/', b'a/b/d/']),
             sorted(dirs)
         )