changeset 8080:e7dbe089e10d

py3: start using ascii_str and ascii_bytes - we will need it later
author Mads Kiilerich <mads@kiilerich.com>
date Thu, 02 Jan 2020 03:15:36 +0100
parents 88e0d0c0c208
children 2837b66f68bb
files kallithea/controllers/compare.py kallithea/controllers/pullrequests.py kallithea/lib/auth.py kallithea/lib/hooks.py kallithea/lib/middleware/pygrack.py kallithea/lib/ssh.py kallithea/lib/utils.py kallithea/lib/utils2.py kallithea/lib/vcs/backends/git/changeset.py kallithea/lib/vcs/backends/git/inmemory.py kallithea/lib/vcs/backends/git/repository.py kallithea/lib/vcs/backends/git/workdir.py kallithea/lib/vcs/backends/hg/changeset.py kallithea/lib/vcs/backends/hg/inmemory.py kallithea/lib/vcs/backends/hg/repository.py kallithea/lib/vcs/backends/hg/workdir.py kallithea/model/pull_request.py kallithea/tests/base.py kallithea/tests/other/test_vcs_operations.py
diffstat 19 files changed, 80 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/controllers/compare.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/controllers/compare.py	Thu Jan 02 03:15:36 2020 +0100
@@ -42,7 +42,7 @@
 from kallithea.lib.auth import HasRepoPermissionLevelDecorator, LoginRequired
 from kallithea.lib.base import BaseRepoController, render
 from kallithea.lib.graphmod import graph_data
-from kallithea.lib.utils2 import safe_int, safe_str
+from kallithea.lib.utils2 import ascii_bytes, ascii_str, safe_int, safe_str
 from kallithea.lib.vcs.utils.hgcompat import unionrepo
 from kallithea.model.db import Repository
 
@@ -107,26 +107,26 @@
             else:
                 hgrepo = other_repo._repo
 
-            ancestors = [hgrepo[ancestor].hex() for ancestor in
-                         hgrepo.revs(b"id(%s) & ::id(%s)", other_rev, org_rev)]
+            ancestors = [ascii_str(hgrepo[ancestor].hex()) for ancestor in
+                         hgrepo.revs(b"id(%s) & ::id(%s)", ascii_bytes(other_rev), ascii_bytes(org_rev))]
             if ancestors:
                 log.debug("shortcut found: %s is already an ancestor of %s", other_rev, org_rev)
             else:
                 log.debug("no shortcut found: %s is not an ancestor of %s", other_rev, org_rev)
-                ancestors = [hgrepo[ancestor].hex() for ancestor in
-                             hgrepo.revs(b"heads(::id(%s) & ::id(%s))", org_rev, other_rev)] # FIXME: expensive!
+                ancestors = [ascii_str(hgrepo[ancestor].hex()) for ancestor in
+                             hgrepo.revs(b"heads(::id(%s) & ::id(%s))", ascii_bytes(org_rev), ascii_bytes(other_rev))] # FIXME: expensive!
 
             other_changesets = [
                 other_repo.get_changeset(rev)
                 for rev in hgrepo.revs(
                     b"ancestors(id(%s)) and not ancestors(id(%s)) and not id(%s)",
-                     other_rev, org_rev, org_rev)
+                    ascii_bytes(other_rev), ascii_bytes(org_rev), ascii_bytes(org_rev))
             ]
             org_changesets = [
-                org_repo.get_changeset(hgrepo[rev].hex())
+                org_repo.get_changeset(ascii_str(hgrepo[rev].hex()))
                 for rev in hgrepo.revs(
                     b"ancestors(id(%s)) and not ancestors(id(%s)) and not id(%s)",
-                    org_rev, other_rev, other_rev)
+                    ascii_bytes(org_rev), ascii_bytes(other_rev), ascii_bytes(other_rev))
             ]
 
         elif alias == 'git':
@@ -141,9 +141,9 @@
                 SubprocessGitClient(thin_packs=False).fetch(safe_str(org_repo.path), gitrepo_remote)
 
                 revs = [
-                    x.commit.id
-                    for x in gitrepo_remote.get_walker(include=[other_rev],
-                                                       exclude=[org_rev])
+                    ascii_str(x.commit.id)
+                    for x in gitrepo_remote.get_walker(include=[ascii_bytes(other_rev)],
+                                                       exclude=[ascii_bytes(org_rev)])
                 ]
                 other_changesets = [other_repo.get_changeset(rev) for rev in reversed(revs)]
                 if other_changesets:
--- a/kallithea/controllers/pullrequests.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/controllers/pullrequests.py	Thu Jan 02 03:15:36 2020 +0100
@@ -42,9 +42,8 @@
 from kallithea.lib.base import BaseRepoController, jsonify, render
 from kallithea.lib.graphmod import graph_data
 from kallithea.lib.page import Page
-from kallithea.lib.utils2 import safe_int
+from kallithea.lib.utils2 import ascii_bytes, safe_int, safe_str
 from kallithea.lib.vcs.exceptions import ChangesetDoesNotExistError, EmptyRepositoryError
-from kallithea.lib.vcs.utils import safe_str
 from kallithea.lib.vcs.utils.hgcompat import unionrepo
 from kallithea.model.changeset_status import ChangesetStatusModel
 from kallithea.model.comment import ChangesetCommentsModel
@@ -90,7 +89,6 @@
             branch = safe_str(branch)
 
         if branch_rev:
-            branch_rev = safe_str(branch_rev)
             # a revset not restricting to merge() would be better
             # (especially because it would get the branch point)
             # ... but is currently too expensive
@@ -98,7 +96,7 @@
             peerbranches = set()
             for i in repo._repo.revs(
                 b"sort(parents(branch(id(%s)) and merge()) - branch(id(%s)), -rev)",
-                branch_rev, branch_rev
+                ascii_bytes(branch_rev), ascii_bytes(branch_rev),
             ):
                 for abranch in repo.get_changeset(i).branches:
                     if abranch not in peerbranches:
--- a/kallithea/lib/auth.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/lib/auth.py	Thu Jan 02 03:15:36 2020 +0100
@@ -41,7 +41,7 @@
 from kallithea.config.routing import url
 from kallithea.lib.caching_query import FromCache
 from kallithea.lib.utils import conditional_cache, get_repo_group_slug, get_repo_slug, get_user_group_slug
-from kallithea.lib.utils2 import safe_str, safe_unicode
+from kallithea.lib.utils2 import ascii_bytes, ascii_str, safe_str, safe_unicode
 from kallithea.lib.vcs.utils.lazy import LazyProperty
 from kallithea.model.db import (
     Permission, RepoGroup, Repository, User, UserApiKeys, UserGroup, UserGroupMember, UserGroupRepoGroupToPerm, UserGroupRepoToPerm, UserGroupToPerm, UserGroupUserGroupToPerm, UserIpMap, UserToPerm)
@@ -95,7 +95,7 @@
         return hashlib.sha256(password).hexdigest()
     elif is_unix:
         import bcrypt
-        return bcrypt.hashpw(safe_str(password), bcrypt.gensalt(10))
+        return ascii_str(bcrypt.hashpw(safe_str(password), bcrypt.gensalt(10)))
     else:
         raise Exception('Unknown or unsupported platform %s'
                         % __platform__)
@@ -115,7 +115,7 @@
     elif is_unix:
         import bcrypt
         try:
-            return bcrypt.checkpw(safe_str(password), safe_str(hashed))
+            return bcrypt.checkpw(safe_str(password), ascii_bytes(hashed))
         except ValueError as e:
             # bcrypt will throw ValueError 'Invalid hashed_password salt' on all password errors
             log.error('error from bcrypt checking password: %s', e)
--- a/kallithea/lib/hooks.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/lib/hooks.py	Thu Jan 02 03:15:36 2020 +0100
@@ -25,14 +25,13 @@
 :license: GPLv3, see LICENSE.md for more details.
 """
 
-import binascii
 import os
 import time
 
 from kallithea.lib import helpers as h
 from kallithea.lib.exceptions import UserCreationError
 from kallithea.lib.utils import action_logger, make_ui, setup_cache_regions
-from kallithea.lib.utils2 import get_hook_environment, safe_str, safe_unicode
+from kallithea.lib.utils2 import ascii_str, get_hook_environment, safe_str, safe_unicode
 from kallithea.lib.vcs.backends.base import EmptyChangeset
 from kallithea.lib.vcs.utils.hgcompat import revrange
 from kallithea.model.db import Repository, User
@@ -72,7 +71,7 @@
 
     msg = ('Repository size .hg: %s Checkout: %s Total: %s\n'
            'Last revision is now r%s:%s\n') % (
-        size_hg_f, size_root_f, size_total_f, last_cs.rev(), last_cs.hex()[:12]
+        size_hg_f, size_root_f, size_total_f, last_cs.rev(), ascii_str(last_cs.hex())[:12]
     )
     ui.status(msg)
 
@@ -109,8 +108,7 @@
     Note: This hook is not only logging, but also the side effect invalidating
     cahes! The function should perhaps be renamed.
     """
-    _h = binascii.hexlify
-    revs = [_h(repo[r].node()) for r in revrange(repo, [b'%s:%s' % (node, node_last)])]
+    revs = [ascii_str(repo[r].hex()) for r in revrange(repo, [b'%s:%s' % (node, node_last)])]
     process_pushed_raw_ids(revs)
     return 0
 
--- a/kallithea/lib/middleware/pygrack.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/lib/middleware/pygrack.py	Thu Jan 02 03:15:36 2020 +0100
@@ -33,7 +33,7 @@
 from webob import Request, Response, exc
 
 import kallithea
-from kallithea.lib.utils2 import safe_unicode
+from kallithea.lib.utils2 import ascii_bytes, safe_unicode
 from kallithea.lib.vcs import subprocessio
 
 
@@ -113,14 +113,14 @@
         #                     ref_list
         #                     "0000"
         server_advert = '# service=%s\n' % git_command
-        packet_len = str(hex(len(server_advert) + 4)[2:].rjust(4, '0')).lower()
+        packet_len = hex(len(server_advert) + 4)[2:].rjust(4, '0').lower()
         _git_path = kallithea.CONFIG.get('git_path', 'git')
         cmd = [_git_path, git_command[4:],
                '--stateless-rpc', '--advertise-refs', self.content_path]
         log.debug('handling cmd %s', cmd)
         try:
             out = subprocessio.SubprocessIOChunker(cmd,
-                starting_values=[packet_len + server_advert + '0000']
+                starting_values=[ascii_bytes(packet_len + server_advert + '0000')]
             )
         except EnvironmentError as e:
             log.error(traceback.format_exc())
--- a/kallithea/lib/ssh.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/lib/ssh.py	Thu Jan 02 03:15:36 2020 +0100
@@ -27,6 +27,8 @@
 
 from tg.i18n import ugettext as _
 
+from kallithea.lib.utils2 import ascii_bytes, ascii_str
+
 
 log = logging.getLogger(__name__)
 
@@ -84,14 +86,14 @@
         raise SshKeyParseError(_("Incorrect SSH key - unexpected characters in base64 part %r") % keyvalue)
 
     try:
-        decoded = base64.b64decode(keyvalue)
+        key_bytes = base64.b64decode(keyvalue)
     except TypeError:
         raise SshKeyParseError(_("Incorrect SSH key - failed to decode base64 part %r") % keyvalue)
 
-    if not decoded.startswith(b'\x00\x00\x00' + chr(len(keytype)) + str(keytype) + b'\x00'):
-        raise SshKeyParseError(_("Incorrect SSH key - base64 part is not %r as claimed but %r") % (str(keytype), str(decoded[4:].split(b'\0', 1)[0])))
+    if not key_bytes.startswith(b'\x00\x00\x00%c%s\x00' % (len(keytype), ascii_bytes(keytype))):
+        raise SshKeyParseError(_("Incorrect SSH key - base64 part is not %r as claimed but %r") % (keytype, ascii_str(key_bytes[4:].split(b'\0', 1)[0])))
 
-    return keytype, decoded, comment
+    return keytype, key_bytes, comment
 
 
 SSH_OPTIONS = 'no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding'
@@ -112,7 +114,7 @@
         keytype, key_bytes, comment = parse_pub_key(key.public_key)
     except SshKeyParseError:
         return '# Invalid Kallithea SSH key: %s %s\n' % (key.user.user_id, key.user_ssh_key_id)
-    base64_key = base64.b64encode(key_bytes)
+    base64_key = ascii_str(base64.b64encode(key_bytes))
     assert '\n' not in base64_key
     return '%s,command="%s ssh-serve -c %s %s %s" %s %s\n' % (
         SSH_OPTIONS, kallithea_cli_path, config_file,
--- a/kallithea/lib/utils.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/lib/utils.py	Thu Jan 02 03:15:36 2020 +0100
@@ -39,7 +39,7 @@
 
 import kallithea.config.conf
 from kallithea.lib.exceptions import HgsubversionImportError
-from kallithea.lib.utils2 import aslist, get_current_authuser, safe_str, safe_unicode
+from kallithea.lib.utils2 import ascii_bytes, aslist, get_current_authuser, safe_bytes, safe_str, safe_unicode
 from kallithea.lib.vcs.backends.git.repository import GitRepository
 from kallithea.lib.vcs.backends.hg.repository import MercurialRepository
 from kallithea.lib.vcs.conf import settings
@@ -340,7 +340,7 @@
             ui_val = b'' if ui_.ui_value is None else safe_str(ui_.ui_value)
             log.debug('config from db: [%s] %s=%r', ui_.ui_section,
                       ui_.ui_key, ui_val)
-            baseui.setconfig(safe_str(ui_.ui_section), safe_str(ui_.ui_key),
+            baseui.setconfig(ascii_bytes(ui_.ui_section), ascii_bytes(ui_.ui_key),
                              ui_val)
 
     # force set push_ssl requirement to False, Kallithea handles that
@@ -362,7 +362,7 @@
             for section in ui_sections:
                 for k, v in cfg.items(section):
                     log.debug('config from file: [%s] %s=%s', section, k, v)
-                    baseui.setconfig(safe_str(section), safe_str(k), safe_str(v))
+                    baseui.setconfig(ascii_bytes(section), ascii_bytes(k), safe_bytes(v))
         else:
             log.debug('hgrc file is not present at %s, skipping...', hgrc_path)
 
--- a/kallithea/lib/utils2.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/lib/utils2.py	Thu Jan 02 03:15:36 2020 +0100
@@ -141,7 +141,7 @@
         unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
     """
     # Hexadecimal certainly qualifies as URL-safe.
-    return binascii.hexlify(os.urandom(20))
+    return ascii_str(binascii.hexlify(os.urandom(20)))
 
 
 def safe_int(val, default=None):
--- a/kallithea/lib/vcs/backends/git/changeset.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/lib/vcs/backends/git/changeset.py	Thu Jan 02 03:15:36 2020 +0100
@@ -11,7 +11,7 @@
 from kallithea.lib.vcs.exceptions import ChangesetDoesNotExistError, ChangesetError, ImproperArchiveTypeError, NodeDoesNotExistError, RepositoryError, VCSError
 from kallithea.lib.vcs.nodes import (
     AddedFileNodesGenerator, ChangedFileNodesGenerator, DirNode, FileNode, NodeKind, RemovedFileNodesGenerator, RootNode, SubModuleNode)
-from kallithea.lib.vcs.utils import date_fromtimestamp, safe_int, safe_str, safe_unicode
+from kallithea.lib.vcs.utils import ascii_bytes, ascii_str, date_fromtimestamp, safe_int, safe_str, safe_unicode
 from kallithea.lib.vcs.utils.lazy import LazyProperty
 
 
@@ -25,16 +25,16 @@
         self.repository = repository
         revision = safe_str(revision)
         try:
-            commit = self.repository._repo[revision]
+            commit = self.repository._repo[ascii_bytes(revision)]
             if isinstance(commit, objects.Tag):
                 revision = safe_str(commit.object[1])
                 commit = self.repository._repo.get_object(commit.object[1])
         except KeyError:
             raise RepositoryError("Cannot get object with id %s" % revision)
-        self.raw_id = revision
+        self.raw_id = ascii_str(commit.id)
         self.id = self.raw_id
         self.short_id = self.raw_id[:12]
-        self._commit = commit
+        self._commit = commit  # a Dulwich Commmit with .id
         self._tree_id = commit.tree
         self._committer_property = 'committer'
         self._author_property = 'author'
@@ -185,8 +185,8 @@
         """
         Returns list of parents changesets.
         """
-        return [self.repository.get_changeset(parent)
-                for parent in self._commit.parents]
+        return [self.repository.get_changeset(ascii_str(parent_id))
+                for parent_id in self._commit.parents]
 
     @LazyProperty
     def children(self):
@@ -314,8 +314,8 @@
         include = [self.id]
         walker = Walker(self.repository._repo.object_store, include,
                         paths=[path], max_entries=1)
-        return [self.repository.get_changeset(sha)
-                for sha in (x.commit.id for x in walker)]
+        return [self.repository.get_changeset(ascii_str(x.commit.id.decode))
+                for x in walker]
 
     def get_file_annotate(self, path):
         """
@@ -419,8 +419,8 @@
             if objects.S_ISGITLINK(stat):
                 root_tree = self.repository._repo[self._tree_id]
                 cf = ConfigFile.from_file(BytesIO(self.repository._repo.get_object(root_tree[b'.gitmodules'][1]).data))
-                url = cf.get(('submodule', obj_path), 'url')
-                dirnodes.append(SubModuleNode(obj_path, url=url, changeset=id,
+                url = ascii_str(cf.get(('submodule', obj_path), 'url'))
+                dirnodes.append(SubModuleNode(obj_path, url=url, changeset=ascii_str(id),
                                               alias=als))
                 continue
 
@@ -458,8 +458,8 @@
             if _GL(self._stat_modes.get(path)):
                 tree = self.repository._repo[self._tree_id]
                 cf = ConfigFile.from_file(BytesIO(self.repository._repo.get_object(tree[b'.gitmodules'][1]).data))
-                url = cf.get(('submodule', path), 'url')
-                node = SubModuleNode(path, url=url, changeset=id_,
+                url = ascii_str(cf.get(('submodule', path), 'url'))
+                node = SubModuleNode(path, url=url, changeset=ascii_str(id_),
                                      alias=self.repository.alias)
             else:
                 obj = self.repository._repo.get_object(id_)
--- a/kallithea/lib/vcs/backends/git/inmemory.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/lib/vcs/backends/git/inmemory.py	Thu Jan 02 03:15:36 2020 +0100
@@ -7,7 +7,7 @@
 
 from kallithea.lib.vcs.backends.base import BaseInMemoryChangeset
 from kallithea.lib.vcs.exceptions import RepositoryError
-from kallithea.lib.vcs.utils import safe_bytes, safe_str
+from kallithea.lib.vcs.utils import ascii_str, safe_bytes, safe_str
 
 
 class GitInMemoryChangeset(BaseInMemoryChangeset):
@@ -149,7 +149,7 @@
         # Update vcs repository object & recreate dulwich repo
         ref = b'refs/heads/%s' % branch
         repo.refs[ref] = commit.id
-        self.repository.revisions.append(commit.id)
+        self.repository.revisions.append(ascii_str(commit.id))
         # invalidate parsed refs after commit
         self.repository._parsed_refs = self.repository._get_parsed_refs()
         tip = self.repository.get_changeset()
--- a/kallithea/lib/vcs/backends/git/repository.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/lib/vcs/backends/git/repository.py	Thu Jan 02 03:15:36 2020 +0100
@@ -27,7 +27,7 @@
 from kallithea.lib.vcs.conf import settings
 from kallithea.lib.vcs.exceptions import (
     BranchDoesNotExistError, ChangesetDoesNotExistError, EmptyRepositoryError, RepositoryError, TagAlreadyExistError, TagDoesNotExistError)
-from kallithea.lib.vcs.utils import date_fromtimestamp, makedate, safe_str, safe_unicode
+from kallithea.lib.vcs.utils import ascii_str, date_fromtimestamp, makedate, safe_str, safe_unicode
 from kallithea.lib.vcs.utils.hgcompat import hg_url, httpbasicauthhandler, httpdigestauthhandler
 from kallithea.lib.vcs.utils.lazy import LazyProperty
 from kallithea.lib.vcs.utils.paths import abspath, get_user_home
@@ -251,7 +251,7 @@
 
     def _get_all_revisions2(self):
         # alternate implementation using dulwich
-        includes = [x[1][0] for x in self._parsed_refs.iteritems()
+        includes = [ascii_str(x[1][0]) for x in self._parsed_refs.iteritems()
                     if x[1][1] != b'T']
         return [c.commit.id for c in self._repo.get_walker(include=includes)]
 
@@ -283,7 +283,7 @@
             # get by branch/tag name
             _ref_revision = self._parsed_refs.get(revision)
             if _ref_revision:  # and _ref_revision[1] in [b'H', b'RH', b'T']:
-                return _ref_revision[0]
+                return ascii_str(_ref_revision[0])
 
             if revision in self.revisions:
                 return revision
@@ -367,7 +367,7 @@
         if not self.revisions:
             return {}
         sortkey = lambda ctx: ctx[0]
-        _branches = [(x[0], x[1][0])
+        _branches = [(x[0], ascii_str(x[1][0]))
                      for x in self._parsed_refs.iteritems() if x[1][1] == b'H']
         return OrderedDict(sorted(_branches, key=sortkey, reverse=False))
 
@@ -384,7 +384,7 @@
             return {}
 
         sortkey = lambda ctx: ctx[0]
-        _tags = [(x[0], x[1][0])
+        _tags = [(x[0], ascii_str(x[1][0]))
                  for x in self._parsed_refs.iteritems() if x[1][1] == b'T']
         return OrderedDict(sorted(_tags, key=sortkey, reverse=True))
 
--- a/kallithea/lib/vcs/backends/git/workdir.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/lib/vcs/backends/git/workdir.py	Thu Jan 02 03:15:36 2020 +0100
@@ -1,5 +1,6 @@
 import re
 
+from kallithea.lib.utils2 import ascii_str
 from kallithea.lib.vcs.backends.base import BaseWorkdir
 from kallithea.lib.vcs.exceptions import BranchDoesNotExistError, RepositoryError
 
@@ -20,7 +21,7 @@
             raise RepositoryError("Couldn't compute workdir's branch")
 
     def get_changeset(self):
-        wk_dir_id = self.repository._repo.refs.as_dict().get(b'HEAD')
+        wk_dir_id = ascii_str(self.repository._repo.refs.as_dict().get(b'HEAD'))
         return self.repository.get_changeset(wk_dir_id)
 
     def checkout_branch(self, branch=None):
--- a/kallithea/lib/vcs/backends/hg/changeset.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/lib/vcs/backends/hg/changeset.py	Thu Jan 02 03:15:36 2020 +0100
@@ -6,7 +6,7 @@
 from kallithea.lib.vcs.exceptions import ChangesetDoesNotExistError, ChangesetError, ImproperArchiveTypeError, NodeDoesNotExistError, VCSError
 from kallithea.lib.vcs.nodes import (
     AddedFileNodesGenerator, ChangedFileNodesGenerator, DirNode, FileNode, NodeKind, RemovedFileNodesGenerator, RootNode, SubModuleNode)
-from kallithea.lib.vcs.utils import date_fromtimestamp, safe_str, safe_unicode
+from kallithea.lib.vcs.utils import ascii_bytes, ascii_str, date_fromtimestamp, safe_str, safe_unicode
 from kallithea.lib.vcs.utils.hgcompat import archival, hex, obsutil
 from kallithea.lib.vcs.utils.lazy import LazyProperty
 from kallithea.lib.vcs.utils.paths import get_dirs_for_path
@@ -20,8 +20,8 @@
     def __init__(self, repository, revision):
         self.repository = repository
         assert isinstance(revision, basestring), repr(revision)
-        self.raw_id = revision
-        self._ctx = repository._repo[revision]
+        self._ctx = repository._repo[ascii_bytes(revision)]
+        self.raw_id = ascii_str(self._ctx.hex())
         self.revision = self._ctx._rev
         self.nodes = {}
 
@@ -285,7 +285,7 @@
         annotations = self._get_filectx(path).annotate()
         annotation_lines = [(annotateline.fctx, annotateline.text) for annotateline in annotations]
         for i, (fctx, l) in enumerate(annotation_lines):
-            sha = fctx.hex()
+            sha = ascii_str(fctx.hex())
             yield (i + 1, sha, lambda sha=sha, l=l: self.repository.get_changeset(sha), l)
 
     def fill_archive(self, stream=None, kind='tgz', prefix=None,
@@ -320,7 +320,7 @@
         elif prefix.strip() == '':
             raise VCSError("Prefix cannot be empty")
 
-        archival.archive(self.repository._repo, stream, self.raw_id,
+        archival.archive(self.repository._repo, stream, ascii_bytes(self.raw_id),
                          kind, prefix=prefix, subrepos=subrepos)
 
     def get_nodes(self, path):
--- a/kallithea/lib/vcs/backends/hg/inmemory.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/lib/vcs/backends/hg/inmemory.py	Thu Jan 02 03:15:36 2020 +0100
@@ -2,7 +2,7 @@
 
 from kallithea.lib.vcs.backends.base import BaseInMemoryChangeset
 from kallithea.lib.vcs.exceptions import RepositoryError
-from kallithea.lib.vcs.utils import safe_bytes
+from kallithea.lib.vcs.utils import ascii_str, safe_bytes
 from kallithea.lib.vcs.utils.hgcompat import hex, memctx, memfilectx
 
 
@@ -97,9 +97,8 @@
         self._commit_ctx = commit_ctx  # For reference
         # Update vcs repository object & recreate mercurial _repo
         # new_ctx = self.repository._repo[node]
-        # new_tip = self.repository.get_changeset(new_ctx.hex())
-        new_id = hex(n)
-        self.repository.revisions.append(new_id)
+        # new_tip = ascii_str(self.repository.get_changeset(new_ctx.hex()))
+        self.repository.revisions.append(ascii_str(hex(n)))
         self._repo = self.repository._get_repo(create=False)
         self.repository.branches = self.repository._get_branches()
         tip = self.repository.get_changeset()
--- a/kallithea/lib/vcs/backends/hg/repository.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/lib/vcs/backends/hg/repository.py	Thu Jan 02 03:15:36 2020 +0100
@@ -20,7 +20,7 @@
 from kallithea.lib.vcs.backends.base import BaseRepository, CollectionGenerator
 from kallithea.lib.vcs.exceptions import (
     BranchDoesNotExistError, ChangesetDoesNotExistError, EmptyRepositoryError, RepositoryError, TagAlreadyExistError, TagDoesNotExistError, VCSError)
-from kallithea.lib.vcs.utils import author_email, author_name, date_fromtimestamp, makedate, safe_bytes, safe_str, safe_unicode
+from kallithea.lib.vcs.utils import ascii_str, author_email, author_name, date_fromtimestamp, makedate, safe_bytes, safe_str, safe_unicode
 from kallithea.lib.vcs.utils.hgcompat import (
     Abort, RepoError, RepoLookupError, clone, diffopts, get_contact, hex, hg_url, httpbasicauthhandler, httpdigestauthhandler, httppeer, localrepo, match_exact, nullid, patch, peer, scmutil, sshpeer, tag, ui)
 from kallithea.lib.vcs.utils.lazy import LazyProperty
@@ -115,14 +115,13 @@
             return {}
 
         bt = OrderedDict()
-        for bn, _heads, tip, isclosed in sorted(self._repo.branchmap().iterbranches()):
+        for bn, _heads, node, isclosed in sorted(self._repo.branchmap().iterbranches()):
             if isclosed:
                 if closed:
-                    bt[safe_unicode(bn)] = hex(tip)
+                    bt[safe_unicode(bn)] = ascii_str(hex(node))
             else:
                 if normal:
-                    bt[safe_unicode(bn)] = hex(tip)
-
+                    bt[safe_unicode(bn)] = ascii_str(hex(node))
         return bt
 
     @LazyProperty
@@ -137,7 +136,7 @@
             return {}
 
         return OrderedDict(sorted(
-            ((safe_unicode(n), hex(h)) for n, h in self._repo.tags().items()),
+            ((safe_unicode(n), ascii_str(hex(h))) for n, h in self._repo.tags().items()),
             reverse=True,
             key=lambda x: x[0],  # sort by name
         ))
@@ -215,13 +214,13 @@
             return {}
 
         return OrderedDict(sorted(
-            ((safe_unicode(n), hex(h)) for n, h in self._repo._bookmarks.items()),
+            ((safe_unicode(n), ascii_str(h)) for n, h in self._repo._bookmarks.items()),
             reverse=True,
             key=lambda x: x[0],  # sort by name
         ))
 
     def _get_all_revisions(self):
-        return [self._repo[x].hex() for x in self._repo.filtered(b'visible').changelog.revs()]
+        return [ascii_str(self._repo[x].hex()) for x in self._repo.filtered(b'visible').changelog.revs()]
 
     def get_diff(self, rev1, rev2, path='', ignore_whitespace=False,
                   context=3):
@@ -416,8 +415,8 @@
 
         try:
             if isinstance(revision, int):
-                return self._repo[revision].hex()
-            return scmutil.revsymbol(self._repo, revision).hex()
+                return ascii_str(self._repo[revision].hex())
+            return ascii_str(scmutil.revsymbol(self._repo, revision).hex())
         except (IndexError, ValueError, RepoLookupError, TypeError):
             msg = ("Revision %s does not exist for %s" % (revision, self))
             raise ChangesetDoesNotExistError(msg)
--- a/kallithea/lib/vcs/backends/hg/workdir.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/lib/vcs/backends/hg/workdir.py	Thu Jan 02 03:15:36 2020 +0100
@@ -1,5 +1,6 @@
 from kallithea.lib.vcs.backends.base import BaseWorkdir
 from kallithea.lib.vcs.exceptions import BranchDoesNotExistError
+from kallithea.lib.vcs.utils import ascii_bytes, ascii_str
 from kallithea.lib.vcs.utils.hgcompat import hg_merge
 
 
@@ -9,7 +10,7 @@
         return self.repository._repo.dirstate.branch()
 
     def get_changeset(self):
-        wk_dir_id = self.repository._repo[None].parents()[0].hex()
+        wk_dir_id = ascii_str(self.repository._repo[None].parents()[0].hex())
         return self.repository.get_changeset(wk_dir_id)
 
     def checkout_branch(self, branch=None):
@@ -19,4 +20,4 @@
             raise BranchDoesNotExistError
 
         raw_id = self.repository.branches[branch]
-        hg_merge.update(self.repository._repo, raw_id, False, False, None)
+        hg_merge.update(self.repository._repo, ascii_bytes(raw_id), False, False, None)
--- a/kallithea/model/pull_request.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/model/pull_request.py	Thu Jan 02 03:15:36 2020 +0100
@@ -33,7 +33,7 @@
 from tg.i18n import ugettext as _
 
 from kallithea.lib import helpers as h
-from kallithea.lib.utils2 import extract_mentioned_users, safe_str, safe_unicode
+from kallithea.lib.utils2 import ascii_bytes, extract_mentioned_users, safe_unicode
 from kallithea.model.db import ChangesetStatus, PullRequest, PullRequestReviewer, User
 from kallithea.model.meta import Session
 from kallithea.model.notification import NotificationModel
@@ -261,7 +261,7 @@
 
         if self.org_repo.scm_instance.alias == 'git':
             # create a ref under refs/pull/ so that commits don't get garbage-collected
-            self.org_repo.scm_instance._repo[b"refs/pull/%d/head" % pr.pull_request_id] = safe_str(self.org_rev)
+            self.org_repo.scm_instance._repo[b"refs/pull/%d/head" % pr.pull_request_id] = ascii_bytes(self.org_rev)
 
         # reset state to under-review
         from kallithea.model.changeset_status import ChangesetStatusModel
--- a/kallithea/tests/base.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/tests/base.py	Thu Jan 02 03:15:36 2020 +0100
@@ -22,7 +22,7 @@
 import pytest
 from webtest import TestApp
 
-from kallithea.lib.utils2 import safe_str
+from kallithea.lib.utils2 import ascii_str, safe_str
 from kallithea.model.db import User
 
 
@@ -176,7 +176,7 @@
         assert user == expected_username
 
     def session_csrf_secret_token(self):
-        return self.app.get(url('session_csrf_secret_token')).body
+        return ascii_str(self.app.get(url('session_csrf_secret_token')).body)
 
     def checkSessionFlash(self, response, msg=None, skip=0, _matcher=lambda msg, m: msg in m):
         if 'flash' not in response.session:
--- a/kallithea/tests/other/test_vcs_operations.py	Fri Dec 27 02:02:20 2019 +0100
+++ b/kallithea/tests/other/test_vcs_operations.py	Thu Jan 02 03:15:36 2020 +0100
@@ -39,6 +39,7 @@
 import pytest
 
 from kallithea import CONFIG
+from kallithea.lib.utils2 import ascii_bytes
 from kallithea.model.db import CacheInvalidation, Repository, Ui, User, UserIpMap, UserLog
 from kallithea.model.meta import Session
 from kallithea.model.ssh_key import SshKeyModel
@@ -330,7 +331,7 @@
         }
         req = urllib2.Request(
             'http://%s:%s/_admin/api' % webserver.server_address,
-            data=json.dumps(params),
+            data=ascii_bytes(json.dumps(params)),
             headers={'content-type': 'application/json'})
         response = urllib2.urlopen(req)
         result = json.loads(response.read())