diff hgext3rd/topic/__init__.py @ 4814:48b30ff742cb

python3: use format-source to run byteify-strings in .py files Using the format-source extension smooth out the pain of merging after auto-formatting. This change makes all of the Evolve test suite pass under python3 and has added benefit of being 100% automated using mercurial's `byteify-strings` script version 1.0 (revision 11498aa91c036c6d70f7ac5ee5af2664a84a1130). How to benefit from the help of format-source is explained in the README.
author Rapha?l Gom?s <rgomes@octobus.net>
date Tue, 06 Aug 2019 15:06:38 +0200
parents 67567d7f1174
children 6f5d3f58fbe4
line wrap: on
line diff
--- a/hgext3rd/topic/__init__.py	Tue Aug 06 15:06:27 2019 +0200
+++ b/hgext3rd/topic/__init__.py	Tue Aug 06 15:06:38 2019 +0200
@@ -160,32 +160,32 @@
 
 cmdtable = {}
 command = registrar.command(cmdtable)
-colortable = {'topic.active': 'green',
-              'topic.list.unstablecount': 'red',
-              'topic.list.headcount.multiple': 'yellow',
-              'topic.list.behindcount': 'cyan',
-              'topic.list.behinderror': 'red',
-              'stack.index': 'yellow',
-              'stack.index.base': 'none dim',
-              'stack.desc.base': 'none dim',
-              'stack.shortnode.base': 'none dim',
-              'stack.state.base': 'dim',
-              'stack.state.clean': 'green',
-              'stack.index.current': 'cyan',       # random pick
-              'stack.state.current': 'cyan bold',  # random pick
-              'stack.desc.current': 'cyan',        # random pick
-              'stack.shortnode.current': 'cyan',   # random pick
-              'stack.state.orphan': 'red',
-              'stack.state.content-divergent': 'red',
-              'stack.state.phase-divergent': 'red',
-              'stack.summary.behindcount': 'cyan',
-              'stack.summary.behinderror': 'red',
-              'stack.summary.headcount.multiple': 'yellow',
+colortable = {b'topic.active': b'green',
+              b'topic.list.unstablecount': b'red',
+              b'topic.list.headcount.multiple': b'yellow',
+              b'topic.list.behindcount': b'cyan',
+              b'topic.list.behinderror': b'red',
+              b'stack.index': b'yellow',
+              b'stack.index.base': b'none dim',
+              b'stack.desc.base': b'none dim',
+              b'stack.shortnode.base': b'none dim',
+              b'stack.state.base': b'dim',
+              b'stack.state.clean': b'green',
+              b'stack.index.current': b'cyan',       # random pick
+              b'stack.state.current': b'cyan bold',  # random pick
+              b'stack.desc.current': b'cyan',        # random pick
+              b'stack.shortnode.current': b'cyan',   # random pick
+              b'stack.state.orphan': b'red',
+              b'stack.state.content-divergent': b'red',
+              b'stack.state.phase-divergent': b'red',
+              b'stack.summary.behindcount': b'cyan',
+              b'stack.summary.behinderror': b'red',
+              b'stack.summary.headcount.multiple': b'yellow',
               # default color to help log output and thg
               # (first pick I could think off, update as needed
-              'log.topic': 'green_background',
-              'topic.active': 'green',
-             }
+              b'log.topic': b'green_background',
+              b'topic.active': b'green',
+              }
 
 __version__ = b'0.17.0.dev'
 
@@ -200,25 +200,25 @@
     configtable = {}
     configitem = registrar.configitem(configtable)
 
-    configitem('experimental', 'enforce-topic',
+    configitem(b'experimental', b'enforce-topic',
                default=False,
     )
-    configitem('experimental', 'enforce-single-head',
+    configitem(b'experimental', b'enforce-single-head',
                default=False,
     )
-    configitem('experimental', 'topic-mode',
+    configitem(b'experimental', b'topic-mode',
                default=None,
     )
-    configitem('experimental', 'topic.publish-bare-branch',
+    configitem(b'experimental', b'topic.publish-bare-branch',
                default=False,
     )
-    configitem('experimental', 'topic.allow-publish',
+    configitem(b'experimental', b'topic.allow-publish',
                default=configitems.dynamicdefault,
     )
-    configitem('_internal', 'keep-topic',
+    configitem(b'_internal', b'keep-topic',
                default=False,
     )
-    configitem('experimental', 'topic-mode.server',
+    configitem(b'experimental', b'topic-mode.server',
                default=configitems.dynamicdefault,
     )
 
@@ -229,14 +229,14 @@
         # nobody else did so far.
         from mercurial import configitems
         extraitem = functools.partial(configitems._register, ui._knownconfig)
-        if ('experimental' not in ui._knownconfig
-                or not ui._knownconfig['experimental'].get('thg.displaynames')):
-            extraitem('experimental', 'thg.displaynames',
+        if (b'experimental' not in ui._knownconfig
+                or not ui._knownconfig[b'experimental'].get(b'thg.displaynames')):
+            extraitem(b'experimental', b'thg.displaynames',
                       default=None,
             )
-        if ('devel' not in ui._knownconfig
-                or not ui._knownconfig['devel'].get('random')):
-            extraitem('devel', 'randomseed',
+        if (b'devel' not in ui._knownconfig
+                or not ui._knownconfig[b'devel'].get(b'random')):
+            extraitem(b'devel', b'randomseed',
                       default=None,
             )
 
@@ -246,8 +246,8 @@
 
 def _contexttopic(self, force=False):
     if not (force or self.mutable()):
-        return ''
-    return self.extra().get(constants.extrakey, '')
+        return b''
+    return self.extra().get(constants.extrakey, b'')
 context.basectx.topic = _contexttopic
 
 def _contexttopicidx(self):
@@ -275,38 +275,38 @@
         idx = int(name[1:])
         tname = topic = repo.currenttopic
         if topic:
-            ttype = 'topic'
+            ttype = b'topic'
             revs = list(stack.stack(repo, topic=topic))
         else:
-            ttype = 'branch'
+            ttype = b'branch'
             tname = branch = repo[None].branch()
             revs = list(stack.stack(repo, branch=branch))
     elif topicrev.match(name):
         idx = int(name[1:])
-        ttype = 'topic'
+        ttype = b'topic'
         tname = topic = repo.currenttopic
         if not tname:
-            raise error.Abort(_('cannot resolve "%s": no active topic') % name)
+            raise error.Abort(_(b'cannot resolve "%s": no active topic') % name)
         revs = list(stack.stack(repo, topic=topic))
 
     if revs is not None:
         try:
             r = revs[idx]
         except IndexError:
-            if ttype == 'topic':
-                msg = _('cannot resolve "%s": %s "%s" has only %d changesets')
-            elif ttype == 'branch':
-                msg = _('cannot resolve "%s": %s "%s" has only %d non-public changesets')
+            if ttype == b'topic':
+                msg = _(b'cannot resolve "%s": %s "%s" has only %d changesets')
+            elif ttype == b'branch':
+                msg = _(b'cannot resolve "%s": %s "%s" has only %d non-public changesets')
             raise error.Abort(msg % (name, ttype, tname, len(revs) - 1))
         # t0 or s0 can be None
         if r == -1 and idx == 0:
-            msg = _('the %s "%s" has no %s')
+            msg = _(b'the %s "%s" has no %s')
             raise error.Abort(msg % (ttype, tname, name))
         return [repo[r].node()]
     if name not in repo.topics:
         return []
     node = repo.changelog.node
-    return [node(rev) for rev in repo.revs('topic(%s)', name)]
+    return [node(rev) for rev in repo.revs(b'topic(%s)', name)]
 
 def _nodemap(repo, node):
     ctx = repo[node]
@@ -321,22 +321,22 @@
     topicmap.modsetup(ui)
     setupimportexport(ui)
 
-    extensions.afterloaded('rebase', _fixrebase)
+    extensions.afterloaded(b'rebase', _fixrebase)
 
     flow.installpushflag(ui)
 
-    entry = extensions.wrapcommand(commands.table, 'commit', commitwrap)
-    entry[1].append(('t', 'topic', '',
-                     _("use specified topic"), _('TOPIC')))
+    entry = extensions.wrapcommand(commands.table, b'commit', commitwrap)
+    entry[1].append((b't', b'topic', b'',
+                     _(b"use specified topic"), _(b'TOPIC')))
 
-    entry = extensions.wrapcommand(commands.table, 'push', pushoutgoingwrap)
-    entry[1].append(('t', 'topic', '',
-                     _("topic to push"), _('TOPIC')))
+    entry = extensions.wrapcommand(commands.table, b'push', pushoutgoingwrap)
+    entry[1].append((b't', b'topic', b'',
+                     _(b"topic to push"), _(b'TOPIC')))
 
-    entry = extensions.wrapcommand(commands.table, 'outgoing',
+    entry = extensions.wrapcommand(commands.table, b'outgoing',
                                    pushoutgoingwrap)
-    entry[1].append(('t', 'topic', '',
-                     _("topic to push"), _('TOPIC')))
+    entry[1].append((b't', b'topic', b'',
+                     _(b"topic to push"), _(b'TOPIC')))
 
     extensions.wrapfunction(cmdutil, 'buildcommittext', committextwrap)
     extensions.wrapfunction(merge, 'update', mergeupdatewrap)
@@ -344,20 +344,20 @@
     # behaviour of changing topic and I can't find a better way
     # to do that as scmutil.revsingle returns the rev number and hence we can't
     # plug into logic for this into mergemod.update().
-    extensions.wrapcommand(commands.table, 'update', checkt0)
+    extensions.wrapcommand(commands.table, b'update', checkt0)
 
     try:
-        evolve = extensions.find('evolve')
+        evolve = extensions.find(b'evolve')
         extensions.wrapfunction(evolve.rewriteutil, "presplitupdate",
                                 presplitupdatetopic)
     except (KeyError, AttributeError):
         pass
 
-    cmdutil.summaryhooks.add('topic', summaryhook)
+    cmdutil.summaryhooks.add(b'topic', summaryhook)
 
     if not post45template:
-        templatekw.keywords['topic'] = topickw
-        templatekw.keywords['topicidx'] = topicidxkw
+        templatekw.keywords[b'topic'] = topickw
+        templatekw.keywords[b'topicidx'] = topicidxkw
     # Wrap workingctx extra to return the topic name
     extensions.wrapfunction(context.workingctx, '__init__', wrapinit)
     # Wrap changelog.add to drop empty topic
@@ -369,9 +369,9 @@
 
     repo = repo.unfiltered()
 
-    if repo.ui.config('experimental', 'thg.displaynames') is None:
-        repo.ui.setconfig('experimental', 'thg.displaynames', 'topics',
-                          source='topic-extension')
+    if repo.ui.config(b'experimental', b'thg.displaynames') is None:
+        repo.ui.setconfig(b'experimental', b'thg.displaynames', b'topics',
+                          source=b'topic-extension')
 
     class topicrepo(repo.__class__):
 
@@ -380,15 +380,15 @@
 
         def _restrictcapabilities(self, caps):
             caps = super(topicrepo, self)._restrictcapabilities(caps)
-            caps.add('topics')
+            caps.add(b'topics')
             return caps
 
         def commit(self, *args, **kwargs):
-            backup = self.ui.backupconfig('ui', 'allowemptycommit')
+            backup = self.ui.backupconfig(b'ui', b'allowemptycommit')
             try:
-                if self.currenttopic != self['.'].topic():
+                if self.currenttopic != self[b'.'].topic():
                     # bypass the core "nothing changed" logic
-                    self.ui.setconfig('ui', 'allowemptycommit', True)
+                    self.ui.setconfig(b'ui', b'allowemptycommit', True)
                 return super(topicrepo, self).commit(*args, **kwargs)
             finally:
                 self.ui.restoreconfig(backup)
@@ -404,7 +404,7 @@
                 if current:
                     ctx.extra()[constants.extrakey] = current
             if (isinstance(ctx, context.memctx)
-                and ctx.extra().get('amend_source')
+                and ctx.extra().get(b'amend_source')
                 and ctx.topic()
                 and not self.currenttopic):
                 # we are amending and need to remove a topic
@@ -415,16 +415,16 @@
         def topics(self):
             if self._topics is not None:
                 return self._topics
-            topics = set(['', self.currenttopic])
-            for c in self.set('not public()'):
+            topics = set([b'', self.currenttopic])
+            for c in self.set(b'not public()'):
                 topics.add(c.topic())
-            topics.remove('')
+            topics.remove(b'')
             self._topics = topics
             return topics
 
         @property
         def currenttopic(self):
-            return self.vfs.tryread('topic')
+            return self.vfs.tryread(b'topic')
 
         # overwritten at the instance level by topicmap.py
         _autobranchmaptopic = True
@@ -441,7 +441,7 @@
             if branch is None:
                 branch = self[None].branch()
             if self.currenttopic:
-                branch = "%s:%s" % (branch, self.currenttopic)
+                branch = b"%s:%s" % (branch, self.currenttopic)
             return super(topicrepo, self).branchheads(branch=branch,
                                                       start=start,
                                                       closed=closed)
@@ -464,11 +464,11 @@
         def transaction(self, desc, *a, **k):
             ctr = self.currenttransaction()
             tr = super(topicrepo, self).transaction(desc, *a, **k)
-            if desc in ('strip', 'repair') or ctr is not None:
+            if desc in (b'strip', b'repair') or ctr is not None:
                 return tr
 
             reporef = weakref.ref(self)
-            if self.ui.configbool('experimental', 'enforce-single-head'):
+            if self.ui.configbool(b'experimental', b'enforce-single-head'):
                 if util.safehasattr(tr, 'validator'): # hg <= 4.7
                     origvalidator = tr.validator
                 else:
@@ -484,10 +484,10 @@
                 else:
                     tr._validator = validator
 
-            topicmodeserver = self.ui.config('experimental',
-                                             'topic-mode.server', 'ignore')
-            ispush = (desc.startswith('push') or desc.startswith('serve'))
-            if (topicmodeserver != 'ignore' and ispush):
+            topicmodeserver = self.ui.config(b'experimental',
+                                             b'topic-mode.server', b'ignore')
+            ispush = (desc.startswith(b'push') or desc.startswith(b'serve'))
+            if (topicmodeserver != b'ignore' and ispush):
                 if util.safehasattr(tr, 'validator'): # hg <= 4.7
                     origvalidator = tr.validator
                 else:
@@ -502,9 +502,9 @@
                 else:
                     tr._validator = validator
 
-            elif (self.ui.configbool('experimental', 'topic.publish-bare-branch')
-                    and (desc.startswith('push')
-                         or desc.startswith('serve'))
+            elif (self.ui.configbool(b'experimental', b'topic.publish-bare-branch')
+                    and (desc.startswith(b'push')
+                         or desc.startswith(b'serve'))
                     ):
                 origclose = tr.close
                 trref = weakref.ref(tr)
@@ -515,8 +515,8 @@
                     flow.publishbarebranch(repo, tr2)
                     origclose()
                 tr.close = close
-            allow_publish = self.ui.configbool('experimental',
-                                               'topic.allow-publish',
+            allow_publish = self.ui.configbool(b'experimental',
+                                               b'topic.allow-publish',
                                                True)
             if not allow_publish:
                 if util.safehasattr(tr, 'validator'): # hg <= 4.7
@@ -547,62 +547,62 @@
                 csetcount = stack.stack(repo, topic=ct).changesetcount
                 empty = csetcount == 0
                 if empty and not ctwasempty:
-                    ui.status("active topic '%s' is now empty\n" % ct)
+                    ui.status(b"active topic '%s' is now empty\n" % ct)
                     trnames = getattr(tr, 'names', getattr(tr, '_names', ()))
-                    if ('phase' in trnames
-                            or any(n.startswith('push-response')
+                    if (b'phase' in trnames
+                            or any(n.startswith(b'push-response')
                                    for n in trnames)):
-                        ui.status(_("(use 'hg topic --clear' to clear it if needed)\n"))
-                hint = _("(see 'hg help topics' for more information)\n")
+                        ui.status(_(b"(use 'hg topic --clear' to clear it if needed)\n"))
+                hint = _(b"(see 'hg help topics' for more information)\n")
                 if ctwasempty and not empty:
                     if csetcount == 1:
-                        msg = _("active topic '%s' grew its first changeset\n%s")
+                        msg = _(b"active topic '%s' grew its first changeset\n%s")
                         ui.status(msg % (ct, hint))
                     else:
-                        msg = _("active topic '%s' grew its %s first changesets\n%s")
+                        msg = _(b"active topic '%s' grew its %s first changesets\n%s")
                         ui.status(msg % (ct, csetcount, hint))
 
-            tr.addpostclose('signalcurrenttopicempty', currenttopicempty)
+            tr.addpostclose(b'signalcurrenttopicempty', currenttopicempty)
             return tr
 
     repo.__class__ = topicrepo
     repo._topics = None
     if util.safehasattr(repo, 'names'):
         repo.names.addnamespace(namespaces.namespace(
-            'topics', 'topic', namemap=_namemap, nodemap=_nodemap,
+            b'topics', b'topic', namemap=_namemap, nodemap=_nodemap,
             listnames=lambda repo: repo.topics))
 
 if post45template:
     @templatekeyword(b'topic', requires={b'ctx'})
     def topickw(context, mapping):
         """:topic: String. The topic of the changeset"""
-        ctx = context.resource(mapping, 'ctx')
+        ctx = context.resource(mapping, b'ctx')
         return ctx.topic()
 
     @templatekeyword(b'topicidx', requires={b'ctx'})
     def topicidxkw(context, mapping):
         """:topicidx: Integer. Index of the changeset as a stack alias"""
-        ctx = context.resource(mapping, 'ctx')
+        ctx = context.resource(mapping, b'ctx')
         return ctx.topicidx()
 else:
     def topickw(**args):
         """:topic: String. The topic of the changeset"""
-        return args['ctx'].topic()
+        return args[b'ctx'].topic()
 
     def topicidxkw(**args):
         """:topicidx: Integer. Index of the changeset as a stack alias"""
-        return args['ctx'].topicidx()
+        return args[b'ctx'].topicidx()
 
 def wrapinit(orig, self, repo, *args, **kwargs):
     orig(self, repo, *args, **kwargs)
     if not hastopicext(repo):
         return
     if constants.extrakey not in self._extra:
-        if getattr(repo, 'currenttopic', ''):
+        if getattr(repo, 'currenttopic', b''):
             self._extra[constants.extrakey] = repo.currenttopic
         else:
             # Empty key will be dropped from extra by another hack at the changegroup level
-            self._extra[constants.extrakey] = ''
+            self._extra[constants.extrakey] = b''
 
 def wrapadd(orig, cl, manifest, files, desc, transaction, p1, p2, user,
             date=None, extra=None, p1copies=None, p2copies=None,
@@ -679,13 +679,13 @@
     age = opts.get('age')
 
     if current and topic:
-        raise error.Abort(_("cannot use --current when setting a topic"))
+        raise error.Abort(_(b"cannot use --current when setting a topic"))
     if current and clear:
-        raise error.Abort(_("cannot use --current and --clear"))
+        raise error.Abort(_(b"cannot use --current and --clear"))
     if clear and topic:
-        raise error.Abort(_("cannot use --clear when setting a topic"))
+        raise error.Abort(_(b"cannot use --clear when setting a topic"))
     if age and topic:
-        raise error.Abort(_("cannot use --age while setting a topic"))
+        raise error.Abort(_(b"cannot use --age while setting a topic"))
 
     touchedrevs = set()
     if rev:
@@ -694,50 +694,50 @@
     if topic:
         topic = topic.strip()
         if not topic:
-            raise error.Abort(_("topic name cannot consist entirely of whitespaces"))
+            raise error.Abort(_(b"topic name cannot consist entirely of whitespaces"))
         # Have some restrictions on the topic name just like bookmark name
-        scmutil.checknewlabel(repo, topic, 'topic')
+        scmutil.checknewlabel(repo, topic, b'topic')
 
         rmatch = re.match(br'[-_.\w]+', topic)
         if not rmatch or rmatch.group(0) != topic:
-            helptxt = _("topic names can only consist of alphanumeric, '-'"
-                        " '_' and '.' characters")
-            raise error.Abort(_("invalid topic name: '%s'") % topic, hint=helptxt)
+            helptxt = _(b"topic names can only consist of alphanumeric, '-'"
+                        b" '_' and '.' characters")
+            raise error.Abort(_(b"invalid topic name: '%s'") % topic, hint=helptxt)
 
     if list:
-        ui.pager('topics')
+        ui.pager(b'topics')
         if clear or rev:
-            raise error.Abort(_("cannot use --clear or --rev with --list"))
+            raise error.Abort(_(b"cannot use --clear or --rev with --list"))
         if not topic:
             topic = repo.currenttopic
         if not topic:
-            raise error.Abort(_('no active topic to list'))
+            raise error.Abort(_(b'no active topic to list'))
         return stack.showstack(ui, repo, topic=topic,
                                opts=pycompat.byteskwargs(opts))
 
     if touchedrevs:
         if not obsolete.isenabled(repo, obsolete.createmarkersopt):
-            raise error.Abort(_('must have obsolete enabled to change topics'))
+            raise error.Abort(_(b'must have obsolete enabled to change topics'))
         if clear:
             topic = None
         elif opts.get('current'):
             topic = repo.currenttopic
         elif not topic:
-            raise error.Abort('changing topic requires a topic name or --clear')
-        if repo.revs('%ld and public()', touchedrevs):
-            raise error.Abort("can't change topic of a public change")
+            raise error.Abort(b'changing topic requires a topic name or --clear')
+        if repo.revs(b'%ld and public()', touchedrevs):
+            raise error.Abort(b"can't change topic of a public change")
         wl = lock = txn = None
         try:
             wl = repo.wlock()
             lock = repo.lock()
-            txn = repo.transaction('rewrite-topics')
+            txn = repo.transaction(b'rewrite-topics')
             rewrote = _changetopics(ui, repo, touchedrevs, topic)
             txn.close()
             if topic is None:
-                ui.status('cleared topic on %d changesets\n' % rewrote)
+                ui.status(b'cleared topic on %d changesets\n' % rewrote)
             else:
-                ui.status('changed topic on %d changesets to "%s"\n' % (rewrote,
-                                                                        topic))
+                ui.status(b'changed topic on %d changesets to "%s"\n' % (rewrote,
+                                                                         topic))
         finally:
             lockmod.release(txn, lock, wl)
             repo.invalidate()
@@ -748,37 +748,37 @@
         if ct:
             st = stack.stack(repo, topic=ct)
             if not st:
-                ui.status(_('clearing empty topic "%s"\n') % ct)
+                ui.status(_(b'clearing empty topic "%s"\n') % ct)
         return _changecurrenttopic(repo, None)
 
     if topic:
         if not ct:
-            ui.status(_('marked working directory as topic: %s\n') % topic)
+            ui.status(_(b'marked working directory as topic: %s\n') % topic)
         return _changecurrenttopic(repo, topic)
 
-    ui.pager('topics')
+    ui.pager(b'topics')
     # `hg topic --current`
     ret = 0
     if current and not ct:
-        ui.write_err(_('no active topic\n'))
+        ui.write_err(_(b'no active topic\n'))
         ret = 1
     elif current:
-        fm = ui.formatter('topic', pycompat.byteskwargs(opts))
-        namemask = '%s\n'
-        label = 'topic.active'
+        fm = ui.formatter(b'topic', pycompat.byteskwargs(opts))
+        namemask = b'%s\n'
+        label = b'topic.active'
         fm.startitem()
-        fm.write('topic', namemask, ct, label=label)
+        fm.write(b'topic', namemask, ct, label=label)
         fm.end()
     else:
         _listtopics(ui, repo, opts)
     return ret
 
-@command('stack', [
-        ('c', 'children', None,
-            _('display data about children outside of the stack'))
+@command(b'stack', [
+        (b'c', b'children', None,
+            _(b'display data about children outside of the stack'))
     ] + commands.formatteropts,
-    _('hg stack [TOPIC]'))
-def cmdstack(ui, repo, topic='', **opts):
+    _(b'hg stack [TOPIC]'))
+def cmdstack(ui, repo, topic=b'', **opts):
     """list all changesets in a topic and other information
 
     List the current topic by default.
@@ -792,15 +792,15 @@
         topic = repo.currenttopic
     if topic is None:
         branch = repo[None].branch()
-    ui.pager('stack')
+    ui.pager(b'stack')
     return stack.showstack(ui, repo, branch=branch, topic=topic,
                            opts=pycompat.byteskwargs(opts))
 
-@command('debugcb|debugconvertbookmark', [
-        ('b', 'bookmark', '', _('bookmark to convert to topic')),
-        ('', 'all', None, _('convert all bookmarks to topics')),
+@command(b'debugcb|debugconvertbookmark', [
+        (b'b', b'bookmark', b'', _(b'bookmark to convert to topic')),
+        (b'', b'all', None, _(b'convert all bookmarks to topics')),
     ],
-    _('[-b BOOKMARK] [--all]'))
+    _(b'[-b BOOKMARK] [--all]'))
 def debugconvertbookmark(ui, repo, **opts):
     """Converts a bookmark to a topic with the same name.
     """
@@ -809,9 +809,9 @@
     convertall = opts.get('all')
 
     if convertall and bookmark:
-        raise error.Abort(_("cannot use '--all' and '-b' together"))
+        raise error.Abort(_(b"cannot use '--all' and '-b' together"))
     if not (convertall or bookmark):
-        raise error.Abort(_("you must specify either '--all' or '-b'"))
+        raise error.Abort(_(b"you must specify either '--all' or '-b'"))
 
     bmstore = repo._bookmarks
 
@@ -836,12 +836,12 @@
             try:
                 node = bmstore[bookmark]
             except KeyError:
-                raise error.Abort(_("no such bookmark exists: '%s'") % bookmark)
+                raise error.Abort(_(b"no such bookmark exists: '%s'") % bookmark)
 
             revnum = repo[node].rev()
             if len(nodetobook[node]) > 1:
-                ui.status(_("skipping revision '%d' as it has multiple bookmarks "
-                          "on it\n") % revnum)
+                ui.status(_(b"skipping revision '%d' as it has multiple bookmarks "
+                          b"on it\n") % revnum)
                 return
             targetrevs = _findconvertbmarktopic(repo, bookmark)
             if targetrevs:
@@ -853,11 +853,11 @@
                 if revnum in skipped:
                     continue
                 if len(nodetobook[revnode]) > 1:
-                    ui.status(_("skipping '%d' as it has multiple bookmarks on"
-                              " it\n") % revnum)
+                    ui.status(_(b"skipping '%d' as it has multiple bookmarks on"
+                              b" it\n") % revnum)
                     skipped.append(revnum)
                     continue
-                if bmark == '@':
+                if bmark == b'@':
                     continue
                 targetrevs = _findconvertbmarktopic(repo, bmark)
                 if targetrevs:
@@ -865,7 +865,7 @@
 
         if actions:
             try:
-                tr = repo.transaction('debugconvertbookmark')
+                tr = repo.transaction(b'debugconvertbookmark')
                 for ((bmark, revnum), targetrevs) in sorted(actions.items()):
                     _applyconvertbmarktopic(ui, repo, targetrevs, revnum, bmark, tr)
                 tr.close()
@@ -875,7 +875,7 @@
         lockmod.release(lock, wlock)
 
 # inspired from mercurial.repair.stripbmrevset
-CONVERTBOOKREVSET = """
+CONVERTBOOKREVSET = b"""
 not public() and (
     ancestors(bookmark(%s))
     and not ancestors(
@@ -913,9 +913,9 @@
     # changeset
     if rewrote == 0:
         return
-    ui.status(_('changed topic to "%s" on %d revisions\n') % (bmark,
+    ui.status(_(b'changed topic to "%s" on %d revisions\n') % (bmark,
               rewrote))
-    ui.debug('removing bookmark "%s" from "%d"' % (bmark, old))
+    ui.debug(b'removing bookmark "%s" from "%d"' % (bmark, old))
     bookmarks.delete(repo, tr, [bmark])
 
 def _changecurrenttopic(repo, newtopic):
@@ -926,8 +926,8 @@
             with repo.vfs.open(b'topic', b'w') as f:
                 f.write(newtopic)
     else:
-        if repo.vfs.exists('topic'):
-            repo.vfs.unlink('topic')
+        if repo.vfs.exists(b'topic'):
+            repo.vfs.unlink(b'topic')
 
 def _changetopics(ui, repo, revs, newtopic):
     """ Changes topic to newtopic of all the revisions in the revset and return
@@ -946,8 +946,8 @@
             except error.ManifestLookupError:
                 return None
         fixedextra = dict(c.extra())
-        ui.debug('old node id is %s\n' % node.hex(c.node()))
-        ui.debug('origextra: %r\n' % fixedextra)
+        ui.debug(b'old node id is %s\n' % node.hex(c.node()))
+        ui.debug(b'origextra: %r\n' % fixedextra)
         oldtopic = fixedextra.get(constants.extrakey, None)
         if oldtopic == newtopic:
             continue
@@ -956,16 +956,16 @@
         else:
             fixedextra[constants.extrakey] = newtopic
         fixedextra[constants.changekey] = c.hex()
-        if 'amend_source' in fixedextra:
+        if b'amend_source' in fixedextra:
             # TODO: right now the commitctx wrapper in
             # topicrepo overwrites the topic in extra if
             # amend_source is set to support 'hg commit
             # --amend'. Support for amend should be adjusted
             # to not be so invasive.
-            del fixedextra['amend_source']
-        ui.debug('changing topic of %s from %s to %s\n' % (
-            c, oldtopic or '<none>', newtopic or '<none>'))
-        ui.debug('fixedextra: %r\n' % fixedextra)
+            del fixedextra[b'amend_source']
+        ui.debug(b'changing topic of %s from %s to %s\n' % (
+            c, oldtopic or b'<none>', newtopic or b'<none>'))
+        ui.debug(b'fixedextra: %r\n' % fixedextra)
         # While changing topic of set of linear commits, make sure that
         # we base our commits on new parent rather than old parent which
         # was obsoleted while changing the topic
@@ -986,18 +986,18 @@
 
         # phase handling
         commitphase = c.phase()
-        overrides = {('phases', 'new-commit'): commitphase}
-        with repo.ui.configoverride(overrides, 'changetopic'):
+        overrides = {(b'phases', b'new-commit'): commitphase}
+        with repo.ui.configoverride(overrides, b'changetopic'):
             newnode = repo.commitctx(mc)
 
         successors[c.node()] = (newnode,)
-        ui.debug('new node id is %s\n' % node.hex(newnode))
+        ui.debug(b'new node id is %s\n' % node.hex(newnode))
         rewrote += 1
 
     # create obsmarkers and move bookmarks
     # XXX we should be creating marker as we go instead of only at the end,
     # this makes the operations more modulars
-    scmutil.cleanupnodes(repo, successors, 'changetopics')
+    scmutil.cleanupnodes(repo, successors, b'changetopics')
 
     # move the working copy too
     wctx = repo[None]
@@ -1009,12 +1009,12 @@
     return rewrote
 
 def _listtopics(ui, repo, opts):
-    fm = ui.formatter('topics', pycompat.byteskwargs(opts))
+    fm = ui.formatter(b'topics', pycompat.byteskwargs(opts))
     activetopic = repo.currenttopic
-    namemask = '%s'
+    namemask = b'%s'
     if repo.topics:
         maxwidth = max(len(t) for t in repo.topics)
-        namemask = '%%-%is' % maxwidth
+        namemask = b'%%-%is' % maxwidth
     if opts.get('age'):
         # here we sort by age and topic name
         topicsdata = sorted(_getlasttouched(repo, repo.topics))
@@ -1026,70 +1026,70 @@
         )
     for age, topic, date, user in topicsdata:
         fm.startitem()
-        marker = ' '
-        label = 'topic'
+        marker = b' '
+        label = b'topic'
         active = (topic == activetopic)
         if active:
-            marker = '*'
-            label = 'topic.active'
+            marker = b'*'
+            label = b'topic.active'
         if not ui.quiet:
             # registering the active data is made explicitly later
-            fm.plain(' %s ' % marker, label=label)
-        fm.write('topic', namemask, topic, label=label)
+            fm.plain(b' %s ' % marker, label=label)
+        fm.write(b'topic', namemask, topic, label=label)
         fm.data(active=active)
 
         if ui.quiet:
-            fm.plain('\n')
+            fm.plain(b'\n')
             continue
-        fm.plain(' (')
+        fm.plain(b' (')
         if date:
             if age == -1:
-                timestr = 'empty and active'
+                timestr = b'empty and active'
             else:
                 timestr = templatefilters.age(date)
-            fm.write('lasttouched', '%s', timestr, label='topic.list.time')
+            fm.write(b'lasttouched', b'%s', timestr, label=b'topic.list.time')
         if user:
-            fm.write('usertouched', ' by %s', user, label='topic.list.user')
+            fm.write(b'usertouched', b' by %s', user, label=b'topic.list.user')
         if date:
-            fm.plain(', ')
+            fm.plain(b', ')
         data = stack.stack(repo, topic=topic)
         if ui.verbose:
-            fm.write('branches+', 'on branch: %s',
-                     '+'.join(data.branches), # XXX use list directly after 4.0 is released
-                     label='topic.list.branches')
+            fm.write(b'branches+', b'on branch: %s',
+                     b'+'.join(data.branches), # XXX use list directly after 4.0 is released
+                     label=b'topic.list.branches')
 
-            fm.plain(', ')
-        fm.write('changesetcount', '%d changesets', data.changesetcount,
-                 label='topic.list.changesetcount')
+            fm.plain(b', ')
+        fm.write(b'changesetcount', b'%d changesets', data.changesetcount,
+                 label=b'topic.list.changesetcount')
 
         if data.unstablecount:
-            fm.plain(', ')
-            fm.write('unstablecount', '%d unstable',
+            fm.plain(b', ')
+            fm.write(b'unstablecount', b'%d unstable',
                      data.unstablecount,
-                     label='topic.list.unstablecount')
+                     label=b'topic.list.unstablecount')
 
         headcount = len(data.heads)
         if 1 < headcount:
-            fm.plain(', ')
-            fm.write('headcount', '%d heads',
+            fm.plain(b', ')
+            fm.write(b'headcount', b'%d heads',
                      headcount,
-                     label='topic.list.headcount.multiple')
+                     label=b'topic.list.headcount.multiple')
 
         if ui.verbose:
             # XXX we should include the data even when not verbose
 
             behindcount = data.behindcount
             if 0 < behindcount:
-                fm.plain(', ')
-                fm.write('behindcount', '%d behind',
+                fm.plain(b', ')
+                fm.write(b'behindcount', b'%d behind',
                          behindcount,
-                         label='topic.list.behindcount')
+                         label=b'topic.list.behindcount')
             elif -1 == behindcount:
-                fm.plain(', ')
-                fm.write('behinderror', '%s',
-                         _('ambiguous destination: %s') % data.behinderror,
-                         label='topic.list.behinderror')
-        fm.plain(')\n')
+                fm.plain(b', ')
+                fm.write(b'behinderror', b'%s',
+                         _(b'ambiguous destination: %s') % data.behinderror,
+                         label=b'topic.list.behinderror')
+        fm.plain(b')\n')
     fm.end()
 
 def _getlasttouched(repo, topics):
@@ -1102,7 +1102,7 @@
         age = -1
         user = None
         maxtime = (0, 0)
-        trevs = repo.revs("topic(%s)", topic)
+        trevs = repo.revs(b"topic(%s)", topic)
         # Need to check for the time of all changesets in the topic, whether
         # they are obsolete of non-heads
         # XXX: can we just rely on the max rev number for this
@@ -1119,7 +1119,7 @@
             for marker in obsmarkers:
                 rt = marker.date()
                 if rt[0] > maxtime[0]:
-                    user = marker.metadata().get('user', user)
+                    user = marker.metadata().get(b'user', user)
                     maxtime = rt
 
         username = stack.parseusername(user)
@@ -1129,31 +1129,31 @@
         yield (age, topic, maxtime, username)
 
 def summaryhook(ui, repo):
-    t = getattr(repo, 'currenttopic', '')
+    t = getattr(repo, 'currenttopic', b'')
     if not t:
         return
     # i18n: column positioning for "hg summary"
-    ui.write(_("topic:  %s\n") % ui.label(t, 'topic.active'))
+    ui.write(_(b"topic:  %s\n") % ui.label(t, b'topic.active'))
 
 _validmode = [
-    'ignore',
-    'warning',
-    'enforce',
-    'enforce-all',
-    'random',
-    'random-all',
+    b'ignore',
+    b'warning',
+    b'enforce',
+    b'enforce-all',
+    b'random',
+    b'random-all',
 ]
 
 def _configtopicmode(ui):
     """ Parse the config to get the topicmode
     """
-    topicmode = ui.config('experimental', 'topic-mode')
+    topicmode = ui.config(b'experimental', b'topic-mode')
 
     # Fallback to read enforce-topic
     if topicmode is None:
-        enforcetopic = ui.configbool('experimental', 'enforce-topic')
+        enforcetopic = ui.configbool(b'experimental', b'enforce-topic')
         if enforcetopic:
-            topicmode = "enforce"
+            topicmode = b"enforce"
     if topicmode not in _validmode:
         topicmode = _validmode[0]
 
@@ -1167,22 +1167,22 @@
         ismergecommit = len(repo[None].parents()) == 2
 
         notopic = not repo.currenttopic
-        mayabort = (topicmode == "enforce" and not ismergecommit)
-        maywarn = (topicmode == "warning"
-                   or (topicmode == "enforce" and ismergecommit))
+        mayabort = (topicmode == b"enforce" and not ismergecommit)
+        maywarn = (topicmode == b"warning"
+                   or (topicmode == b"enforce" and ismergecommit))
 
         mayrandom = False
-        if topicmode == "random":
+        if topicmode == b"random":
             mayrandom = not ismergecommit
-        elif topicmode == "random-all":
+        elif topicmode == b"random-all":
             mayrandom = True
 
-        if topicmode == 'enforce-all':
+        if topicmode == b'enforce-all':
             ismergecommit = False
             mayabort = True
             maywarn = False
 
-        hint = _("see 'hg help -e topic.topic-mode' for details")
+        hint = _(b"see 'hg help -e topic.topic-mode' for details")
         if opts.get('topic'):
             t = opts['topic']
             with repo.vfs.open(b'topic', b'w') as f:
@@ -1190,12 +1190,12 @@
         elif opts.get('amend'):
             pass
         elif notopic and mayabort:
-            msg = _("no active topic")
+            msg = _(b"no active topic")
             raise error.Abort(msg, hint=hint)
         elif notopic and maywarn:
-            ui.warn(_("warning: new draft commit without topic\n"))
+            ui.warn(_(b"warning: new draft commit without topic\n"))
             if not ui.quiet:
-                ui.warn(("(%s)\n") % hint)
+                ui.warn((b"(%s)\n") % hint)
         elif notopic and mayrandom:
             with repo.vfs.open(b'topic', b'w') as f:
                 f.write(randomname.randomtopicname(ui))
@@ -1206,13 +1206,13 @@
     if hastopicext(repo):
         t = repo.currenttopic
         if t:
-            ret = ret.replace("\nHG: branch",
-                              "\nHG: topic '%s'\nHG: branch" % t)
+            ret = ret.replace(b"\nHG: branch",
+                              b"\nHG: topic '%s'\nHG: branch" % t)
     return ret
 
 def pushoutgoingwrap(orig, ui, repo, *args, **opts):
     if opts.get('topic'):
-        topicrevs = repo.revs('topic(%s) - obsolete()', opts['topic'])
+        topicrevs = repo.revs(b'topic(%s) - obsolete()', opts['topic'])
         opts.setdefault('rev', []).extend(topicrevs)
     return orig(ui, repo, *args, **opts)
 
@@ -1232,37 +1232,37 @@
         # rebased commit. We have explicitly stored in config if rebase is
         # running.
         ot = repo.currenttopic
-        if repo.ui.hasconfig('experimental', 'topicrebase'):
+        if repo.ui.hasconfig(b'experimental', b'topicrebase'):
             isrebase = True
-        if repo.ui.configbool('_internal', 'keep-topic'):
+        if repo.ui.configbool(b'_internal', b'keep-topic'):
             ist0 = True
         if ((not partial and not branchmerge) or isrebase) and not ist0:
-            t = ''
+            t = b''
             pctx = repo[node]
             if pctx.phase() > phases.public:
                 t = pctx.topic()
             with repo.vfs.open(b'topic', b'w') as f:
                 f.write(t)
             if t and t != ot:
-                repo.ui.status(_("switching to topic %s\n") % t)
+                repo.ui.status(_(b"switching to topic %s\n") % t)
             if ot and not t:
                 st = stack.stack(repo, topic=ot)
                 if not st:
-                    repo.ui.status(_('clearing empty topic "%s"\n') % ot)
+                    repo.ui.status(_(b'clearing empty topic "%s"\n') % ot)
         elif ist0:
-            repo.ui.status(_("preserving the current topic '%s'\n") % ot)
+            repo.ui.status(_(b"preserving the current topic '%s'\n") % ot)
         return ret
     finally:
         wlock.release()
 
 def checkt0(orig, ui, repo, node=None, rev=None, *args, **kwargs):
 
-    thezeros = set(['t0', 'b0', 's0'])
-    backup = repo.ui.backupconfig('_internal', 'keep-topic')
+    thezeros = set([b't0', b'b0', b's0'])
+    backup = repo.ui.backupconfig(b'_internal', b'keep-topic')
     try:
         if node in thezeros or rev in thezeros:
-            repo.ui.setconfig('_internal', 'keep-topic', 'yes',
-                              source='topic-extension')
+            repo.ui.setconfig(b'_internal', b'keep-topic', b'yes',
+                              source=b'topic-extension')
         return orig(ui, repo, node=node, rev=rev, *args, **kwargs)
     finally:
         repo.ui.restoreconfig(backup)
@@ -1276,8 +1276,8 @@
             extra[constants.extrakey] = ctx.topic()
 
     def setrebaseconfig(orig, ui, repo, **opts):
-        repo.ui.setconfig('experimental', 'topicrebase', 'yes',
-                          source='topic-extension')
+        repo.ui.setconfig(b'experimental', b'topicrebase', b'yes',
+                          source=b'topic-extension')
         return orig(ui, repo, **opts)
 
     def new_init(orig, *args, **kwargs):
@@ -1289,12 +1289,12 @@
         return runtime
 
     try:
-        rebase = extensions.find("rebase")
+        rebase = extensions.find(b"rebase")
         extensions.wrapfunction(rebase.rebaseruntime, '__init__', new_init)
         # This exists to store in the config that rebase is running so that we can
         # update the topic according to rebase. This is a hack and should be removed
         # when we have better options.
-        extensions.wrapcommand(rebase.cmdtable, 'rebase', setrebaseconfig)
+        extensions.wrapcommand(rebase.cmdtable, b'rebase', setrebaseconfig)
     except KeyError:
         pass
 
@@ -1303,20 +1303,20 @@
 def _exporttopic(seq, ctx):
     topic = ctx.topic()
     if topic:
-        return 'EXP-Topic %s' % topic
+        return b'EXP-Topic %s' % topic
     return None
 
 def _importtopic(repo, patchdata, extra, opts):
-    if 'topic' in patchdata:
-        extra['topic'] = patchdata['topic']
+    if b'topic' in patchdata:
+        extra[b'topic'] = patchdata[b'topic']
 
 def setupimportexport(ui):
     """run at ui setup time to install import/export logic"""
-    cmdutil.extraexport.append('topic')
-    cmdutil.extraexportmap['topic'] = _exporttopic
-    cmdutil.extrapreimport.append('topic')
-    cmdutil.extrapreimportmap['topic'] = _importtopic
-    patch.patchheadermap.append(('EXP-Topic', 'topic'))
+    cmdutil.extraexport.append(b'topic')
+    cmdutil.extraexportmap[b'topic'] = _exporttopic
+    cmdutil.extrapreimport.append(b'topic')
+    cmdutil.extrapreimportmap[b'topic'] = _importtopic
+    patch.patchheadermap.append((b'EXP-Topic', b'topic'))
 
 ## preserve topic during split