Patchwork [01,of,11] doctest: bulk-replace string literals with b'' for Python 3

login
register
mail settings
Submitter Yuya Nishihara
Date Sept. 4, 2017, 3:08 p.m.
Message ID <f47091c3f4d6d27bd2c3.1504537700@mimosa>
Download mbox | patch
Permalink /patch/23657/
State Accepted
Headers show

Comments

Yuya Nishihara - Sept. 4, 2017, 3:08 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1504416731 -32400
#      Sun Sep 03 14:32:11 2017 +0900
# Node ID f47091c3f4d6d27bd2c38306c1d8d5e8a67707a5
# Parent  a9d8caf95941ff03466c7087f3d8ae92ebe61713
doctest: bulk-replace string literals with b'' for Python 3

Our code transformer can't rewrite string literals in docstrings, and I
don't want to make the transformer more complex.

Patch

diff --git a/hgext/convert/convcmd.py b/hgext/convert/convcmd.py
--- a/hgext/convert/convcmd.py
+++ b/hgext/convert/convcmd.py
@@ -59,18 +59,18 @@  def recode(s):
 
 def mapbranch(branch, branchmap):
     '''
-    >>> bmap = {'default': 'branch1'}
-    >>> for i in ['', None]:
+    >>> bmap = {b'default': b'branch1'}
+    >>> for i in [b'', None]:
     ...     mapbranch(i, bmap)
     'branch1'
     'branch1'
-    >>> bmap = {'None': 'branch2'}
-    >>> for i in ['', None]:
+    >>> bmap = {b'None': b'branch2'}
+    >>> for i in [b'', None]:
     ...     mapbranch(i, bmap)
     'branch2'
     'branch2'
-    >>> bmap = {'None': 'branch3', 'default': 'branch4'}
-    >>> for i in ['None', '', None, 'default', 'branch5']:
+    >>> bmap = {b'None': b'branch3', b'default': b'branch4'}
+    >>> for i in [b'None', b'', None, b'default', b'branch5']:
     ...     mapbranch(i, bmap)
     'branch3'
     'branch4'
diff --git a/hgext/convert/cvsps.py b/hgext/convert/cvsps.py
--- a/hgext/convert/cvsps.py
+++ b/hgext/convert/cvsps.py
@@ -54,23 +54,23 @@  class logerror(Exception):
 def getrepopath(cvspath):
     """Return the repository path from a CVS path.
 
-    >>> getrepopath('/foo/bar')
+    >>> getrepopath(b'/foo/bar')
     '/foo/bar'
-    >>> getrepopath('c:/foo/bar')
+    >>> getrepopath(b'c:/foo/bar')
     '/foo/bar'
-    >>> getrepopath(':pserver:10/foo/bar')
+    >>> getrepopath(b':pserver:10/foo/bar')
     '/foo/bar'
-    >>> getrepopath(':pserver:10c:/foo/bar')
+    >>> getrepopath(b':pserver:10c:/foo/bar')
     '/foo/bar'
-    >>> getrepopath(':pserver:/foo/bar')
+    >>> getrepopath(b':pserver:/foo/bar')
     '/foo/bar'
-    >>> getrepopath(':pserver:c:/foo/bar')
+    >>> getrepopath(b':pserver:c:/foo/bar')
     '/foo/bar'
-    >>> getrepopath(':pserver:truc@foo.bar:/foo/bar')
+    >>> getrepopath(b':pserver:truc@foo.bar:/foo/bar')
     '/foo/bar'
-    >>> getrepopath(':pserver:truc@foo.bar:c:/foo/bar')
+    >>> getrepopath(b':pserver:truc@foo.bar:c:/foo/bar')
     '/foo/bar'
-    >>> getrepopath('user@server/path/to/repository')
+    >>> getrepopath(b'user@server/path/to/repository')
     '/path/to/repository'
     """
     # According to CVS manual, CVS paths are expressed like:
diff --git a/hgext/convert/filemap.py b/hgext/convert/filemap.py
--- a/hgext/convert/filemap.py
+++ b/hgext/convert/filemap.py
@@ -18,7 +18,7 @@  SKIPREV = common.SKIPREV
 def rpairs(path):
     '''Yield tuples with path split at '/', starting with the full path.
     No leading, trailing or double '/', please.
-    >>> for x in rpairs('foo/bar/baz'): print x
+    >>> for x in rpairs(b'foo/bar/baz'): print x
     ('foo/bar/baz', '')
     ('foo/bar', 'baz')
     ('foo', 'bar/baz')
diff --git a/hgext/convert/p4.py b/hgext/convert/p4.py
--- a/hgext/convert/p4.py
+++ b/hgext/convert/p4.py
@@ -32,9 +32,9 @@  def decodefilename(filename):
     """Perforce escapes special characters @, #, *, or %
     with %40, %23, %2A, or %25 respectively
 
-    >>> decodefilename('portable-net45%252Bnetcore45%252Bwp8%252BMonoAndroid')
+    >>> decodefilename(b'portable-net45%252Bnetcore45%252Bwp8%252BMonoAndroid')
     'portable-net45%2Bnetcore45%2Bwp8%2BMonoAndroid'
-    >>> decodefilename('//Depot/Directory/%2525/%2523/%23%40.%2A')
+    >>> decodefilename(b'//Depot/Directory/%2525/%2523/%23%40.%2A')
     '//Depot/Directory/%25/%23/#@.*'
     """
     replacements = [('%2A', '*'), ('%23', '#'), ('%40', '@'), ('%25', '%')]
diff --git a/hgext/convert/subversion.py b/hgext/convert/subversion.py
--- a/hgext/convert/subversion.py
+++ b/hgext/convert/subversion.py
@@ -61,16 +61,16 @@  class SvnPathNotFound(Exception):
 
 def revsplit(rev):
     """Parse a revision string and return (uuid, path, revnum).
-    >>> revsplit('svn:a2147622-4a9f-4db4-a8d3-13562ff547b2'
-    ...          '/proj%20B/mytrunk/mytrunk@1')
+    >>> revsplit(b'svn:a2147622-4a9f-4db4-a8d3-13562ff547b2'
+    ...          b'/proj%20B/mytrunk/mytrunk@1')
     ('a2147622-4a9f-4db4-a8d3-13562ff547b2', '/proj%20B/mytrunk/mytrunk', 1)
-    >>> revsplit('svn:8af66a51-67f5-4354-b62c-98d67cc7be1d@1')
+    >>> revsplit(b'svn:8af66a51-67f5-4354-b62c-98d67cc7be1d@1')
     ('', '', 1)
-    >>> revsplit('@7')
+    >>> revsplit(b'@7')
     ('', '', 7)
-    >>> revsplit('7')
+    >>> revsplit(b'7')
     ('', '', 0)
-    >>> revsplit('bad')
+    >>> revsplit(b'bad')
     ('', '', 0)
     """
     parts = rev.rsplit('@', 1)
diff --git a/hgext/mq.py b/hgext/mq.py
--- a/hgext/mq.py
+++ b/hgext/mq.py
@@ -154,23 +154,25 @@  PLAINHEADERS = {
 
 def inserthgheader(lines, header, value):
     """Assuming lines contains a HG patch header, add a header line with value.
-    >>> try: inserthgheader([], '# Date ', 'z')
+    >>> try: inserthgheader([], b'# Date ', b'z')
     ... except ValueError, inst: print "oops"
     oops
-    >>> inserthgheader(['# HG changeset patch'], '# Date ', 'z')
+    >>> inserthgheader([b'# HG changeset patch'], b'# Date ', b'z')
     ['# HG changeset patch', '# Date z']
-    >>> inserthgheader(['# HG changeset patch', ''], '# Date ', 'z')
+    >>> inserthgheader([b'# HG changeset patch', b''], b'# Date ', b'z')
     ['# HG changeset patch', '# Date z', '']
-    >>> inserthgheader(['# HG changeset patch', '# User y'], '# Date ', 'z')
+    >>> inserthgheader([b'# HG changeset patch', b'# User y'], b'# Date ', b'z')
     ['# HG changeset patch', '# User y', '# Date z']
-    >>> inserthgheader(['# HG changeset patch', '# Date x', '# User y'],
-    ...                '# User ', 'z')
+    >>> inserthgheader([b'# HG changeset patch', b'# Date x', b'# User y'],
+    ...                b'# User ', b'z')
     ['# HG changeset patch', '# Date x', '# User z']
-    >>> inserthgheader(['# HG changeset patch', '# Date y'], '# Date ', 'z')
+    >>> inserthgheader([b'# HG changeset patch', b'# Date y'], b'# Date ', b'z')
     ['# HG changeset patch', '# Date z']
-    >>> inserthgheader(['# HG changeset patch', '', '# Date y'], '# Date ', 'z')
+    >>> inserthgheader([b'# HG changeset patch', b'', b'# Date y'],
+    ...                b'# Date ', b'z')
     ['# HG changeset patch', '# Date z', '', '# Date y']
-    >>> inserthgheader(['# HG changeset patch', '# Parent  y'], '# Date ', 'z')
+    >>> inserthgheader([b'# HG changeset patch', b'# Parent  y'],
+    ...                b'# Date ', b'z')
     ['# HG changeset patch', '# Date z', '# Parent  y']
     """
     start = lines.index('# HG changeset patch') + 1
@@ -194,19 +196,19 @@  def inserthgheader(lines, header, value)
 
 def insertplainheader(lines, header, value):
     """For lines containing a plain patch header, add a header line with value.
-    >>> insertplainheader([], 'Date', 'z')
+    >>> insertplainheader([], b'Date', b'z')
     ['Date: z']
-    >>> insertplainheader([''], 'Date', 'z')
+    >>> insertplainheader([b''], b'Date', b'z')
     ['Date: z', '']
-    >>> insertplainheader(['x'], 'Date', 'z')
+    >>> insertplainheader([b'x'], b'Date', b'z')
     ['Date: z', '', 'x']
-    >>> insertplainheader(['From: y', 'x'], 'Date', 'z')
+    >>> insertplainheader([b'From: y', b'x'], b'Date', b'z')
     ['From: y', 'Date: z', '', 'x']
-    >>> insertplainheader([' date : x', ' from : y', ''], 'From', 'z')
+    >>> insertplainheader([b' date : x', b' from : y', b''], b'From', b'z')
     [' date : x', 'From: z', '']
-    >>> insertplainheader(['', 'Date: y'], 'Date', 'z')
+    >>> insertplainheader([b'', b'Date: y'], b'Date', b'z')
     ['Date: z', '', 'Date: y']
-    >>> insertplainheader(['foo: bar', 'DATE: z', 'x'], 'From', 'y')
+    >>> insertplainheader([b'foo: bar', b'DATE: z', b'x'], b'From', b'y')
     ['From: y', 'foo: bar', 'DATE: z', '', 'x']
     """
     newprio = PLAINHEADERS[header.lower()]
diff --git a/mercurial/byterange.py b/mercurial/byterange.py
--- a/mercurial/byterange.py
+++ b/mercurial/byterange.py
@@ -91,7 +91,7 @@  class RangeableFileObject(object):
     Examples:
         # expose 10 bytes, starting at byte position 20, from
         # /etc/aliases.
-        >>> fo = RangeableFileObject(file('/etc/passwd', 'r'), (20,30))
+        >>> fo = RangeableFileObject(file(b'/etc/passwd', b'r'), (20,30))
         # seek seeks within the range (to position 23 in this case)
         >>> fo.seek(3)
         # tell tells where your at _within the range_ (position 3 in
diff --git a/mercurial/changelog.py b/mercurial/changelog.py
--- a/mercurial/changelog.py
+++ b/mercurial/changelog.py
@@ -27,8 +27,8 @@  from . import (
 
 def _string_escape(text):
     """
-    >>> d = {'nl': chr(10), 'bs': chr(92), 'cr': chr(13), 'nul': chr(0)}
-    >>> s = "ab%(nl)scd%(bs)s%(bs)sn%(nul)sab%(cr)scd%(bs)s%(nl)s" % d
+    >>> d = {b'nl': chr(10), b'bs': chr(92), b'cr': chr(13), b'nul': chr(0)}
+    >>> s = b"ab%(nl)scd%(bs)s%(bs)sn%(nul)sab%(cr)scd%(bs)s%(nl)s" % d
     >>> s
     'ab\\ncd\\\\\\\\n\\x00ab\\rcd\\\\\\n'
     >>> res = _string_escape(s)
@@ -41,11 +41,11 @@  def _string_escape(text):
 
 def decodeextra(text):
     """
-    >>> sorted(decodeextra(encodeextra({'foo': 'bar', 'baz': chr(0) + '2'})
+    >>> sorted(decodeextra(encodeextra({b'foo': b'bar', b'baz': chr(0) + b'2'})
     ...                    ).iteritems())
     [('baz', '\\x002'), ('branch', 'default'), ('foo', 'bar')]
-    >>> sorted(decodeextra(encodeextra({'foo': 'bar',
-    ...                                 'baz': chr(92) + chr(0) + '2'})
+    >>> sorted(decodeextra(encodeextra({b'foo': b'bar',
+    ...                                 b'baz': chr(92) + chr(0) + b'2'})
     ...                    ).iteritems())
     [('baz', '\\\\\\x002'), ('branch', 'default'), ('foo', 'bar')]
     """
diff --git a/mercurial/color.py b/mercurial/color.py
--- a/mercurial/color.py
+++ b/mercurial/color.py
@@ -320,10 +320,10 @@  def _effect_str(ui, effect):
 def _mergeeffects(text, start, stop):
     """Insert start sequence at every occurrence of stop sequence
 
-    >>> s = _mergeeffects('cyan', '[C]', '|')
-    >>> s = _mergeeffects(s + 'yellow', '[Y]', '|')
-    >>> s = _mergeeffects('ma' + s + 'genta', '[M]', '|')
-    >>> s = _mergeeffects('red' + s, '[R]', '|')
+    >>> s = _mergeeffects(b'cyan', b'[C]', b'|')
+    >>> s = _mergeeffects(s + b'yellow', b'[Y]', b'|')
+    >>> s = _mergeeffects(b'ma' + s + b'genta', b'[M]', b'|')
+    >>> s = _mergeeffects(b'red' + s, b'[R]', b'|')
     >>> s
     '[R]red[M]ma[Y][C]cyan|[R][M][Y]yellow|[R][M]genta|'
     """
diff --git a/mercurial/config.py b/mercurial/config.py
--- a/mercurial/config.py
+++ b/mercurial/config.py
@@ -183,7 +183,7 @@  class config(object):
 def parselist(value):
     """parse a configuration value as a list of comma/space separated strings
 
-    >>> parselist('this,is "a small" ,test')
+    >>> parselist(b'this,is "a small" ,test')
     ['this', 'is', 'a small', 'test']
     """
 
diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -1112,16 +1112,16 @@  def _annotatepair(parents, childfctx, ch
     Additionally, if `skipchild` is True, replace all other lines with parent
     annotate data as well such that child is never blamed for any lines.
 
-    >>> oldfctx = 'old'
-    >>> p1fctx, p2fctx, childfctx = 'p1', 'p2', 'c'
-    >>> olddata = 'a\nb\n'
-    >>> p1data = 'a\nb\nc\n'
-    >>> p2data = 'a\nc\nd\n'
-    >>> childdata = 'a\nb2\nc\nc2\nd\n'
+    >>> oldfctx = b'old'
+    >>> p1fctx, p2fctx, childfctx = b'p1', b'p2', b'c'
+    >>> olddata = b'a\nb\n'
+    >>> p1data = b'a\nb\nc\n'
+    >>> p2data = b'a\nc\nd\n'
+    >>> childdata = b'a\nb2\nc\nc2\nd\n'
     >>> diffopts = mdiff.diffopts()
 
     >>> def decorate(text, rev):
-    ...     return ([(rev, i) for i in xrange(1, text.count('\n') + 1)], text)
+    ...     return ([(rev, i) for i in xrange(1, text.count(b'\n') + 1)], text)
 
     Basic usage:
 
diff --git a/mercurial/dagparser.py b/mercurial/dagparser.py
--- a/mercurial/dagparser.py
+++ b/mercurial/dagparser.py
@@ -54,7 +54,7 @@  def parsedag(desc):
 
     Example of a complex graph (output not shown for brevity):
 
-        >>> len(list(parsedag("""
+        >>> len(list(parsedag(b"""
         ...
         ... +3         # 3 nodes in linear run
         ... :forkhere  # a label for the last of the 3 nodes from above
@@ -74,88 +74,88 @@  def parsedag(desc):
 
     Empty list:
 
-        >>> list(parsedag(""))
+        >>> list(parsedag(b""))
         []
 
     A simple linear run:
 
-        >>> list(parsedag("+3"))
+        >>> list(parsedag(b"+3"))
         [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
 
     Some non-standard ways to define such runs:
 
-        >>> list(parsedag("+1+2"))
+        >>> list(parsedag(b"+1+2"))
         [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
 
-        >>> list(parsedag("+1*1*"))
+        >>> list(parsedag(b"+1*1*"))
         [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
 
-        >>> list(parsedag("*"))
+        >>> list(parsedag(b"*"))
         [('n', (0, [-1]))]
 
-        >>> list(parsedag("..."))
+        >>> list(parsedag(b"..."))
         [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
 
     A fork and a join, using numeric back references:
 
-        >>> list(parsedag("+2*2*/2"))
+        >>> list(parsedag(b"+2*2*/2"))
         [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [0])), ('n', (3, [2, 1]))]
 
-        >>> list(parsedag("+2<2+1/2"))
+        >>> list(parsedag(b"+2<2+1/2"))
         [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [0])), ('n', (3, [2, 1]))]
 
     Placing a label:
 
-        >>> list(parsedag("+1 :mylabel +1"))
+        >>> list(parsedag(b"+1 :mylabel +1"))
         [('n', (0, [-1])), ('l', (0, 'mylabel')), ('n', (1, [0]))]
 
     An empty label (silly, really):
 
-        >>> list(parsedag("+1:+1"))
+        >>> list(parsedag(b"+1:+1"))
         [('n', (0, [-1])), ('l', (0, '')), ('n', (1, [0]))]
 
     Fork and join, but with labels instead of numeric back references:
 
-        >>> list(parsedag("+1:f +1:p2 *f */p2"))
+        >>> list(parsedag(b"+1:f +1:p2 *f */p2"))
         [('n', (0, [-1])), ('l', (0, 'f')), ('n', (1, [0])), ('l', (1, 'p2')),
          ('n', (2, [0])), ('n', (3, [2, 1]))]
 
-        >>> list(parsedag("+1:f +1:p2 <f +1 /p2"))
+        >>> list(parsedag(b"+1:f +1:p2 <f +1 /p2"))
         [('n', (0, [-1])), ('l', (0, 'f')), ('n', (1, [0])), ('l', (1, 'p2')),
          ('n', (2, [0])), ('n', (3, [2, 1]))]
 
     Restarting from the root:
 
-        >>> list(parsedag("+1 $ +1"))
+        >>> list(parsedag(b"+1 $ +1"))
         [('n', (0, [-1])), ('n', (1, [-1]))]
 
     Annotations, which are meant to introduce sticky state for subsequent nodes:
 
-        >>> list(parsedag("+1 @ann +1"))
+        >>> list(parsedag(b"+1 @ann +1"))
         [('n', (0, [-1])), ('a', 'ann'), ('n', (1, [0]))]
 
-        >>> list(parsedag('+1 @"my annotation" +1'))
+        >>> list(parsedag(b'+1 @"my annotation" +1'))
         [('n', (0, [-1])), ('a', 'my annotation'), ('n', (1, [0]))]
 
     Commands, which are meant to operate on the most recently created node:
 
-        >>> list(parsedag("+1 !cmd +1"))
+        >>> list(parsedag(b"+1 !cmd +1"))
         [('n', (0, [-1])), ('c', 'cmd'), ('n', (1, [0]))]
 
-        >>> list(parsedag('+1 !"my command" +1'))
+        >>> list(parsedag(b'+1 !"my command" +1'))
         [('n', (0, [-1])), ('c', 'my command'), ('n', (1, [0]))]
 
-        >>> list(parsedag('+1 !!my command line\\n +1'))
+        >>> list(parsedag(b'+1 !!my command line\\n +1'))
         [('n', (0, [-1])), ('C', 'my command line'), ('n', (1, [0]))]
 
     Comments, which extend to the end of the line:
 
-        >>> list(parsedag('+1 # comment\\n+1'))
+        >>> list(parsedag(b'+1 # comment\\n+1'))
         [('n', (0, [-1])), ('n', (1, [0]))]
 
     Error:
 
-        >>> try: list(parsedag('+1 bad'))
+        >>> try: list(parsedag(b'+1 bad'))
         ... except Exception, e: print(e)
         invalid character in dag description: bad...
 
@@ -413,52 +413,54 @@  def dagtext(dag,
 
     Linear run:
 
-        >>> dagtext([('n', (0, [-1])), ('n', (1, [0]))])
+        >>> dagtext([(b'n', (0, [-1])), (b'n', (1, [0]))])
         '+2'
 
     Two roots:
 
-        >>> dagtext([('n', (0, [-1])), ('n', (1, [-1]))])
+        >>> dagtext([(b'n', (0, [-1])), (b'n', (1, [-1]))])
         '+1 $ +1'
 
     Fork and join:
 
-        >>> dagtext([('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [0])),
-        ...          ('n', (3, [2, 1]))])
+        >>> dagtext([(b'n', (0, [-1])), (b'n', (1, [0])), (b'n', (2, [0])),
+        ...          (b'n', (3, [2, 1]))])
         '+2 *2 */2'
 
     Fork and join with labels:
 
-        >>> dagtext([('n', (0, [-1])), ('l', (0, 'f')), ('n', (1, [0])),
-        ...          ('l', (1, 'p2')), ('n', (2, [0])), ('n', (3, [2, 1]))])
+        >>> dagtext([(b'n', (0, [-1])), (b'l', (0, b'f')), (b'n', (1, [0])),
+        ...          (b'l', (1, b'p2')), (b'n', (2, [0])), (b'n', (3, [2, 1]))])
         '+1 :f +1 :p2 *f */p2'
 
     Annotations:
 
-        >>> dagtext([('n', (0, [-1])), ('a', 'ann'), ('n', (1, [0]))])
+        >>> dagtext([(b'n', (0, [-1])), (b'a', b'ann'), (b'n', (1, [0]))])
         '+1 @ann +1'
 
-        >>> dagtext([('n', (0, [-1])),
-        ...          ('a', 'my annotation'),
-        ...          ('n', (1, [0]))])
+        >>> dagtext([(b'n', (0, [-1])),
+        ...          (b'a', b'my annotation'),
+        ...          (b'n', (1, [0]))])
         '+1 @"my annotation" +1'
 
     Commands:
 
-        >>> dagtext([('n', (0, [-1])), ('c', 'cmd'), ('n', (1, [0]))])
+        >>> dagtext([(b'n', (0, [-1])), (b'c', b'cmd'), (b'n', (1, [0]))])
         '+1 !cmd +1'
 
-        >>> dagtext([('n', (0, [-1])), ('c', 'my command'), ('n', (1, [0]))])
+        >>> dagtext([(b'n', (0, [-1])),
+        ...          (b'c', b'my command'),
+        ...          (b'n', (1, [0]))])
         '+1 !"my command" +1'
 
-        >>> dagtext([('n', (0, [-1])),
-        ...          ('C', 'my command line'),
-        ...          ('n', (1, [0]))])
+        >>> dagtext([(b'n', (0, [-1])),
+        ...          (b'C', b'my command line'),
+        ...          (b'n', (1, [0]))])
         '+1 !!my command line\\n+1'
 
     Comments:
 
-        >>> dagtext([('n', (0, [-1])), ('#', ' comment'), ('n', (1, [0]))])
+        >>> dagtext([(b'n', (0, [-1])), (b'#', b' comment'), (b'n', (1, [0]))])
         '+1 # comment\\n+1'
 
         >>> dagtext([])
@@ -466,7 +468,7 @@  def dagtext(dag,
 
     Combining parsedag and dagtext:
 
-        >>> dagtext(parsedag('+1 :f +1 :p2 *f */p2'))
+        >>> dagtext(parsedag(b'+1 :f +1 :p2 *f */p2'))
         '+1 :f +1 :p2 *f */p2'
 
     '''
diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py
--- a/mercurial/dispatch.py
+++ b/mercurial/dispatch.py
@@ -604,20 +604,20 @@  def _earlygetopt(aliases, args):
     The values are listed in the order they appear in args.
     The options and values are removed from args.
 
-    >>> args = ['x', '--cwd', 'foo', 'y']
-    >>> _earlygetopt(['--cwd'], args), args
+    >>> args = [b'x', b'--cwd', b'foo', b'y']
+    >>> _earlygetopt([b'--cwd'], args), args
     (['foo'], ['x', 'y'])
 
-    >>> args = ['x', '--cwd=bar', 'y']
-    >>> _earlygetopt(['--cwd'], args), args
+    >>> args = [b'x', b'--cwd=bar', b'y']
+    >>> _earlygetopt([b'--cwd'], args), args
     (['bar'], ['x', 'y'])
 
-    >>> args = ['x', '-R', 'foo', 'y']
-    >>> _earlygetopt(['-R'], args), args
+    >>> args = [b'x', b'-R', b'foo', b'y']
+    >>> _earlygetopt([b'-R'], args), args
     (['foo'], ['x', 'y'])
 
-    >>> args = ['x', '-Rbar', 'y']
-    >>> _earlygetopt(['-R'], args), args
+    >>> args = [b'x', b'-Rbar', b'y']
+    >>> _earlygetopt([b'-R'], args), args
     (['bar'], ['x', 'y'])
     """
     try:
diff --git a/mercurial/encoding.py b/mercurial/encoding.py
--- a/mercurial/encoding.py
+++ b/mercurial/encoding.py
@@ -108,19 +108,19 @@  def tolocal(s):
     strings next to their local representation to allow lossless
     round-trip conversion back to UTF-8.
 
-    >>> u = 'foo: \\xc3\\xa4' # utf-8
+    >>> u = b'foo: \\xc3\\xa4' # utf-8
     >>> l = tolocal(u)
     >>> l
     'foo: ?'
     >>> fromlocal(l)
     'foo: \\xc3\\xa4'
-    >>> u2 = 'foo: \\xc3\\xa1'
+    >>> u2 = b'foo: \\xc3\\xa1'
     >>> d = { l: 1, tolocal(u2): 2 }
     >>> len(d) # no collision
     2
-    >>> 'foo: ?' in d
+    >>> b'foo: ?' in d
     False
-    >>> l1 = 'foo: \\xe4' # historical latin1 fallback
+    >>> l1 = b'foo: \\xe4' # historical latin1 fallback
     >>> l = tolocal(l1)
     >>> l
     'foo: ?'
@@ -247,10 +247,10 @@  def trim(s, width, ellipsis='', leftside
     If 'leftside' is True, left side of string 's' is trimmed.
     'ellipsis' is always placed at trimmed side.
 
-    >>> ellipsis = '+++'
+    >>> ellipsis = b'+++'
     >>> from . import encoding
-    >>> encoding.encoding = 'utf-8'
-    >>> t= '1234567890'
+    >>> encoding.encoding = b'utf-8'
+    >>> t = b'1234567890'
     >>> print trim(t, 12, ellipsis=ellipsis)
     1234567890
     >>> print trim(t, 10, ellipsis=ellipsis)
@@ -285,7 +285,7 @@  def trim(s, width, ellipsis='', leftside
     +++
     >>> print trim(t, 4, ellipsis=ellipsis, leftside=True)
     +++
-    >>> t = '\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa' # invalid byte sequence
+    >>> t = b'\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa' # invalid byte sequence
     >>> print trim(t, 12, ellipsis=ellipsis)
     \x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa
     >>> print trim(t, 10, ellipsis=ellipsis)
@@ -406,35 +406,35 @@  def jsonescape(s, paranoid=False):
 
     (escapes are doubled in these tests)
 
-    >>> jsonescape('this is a test')
+    >>> jsonescape(b'this is a test')
     'this is a test'
-    >>> jsonescape('escape characters: \\0 \\x0b \\x7f')
+    >>> jsonescape(b'escape characters: \\0 \\x0b \\x7f')
     'escape characters: \\\\u0000 \\\\u000b \\\\u007f'
-    >>> jsonescape('escape characters: \\b \\t \\n \\f \\r \\" \\\\')
+    >>> jsonescape(b'escape characters: \\b \\t \\n \\f \\r \\" \\\\')
     'escape characters: \\\\b \\\\t \\\\n \\\\f \\\\r \\\\" \\\\\\\\'
-    >>> jsonescape('a weird byte: \\xdd')
+    >>> jsonescape(b'a weird byte: \\xdd')
     'a weird byte: \\xed\\xb3\\x9d'
-    >>> jsonescape('utf-8: caf\\xc3\\xa9')
+    >>> jsonescape(b'utf-8: caf\\xc3\\xa9')
     'utf-8: caf\\xc3\\xa9'
-    >>> jsonescape('')
+    >>> jsonescape(b'')
     ''
 
     If paranoid, non-ascii and common troublesome characters are also escaped.
     This is suitable for web output.
 
-    >>> s = 'escape characters: \\0 \\x0b \\x7f'
+    >>> s = b'escape characters: \\0 \\x0b \\x7f'
     >>> assert jsonescape(s) == jsonescape(s, paranoid=True)
-    >>> s = 'escape characters: \\b \\t \\n \\f \\r \\" \\\\'
+    >>> s = b'escape characters: \\b \\t \\n \\f \\r \\" \\\\'
     >>> assert jsonescape(s) == jsonescape(s, paranoid=True)
-    >>> jsonescape('escape boundary: \\x7e \\x7f \\xc2\\x80', paranoid=True)
+    >>> jsonescape(b'escape boundary: \\x7e \\x7f \\xc2\\x80', paranoid=True)
     'escape boundary: ~ \\\\u007f \\\\u0080'
-    >>> jsonescape('a weird byte: \\xdd', paranoid=True)
+    >>> jsonescape(b'a weird byte: \\xdd', paranoid=True)
     'a weird byte: \\\\udcdd'
-    >>> jsonescape('utf-8: caf\\xc3\\xa9', paranoid=True)
+    >>> jsonescape(b'utf-8: caf\\xc3\\xa9', paranoid=True)
     'utf-8: caf\\\\u00e9'
-    >>> jsonescape('non-BMP: \\xf0\\x9d\\x84\\x9e', paranoid=True)
+    >>> jsonescape(b'non-BMP: \\xf0\\x9d\\x84\\x9e', paranoid=True)
     'non-BMP: \\\\ud834\\\\udd1e'
-    >>> jsonescape('<foo@example.org>', paranoid=True)
+    >>> jsonescape(b'<foo@example.org>', paranoid=True)
     '\\\\u003cfoo@example.org\\\\u003e'
     '''
 
@@ -531,18 +531,18 @@  def fromutf8b(s):
     that's was passed through tolocal will remain in UTF-8.
 
     >>> roundtrip = lambda x: fromutf8b(toutf8b(x)) == x
-    >>> m = "\\xc3\\xa9\\x99abcd"
+    >>> m = b"\\xc3\\xa9\\x99abcd"
     >>> toutf8b(m)
     '\\xc3\\xa9\\xed\\xb2\\x99abcd'
     >>> roundtrip(m)
     True
-    >>> roundtrip("\\xc2\\xc2\\x80")
+    >>> roundtrip(b"\\xc2\\xc2\\x80")
     True
-    >>> roundtrip("\\xef\\xbf\\xbd")
+    >>> roundtrip(b"\\xef\\xbf\\xbd")
     True
-    >>> roundtrip("\\xef\\xef\\xbf\\xbd")
+    >>> roundtrip(b"\\xef\\xef\\xbf\\xbd")
     True
-    >>> roundtrip("\\xf1\\x80\\x80\\x80\\x80")
+    >>> roundtrip(b"\\xf1\\x80\\x80\\x80\\x80")
     True
     '''
 
diff --git a/mercurial/formatter.py b/mercurial/formatter.py
--- a/mercurial/formatter.py
+++ b/mercurial/formatter.py
@@ -52,14 +52,14 @@  Doctest helper:
 Basic example:
 
 >>> def files(ui, fm):
-...     files = [('foo', 123, (0, 0)), ('bar', 456, (1, 0))]
+...     files = [(b'foo', 123, (0, 0)), (b'bar', 456, (1, 0))]
 ...     for f in files:
 ...         fm.startitem()
-...         fm.write('path', '%s', f[0])
-...         fm.condwrite(ui.verbose, 'date', '  %s',
-...                      fm.formatdate(f[2], '%Y-%m-%d %H:%M:%S'))
+...         fm.write(b'path', b'%s', f[0])
+...         fm.condwrite(ui.verbose, b'date', b'  %s',
+...                      fm.formatdate(f[2], b'%Y-%m-%d %H:%M:%S'))
 ...         fm.data(size=f[1])
-...         fm.plain('\\n')
+...         fm.plain(b'\\n')
 ...     fm.end()
 >>> show(files)
 foo
@@ -67,7 +67,7 @@  bar
 >>> show(files, verbose=True)
 foo  1970-01-01 00:00:00
 bar  1970-01-01 00:00:01
->>> show(files, template='json')
+>>> show(files, template=b'json')
 [
  {
   "date": [0, 0],
@@ -80,7 +80,7 @@  bar  1970-01-01 00:00:01
   "size": 456
  }
 ]
->>> show(files, template='path: {path}\\ndate: {date|rfc3339date}\\n')
+>>> show(files, template=b'path: {path}\\ndate: {date|rfc3339date}\\n')
 path: foo
 date: 1970-01-01T00:00:00+00:00
 path: bar
@@ -90,14 +90,14 @@  Nested example:
 
 >>> def subrepos(ui, fm):
 ...     fm.startitem()
-...     fm.write('repo', '[%s]\\n', 'baz')
-...     files(ui, fm.nested('files'))
+...     fm.write(b'repo', b'[%s]\\n', b'baz')
+...     files(ui, fm.nested(b'files'))
 ...     fm.end()
 >>> show(subrepos)
 [baz]
 foo
 bar
->>> show(subrepos, template='{repo}: {join(files % "{path}", ", ")}\\n')
+>>> show(subrepos, template=b'{repo}: {join(files % "{path}", ", ")}\\n')
 baz: foo, bar
 """
 
diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -180,17 +180,17 @@  def peer(uiorrepo, opts, path, create=Fa
 def defaultdest(source):
     '''return default destination of clone if none is given
 
-    >>> defaultdest('foo')
+    >>> defaultdest(b'foo')
     'foo'
-    >>> defaultdest('/foo/bar')
+    >>> defaultdest(b'/foo/bar')
     'bar'
-    >>> defaultdest('/')
+    >>> defaultdest(b'/')
     ''
-    >>> defaultdest('')
+    >>> defaultdest(b'')
     ''
-    >>> defaultdest('http://example.org/')
+    >>> defaultdest(b'http://example.org/')
     ''
-    >>> defaultdest('http://example.org/foo/')
+    >>> defaultdest(b'http://example.org/foo/')
     'foo'
     '''
     path = util.url(source).path
diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py
--- a/mercurial/hgweb/hgwebdir_mod.py
+++ b/mercurial/hgweb/hgwebdir_mod.py
@@ -70,9 +70,9 @@  def urlrepos(prefix, roothead, paths):
     """yield url paths and filesystem paths from a list of repo paths
 
     >>> conv = lambda seq: [(v, util.pconvert(p)) for v,p in seq]
-    >>> conv(urlrepos('hg', '/opt', ['/opt/r', '/opt/r/r', '/opt']))
+    >>> conv(urlrepos(b'hg', b'/opt', [b'/opt/r', b'/opt/r/r', b'/opt']))
     [('hg/r', '/opt/r'), ('hg/r/r', '/opt/r/r'), ('hg', '/opt')]
-    >>> conv(urlrepos('', '/opt', ['/opt/r', '/opt/r/r', '/opt']))
+    >>> conv(urlrepos(b'', b'/opt', [b'/opt/r', b'/opt/r/r', b'/opt']))
     [('r', '/opt/r'), ('r/r', '/opt/r/r'), ('', '/opt')]
     """
     for path in paths:
@@ -84,17 +84,17 @@  def geturlcgivars(baseurl, port):
     """
     Extract CGI variables from baseurl
 
-    >>> geturlcgivars("http://host.org/base", "80")
+    >>> geturlcgivars(b"http://host.org/base", b"80")
     ('host.org', '80', '/base')
-    >>> geturlcgivars("http://host.org:8000/base", "80")
+    >>> geturlcgivars(b"http://host.org:8000/base", b"80")
     ('host.org', '8000', '/base')
-    >>> geturlcgivars('/base', 8000)
+    >>> geturlcgivars(b'/base', 8000)
     ('', '8000', '/base')
-    >>> geturlcgivars("base", '8000')
+    >>> geturlcgivars(b"base", b'8000')
     ('', '8000', '/base')
-    >>> geturlcgivars("http://host", '8000')
+    >>> geturlcgivars(b"http://host", b'8000')
     ('host', '8000', '/')
-    >>> geturlcgivars("http://host/", '8000')
+    >>> geturlcgivars(b"http://host/", b'8000')
     ('host', '8000', '/')
     """
     u = util.url(baseurl)
diff --git a/mercurial/match.py b/mercurial/match.py
--- a/mercurial/match.py
+++ b/mercurial/match.py
@@ -580,28 +580,28 @@  class subdirmatcher(basematcher):
 
     The paths are remapped to remove/insert the path as needed:
 
-    >>> m1 = match('root', '', ['a.txt', 'sub/b.txt'])
-    >>> m2 = subdirmatcher('sub', m1)
-    >>> bool(m2('a.txt'))
+    >>> m1 = match(b'root', b'', [b'a.txt', b'sub/b.txt'])
+    >>> m2 = subdirmatcher(b'sub', m1)
+    >>> bool(m2(b'a.txt'))
     False
-    >>> bool(m2('b.txt'))
+    >>> bool(m2(b'b.txt'))
     True
-    >>> bool(m2.matchfn('a.txt'))
+    >>> bool(m2.matchfn(b'a.txt'))
     False
-    >>> bool(m2.matchfn('b.txt'))
+    >>> bool(m2.matchfn(b'b.txt'))
     True
     >>> m2.files()
     ['b.txt']
-    >>> m2.exact('b.txt')
+    >>> m2.exact(b'b.txt')
     True
-    >>> util.pconvert(m2.rel('b.txt'))
+    >>> util.pconvert(m2.rel(b'b.txt'))
     'sub/b.txt'
     >>> def bad(f, msg):
-    ...     print "%s: %s" % (f, msg)
+    ...     print b"%s: %s" % (f, msg)
     >>> m1.bad = bad
-    >>> m2.bad('x.txt', 'No such file')
+    >>> m2.bad(b'x.txt', b'No such file')
     sub/x.txt: No such file
-    >>> m2.abs('c.txt')
+    >>> m2.abs(b'c.txt')
     'sub/c.txt'
     """
 
@@ -703,21 +703,21 @@  def _patsplit(pattern, default):
 def _globre(pat):
     r'''Convert an extended glob string to a regexp string.
 
-    >>> print _globre(r'?')
+    >>> print _globre(br'?')
     .
-    >>> print _globre(r'*')
+    >>> print _globre(br'*')
     [^/]*
-    >>> print _globre(r'**')
+    >>> print _globre(br'**')
     .*
-    >>> print _globre(r'**/a')
+    >>> print _globre(br'**/a')
     (?:.*/)?a
-    >>> print _globre(r'a/**/b')
+    >>> print _globre(br'a/**/b')
     a\/(?:.*/)?b
-    >>> print _globre(r'[a*?!^][^b][!c]')
+    >>> print _globre(br'[a*?!^][^b][!c]')
     [a*?!^][\^b][^c]
-    >>> print _globre(r'{a,b}')
+    >>> print _globre(br'{a,b}')
     (?:a|b)
-    >>> print _globre(r'.\*\?')
+    >>> print _globre(br'.\*\?')
     \.\*\?
     '''
     i, n = 0, len(pat)
@@ -910,17 +910,20 @@  def _rootsanddirs(kindpats):
     include directories that need to be implicitly considered as either, such as
     parent directories.
 
-    >>> _rootsanddirs(\
-        [('glob', 'g/h/*', ''), ('glob', 'g/h', ''), ('glob', 'g*', '')])
+    >>> _rootsanddirs(
+    ...     [(b'glob', b'g/h/*', b''), (b'glob', b'g/h', b''),
+    ...      (b'glob', b'g*', b'')])
     (['g/h', 'g/h', '.'], ['g', '.'])
-    >>> _rootsanddirs(\
-        [('rootfilesin', 'g/h', ''), ('rootfilesin', '', '')])
+    >>> _rootsanddirs(
+    ...     [(b'rootfilesin', b'g/h', b''), (b'rootfilesin', b'', b'')])
     ([], ['g/h', '.', 'g', '.'])
-    >>> _rootsanddirs(\
-        [('relpath', 'r', ''), ('path', 'p/p', ''), ('path', '', '')])
+    >>> _rootsanddirs(
+    ...     [(b'relpath', b'r', b''), (b'path', b'p/p', b''),
+    ...      (b'path', b'', b'')])
     (['r', 'p/p', '.'], ['p', '.'])
-    >>> _rootsanddirs(\
-        [('relglob', 'rg*', ''), ('re', 're/', ''), ('relre', 'rr', '')])
+    >>> _rootsanddirs(
+    ...     [(b'relglob', b'rg*', b''), (b're', b're/', b''),
+    ...      (b'relre', b'rr', b'')])
     (['.', '.', '.'], ['.'])
     '''
     r, d = _patternrootsanddirs(kindpats)
@@ -937,9 +940,9 @@  def _rootsanddirs(kindpats):
 def _explicitfiles(kindpats):
     '''Returns the potential explicit filenames from the patterns.
 
-    >>> _explicitfiles([('path', 'foo/bar', '')])
+    >>> _explicitfiles([(b'path', b'foo/bar', b'')])
     ['foo/bar']
-    >>> _explicitfiles([('rootfilesin', 'foo/bar', '')])
+    >>> _explicitfiles([(b'rootfilesin', b'foo/bar', b'')])
     []
     '''
     # Keep only the pattern kinds where one can specify filenames (vs only
diff --git a/mercurial/minirst.py b/mercurial/minirst.py
--- a/mercurial/minirst.py
+++ b/mercurial/minirst.py
@@ -46,13 +46,13 @@  def replace(text, substs):
     '''
     Apply a list of (find, replace) pairs to a text.
 
-    >>> replace("foo bar", [('f', 'F'), ('b', 'B')])
+    >>> replace(b"foo bar", [(b'f', b'F'), (b'b', b'B')])
     'Foo Bar'
-    >>> encoding.encoding = 'latin1'
-    >>> replace('\\x81\\\\', [('\\\\', '/')])
+    >>> encoding.encoding = b'latin1'
+    >>> replace(b'\\x81\\\\', [(b'\\\\', b'/')])
     '\\x81/'
-    >>> encoding.encoding = 'shiftjis'
-    >>> replace('\\x81\\\\', [('\\\\', '/')])
+    >>> encoding.encoding = b'shiftjis'
+    >>> replace(b'\\x81\\\\', [(b'\\\\', b'/')])
     '\\x81\\\\'
     '''
 
diff --git a/mercurial/parser.py b/mercurial/parser.py
--- a/mercurial/parser.py
+++ b/mercurial/parser.py
@@ -97,15 +97,15 @@  class parser(object):
 def splitargspec(spec):
     """Parse spec of function arguments into (poskeys, varkey, keys, optkey)
 
-    >>> splitargspec('')
+    >>> splitargspec(b'')
     ([], None, [], None)
-    >>> splitargspec('foo bar')
+    >>> splitargspec(b'foo bar')
     ([], None, ['foo', 'bar'], None)
-    >>> splitargspec('foo *bar baz **qux')
+    >>> splitargspec(b'foo *bar baz **qux')
     (['foo'], 'bar', ['baz'], 'qux')
-    >>> splitargspec('*foo')
+    >>> splitargspec(b'*foo')
     ([], 'foo', [], None)
-    >>> splitargspec('**foo')
+    >>> splitargspec(b'**foo')
     ([], None, [], 'foo')
     """
     optkey = None
@@ -221,39 +221,39 @@  def simplifyinfixops(tree, targetnodes):
     """Flatten chained infix operations to reduce usage of Python stack
 
     >>> def f(tree):
-    ...     print prettyformat(simplifyinfixops(tree, ('or',)), ('symbol',))
-    >>> f(('or',
-    ...     ('or',
-    ...       ('symbol', '1'),
-    ...       ('symbol', '2')),
-    ...     ('symbol', '3')))
+    ...     print prettyformat(simplifyinfixops(tree, (b'or',)), (b'symbol',))
+    >>> f((b'or',
+    ...     (b'or',
+    ...       (b'symbol', b'1'),
+    ...       (b'symbol', b'2')),
+    ...     (b'symbol', b'3')))
     (or
       (symbol '1')
       (symbol '2')
       (symbol '3'))
-    >>> f(('func',
-    ...     ('symbol', 'p1'),
-    ...     ('or',
-    ...       ('or',
-    ...         ('func',
-    ...           ('symbol', 'sort'),
-    ...           ('list',
-    ...             ('or',
-    ...               ('or',
-    ...                 ('symbol', '1'),
-    ...                 ('symbol', '2')),
-    ...               ('symbol', '3')),
-    ...             ('negate',
-    ...               ('symbol', 'rev')))),
-    ...         ('and',
-    ...           ('symbol', '4'),
-    ...           ('group',
-    ...             ('or',
-    ...               ('or',
-    ...                 ('symbol', '5'),
-    ...                 ('symbol', '6')),
-    ...               ('symbol', '7'))))),
-    ...       ('symbol', '8'))))
+    >>> f((b'func',
+    ...     (b'symbol', b'p1'),
+    ...     (b'or',
+    ...       (b'or',
+    ...         (b'func',
+    ...           (b'symbol', b'sort'),
+    ...           (b'list',
+    ...             (b'or',
+    ...               (b'or',
+    ...                 (b'symbol', b'1'),
+    ...                 (b'symbol', b'2')),
+    ...               (b'symbol', b'3')),
+    ...             (b'negate',
+    ...               (b'symbol', b'rev')))),
+    ...         (b'and',
+    ...           (b'symbol', b'4'),
+    ...           (b'group',
+    ...             (b'or',
+    ...               (b'or',
+    ...                 (b'symbol', b'5'),
+    ...                 (b'symbol', b'6')),
+    ...               (b'symbol', b'7'))))),
+    ...       (b'symbol', b'8'))))
     (func
       (symbol 'p1')
       (or
@@ -304,13 +304,13 @@  def _buildtree(template, placeholder, re
 def buildtree(template, placeholder, *repls):
     """Create new tree by substituting placeholders by replacements
 
-    >>> _ = ('symbol', '_')
+    >>> _ = (b'symbol', b'_')
     >>> def f(template, *repls):
     ...     return buildtree(template, _, *repls)
-    >>> f(('func', ('symbol', 'only'), ('list', _, _)),
+    >>> f((b'func', (b'symbol', b'only'), (b'list', _, _)),
     ...   ('symbol', '1'), ('symbol', '2'))
     ('func', ('symbol', 'only'), ('list', ('symbol', '1'), ('symbol', '2')))
-    >>> f(('and', _, ('not', _)), ('symbol', '1'), ('symbol', '2'))
+    >>> f((b'and', _, (b'not', _)), (b'symbol', b'1'), (b'symbol', b'2'))
     ('and', ('symbol', '1'), ('not', ('symbol', '2')))
     """
     if not isinstance(placeholder, tuple):
@@ -339,34 +339,34 @@  def matchtree(pattern, tree, placeholder
     matched with the placeholder; Otherwise None
 
     >>> def f(pattern, tree):
-    ...     m = matchtree(pattern, tree, _, {'keyvalue', 'list'})
+    ...     m = matchtree(pattern, tree, _, {b'keyvalue', b'list'})
     ...     if m:
     ...         return m[1:]
 
-    >>> _ = ('symbol', '_')
-    >>> f(('func', ('symbol', 'ancestors'), _),
-    ...   ('func', ('symbol', 'ancestors'), ('symbol', '1')))
+    >>> _ = (b'symbol', b'_')
+    >>> f((b'func', (b'symbol', b'ancestors'), _),
+    ...   (b'func', (b'symbol', b'ancestors'), (b'symbol', b'1')))
     [('symbol', '1')]
-    >>> f(('func', ('symbol', 'ancestors'), _),
-    ...   ('func', ('symbol', 'ancestors'), None))
-    >>> f(('range', ('dagrange', _, _), _),
-    ...   ('range',
-    ...     ('dagrange', ('symbol', '1'), ('symbol', '2')),
-    ...     ('symbol', '3')))
+    >>> f((b'func', (b'symbol', b'ancestors'), _),
+    ...   (b'func', (b'symbol', b'ancestors'), None))
+    >>> f((b'range', (b'dagrange', _, _), _),
+    ...   (b'range',
+    ...     (b'dagrange', (b'symbol', b'1'), (b'symbol', b'2')),
+    ...     (b'symbol', b'3')))
     [('symbol', '1'), ('symbol', '2'), ('symbol', '3')]
 
     The placeholder does not match the specified incomplete nodes because
     an incomplete node (e.g. argument list) cannot construct an expression.
 
-    >>> f(('func', ('symbol', 'ancestors'), _),
-    ...   ('func', ('symbol', 'ancestors'),
-    ...     ('list', ('symbol', '1'), ('symbol', '2'))))
+    >>> f((b'func', (b'symbol', b'ancestors'), _),
+    ...   (b'func', (b'symbol', b'ancestors'),
+    ...     (b'list', (b'symbol', b'1'), (b'symbol', b'2'))))
 
     The placeholder may be omitted, but which shouldn't match a None node.
 
     >>> _ = None
-    >>> f(('func', ('symbol', 'ancestors'), None),
-    ...   ('func', ('symbol', 'ancestors'), ('symbol', '0')))
+    >>> f((b'func', (b'symbol', b'ancestors'), None),
+    ...   (b'func', (b'symbol', b'ancestors'), (b'symbol', b'0')))
     """
     if placeholder is not None and not isinstance(placeholder, tuple):
         raise error.ProgrammingError('placeholder must be a node tuple')
@@ -436,27 +436,27 @@  class basealiasrules(object):
         - ``args``: list of argument names (or None for symbol declaration)
         - ``errorstr``: detail about detected error (or None)
 
-        >>> sym = lambda x: ('symbol', x)
-        >>> symlist = lambda *xs: ('list',) + tuple(sym(x) for x in xs)
-        >>> func = lambda n, a: ('func', sym(n), a)
+        >>> sym = lambda x: (b'symbol', x)
+        >>> symlist = lambda *xs: (b'list',) + tuple(sym(x) for x in xs)
+        >>> func = lambda n, a: (b'func', sym(n), a)
         >>> parsemap = {
-        ...     'foo': sym('foo'),
-        ...     '$foo': sym('$foo'),
-        ...     'foo::bar': ('dagrange', sym('foo'), sym('bar')),
-        ...     'foo()': func('foo', None),
-        ...     '$foo()': func('$foo', None),
-        ...     'foo($1, $2)': func('foo', symlist('$1', '$2')),
-        ...     'foo(bar_bar, baz.baz)':
-        ...         func('foo', symlist('bar_bar', 'baz.baz')),
-        ...     'foo(bar($1, $2))':
-        ...         func('foo', func('bar', symlist('$1', '$2'))),
-        ...     'foo($1, $2, nested($1, $2))':
-        ...         func('foo', (symlist('$1', '$2') +
-        ...                      (func('nested', symlist('$1', '$2')),))),
-        ...     'foo("bar")': func('foo', ('string', 'bar')),
-        ...     'foo($1, $2': error.ParseError('unexpected token: end', 10),
-        ...     'foo("bar': error.ParseError('unterminated string', 5),
-        ...     'foo($1, $2, $1)': func('foo', symlist('$1', '$2', '$1')),
+        ...     b'foo': sym(b'foo'),
+        ...     b'$foo': sym(b'$foo'),
+        ...     b'foo::bar': (b'dagrange', sym(b'foo'), sym(b'bar')),
+        ...     b'foo()': func(b'foo', None),
+        ...     b'$foo()': func(b'$foo', None),
+        ...     b'foo($1, $2)': func(b'foo', symlist(b'$1', b'$2')),
+        ...     b'foo(bar_bar, baz.baz)':
+        ...         func(b'foo', symlist(b'bar_bar', b'baz.baz')),
+        ...     b'foo(bar($1, $2))':
+        ...         func(b'foo', func(b'bar', symlist(b'$1', b'$2'))),
+        ...     b'foo($1, $2, nested($1, $2))':
+        ...         func(b'foo', (symlist(b'$1', b'$2') +
+        ...                      (func(b'nested', symlist(b'$1', b'$2')),))),
+        ...     b'foo("bar")': func(b'foo', (b'string', b'bar')),
+        ...     b'foo($1, $2': error.ParseError(b'unexpected token: end', 10),
+        ...     b'foo("bar': error.ParseError(b'unterminated string', 5),
+        ...     b'foo($1, $2, $1)': func(b'foo', symlist(b'$1', b'$2', b'$1')),
         ... }
         >>> def parse(expr):
         ...     x = parsemap[expr]
@@ -464,42 +464,42 @@  class basealiasrules(object):
         ...         raise x
         ...     return x
         >>> def trygetfunc(tree):
-        ...     if not tree or tree[0] != 'func' or tree[1][0] != 'symbol':
+        ...     if not tree or tree[0] != b'func' or tree[1][0] != b'symbol':
         ...         return None
         ...     if not tree[2]:
         ...         return tree[1][1], []
-        ...     if tree[2][0] == 'list':
+        ...     if tree[2][0] == b'list':
         ...         return tree[1][1], list(tree[2][1:])
         ...     return tree[1][1], [tree[2]]
         >>> class aliasrules(basealiasrules):
         ...     _parse = staticmethod(parse)
         ...     _trygetfunc = staticmethod(trygetfunc)
         >>> builddecl = aliasrules._builddecl
-        >>> builddecl('foo')
+        >>> builddecl(b'foo')
         ('foo', None, None)
-        >>> builddecl('$foo')
+        >>> builddecl(b'$foo')
         ('$foo', None, "invalid symbol '$foo'")
-        >>> builddecl('foo::bar')
+        >>> builddecl(b'foo::bar')
         ('foo::bar', None, 'invalid format')
-        >>> builddecl('foo()')
+        >>> builddecl(b'foo()')
         ('foo', [], None)
-        >>> builddecl('$foo()')
+        >>> builddecl(b'$foo()')
         ('$foo()', None, "invalid function '$foo'")
-        >>> builddecl('foo($1, $2)')
+        >>> builddecl(b'foo($1, $2)')
         ('foo', ['$1', '$2'], None)
-        >>> builddecl('foo(bar_bar, baz.baz)')
+        >>> builddecl(b'foo(bar_bar, baz.baz)')
         ('foo', ['bar_bar', 'baz.baz'], None)
-        >>> builddecl('foo($1, $2, nested($1, $2))')
+        >>> builddecl(b'foo($1, $2, nested($1, $2))')
         ('foo($1, $2, nested($1, $2))', None, 'invalid argument list')
-        >>> builddecl('foo(bar($1, $2))')
+        >>> builddecl(b'foo(bar($1, $2))')
         ('foo(bar($1, $2))', None, 'invalid argument list')
-        >>> builddecl('foo("bar")')
+        >>> builddecl(b'foo("bar")')
         ('foo("bar")', None, 'invalid argument list')
-        >>> builddecl('foo($1, $2')
+        >>> builddecl(b'foo($1, $2')
         ('foo($1, $2', None, 'at 10: unexpected token: end')
-        >>> builddecl('foo("bar')
+        >>> builddecl(b'foo("bar')
         ('foo("bar', None, 'at 5: unterminated string')
-        >>> builddecl('foo($1, $2, $1)')
+        >>> builddecl(b'foo($1, $2, $1)')
         ('foo', None, 'argument names collide with each other')
         """
         try:
@@ -556,33 +556,36 @@  class basealiasrules(object):
         is declared as a symbol.
 
         >>> parsemap = {
-        ...     '$1 or foo': ('or', ('symbol', '$1'), ('symbol', 'foo')),
-        ...     '$1 or $bar': ('or', ('symbol', '$1'), ('symbol', '$bar')),
-        ...     '$10 or baz': ('or', ('symbol', '$10'), ('symbol', 'baz')),
-        ...     '"$1" or "foo"': ('or', ('string', '$1'), ('string', 'foo')),
+        ...     b'$1 or foo': (b'or', (b'symbol', b'$1'), (b'symbol', b'foo')),
+        ...     b'$1 or $bar':
+        ...         (b'or', (b'symbol', b'$1'), (b'symbol', b'$bar')),
+        ...     b'$10 or baz':
+        ...         (b'or', (b'symbol', b'$10'), (b'symbol', b'baz')),
+        ...     b'"$1" or "foo"':
+        ...         (b'or', (b'string', b'$1'), (b'string', b'foo')),
         ... }
         >>> class aliasrules(basealiasrules):
         ...     _parse = staticmethod(parsemap.__getitem__)
         ...     _trygetfunc = staticmethod(lambda x: None)
         >>> builddefn = aliasrules._builddefn
         >>> def pprint(tree):
-        ...     print prettyformat(tree, ('_aliasarg', 'string', 'symbol'))
-        >>> args = ['$1', '$2', 'foo']
-        >>> pprint(builddefn('$1 or foo', args))
+        ...     print prettyformat(tree, (b'_aliasarg', b'string', b'symbol'))
+        >>> args = [b'$1', b'$2', b'foo']
+        >>> pprint(builddefn(b'$1 or foo', args))
         (or
           (_aliasarg '$1')
           (_aliasarg 'foo'))
         >>> try:
-        ...     builddefn('$1 or $bar', args)
+        ...     builddefn(b'$1 or $bar', args)
         ... except error.ParseError as inst:
         ...     print parseerrordetail(inst)
         invalid symbol '$bar'
-        >>> args = ['$1', '$10', 'foo']
-        >>> pprint(builddefn('$10 or baz', args))
+        >>> args = [b'$1', b'$10', b'foo']
+        >>> pprint(builddefn(b'$10 or baz', args))
         (or
           (_aliasarg '$10')
           (symbol 'baz'))
-        >>> pprint(builddefn('"$1" or "foo"', args))
+        >>> pprint(builddefn(b'"$1" or "foo"', args))
         (or
           (string '$1')
           (string 'foo'))
diff --git a/mercurial/patch.py b/mercurial/patch.py
--- a/mercurial/patch.py
+++ b/mercurial/patch.py
@@ -1479,7 +1479,7 @@  def reversehunks(hunks):
     This function operates on hunks coming out of patch.filterpatch, that is
     a list of the form: [header1, hunk1, hunk2, header2...]. Example usage:
 
-    >>> rawpatch = """diff --git a/folder1/g b/folder1/g
+    >>> rawpatch = b"""diff --git a/folder1/g b/folder1/g
     ... --- a/folder1/g
     ... +++ b/folder1/g
     ... @@ -1,7 +1,7 @@
@@ -1541,7 +1541,7 @@  def parsepatch(originalchunks, maxcontex
 
     If maxcontext is not None, trim context lines if necessary.
 
-    >>> rawpatch = '''diff --git a/folder1/g b/folder1/g
+    >>> rawpatch = b'''diff --git a/folder1/g b/folder1/g
     ... --- a/folder1/g
     ... +++ b/folder1/g
     ... @@ -1,8 +1,10 @@
@@ -1667,17 +1667,17 @@  def pathtransform(path, strip, prefix):
 
     Returns (stripped components, path in repository).
 
-    >>> pathtransform('a/b/c', 0, '')
+    >>> pathtransform(b'a/b/c', 0, b'')
     ('', 'a/b/c')
-    >>> pathtransform('   a/b/c   ', 0, '')
+    >>> pathtransform(b'   a/b/c   ', 0, b'')
     ('', '   a/b/c')
-    >>> pathtransform('   a/b/c   ', 2, '')
+    >>> pathtransform(b'   a/b/c   ', 2, b'')
     ('a/b/', 'c')
-    >>> pathtransform('a/b/c', 0, 'd/e/')
+    >>> pathtransform(b'a/b/c', 0, b'd/e/')
     ('', 'd/e/a/b/c')
-    >>> pathtransform('   a//b/c   ', 2, 'd/e/')
+    >>> pathtransform(b'   a//b/c   ', 2, b'd/e/')
     ('a//b/', 'd/e/c')
-    >>> pathtransform('a/b/c', 3, '')
+    >>> pathtransform(b'a/b/c', 3, b'')
     Traceback (most recent call last):
     PatchError: unable to strip away 1 of 3 dirs from a/b/c
     '''
diff --git a/mercurial/pathutil.py b/mercurial/pathutil.py
--- a/mercurial/pathutil.py
+++ b/mercurial/pathutil.py
@@ -203,9 +203,9 @@  def normasprefix(path):
 
     See also issue3033 for detail about need of this function.
 
-    >>> normasprefix('/foo/bar').replace(os.sep, '/')
+    >>> normasprefix(b'/foo/bar').replace(os.sep, b'/')
     '/foo/bar/'
-    >>> normasprefix('/').replace(os.sep, '/')
+    >>> normasprefix(b'/').replace(os.sep, b'/')
     '/'
     '''
     d, p = os.path.splitdrive(path)
diff --git a/mercurial/posix.py b/mercurial/posix.py
--- a/mercurial/posix.py
+++ b/mercurial/posix.py
@@ -52,14 +52,14 @@  def split(p):
     '''Same as posixpath.split, but faster
 
     >>> import posixpath
-    >>> for f in ['/absolute/path/to/file',
-    ...           'relative/path/to/file',
-    ...           'file_alone',
-    ...           'path/to/directory/',
-    ...           '/multiple/path//separators',
-    ...           '/file_at_root',
-    ...           '///multiple_leading_separators_at_root',
-    ...           '']:
+    >>> for f in [b'/absolute/path/to/file',
+    ...           b'relative/path/to/file',
+    ...           b'file_alone',
+    ...           b'path/to/directory/',
+    ...           b'/multiple/path//separators',
+    ...           b'/file_at_root',
+    ...           b'///multiple_leading_separators_at_root',
+    ...           b'']:
     ...     assert split(f) == posixpath.split(f), f
     '''
     ht = p.rsplit('/', 1)
@@ -342,13 +342,13 @@  if pycompat.sysplatform == 'darwin':
         - lowercase
         - omit ignored characters [200c-200f, 202a-202e, 206a-206f,feff]
 
-        >>> normcase('UPPER')
+        >>> normcase(b'UPPER')
         'upper'
-        >>> normcase('Caf\xc3\xa9')
+        >>> normcase(b'Caf\xc3\xa9')
         'cafe\\xcc\\x81'
-        >>> normcase('\xc3\x89')
+        >>> normcase(b'\xc3\x89')
         'e\\xcc\\x81'
-        >>> normcase('\xb8\xca\xc3\xca\xbe\xc8.JPG') # issue3918
+        >>> normcase(b'\xb8\xca\xc3\xca\xbe\xc8.JPG') # issue3918
         '%b8%ca%c3\\xca\\xbe%c8.jpg'
         '''
 
diff --git a/mercurial/revsetlang.py b/mercurial/revsetlang.py
--- a/mercurial/revsetlang.py
+++ b/mercurial/revsetlang.py
@@ -78,7 +78,7 @@  def tokenize(program, lookup=None, symin
     letters of symbols, if ``c.isalnum() or c in '-._/@' or ord(c) > 127``.
 
     Check that @ is a valid unquoted token character (issue3686):
-    >>> list(tokenize("@::"))
+    >>> list(tokenize(b"@::"))
     [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)]
 
     '''
@@ -252,7 +252,7 @@  def _cachedtree(spec):
 def _build(tmplspec, *repls):
     """Create raw parsed tree from a template revset statement
 
-    >>> _build('f(_) and _', ('string', '1'), ('symbol', '2'))
+    >>> _build(b'f(_) and _', (b'string', b'1'), (b'symbol', b'2'))
     ('and', ('func', ('symbol', 'f'), ('string', '1')), ('symbol', '2'))
     """
     template = _cachedtree(tmplspec)
@@ -261,10 +261,10 @@  def _build(tmplspec, *repls):
 def _match(patspec, tree):
     """Test if a tree matches the given pattern statement; return the matches
 
-    >>> _match('f(_)', parse('f()'))
-    >>> _match('f(_)', parse('f(1)'))
+    >>> _match(b'f(_)', parse(b'f()'))
+    >>> _match(b'f(_)', parse(b'f(1)'))
     [('func', ('symbol', 'f'), ('symbol', '1')), ('symbol', '1')]
-    >>> _match('f(_)', parse('f(1, 2)'))
+    >>> _match(b'f(_)', parse(b'f(1, 2)'))
     """
     pattern = _cachedtree(patspec)
     return parser.matchtree(pattern, tree, ('symbol', '_'),
@@ -478,13 +478,13 @@  def optimize(tree):
 def _parsewith(spec, lookup=None, syminitletters=None):
     """Generate a parse tree of given spec with given tokenizing options
 
-    >>> _parsewith('foo($1)', syminitletters=_aliassyminitletters)
+    >>> _parsewith(b'foo($1)', syminitletters=_aliassyminitletters)
     ('func', ('symbol', 'foo'), ('symbol', '$1'))
-    >>> _parsewith('$1')
+    >>> _parsewith(b'$1')
     Traceback (most recent call last):
       ...
     ParseError: ("syntax error in revset '$1'", 0)
-    >>> _parsewith('foo bar')
+    >>> _parsewith(b'foo bar')
     Traceback (most recent call last):
       ...
     ParseError: ('invalid token', 4)
@@ -554,11 +554,11 @@  def parse(spec, lookup=None):
 def _quote(s):
     r"""Quote a value in order to make it safe for the revset engine.
 
-    >>> _quote('asdf')
+    >>> _quote(b'asdf')
     "'asdf'"
-    >>> _quote("asdf'\"")
+    >>> _quote(b"asdf'\"")
     '\'asdf\\\'"\''
-    >>> _quote('asdf\'')
+    >>> _quote(b'asdf\'')
     "'asdf\\''"
     >>> _quote(1)
     "'1'"
@@ -582,19 +582,19 @@  def formatspec(expr, *args):
 
     Prefixing the type with 'l' specifies a parenthesized list of that type.
 
-    >>> formatspec('%r:: and %lr', '10 or 11', ("this()", "that()"))
+    >>> formatspec(b'%r:: and %lr', b'10 or 11', (b"this()", b"that()"))
     '(10 or 11):: and ((this()) or (that()))'
-    >>> formatspec('%d:: and not %d::', 10, 20)
+    >>> formatspec(b'%d:: and not %d::', 10, 20)
     '10:: and not 20::'
-    >>> formatspec('%ld or %ld', [], [1])
+    >>> formatspec(b'%ld or %ld', [], [1])
     "_list('') or 1"
-    >>> formatspec('keyword(%s)', 'foo\\xe9')
+    >>> formatspec(b'keyword(%s)', b'foo\\xe9')
     "keyword('foo\\\\xe9')"
-    >>> b = lambda: 'default'
+    >>> b = lambda: b'default'
     >>> b.branch = b
-    >>> formatspec('branch(%b)', b)
+    >>> formatspec(b'branch(%b)', b)
     "branch('default')"
-    >>> formatspec('root(%ls)', ['a', 'b', 'c', 'd'])
+    >>> formatspec(b'root(%ls)', [b'a', b'b', b'c', b'd'])
     "root(_list('a\\x00b\\x00c\\x00d'))"
     '''
 
diff --git a/mercurial/store.py b/mercurial/store.py
--- a/mercurial/store.py
+++ b/mercurial/store.py
@@ -27,13 +27,13 @@  parsers = policy.importmod(r'parsers')
 # foo.i or foo.d
 def _encodedir(path):
     '''
-    >>> _encodedir('data/foo.i')
+    >>> _encodedir(b'data/foo.i')
     'data/foo.i'
-    >>> _encodedir('data/foo.i/bla.i')
+    >>> _encodedir(b'data/foo.i/bla.i')
     'data/foo.i.hg/bla.i'
-    >>> _encodedir('data/foo.i.hg/bla.i')
+    >>> _encodedir(b'data/foo.i.hg/bla.i')
     'data/foo.i.hg.hg/bla.i'
-    >>> _encodedir('data/foo.i\\ndata/foo.i/bla.i\\ndata/foo.i.hg/bla.i\\n')
+    >>> _encodedir(b'data/foo.i\\ndata/foo.i/bla.i\\ndata/foo.i.hg/bla.i\\n')
     'data/foo.i\\ndata/foo.i.hg/bla.i\\ndata/foo.i.hg.hg/bla.i\\n'
     '''
     return (path
@@ -45,11 +45,11 @@  encodedir = getattr(parsers, 'encodedir'
 
 def decodedir(path):
     '''
-    >>> decodedir('data/foo.i')
+    >>> decodedir(b'data/foo.i')
     'data/foo.i'
-    >>> decodedir('data/foo.i.hg/bla.i')
+    >>> decodedir(b'data/foo.i.hg/bla.i')
     'data/foo.i/bla.i'
-    >>> decodedir('data/foo.i.hg.hg/bla.i')
+    >>> decodedir(b'data/foo.i.hg.hg/bla.i')
     'data/foo.i.hg/bla.i'
     '''
     if ".hg/" not in path:
@@ -80,24 +80,24 @@  def _buildencodefun():
     '''
     >>> enc, dec = _buildencodefun()
 
-    >>> enc('nothing/special.txt')
+    >>> enc(b'nothing/special.txt')
     'nothing/special.txt'
-    >>> dec('nothing/special.txt')
+    >>> dec(b'nothing/special.txt')
     'nothing/special.txt'
 
-    >>> enc('HELLO')
+    >>> enc(b'HELLO')
     '_h_e_l_l_o'
-    >>> dec('_h_e_l_l_o')
+    >>> dec(b'_h_e_l_l_o')
     'HELLO'
 
-    >>> enc('hello:world?')
+    >>> enc(b'hello:world?')
     'hello~3aworld~3f'
-    >>> dec('hello~3aworld~3f')
+    >>> dec(b'hello~3aworld~3f')
     'hello:world?'
 
-    >>> enc('the\x07quick\xADshot')
+    >>> enc(b'the\x07quick\xADshot')
     'the~07quick~adshot'
-    >>> dec('the~07quick~adshot')
+    >>> dec(b'the~07quick~adshot')
     'the\\x07quick\\xadshot'
     '''
     e = '_'
@@ -133,14 +133,14 @@  def _buildencodefun():
 
 def encodefilename(s):
     '''
-    >>> encodefilename('foo.i/bar.d/bla.hg/hi:world?/HELLO')
+    >>> encodefilename(b'foo.i/bar.d/bla.hg/hi:world?/HELLO')
     'foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o'
     '''
     return _encodefname(encodedir(s))
 
 def decodefilename(s):
     '''
-    >>> decodefilename('foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o')
+    >>> decodefilename(b'foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o')
     'foo.i/bar.d/bla.hg/hi:world?/HELLO'
     '''
     return decodedir(_decodefname(s))
@@ -148,13 +148,13 @@  def decodefilename(s):
 def _buildlowerencodefun():
     '''
     >>> f = _buildlowerencodefun()
-    >>> f('nothing/special.txt')
+    >>> f(b'nothing/special.txt')
     'nothing/special.txt'
-    >>> f('HELLO')
+    >>> f(b'HELLO')
     'hello'
-    >>> f('hello:world?')
+    >>> f(b'hello:world?')
     'hello~3aworld~3f'
-    >>> f('the\x07quick\xADshot')
+    >>> f(b'the\x07quick\xADshot')
     'the~07quick~adshot'
     '''
     cmap = dict([(chr(x), chr(x)) for x in xrange(127)])
@@ -180,15 +180,15 @@  def _auxencode(path, dotencode):
     basename (e.g. "aux", "aux.foo"). A directory or file named "foo.aux"
     doesn't need encoding.
 
-    >>> s = '.foo/aux.txt/txt.aux/con/prn/nul/foo.'
-    >>> _auxencode(s.split('/'), True)
+    >>> s = b'.foo/aux.txt/txt.aux/con/prn/nul/foo.'
+    >>> _auxencode(s.split(b'/'), True)
     ['~2efoo', 'au~78.txt', 'txt.aux', 'co~6e', 'pr~6e', 'nu~6c', 'foo~2e']
-    >>> s = '.com1com2/lpt9.lpt4.lpt1/conprn/com0/lpt0/foo.'
-    >>> _auxencode(s.split('/'), False)
+    >>> s = b'.com1com2/lpt9.lpt4.lpt1/conprn/com0/lpt0/foo.'
+    >>> _auxencode(s.split(b'/'), False)
     ['.com1com2', 'lp~749.lpt4.lpt1', 'conprn', 'com0', 'lpt0', 'foo~2e']
-    >>> _auxencode(['foo. '], True)
+    >>> _auxencode([b'foo. '], True)
     ['foo.~20']
-    >>> _auxencode([' .foo'], True)
+    >>> _auxencode([b' .foo'], True)
     ['~20.foo']
     '''
     for i, n in enumerate(path):
diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -1388,23 +1388,23 @@  class gitsubrepo(abstractsubrepo):
         '''ensure git version is new enough
 
         >>> _checkversion = gitsubrepo._checkversion
-        >>> _checkversion('git version 1.6.0')
+        >>> _checkversion(b'git version 1.6.0')
         'ok'
-        >>> _checkversion('git version 1.8.5')
+        >>> _checkversion(b'git version 1.8.5')
         'ok'
-        >>> _checkversion('git version 1.4.0')
+        >>> _checkversion(b'git version 1.4.0')
         'abort'
-        >>> _checkversion('git version 1.5.0')
+        >>> _checkversion(b'git version 1.5.0')
         'warning'
-        >>> _checkversion('git version 1.9-rc0')
+        >>> _checkversion(b'git version 1.9-rc0')
         'ok'
-        >>> _checkversion('git version 1.9.0.265.g81cdec2')
+        >>> _checkversion(b'git version 1.9.0.265.g81cdec2')
         'ok'
-        >>> _checkversion('git version 1.9.0.GIT')
+        >>> _checkversion(b'git version 1.9.0.GIT')
         'ok'
-        >>> _checkversion('git version 12345')
+        >>> _checkversion(b'git version 12345')
         'unknown'
-        >>> _checkversion('no')
+        >>> _checkversion(b'no')
         'unknown'
         '''
         version = gitsubrepo._gitversion(out)
diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py
--- a/mercurial/templatefilters.py
+++ b/mercurial/templatefilters.py
@@ -275,19 +275,19 @@  def person(author):
     """Any text. Returns the name before an email address,
     interpreting it as per RFC 5322.
 
-    >>> person('foo@bar')
+    >>> person(b'foo@bar')
     'foo'
-    >>> person('Foo Bar <foo@bar>')
+    >>> person(b'Foo Bar <foo@bar>')
     'Foo Bar'
-    >>> person('"Foo Bar" <foo@bar>')
+    >>> person(b'"Foo Bar" <foo@bar>')
     'Foo Bar'
-    >>> person('"Foo \"buz\" Bar" <foo@bar>')
+    >>> person(b'"Foo \"buz\" Bar" <foo@bar>')
     'Foo "buz" Bar'
     >>> # The following are invalid, but do exist in real-life
     ...
-    >>> person('Foo "buz" Bar <foo@bar>')
+    >>> person(b'Foo "buz" Bar <foo@bar>')
     'Foo "buz" Bar'
-    >>> person('"Foo Bar <foo@bar>')
+    >>> person(b'"Foo Bar <foo@bar>')
     'Foo Bar'
     """
     if '@' not in author:
diff --git a/mercurial/templater.py b/mercurial/templater.py
--- a/mercurial/templater.py
+++ b/mercurial/templater.py
@@ -147,15 +147,15 @@  def tokenize(program, start, end, term=N
 
 def _parsetemplate(tmpl, start, stop, quote=''):
     r"""
-    >>> _parsetemplate('foo{bar}"baz', 0, 12)
+    >>> _parsetemplate(b'foo{bar}"baz', 0, 12)
     ([('string', 'foo'), ('symbol', 'bar'), ('string', '"baz')], 12)
-    >>> _parsetemplate('foo{bar}"baz', 0, 12, quote='"')
+    >>> _parsetemplate(b'foo{bar}"baz', 0, 12, quote=b'"')
     ([('string', 'foo'), ('symbol', 'bar')], 9)
-    >>> _parsetemplate('foo"{bar}', 0, 9, quote='"')
+    >>> _parsetemplate(b'foo"{bar}', 0, 9, quote=b'"')
     ([('string', 'foo')], 4)
-    >>> _parsetemplate(r'foo\"bar"baz', 0, 12, quote='"')
+    >>> _parsetemplate(br'foo\"bar"baz', 0, 12, quote=b'"')
     ([('string', 'foo"'), ('string', 'bar')], 9)
-    >>> _parsetemplate(r'foo\\"bar', 0, 10, quote='"')
+    >>> _parsetemplate(br'foo\\"bar', 0, 10, quote=b'"')
     ([('string', 'foo\\')], 6)
     """
     parsed = []
@@ -193,18 +193,18 @@  def _unnesttemplatelist(tree):
 
     >>> def f(tree):
     ...     print prettyformat(_unnesttemplatelist(tree))
-    >>> f(('template', []))
+    >>> f((b'template', []))
     (string '')
-    >>> f(('template', [('string', 'foo')]))
+    >>> f((b'template', [(b'string', b'foo')]))
     (string 'foo')
-    >>> f(('template', [('string', 'foo'), ('symbol', 'rev')]))
+    >>> f((b'template', [(b'string', b'foo'), (b'symbol', b'rev')]))
     (template
       (string 'foo')
       (symbol 'rev'))
-    >>> f(('template', [('symbol', 'rev')]))  # template(rev) -> str
+    >>> f((b'template', [(b'symbol', b'rev')]))  # template(rev) -> str
     (template
       (symbol 'rev'))
-    >>> f(('template', [('template', [('string', 'foo')])]))
+    >>> f((b'template', [(b'template', [(b'string', b'foo')])]))
     (string 'foo')
     """
     if not isinstance(tree, tuple):
@@ -231,15 +231,15 @@  def parse(tmpl):
 def _parseexpr(expr):
     """Parse a template expression into tree
 
-    >>> _parseexpr('"foo"')
+    >>> _parseexpr(b'"foo"')
     ('string', 'foo')
-    >>> _parseexpr('foo(bar)')
+    >>> _parseexpr(b'foo(bar)')
     ('func', ('symbol', 'foo'), ('symbol', 'bar'))
-    >>> _parseexpr('foo(')
+    >>> _parseexpr(b'foo(')
     Traceback (most recent call last):
       ...
     ParseError: ('not a prefix: end', 4)
-    >>> _parseexpr('"foo" "bar"')
+    >>> _parseexpr(b'"foo" "bar"')
     Traceback (most recent call last):
       ...
     ParseError: ('invalid token', 7)
@@ -489,10 +489,10 @@  def _buildfuncargs(exp, context, curmeth
     ...     x = _parseexpr(expr)
     ...     n = getsymbol(x[1])
     ...     return _buildfuncargs(x[2], context, exprmethods, n, argspec)
-    >>> fargs('a(l=1, k=2)', 'k l m').keys()
+    >>> fargs(b'a(l=1, k=2)', b'k l m').keys()
     ['l', 'k']
-    >>> args = fargs('a(opts=1, k=2)', '**opts')
-    >>> args.keys(), args['opts'].keys()
+    >>> args = fargs(b'a(opts=1, k=2)', b'**opts')
+    >>> args.keys(), args[b'opts'].keys()
     (['opts'], ['opts', 'k'])
     """
     def compiledict(xs):
diff --git a/mercurial/ui.py b/mercurial/ui.py
--- a/mercurial/ui.py
+++ b/mercurial/ui.py
@@ -531,19 +531,19 @@  class ui(object):
     def configbool(self, section, name, default=_unset, untrusted=False):
         """parse a configuration element as a boolean
 
-        >>> u = ui(); s = 'foo'
-        >>> u.setconfig(s, 'true', 'yes')
-        >>> u.configbool(s, 'true')
+        >>> u = ui(); s = b'foo'
+        >>> u.setconfig(s, b'true', b'yes')
+        >>> u.configbool(s, b'true')
         True
-        >>> u.setconfig(s, 'false', 'no')
-        >>> u.configbool(s, 'false')
+        >>> u.setconfig(s, b'false', b'no')
+        >>> u.configbool(s, b'false')
         False
-        >>> u.configbool(s, 'unknown')
+        >>> u.configbool(s, b'unknown')
         False
-        >>> u.configbool(s, 'unknown', True)
+        >>> u.configbool(s, b'unknown', True)
         True
-        >>> u.setconfig(s, 'invalid', 'somevalue')
-        >>> u.configbool(s, 'invalid')
+        >>> u.setconfig(s, b'invalid', b'somevalue')
+        >>> u.configbool(s, b'invalid')
         Traceback (most recent call last):
             ...
         ConfigError: foo.invalid is not a boolean ('somevalue')
@@ -568,21 +568,21 @@  class ui(object):
                    desc=None, untrusted=False):
         """parse a configuration element with a conversion function
 
-        >>> u = ui(); s = 'foo'
-        >>> u.setconfig(s, 'float1', '42')
-        >>> u.configwith(float, s, 'float1')
+        >>> u = ui(); s = b'foo'
+        >>> u.setconfig(s, b'float1', b'42')
+        >>> u.configwith(float, s, b'float1')
         42.0
-        >>> u.setconfig(s, 'float2', '-4.25')
-        >>> u.configwith(float, s, 'float2')
+        >>> u.setconfig(s, b'float2', b'-4.25')
+        >>> u.configwith(float, s, b'float2')
         -4.25
-        >>> u.configwith(float, s, 'unknown', 7)
+        >>> u.configwith(float, s, b'unknown', 7)
         7.0
-        >>> u.setconfig(s, 'invalid', 'somevalue')
-        >>> u.configwith(float, s, 'invalid')
+        >>> u.setconfig(s, b'invalid', b'somevalue')
+        >>> u.configwith(float, s, b'invalid')
         Traceback (most recent call last):
             ...
         ConfigError: foo.invalid is not a valid float ('somevalue')
-        >>> u.configwith(float, s, 'invalid', desc='womble')
+        >>> u.configwith(float, s, b'invalid', desc=b'womble')
         Traceback (most recent call last):
             ...
         ConfigError: foo.invalid is not a valid womble ('somevalue')
@@ -602,17 +602,17 @@  class ui(object):
     def configint(self, section, name, default=_unset, untrusted=False):
         """parse a configuration element as an integer
 
-        >>> u = ui(); s = 'foo'
-        >>> u.setconfig(s, 'int1', '42')
-        >>> u.configint(s, 'int1')
+        >>> u = ui(); s = b'foo'
+        >>> u.setconfig(s, b'int1', b'42')
+        >>> u.configint(s, b'int1')
         42
-        >>> u.setconfig(s, 'int2', '-42')
-        >>> u.configint(s, 'int2')
+        >>> u.setconfig(s, b'int2', b'-42')
+        >>> u.configint(s, b'int2')
         -42
-        >>> u.configint(s, 'unknown', 7)
+        >>> u.configint(s, b'unknown', 7)
         7
-        >>> u.setconfig(s, 'invalid', 'somevalue')
-        >>> u.configint(s, 'invalid')
+        >>> u.setconfig(s, b'invalid', b'somevalue')
+        >>> u.configint(s, b'invalid')
         Traceback (most recent call last):
             ...
         ConfigError: foo.invalid is not a valid integer ('somevalue')
@@ -627,17 +627,17 @@  class ui(object):
         Units can be specified as b (bytes), k or kb (kilobytes), m or
         mb (megabytes), g or gb (gigabytes).
 
-        >>> u = ui(); s = 'foo'
-        >>> u.setconfig(s, 'val1', '42')
-        >>> u.configbytes(s, 'val1')
+        >>> u = ui(); s = b'foo'
+        >>> u.setconfig(s, b'val1', b'42')
+        >>> u.configbytes(s, b'val1')
         42
-        >>> u.setconfig(s, 'val2', '42.5 kb')
-        >>> u.configbytes(s, 'val2')
+        >>> u.setconfig(s, b'val2', b'42.5 kb')
+        >>> u.configbytes(s, b'val2')
         43520
-        >>> u.configbytes(s, 'unknown', '7 MB')
+        >>> u.configbytes(s, b'unknown', b'7 MB')
         7340032
-        >>> u.setconfig(s, 'invalid', 'somevalue')
-        >>> u.configbytes(s, 'invalid')
+        >>> u.setconfig(s, b'invalid', b'somevalue')
+        >>> u.configbytes(s, b'invalid')
         Traceback (most recent call last):
             ...
         ConfigError: foo.invalid is not a byte quantity ('somevalue')
@@ -660,9 +660,9 @@  class ui(object):
         """parse a configuration element as a list of comma/space separated
         strings
 
-        >>> u = ui(); s = 'foo'
-        >>> u.setconfig(s, 'list1', 'this,is "a small" ,test')
-        >>> u.configlist(s, 'list1')
+        >>> u = ui(); s = b'foo'
+        >>> u.setconfig(s, b'list1', b'this,is "a small" ,test')
+        >>> u.configlist(s, b'list1')
         ['this', 'is', 'a small', 'test']
         """
         # default is not always a list
@@ -677,9 +677,9 @@  class ui(object):
     def configdate(self, section, name, default=_unset, untrusted=False):
         """parse a configuration element as a tuple of ints
 
-        >>> u = ui(); s = 'foo'
-        >>> u.setconfig(s, 'date', '0 0')
-        >>> u.configdate(s, 'date')
+        >>> u = ui(); s = b'foo'
+        >>> u.setconfig(s, b'date', b'0 0')
+        >>> u.configdate(s, b'date')
         (0, 0)
         """
         if self.config(section, name, default, untrusted):
@@ -1256,11 +1256,11 @@  class ui(object):
         This returns tuple "(message, choices)", and "choices" is the
         list of tuple "(response character, text without &)".
 
-        >>> ui.extractchoices("awake? $$ &Yes $$ &No")
+        >>> ui.extractchoices(b"awake? $$ &Yes $$ &No")
         ('awake? ', [('y', 'Yes'), ('n', 'No')])
-        >>> ui.extractchoices("line\\nbreak? $$ &Yes $$ &No")
+        >>> ui.extractchoices(b"line\\nbreak? $$ &Yes $$ &No")
         ('line\\nbreak? ', [('y', 'Yes'), ('n', 'No')])
-        >>> ui.extractchoices("want lots of $$money$$?$$Ye&s$$N&o")
+        >>> ui.extractchoices(b"want lots of $$money$$?$$Ye&s$$N&o")
         ('want lots of $$money$$?', [('s', 'Yes'), ('o', 'No')])
         """
 
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -227,15 +227,15 @@  class digester(object):
 
     This helper can be used to compute one or more digests given their name.
 
-    >>> d = digester(['md5', 'sha1'])
-    >>> d.update('foo')
+    >>> d = digester([b'md5', b'sha1'])
+    >>> d.update(b'foo')
     >>> [k for k in sorted(d)]
     ['md5', 'sha1']
-    >>> d['md5']
+    >>> d[b'md5']
     'acbd18db4cc2f85cedef654fccc4a4d8'
-    >>> d['sha1']
+    >>> d[b'sha1']
     '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
-    >>> digester.preferred(['md5', 'sha1'])
+    >>> digester.preferred([b'md5', b'sha1'])
     'sha1'
     """
 
@@ -448,7 +448,7 @@  def versiontuple(v=None, n=4):
     ``n`` can be 2, 3, or 4. Here is how some version strings map to
     returned values:
 
-    >>> v = '3.6.1+190-df9b73d2d444'
+    >>> v = b'3.6.1+190-df9b73d2d444'
     >>> versiontuple(v, 2)
     (3, 6)
     >>> versiontuple(v, 3)
@@ -456,10 +456,10 @@  def versiontuple(v=None, n=4):
     >>> versiontuple(v, 4)
     (3, 6, 1, '190-df9b73d2d444')
 
-    >>> versiontuple('3.6.1+190-df9b73d2d444+20151118')
+    >>> versiontuple(b'3.6.1+190-df9b73d2d444+20151118')
     (3, 6, 1, '190-df9b73d2d444+20151118')
 
-    >>> v = '3.6'
+    >>> v = b'3.6'
     >>> versiontuple(v, 2)
     (3, 6)
     >>> versiontuple(v, 3)
@@ -467,7 +467,7 @@  def versiontuple(v=None, n=4):
     >>> versiontuple(v, 4)
     (3, 6, None, None)
 
-    >>> v = '3.9-rc'
+    >>> v = b'3.9-rc'
     >>> versiontuple(v, 2)
     (3, 9)
     >>> versiontuple(v, 3)
@@ -475,7 +475,7 @@  def versiontuple(v=None, n=4):
     >>> versiontuple(v, 4)
     (3, 9, None, 'rc')
 
-    >>> v = '3.9-rc+2-02a8fea4289b'
+    >>> v = b'3.9-rc+2-02a8fea4289b'
     >>> versiontuple(v, 2)
     (3, 9)
     >>> versiontuple(v, 3)
@@ -579,11 +579,11 @@  def cachefunc(func):
 class sortdict(collections.OrderedDict):
     '''a simple sorted dictionary
 
-    >>> d1 = sortdict([('a', 0), ('b', 1)])
+    >>> d1 = sortdict([(b'a', 0), (b'b', 1)])
     >>> d2 = d1.copy()
     >>> d2
     sortdict([('a', 0), ('b', 1)])
-    >>> d2.update([('a', 2)])
+    >>> d2.update([(b'a', 2)])
     >>> d2.keys() # should still be in last-set order
     ['b', 'a']
     '''
@@ -1240,24 +1240,24 @@  def checkwinfilename(path):
     r'''Check that the base-relative path is a valid filename on Windows.
     Returns None if the path is ok, or a UI string describing the problem.
 
-    >>> checkwinfilename("just/a/normal/path")
-    >>> checkwinfilename("foo/bar/con.xml")
+    >>> checkwinfilename(b"just/a/normal/path")
+    >>> checkwinfilename(b"foo/bar/con.xml")
     "filename contains 'con', which is reserved on Windows"
-    >>> checkwinfilename("foo/con.xml/bar")
+    >>> checkwinfilename(b"foo/con.xml/bar")
     "filename contains 'con', which is reserved on Windows"
-    >>> checkwinfilename("foo/bar/xml.con")
-    >>> checkwinfilename("foo/bar/AUX/bla.txt")
+    >>> checkwinfilename(b"foo/bar/xml.con")
+    >>> checkwinfilename(b"foo/bar/AUX/bla.txt")
     "filename contains 'AUX', which is reserved on Windows"
-    >>> checkwinfilename("foo/bar/bla:.txt")
+    >>> checkwinfilename(b"foo/bar/bla:.txt")
     "filename contains ':', which is reserved on Windows"
-    >>> checkwinfilename("foo/bar/b\07la.txt")
+    >>> checkwinfilename(b"foo/bar/b\07la.txt")
     "filename contains '\\x07', which is invalid on Windows"
-    >>> checkwinfilename("foo/bar/bla ")
+    >>> checkwinfilename(b"foo/bar/bla ")
     "filename ends with ' ', which is not allowed on Windows"
-    >>> checkwinfilename("../bar")
-    >>> checkwinfilename("foo\\")
+    >>> checkwinfilename(b"../bar")
+    >>> checkwinfilename(b"foo\\")
     "filename ends with '\\', which is invalid on Windows"
-    >>> checkwinfilename("foo\\/bar")
+    >>> checkwinfilename(b"foo\\/bar")
     "directory name ends with '\\', which is invalid on Windows"
     '''
     if path.endswith('\\'):
@@ -2001,15 +2001,15 @@  def parsedate(date, formats=None, bias=N
     The date may be a "unixtime offset" string or in one of the specified
     formats. If the date already is a (unixtime, offset) tuple, it is returned.
 
-    >>> parsedate(' today ') == parsedate(\
+    >>> parsedate(b' today ') == parsedate(\
                                   datetime.date.today().strftime('%b %d'))
     True
-    >>> parsedate( 'yesterday ') == parsedate((datetime.date.today() -\
+    >>> parsedate(b'yesterday ') == parsedate((datetime.date.today() -\
                                                datetime.timedelta(days=1)\
                                               ).strftime('%b %d'))
     True
     >>> now, tz = makedate()
-    >>> strnow, strtz = parsedate('now')
+    >>> strnow, strtz = parsedate(b'now')
     >>> (strnow - now) < 1
     True
     >>> tz == strtz
@@ -2083,12 +2083,12 @@  def matchdate(date):
 
     '>{date}' on or after a given date
 
-    >>> p1 = parsedate("10:29:59")
-    >>> p2 = parsedate("10:30:00")
-    >>> p3 = parsedate("10:30:59")
-    >>> p4 = parsedate("10:31:00")
-    >>> p5 = parsedate("Sep 15 10:30:00 1999")
-    >>> f = matchdate("10:30")
+    >>> p1 = parsedate(b"10:29:59")
+    >>> p2 = parsedate(b"10:30:00")
+    >>> p3 = parsedate(b"10:30:59")
+    >>> p4 = parsedate(b"10:31:00")
+    >>> p5 = parsedate(b"Sep 15 10:30:00 1999")
+    >>> f = matchdate(b"10:30")
     >>> f(p1[0])
     False
     >>> f(p2[0])
@@ -2163,27 +2163,27 @@  def stringmatcher(pattern, casesensitive
     ...     return (kind, pattern, [bool(matcher(t)) for t in tests])
 
     exact matching (no prefix):
-    >>> test('abcdefg', 'abc', 'def', 'abcdefg')
+    >>> test(b'abcdefg', b'abc', b'def', b'abcdefg')
     ('literal', 'abcdefg', [False, False, True])
 
     regex matching ('re:' prefix)
-    >>> test('re:a.+b', 'nomatch', 'fooadef', 'fooadefbar')
+    >>> test(b're:a.+b', b'nomatch', b'fooadef', b'fooadefbar')
     ('re', 'a.+b', [False, False, True])
 
     force exact matches ('literal:' prefix)
-    >>> test('literal:re:foobar', 'foobar', 're:foobar')
+    >>> test(b'literal:re:foobar', b'foobar', b're:foobar')
     ('literal', 're:foobar', [False, True])
 
     unknown prefixes are ignored and treated as literals
-    >>> test('foo:bar', 'foo', 'bar', 'foo:bar')
+    >>> test(b'foo:bar', b'foo', b'bar', b'foo:bar')
     ('literal', 'foo:bar', [False, False, True])
 
     case insensitive regex matches
-    >>> itest('re:A.+b', 'nomatch', 'fooadef', 'fooadefBar')
+    >>> itest(b're:A.+b', b'nomatch', b'fooadef', b'fooadefBar')
     ('re', 'A.+b', [False, False, True])
 
     case insensitive literal matches
-    >>> itest('ABCDEFG', 'abc', 'def', 'abcdefg')
+    >>> itest(b'ABCDEFG', b'abc', b'def', b'abcdefg')
     ('literal', 'ABCDEFG', [False, False, True])
     """
     if pattern.startswith('re:'):
@@ -2656,55 +2656,55 @@  class url(object):
 
     Examples:
 
-    >>> url('http://www.ietf.org/rfc/rfc2396.txt')
+    >>> url(b'http://www.ietf.org/rfc/rfc2396.txt')
     <url scheme: 'http', host: 'www.ietf.org', path: 'rfc/rfc2396.txt'>
-    >>> url('ssh://[::1]:2200//home/joe/repo')
+    >>> url(b'ssh://[::1]:2200//home/joe/repo')
     <url scheme: 'ssh', host: '[::1]', port: '2200', path: '/home/joe/repo'>
-    >>> url('file:///home/joe/repo')
+    >>> url(b'file:///home/joe/repo')
     <url scheme: 'file', path: '/home/joe/repo'>
-    >>> url('file:///c:/temp/foo/')
+    >>> url(b'file:///c:/temp/foo/')
     <url scheme: 'file', path: 'c:/temp/foo/'>
-    >>> url('bundle:foo')
+    >>> url(b'bundle:foo')
     <url scheme: 'bundle', path: 'foo'>
-    >>> url('bundle://../foo')
+    >>> url(b'bundle://../foo')
     <url scheme: 'bundle', path: '../foo'>
-    >>> url(r'c:\foo\bar')
+    >>> url(br'c:\foo\bar')
     <url path: 'c:\\foo\\bar'>
-    >>> url(r'\\blah\blah\blah')
+    >>> url(br'\\blah\blah\blah')
     <url path: '\\\\blah\\blah\\blah'>
-    >>> url(r'\\blah\blah\blah#baz')
+    >>> url(br'\\blah\blah\blah#baz')
     <url path: '\\\\blah\\blah\\blah', fragment: 'baz'>
-    >>> url(r'file:///C:\users\me')
+    >>> url(br'file:///C:\users\me')
     <url scheme: 'file', path: 'C:\\users\\me'>
 
     Authentication credentials:
 
-    >>> url('ssh://joe:xyz@x/repo')
+    >>> url(b'ssh://joe:xyz@x/repo')
     <url scheme: 'ssh', user: 'joe', passwd: 'xyz', host: 'x', path: 'repo'>
-    >>> url('ssh://joe@x/repo')
+    >>> url(b'ssh://joe@x/repo')
     <url scheme: 'ssh', user: 'joe', host: 'x', path: 'repo'>
 
     Query strings and fragments:
 
-    >>> url('http://host/a?b#c')
+    >>> url(b'http://host/a?b#c')
     <url scheme: 'http', host: 'host', path: 'a', query: 'b', fragment: 'c'>
-    >>> url('http://host/a?b#c', parsequery=False, parsefragment=False)
+    >>> url(b'http://host/a?b#c', parsequery=False, parsefragment=False)
     <url scheme: 'http', host: 'host', path: 'a?b#c'>
 
     Empty path:
 
-    >>> url('')
+    >>> url(b'')
     <url path: ''>
-    >>> url('#a')
+    >>> url(b'#a')
     <url path: '', fragment: 'a'>
-    >>> url('http://host/')
+    >>> url(b'http://host/')
     <url scheme: 'http', host: 'host', path: ''>
-    >>> url('http://host/#a')
+    >>> url(b'http://host/#a')
     <url scheme: 'http', host: 'host', path: '', fragment: 'a'>
 
     Only scheme:
 
-    >>> url('http:')
+    >>> url(b'http:')
     <url scheme: 'http'>
     """
 
@@ -2819,33 +2819,33 @@  class url(object):
 
         Examples:
 
-        >>> str(url('http://user:pw@host:80/c:/bob?fo:oo#ba:ar'))
+        >>> str(url(b'http://user:pw@host:80/c:/bob?fo:oo#ba:ar'))
         'http://user:pw@host:80/c:/bob?fo:oo#ba:ar'
-        >>> str(url('http://user:pw@host:80/?foo=bar&baz=42'))
+        >>> str(url(b'http://user:pw@host:80/?foo=bar&baz=42'))
         'http://user:pw@host:80/?foo=bar&baz=42'
-        >>> str(url('http://user:pw@host:80/?foo=bar%3dbaz'))
+        >>> str(url(b'http://user:pw@host:80/?foo=bar%3dbaz'))
         'http://user:pw@host:80/?foo=bar%3dbaz'
-        >>> str(url('ssh://user:pw@[::1]:2200//home/joe#'))
+        >>> str(url(b'ssh://user:pw@[::1]:2200//home/joe#'))
         'ssh://user:pw@[::1]:2200//home/joe#'
-        >>> str(url('http://localhost:80//'))
+        >>> str(url(b'http://localhost:80//'))
         'http://localhost:80//'
-        >>> str(url('http://localhost:80/'))
+        >>> str(url(b'http://localhost:80/'))
         'http://localhost:80/'
-        >>> str(url('http://localhost:80'))
+        >>> str(url(b'http://localhost:80'))
         'http://localhost:80/'
-        >>> str(url('bundle:foo'))
+        >>> str(url(b'bundle:foo'))
         'bundle:foo'
-        >>> str(url('bundle://../foo'))
+        >>> str(url(b'bundle://../foo'))
         'bundle:../foo'
-        >>> str(url('path'))
+        >>> str(url(b'path'))
         'path'
-        >>> str(url('file:///tmp/foo/bar'))
+        >>> str(url(b'file:///tmp/foo/bar'))
         'file:///tmp/foo/bar'
-        >>> str(url('file:///c:/tmp/foo/bar'))
+        >>> str(url(b'file:///c:/tmp/foo/bar'))
         'file:///c:/tmp/foo/bar'
-        >>> print url(r'bundle:foo\bar')
+        >>> print url(br'bundle:foo\bar')
         bundle:foo\bar
-        >>> print url(r'file:///D:\data\hg')
+        >>> print url(br'file:///D:\data\hg')
         file:///D:\data\hg
         """
         if self._localpath:
@@ -3024,11 +3024,11 @@  def timed(func):
 def sizetoint(s):
     '''Convert a space specifier to a byte count.
 
-    >>> sizetoint('30')
+    >>> sizetoint(b'30')
     30
-    >>> sizetoint('2.2kb')
+    >>> sizetoint(b'2.2kb')
     2252
-    >>> sizetoint('6M')
+    >>> sizetoint(b'6M')
     6291456
     '''
     t = s.strip().lower()
diff --git a/mercurial/windows.py b/mercurial/windows.py
--- a/mercurial/windows.py
+++ b/mercurial/windows.py
@@ -267,15 +267,15 @@  def samestat(s1, s2):
 _needsshellquote = None
 def shellquote(s):
     r"""
-    >>> shellquote(r'C:\Users\xyz')
+    >>> shellquote(br'C:\Users\xyz')
     '"C:\\Users\\xyz"'
-    >>> shellquote(r'C:\Users\xyz/mixed')
+    >>> shellquote(br'C:\Users\xyz/mixed')
     '"C:\\Users\\xyz/mixed"'
     >>> # Would be safe not to quote too, since it is all double backslashes
-    >>> shellquote(r'C:\\Users\\xyz')
+    >>> shellquote(br'C:\\Users\\xyz')
     '"C:\\\\Users\\\\xyz"'
     >>> # But this must be quoted
-    >>> shellquote(r'C:\\Users\\xyz/abc')
+    >>> shellquote(br'C:\\Users\\xyz/abc')
     '"C:\\\\Users\\\\xyz/abc"'
     """
     global _quotere