diff --git a/kallithea/config/app_cfg.py b/kallithea/config/app_cfg.py --- a/kallithea/config/app_cfg.py +++ b/kallithea/config/app_cfg.py @@ -162,7 +162,7 @@ def setup_configuration(app): load_rcextensions(root_path=config['here']) - repos_path = make_ui().configitems('paths')[0][1] + repos_path = make_ui().configitems(b'paths')[0][1] config['base_path'] = repos_path set_app_settings(config) diff --git a/kallithea/controllers/compare.py b/kallithea/controllers/compare.py --- a/kallithea/controllers/compare.py +++ b/kallithea/controllers/compare.py @@ -108,20 +108,26 @@ class CompareController(BaseRepoControll hgrepo = other_repo._repo ancestors = [hgrepo[ancestor].hex() for ancestor in - hgrepo.revs("id(%s) & ::id(%s)", other_rev, org_rev)] + hgrepo.revs(b"id(%s) & ::id(%s)", other_rev, 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("heads(::id(%s) & ::id(%s))", org_rev, other_rev)] # FIXME: expensive! + hgrepo.revs(b"heads(::id(%s) & ::id(%s))", org_rev, other_rev)] # FIXME: expensive! - other_revs = hgrepo.revs("ancestors(id(%s)) and not ancestors(id(%s)) and not id(%s)", - other_rev, org_rev, org_rev) - other_changesets = [other_repo.get_changeset(rev) for rev in other_revs] - org_revs = hgrepo.revs("ancestors(id(%s)) and not ancestors(id(%s)) and not id(%s)", - org_rev, other_rev, other_rev) - org_changesets = [org_repo.get_changeset(hgrepo[rev].hex()) for rev in org_revs] + 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) + ] + org_changesets = [ + org_repo.get_changeset(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) + ] elif alias == 'git': if org_repo != other_repo: diff --git a/kallithea/controllers/pullrequests.py b/kallithea/controllers/pullrequests.py --- a/kallithea/controllers/pullrequests.py +++ b/kallithea/controllers/pullrequests.py @@ -97,7 +97,7 @@ class PullrequestsController(BaseRepoCon # including branches of children could be nice too peerbranches = set() for i in repo._repo.revs( - "sort(parents(branch(id(%s)) and merge()) - branch(id(%s)), -rev)", + b"sort(parents(branch(id(%s)) and merge()) - branch(id(%s)), -rev)", branch_rev, branch_rev ): for abranch in repo.get_changeset(i).branches: diff --git a/kallithea/lib/diffs.py b/kallithea/lib/diffs.py --- a/kallithea/lib/diffs.py +++ b/kallithea/lib/diffs.py @@ -236,7 +236,7 @@ def get_gitdiff(filenode_old, filenode_n context = context or 3 submodules = [o for o in [filenode_new, filenode_old] if isinstance(o, SubModuleNode)] if submodules: - return '' + return b'' for filenode in (filenode_old, filenode_new): if not isinstance(filenode, FileNode): @@ -261,7 +261,7 @@ def get_diff(scm_instance, rev1, rev2, p ignore_whitespace=ignore_whitespace, context=context) except MemoryError: h.flash('MemoryError: Diff is too big', category='error') - return '' + return b'' NEW_FILENODE = 1 @@ -279,7 +279,7 @@ class DiffProcessor(object): mentioned in the diff together with a dict of meta information that can be used to render it in a HTML template. """ - _diff_git_re = re.compile('^diff --git', re.MULTILINE) + _diff_git_re = re.compile(b'^diff --git', re.MULTILINE) def __init__(self, diff, vcs='hg', diff_limit=None, inline_diff=True): """ @@ -480,7 +480,7 @@ def _escaper(string): return _escape_re.sub(substitute, safe_unicode(string)) -_git_header_re = re.compile(r""" +_git_header_re = re.compile(br""" ^diff[ ]--git[ ]a/(?P.+?)[ ]b/(?P.+?)\n (?:^old[ ]mode[ ](?P\d+)\n ^new[ ]mode[ ](?P\d+)(?:\n|$))? @@ -497,7 +497,7 @@ def _escaper(string): """, re.VERBOSE | re.MULTILINE) -_hg_header_re = re.compile(r""" +_hg_header_re = re.compile(br""" ^diff[ ]--git[ ]a/(?P.+?)[ ]b/(?P.+?)\n (?:^old[ ]mode[ ](?P\d+)\n ^new[ ]mode[ ](?P\d+)(?:\n|$))? @@ -542,7 +542,7 @@ def _get_header(vcs, diff_chunk): rest = diff_chunk[match.end():] if rest and _header_next_check.match(rest): raise Exception('cannot parse %s diff header: %r followed by %r' % (vcs, diff_chunk[:match.end()], rest[:1000])) - diff_lines = (_escaper(m.group(0)) for m in re.finditer(r'.*\n|.+$', rest)) # don't split on \r as str.splitlines do + diff_lines = (_escaper(m.group(0)) for m in re.finditer(br'.*\n|.+$', rest)) # don't split on \r as str.splitlines do return meta_info, diff_lines diff --git a/kallithea/lib/hooks.py b/kallithea/lib/hooks.py --- a/kallithea/lib/hooks.py +++ b/kallithea/lib/hooks.py @@ -110,7 +110,7 @@ def log_push_action(ui, repo, node, node cahes! The function should perhaps be renamed. """ _h = binascii.hexlify - revs = [_h(repo[r].node()) for r in revrange(repo, [node + ':' + node_last])] + revs = [_h(repo[r].node()) for r in revrange(repo, [b'%s:%s' % (node, node_last)])] process_pushed_raw_ids(revs) return 0 @@ -363,8 +363,9 @@ def handle_git_post_receive(repo_path, g if push_ref['old_rev'] == EmptyChangeset().raw_id: # update the symbolic ref if we push new repo if scm_repo.is_empty(): - scm_repo._repo.refs.set_symbolic_ref('HEAD', - 'refs/heads/%s' % push_ref['name']) + scm_repo._repo.refs.set_symbolic_ref( + b'HEAD', + b'refs/heads/%s' % push_ref['name']) # build exclude list without the ref cmd = ['for-each-ref', '--format=%(refname)', 'refs/heads/*'] diff --git a/kallithea/lib/ssh.py b/kallithea/lib/ssh.py --- a/kallithea/lib/ssh.py +++ b/kallithea/lib/ssh.py @@ -88,8 +88,8 @@ def parse_pub_key(ssh_key): except TypeError: raise SshKeyParseError(_("Incorrect SSH key - failed to decode base64 part %r") % keyvalue) - if not decoded.startswith('\x00\x00\x00' + chr(len(keytype)) + str(keytype) + '\x00'): - raise SshKeyParseError(_("Incorrect SSH key - base64 part is not %r as claimed but %r") % (str(keytype), str(decoded[4:].split('\0', 1)[0]))) + 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]))) return keytype, decoded, comment diff --git a/kallithea/lib/utils.py b/kallithea/lib/utils.py --- a/kallithea/lib/utils.py +++ b/kallithea/lib/utils.py @@ -337,21 +337,21 @@ def make_ui(repo_path=None): sa = meta.Session() for ui_ in sa.query(Ui).all(): if ui_.ui_active: - ui_val = '' if ui_.ui_value is None else safe_str(ui_.ui_value) + 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), ui_val) # force set push_ssl requirement to False, Kallithea handles that - baseui.setconfig('web', 'push_ssl', False) - baseui.setconfig('web', 'allow_push', '*') + baseui.setconfig(b'web', b'push_ssl', False) + baseui.setconfig(b'web', b'allow_push', b'*') # prevent interactive questions for ssh password / passphrase - ssh = baseui.config('ui', 'ssh', default='ssh') - baseui.setconfig('ui', 'ssh', '%s -oBatchMode=yes -oIdentitiesOnly=yes' % ssh) + ssh = baseui.config(b'ui', b'ssh', default=b'ssh') + baseui.setconfig(b'ui', b'ssh', b'%s -oBatchMode=yes -oIdentitiesOnly=yes' % ssh) # push / pull hooks - baseui.setconfig('hooks', 'changegroup.kallithea_log_push_action', 'python:kallithea.lib.hooks.log_push_action') - baseui.setconfig('hooks', 'outgoing.kallithea_log_pull_action', 'python:kallithea.lib.hooks.log_pull_action') + baseui.setconfig(b'hooks', b'changegroup.kallithea_log_push_action', b'python:kallithea.lib.hooks.log_push_action') + baseui.setconfig(b'hooks', b'outgoing.kallithea_log_pull_action', b'python:kallithea.lib.hooks.log_pull_action') if repo_path is not None: hgrc_path = os.path.join(repo_path, '.hg', 'hgrc') diff --git a/kallithea/lib/vcs/backends/git/changeset.py b/kallithea/lib/vcs/backends/git/changeset.py --- a/kallithea/lib/vcs/backends/git/changeset.py +++ b/kallithea/lib/vcs/backends/git/changeset.py @@ -244,7 +244,7 @@ class GitChangeset(BaseChangeset): # Only used to feed diffstat rev1 = self.parents[0] if self.parents else self.repository.EMPTY_CHANGESET rev2 = self - return ''.join(self.repository.get_diff(rev1, rev2, + return b''.join(self.repository.get_diff(rev1, rev2, ignore_whitespace=ignore_whitespace, context=context)) @@ -418,7 +418,7 @@ class GitChangeset(BaseChangeset): obj_path = name 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['.gitmodules'][1]).data)) + 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, alias=als)) @@ -457,7 +457,7 @@ class GitChangeset(BaseChangeset): _GL = lambda m: m and objects.S_ISGITLINK(m) 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['.gitmodules'][1]).data)) + 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_, alias=self.repository.alias) diff --git a/kallithea/lib/vcs/backends/git/inmemory.py b/kallithea/lib/vcs/backends/git/inmemory.py --- a/kallithea/lib/vcs/backends/git/inmemory.py +++ b/kallithea/lib/vcs/backends/git/inmemory.py @@ -39,7 +39,7 @@ class GitInMemoryChangeset(BaseInMemoryC repo = self.repository._repo object_store = repo.object_store - ENCODING = "UTF-8" # TODO: should probably be kept in sync with safe_unicode/safe_bytes and vcs/conf/settings.py DEFAULT_ENCODINGS + ENCODING = b"UTF-8" # TODO: should probably be kept in sync with safe_unicode/safe_bytes and vcs/conf/settings.py DEFAULT_ENCODINGS # Create tree and populates it with blobs commit_tree = self.parents[0] and repo[self.parents[0]._commit.tree] or \ @@ -47,7 +47,7 @@ class GitInMemoryChangeset(BaseInMemoryC for node in self.added + self.changed: # Compute subdirs if needed dirpath, nodename = posixpath.split(node.path) - dirnames = safe_str(dirpath).split('/') if dirpath else [] + dirnames = safe_str(dirpath).split(b'/') if dirpath else [] parent = commit_tree ancestors = [('', parent)] @@ -100,7 +100,7 @@ class GitInMemoryChangeset(BaseInMemoryC for tree in new_trees: object_store.add_object(tree) for node in self.removed: - paths = node.path.split('/') + paths = node.path.split(b'/') tree = commit_tree trees = [tree] # Traverse deep into the forest... @@ -146,10 +146,9 @@ class GitInMemoryChangeset(BaseInMemoryC object_store.add_object(commit) - ref = 'refs/heads/%s' % branch + # Update vcs repository object & recreate dulwich repo + ref = b'refs/heads/%s' % branch repo.refs[ref] = commit.id - - # Update vcs repository object & recreate dulwich repo self.repository.revisions.append(commit.id) # invalidate parsed refs after commit self.repository._parsed_refs = self.repository._get_parsed_refs() diff --git a/kallithea/lib/vcs/backends/git/repository.py b/kallithea/lib/vcs/backends/git/repository.py --- a/kallithea/lib/vcs/backends/git/repository.py +++ b/kallithea/lib/vcs/backends/git/repository.py @@ -123,8 +123,8 @@ class GitRepository(BaseRepository): raise RepositoryError(msg) try: - stdout = ''.join(p.output) - stderr = ''.join(p.error) + stdout = b''.join(p.output) + stderr = b''.join(p.error) finally: p.close() # TODO: introduce option to make commands fail if they have any stderr output? @@ -170,12 +170,12 @@ class GitRepository(BaseRepository): handlers = [] url_obj = hg_url(url) test_uri, authinfo = url_obj.authinfo() - url_obj.passwd = '*****' - cleaned_uri = str(url_obj) - if not test_uri.endswith('info/refs'): test_uri = test_uri.rstrip('/') + '/info/refs' + url_obj.passwd = b'*****' + cleaned_uri = str(url_obj) + if authinfo: # create a password manager passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm() @@ -252,7 +252,7 @@ class GitRepository(BaseRepository): def _get_all_revisions2(self): # alternate implementation using dulwich includes = [x[1][0] for x in self._parsed_refs.iteritems() - if x[1][1] != 'T'] + if x[1][1] != b'T'] return [c.commit.id for c in self._repo.get_walker(include=includes)] def _get_revision(self, revision): @@ -282,7 +282,7 @@ class GitRepository(BaseRepository): # get by branch/tag name _ref_revision = self._parsed_refs.get(revision) - if _ref_revision: # and _ref_revision[1] in ['H', 'RH', 'T']: + if _ref_revision: # and _ref_revision[1] in [b'H', b'RH', b'T']: return _ref_revision[0] if revision in self.revisions: @@ -355,9 +355,7 @@ class GitRepository(BaseRepository): @LazyProperty def description(self): - undefined_description = u'unknown' - _desc = self._repo.get_description() - return safe_unicode(_desc or undefined_description) + return safe_unicode(self._repo.get_description() or b'unknown') @LazyProperty def contact(self): @@ -370,7 +368,7 @@ class GitRepository(BaseRepository): return {} sortkey = lambda ctx: ctx[0] _branches = [(x[0], x[1][0]) - for x in self._parsed_refs.iteritems() if x[1][1] == 'H'] + for x in self._parsed_refs.iteritems() if x[1][1] == b'H'] return OrderedDict(sorted(_branches, key=sortkey, reverse=False)) @LazyProperty @@ -387,7 +385,7 @@ class GitRepository(BaseRepository): sortkey = lambda ctx: ctx[0] _tags = [(x[0], x[1][0]) - for x in self._parsed_refs.iteritems() if x[1][1] == 'T'] + for x in self._parsed_refs.iteritems() if x[1][1] == b'T'] return OrderedDict(sorted(_tags, key=sortkey, reverse=True)) def tag(self, name, user, revision=None, message=None, date=None, @@ -408,7 +406,7 @@ class GitRepository(BaseRepository): changeset = self.get_changeset(revision) message = message or "Added tag %s for commit %s" % (name, changeset.raw_id) - self._repo.refs["refs/tags/%s" % name] = changeset._commit.id + self._repo.refs[b"refs/tags/%s" % name] = changeset._commit.id self._parsed_refs = self._get_parsed_refs() self.tags = self._get_tags() @@ -451,15 +449,15 @@ class GitRepository(BaseRepository): # cache the property _repo = self._repo refs = _repo.get_refs() - keys = [('refs/heads/', 'H'), - ('refs/remotes/origin/', 'RH'), - ('refs/tags/', 'T')] + keys = [(b'refs/heads/', b'H'), + (b'refs/remotes/origin/', b'RH'), + (b'refs/tags/', b'T')] _refs = {} for ref, sha in refs.iteritems(): for k, type_ in keys: if ref.startswith(k): _key = ref[len(k):] - if type_ == 'T': + if type_ == b'T': obj = _repo.get_object(sha) if isinstance(obj, Tag): sha = _repo.get_object(sha).object[1] @@ -472,10 +470,10 @@ class GitRepository(BaseRepository): heads = {} for key, val in refs.items(): - for ref_key in ['refs/heads/', 'refs/remotes/origin/']: + for ref_key in [b'refs/heads/', b'refs/remotes/origin/']: if key.startswith(ref_key): n = key[len(ref_key):] - if n not in ['HEAD']: + if n not in [b'HEAD']: heads[n] = val return heads if reverse else dict((y, x) for x, y in heads.iteritems()) @@ -627,9 +625,9 @@ class GitRepository(BaseRepository): # If we used 'show' command, strip first few lines (until actual diff # starts) if rev1 == self.EMPTY_CHANGESET: - parts = stdout.split('\ndiff ', 1) + parts = stdout.split(b'\ndiff ', 1) if len(parts) > 1: - stdout = 'diff ' + parts[1] + stdout = b'diff ' + parts[1] return stdout @LazyProperty diff --git a/kallithea/lib/vcs/backends/git/workdir.py b/kallithea/lib/vcs/backends/git/workdir.py --- a/kallithea/lib/vcs/backends/git/workdir.py +++ b/kallithea/lib/vcs/backends/git/workdir.py @@ -7,7 +7,7 @@ from kallithea.lib.vcs.exceptions import class GitWorkdir(BaseWorkdir): def get_branch(self): - headpath = self.repository._repo.refs.refpath('HEAD') + headpath = self.repository._repo.refs.refpath(b'HEAD') try: content = open(headpath).read() match = re.match(r'^ref: refs/heads/(?P.+)\n$', content) @@ -20,7 +20,7 @@ class GitWorkdir(BaseWorkdir): raise RepositoryError("Couldn't compute workdir's branch") def get_changeset(self): - wk_dir_id = self.repository._repo.refs.as_dict().get('HEAD') + wk_dir_id = self.repository._repo.refs.as_dict().get(b'HEAD') return self.repository.get_changeset(wk_dir_id) def checkout_branch(self, branch=None): diff --git a/kallithea/lib/vcs/backends/hg/changeset.py b/kallithea/lib/vcs/backends/hg/changeset.py --- a/kallithea/lib/vcs/backends/hg/changeset.py +++ b/kallithea/lib/vcs/backends/hg/changeset.py @@ -194,7 +194,7 @@ class MercurialChangeset(BaseChangeset): def diff(self): # Only used to feed diffstat - return ''.join(self._ctx.diff()) + return b''.join(self._ctx.diff()) def _fix_path(self, path): """ @@ -236,7 +236,7 @@ class MercurialChangeset(BaseChangeset): Returns stat mode of the file at the given ``path``. """ fctx = self._get_filectx(path) - if 'x' in fctx.flags(): + if b'x' in fctx.flags(): return 0o100755 else: return 0o100644 diff --git a/kallithea/lib/vcs/backends/hg/inmemory.py b/kallithea/lib/vcs/backends/hg/inmemory.py --- a/kallithea/lib/vcs/backends/hg/inmemory.py +++ b/kallithea/lib/vcs/backends/hg/inmemory.py @@ -36,7 +36,7 @@ class MercurialInMemoryChangeset(BaseInM if branch is None: branch = MercurialRepository.DEFAULT_BRANCH_NAME - kwargs['branch'] = branch + kwargs[b'branch'] = branch def filectxfn(_repo, memctx, path): """ @@ -79,7 +79,7 @@ class MercurialInMemoryChangeset(BaseInM commit_ctx = memctx(repo=self.repository._repo, parents=parents, - text='', + text=b'', files=self.get_paths(), filectxfn=filectxfn, user=author, diff --git a/kallithea/lib/vcs/backends/hg/repository.py b/kallithea/lib/vcs/backends/hg/repository.py --- a/kallithea/lib/vcs/backends/hg/repository.py +++ b/kallithea/lib/vcs/backends/hg/repository.py @@ -221,8 +221,7 @@ class MercurialRepository(BaseRepository )) def _get_all_revisions(self): - - return [self._repo[x].hex() for x in self._repo.filtered('visible').changelog.revs()] + return [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): @@ -262,7 +261,7 @@ class MercurialRepository(BaseRepository else: file_filter = None - return ''.join(patch.diff(self._repo, rev1, rev2, match=file_filter, + return b''.join(patch.diff(self._repo, rev1, rev2, match=file_filter, opts=diffopts(git=True, showfunc=True, ignorews=ignore_whitespace, @@ -280,23 +279,23 @@ class MercurialRepository(BaseRepository when the return code is non 200 """ # check first if it's not an local url - if os.path.isdir(url) or url.startswith('file:'): + if os.path.isdir(url) or url.startswith(b'file:'): return True - if url.startswith('ssh:'): + if url.startswith(b'ssh:'): # in case of invalid uri or authentication issues, sshpeer will # throw an exception. - sshpeer.instance(repoui or ui.ui(), url, False).lookup('tip') + sshpeer.instance(repoui or ui.ui(), url, False).lookup(b'tip') return True url_prefix = None - if '+' in url[:url.find('://')]: - url_prefix, url = url.split('+', 1) + if b'+' in url[:url.find(b'://')]: + url_prefix, url = url.split(b'+', 1) handlers = [] url_obj = hg_url(url) test_uri, authinfo = url_obj.authinfo() - url_obj.passwd = '*****' + url_obj.passwd = b'*****' cleaned_uri = str(url_obj) if authinfo: @@ -328,7 +327,7 @@ class MercurialRepository(BaseRepository if not url_prefix: # skip svn+http://... (and git+... too) # now check if it's a proper hg repo try: - httppeer.instance(repoui or ui.ui(), url, False).lookup('tip') + httppeer.instance(repoui or ui.ui(), url, False).lookup(b'tip') except Exception as e: raise urllib2.URLError( "url [%s] does not look like an hg repo org_exc: %s" @@ -374,15 +373,13 @@ class MercurialRepository(BaseRepository @LazyProperty def description(self): - undefined_description = u'unknown' - _desc = self._repo.ui.config('web', 'description', None, untrusted=True) - return safe_unicode(_desc or undefined_description) + _desc = self._repo.ui.config(b'web', b'description', None, untrusted=True) + return safe_unicode(_desc or b'unknown') @LazyProperty def contact(self): - undefined_contact = u'Unknown' return safe_unicode(get_contact(self._repo.ui.config) - or undefined_contact) + or b'Unknown') @LazyProperty def last_change(self): @@ -413,7 +410,7 @@ class MercurialRepository(BaseRepository raise EmptyRepositoryError("There are no changesets yet") if revision in [-1, None]: - revision = 'tip' + revision = b'tip' elif isinstance(revision, unicode): revision = safe_bytes(revision) @@ -461,13 +458,13 @@ class MercurialRepository(BaseRepository return self._get_revision(revision) def _get_archives(self, archive_name='tip'): - allowed = self.baseui.configlist("web", "allow_archive", + allowed = self.baseui.configlist(b"web", b"allow_archive", untrusted=True) - for i in [('zip', '.zip'), ('gz', '.tar.gz'), ('bz2', '.tar.bz2')]: - if i[0] in allowed or self._repo.ui.configbool("web", - "allow" + i[0], + for name, ext in [(b'zip', '.zip'), (b'gz', '.tar.gz'), (b'bz2', '.tar.bz2')]: + if name in allowed or self._repo.ui.configbool(b"web", + b"allow" + name, untrusted=True): - yield {"type": i[0], "extension": i[1], "node": archive_name} + yield {"type": name, "extension": ext, "node": archive_name} def _get_url(self, url): """ @@ -525,18 +522,18 @@ class MercurialRepository(BaseRepository # filter branches filter_ = [] if branch_name: - filter_.append('branch("%s")' % safe_str(branch_name)) + filter_.append(b'branch("%s")' % safe_str(branch_name)) if start_date: - filter_.append('date(">%s")' % start_date) + filter_.append(b'date(">%s")' % start_date) if end_date: - filter_.append('date("<%s")' % end_date) + filter_.append(b'date("<%s")' % end_date) if filter_ or max_revisions: if filter_: - revspec = ' and '.join(filter_) + revspec = b' and '.join(filter_) else: - revspec = 'all()' + revspec = b'all()' if max_revisions: - revspec = 'limit(%s, %s)' % (revspec, max_revisions) + revspec = b'limit(%s, %d)' % (revspec, max_revisions) revisions = scmutil.revrange(self._repo, [revspec]) else: revisions = self.revisions diff --git a/kallithea/lib/vcs/backends/hg/ssh.py b/kallithea/lib/vcs/backends/hg/ssh.py --- a/kallithea/lib/vcs/backends/hg/ssh.py +++ b/kallithea/lib/vcs/backends/hg/ssh.py @@ -58,8 +58,8 @@ class MercurialSshHandler(BaseSshHandler # Note: we want a repo with config based on .hg/hgrc and can thus not use self.db_repo.scm_instance._repo.ui baseui = make_ui(repo_path=self.db_repo.repo_full_path) if not self.allow_push: - baseui.setconfig('hooks', 'pretxnopen._ssh_reject', 'python:kallithea.lib.hooks.rejectpush') - baseui.setconfig('hooks', 'prepushkey._ssh_reject', 'python:kallithea.lib.hooks.rejectpush') + baseui.setconfig(b'hooks', b'pretxnopen._ssh_reject', b'python:kallithea.lib.hooks.rejectpush') + baseui.setconfig(b'hooks', b'prepushkey._ssh_reject', b'python:kallithea.lib.hooks.rejectpush') repo = hg.repository(baseui, safe_str(self.db_repo.repo_full_path)) log.debug("Starting Mercurial sshserver for %s", self.db_repo.repo_full_path) diff --git a/kallithea/lib/vcs/subprocessio.py b/kallithea/lib/vcs/subprocessio.py --- a/kallithea/lib/vcs/subprocessio.py +++ b/kallithea/lib/vcs/subprocessio.py @@ -367,11 +367,11 @@ class SubprocessIOChunker(object): and returncode != 0 ): # and it failed bg_out.stop() - out = ''.join(bg_out) + out = b''.join(bg_out) bg_err.stop() - err = ''.join(bg_err) - if (err.strip() == 'fatal: The remote end hung up unexpectedly' and - out.startswith('0034shallow ') + err = b''.join(bg_err) + if (err.strip() == b'fatal: The remote end hung up unexpectedly' and + out.startswith(b'0034shallow ') ): # hack inspired by https://github.com/schacon/grack/pull/7 bg_out = iter([out]) diff --git a/kallithea/model/pull_request.py b/kallithea/model/pull_request.py --- a/kallithea/model/pull_request.py +++ b/kallithea/model/pull_request.py @@ -261,7 +261,7 @@ class CreatePullRequestAction(object): 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["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] = safe_str(self.org_rev) # reset state to under-review from kallithea.model.changeset_status import ChangesetStatusModel diff --git a/kallithea/model/scm.py b/kallithea/model/scm.py --- a/kallithea/model/scm.py +++ b/kallithea/model/scm.py @@ -716,11 +716,11 @@ class ScmModel(object): if not os.path.isdir(loc): os.makedirs(loc) - tmpl_post = "#!%s\n" % self._get_git_hook_interpreter() + tmpl_post = b"#!%s\n" % self._get_git_hook_interpreter() tmpl_post += pkg_resources.resource_string( 'kallithea', os.path.join('config', 'post_receive_tmpl.py') ) - tmpl_pre = "#!%s\n" % self._get_git_hook_interpreter() + tmpl_pre = b"#!%s\n" % self._get_git_hook_interpreter() tmpl_pre += pkg_resources.resource_string( 'kallithea', os.path.join('config', 'pre_receive_tmpl.py') ) @@ -750,7 +750,7 @@ class ScmModel(object): log.debug('writing %s hook file !', h_type) try: with open(_hook_file, 'wb') as f: - tmpl = tmpl.replace('_TMPL_', kallithea.__version__) + tmpl = tmpl.replace(b'_TMPL_', kallithea.__version__) f.write(tmpl) os.chmod(_hook_file, 0o755) except IOError as e: diff --git a/kallithea/tests/api/api_base.py b/kallithea/tests/api/api_base.py --- a/kallithea/tests/api/api_base.py +++ b/kallithea/tests/api/api_base.py @@ -2509,8 +2509,8 @@ class _BaseTestApi(object): "revisions": self.TEST_PR_REVISIONS, } self._compare_ok(random_id, expected, - given=re.sub(r"\d\d\d\d\-\d\d\-\d\dT\d\d\:\d\d\:\d\d", - "2000-01-01T00:00:00", response.body)) + given=re.sub(br"\d\d\d\d\-\d\d\-\d\dT\d\d\:\d\d\:\d\d", + b"2000-01-01T00:00:00", response.body)) def test_api_close_pullrequest(self): pull_request_id = fixture.create_pullrequest(self, self.REPO, self.TEST_PR_SRC, self.TEST_PR_DST, u'close test') diff --git a/kallithea/tests/base.py b/kallithea/tests/base.py --- a/kallithea/tests/base.py +++ b/kallithea/tests/base.py @@ -156,7 +156,7 @@ class TestController(object): 'password': password, '_session_csrf_secret_token': self.session_csrf_secret_token()}) - if 'Invalid username or password' in response.body: + if b'Invalid username or password' in response.body: pytest.fail('could not login using %s %s' % (username, password)) assert response.status == '302 Found' diff --git a/kallithea/tests/fixture.py b/kallithea/tests/fixture.py --- a/kallithea/tests/fixture.py +++ b/kallithea/tests/fixture.py @@ -423,7 +423,7 @@ def create_test_index(repo_location, con def failing_test_hook(ui, repo, **kwargs): - ui.write("failing_test_hook failed\n") + ui.write(b"failing_test_hook failed\n") return 1 @@ -432,5 +432,5 @@ def exception_test_hook(ui, repo, **kwar def passing_test_hook(ui, repo, **kwargs): - ui.write("passing_test_hook succeeded\n") + ui.write(b"passing_test_hook succeeded\n") return 0 diff --git a/kallithea/tests/functional/test_admin_auth_settings.py b/kallithea/tests/functional/test_admin_auth_settings.py --- a/kallithea/tests/functional/test_admin_auth_settings.py +++ b/kallithea/tests/functional/test_admin_auth_settings.py @@ -219,7 +219,7 @@ class TestAuthSettingsController(TestCon url=url(controller='admin/my_account', action='my_account'), extra_environ={'REMOTE_USER': 'john'}, ) - assert 'Log Out' not in response.normal_body + assert b'Log Out' not in response.normal_body def test_crowd_save_settings(self): self.log_user() diff --git a/kallithea/tests/functional/test_admin_gists.py b/kallithea/tests/functional/test_admin_gists.py --- a/kallithea/tests/functional/test_admin_gists.py +++ b/kallithea/tests/functional/test_admin_gists.py @@ -158,14 +158,14 @@ class TestGistsController(TestController gist = _create_gist('gist-show-me', content='GIST CONTENT') response = self.app.get(url('formatted_gist', gist_id=gist.gist_access_id, format='raw')) - assert response.body == 'GIST CONTENT' + assert response.body == b'GIST CONTENT' def test_show_as_raw_individual_file(self): gist = _create_gist('gist-show-me-raw', content='GIST BODY') response = self.app.get(url('formatted_gist_file', gist_id=gist.gist_access_id, format='raw', revision='tip', f_path='gist-show-me-raw')) - assert response.body == 'GIST BODY' + assert response.body == b'GIST BODY' def test_edit(self): response = self.app.get(url('edit_gist', gist_id=1)) diff --git a/kallithea/tests/vcs/test_git.py b/kallithea/tests/vcs/test_git.py --- a/kallithea/tests/vcs/test_git.py +++ b/kallithea/tests/vcs/test_git.py @@ -229,7 +229,7 @@ class TestGitRepository(object): def test_changeset10(self): chset10 = self.repo.get_changeset(self.repo.revisions[9]) - readme = """=== + readme = b"""=== VCS === @@ -649,11 +649,11 @@ class TestGitSpecificWithRepo(_BackendTe def test_paths_slow_traversing(self): cs = self.repo.get_changeset() - assert cs.get_node('foobar').get_node('static').get_node('js').get_node('admin').get_node('base.js').content == 'base' + assert cs.get_node('foobar').get_node('static').get_node('js').get_node('admin').get_node('base.js').content == b'base' def test_paths_fast_traversing(self): cs = self.repo.get_changeset() - assert cs.get_node('foobar/static/js/admin/base.js').content == 'base' + assert cs.get_node('foobar/static/js/admin/base.js').content == b'base' def test_workdir_get_branch(self): self.repo.run_git_command(['checkout', '-b', 'production']) diff --git a/kallithea/tests/vcs/test_hg.py b/kallithea/tests/vcs/test_hg.py --- a/kallithea/tests/vcs/test_hg.py +++ b/kallithea/tests/vcs/test_hg.py @@ -219,7 +219,7 @@ class TestMercurialRepository(object): def test_changeset10(self): chset10 = self.repo.get_changeset(10) - readme = """=== + readme = b"""=== VCS === diff --git a/kallithea/tests/vcs/test_inmemchangesets.py b/kallithea/tests/vcs/test_inmemchangesets.py --- a/kallithea/tests/vcs/test_inmemchangesets.py +++ b/kallithea/tests/vcs/test_inmemchangesets.py @@ -82,8 +82,8 @@ class InMemoryChangesetTestMixin(_Backen changeset = self.imc.commit(u'Initial', u'joe.doe@example.com') assert isinstance(changeset.get_node('foo'), DirNode) assert isinstance(changeset.get_node('foo/bar'), DirNode) - assert changeset.get_node('foo/bar/image.png').content == '\0' - assert changeset.get_node('foo/README.txt').content == 'readme!' + assert changeset.get_node('foo/bar/image.png').content == b'\0' + assert changeset.get_node('foo/README.txt').content == b'readme!' # commit some more files again to_add = [ @@ -95,11 +95,11 @@ class InMemoryChangesetTestMixin(_Backen ] self.imc.add(*to_add) changeset = self.imc.commit(u'Another', u'joe.doe@example.com') - changeset.get_node('foo/bar/foobaz/bar').content == 'foo' - changeset.get_node('foo/bar/another/bar').content == 'foo' - changeset.get_node('foo/baz.txt').content == 'foo' - changeset.get_node('foobar/foobaz/file').content == 'foo' - changeset.get_node('foobar/barbaz').content == 'foo' + changeset.get_node('foo/bar/foobaz/bar').content == b'foo' + changeset.get_node('foo/bar/another/bar').content == b'foo' + changeset.get_node('foo/baz.txt').content == b'foo' + changeset.get_node('foobar/foobaz/file').content == b'foo' + changeset.get_node('foobar/barbaz').content == b'foo' def test_add_non_ascii_files(self): rev_count = len(self.repo.revisions) @@ -154,7 +154,7 @@ class InMemoryChangesetTestMixin(_Backen newtip = self.repo.get_changeset() assert tip != newtip assert tip.id != newtip.id - assert newtip.get_node('foo/bar/baz').content == 'My **changed** content' + assert newtip.get_node('foo/bar/baz').content == b'My **changed** content' def test_change_non_ascii(self): to_add = [ @@ -181,8 +181,8 @@ class InMemoryChangesetTestMixin(_Backen assert tip != newtip assert tip.id != newtip.id - assert newtip.get_node('żółwik/zwierzątko').content == 'My **changed** content' - assert newtip.get_node('żółwik/zwierzątko_uni').content == 'My **changed** content' + assert newtip.get_node('żółwik/zwierzątko').content == b'My **changed** content' + assert newtip.get_node('żółwik/zwierzątko_uni').content == b'My **changed** content' def test_change_raise_empty_repository(self): node = FileNode('foobar') diff --git a/kallithea/tests/vcs/test_nodes.py b/kallithea/tests/vcs/test_nodes.py --- a/kallithea/tests/vcs/test_nodes.py +++ b/kallithea/tests/vcs/test_nodes.py @@ -158,10 +158,10 @@ class TestNodeBasic(object): tar_node = FileNode('test.tar.gz') my_node2 = FileNode('myfile2') - my_node2._content = 'foobar' + my_node2._content = b'foobar' my_node3 = FileNode('myfile3') - my_node3._content = '\0foobar' + my_node3._content = b'\0foobar' assert py_node.mimetype == mimetypes.guess_type(py_node.name)[0] assert py_node.get_mimetype() == mimetypes.guess_type(py_node.name) diff --git a/kallithea/tests/vcs/test_repository.py b/kallithea/tests/vcs/test_repository.py --- a/kallithea/tests/vcs/test_repository.py +++ b/kallithea/tests/vcs/test_repository.py @@ -110,7 +110,7 @@ class TestGitRepositoryGetDiff(Repositor def test_initial_commit_diff(self): initial_rev = self.repo.revisions[0] - assert self.repo.get_diff(self.repo.EMPTY_CHANGESET, initial_rev) == r'''diff --git a/foobar b/foobar + assert self.repo.get_diff(self.repo.EMPTY_CHANGESET, initial_rev) == br'''diff --git a/foobar b/foobar new file mode 100644 index 0000000000000000000000000000000000000000..f6ea0495187600e7b2288c8ac19c5886383a4632 --- /dev/null @@ -130,7 +130,7 @@ index 0000000000000000000000000000000000 def test_second_changeset_diff(self): revs = self.repo.revisions - assert self.repo.get_diff(revs[0], revs[1]) == r'''diff --git a/foobar b/foobar + assert self.repo.get_diff(revs[0], revs[1]) == br'''diff --git a/foobar b/foobar index f6ea0495187600e7b2288c8ac19c5886383a4632..389865bb681b358c9b102d79abd8d5f941e96551 100644 --- a/foobar +++ b/foobar @@ -151,7 +151,7 @@ index 0000000000000000000000000000000000 def test_third_changeset_diff(self): revs = self.repo.revisions - assert self.repo.get_diff(revs[1], revs[2]) == r'''diff --git a/foobar b/foobar + assert self.repo.get_diff(revs[1], revs[2]) == br'''diff --git a/foobar b/foobar deleted file mode 100644 index 389865bb681b358c9b102d79abd8d5f941e96551..0000000000000000000000000000000000000000 --- a/foobar @@ -173,7 +173,7 @@ index c11c37d41d33fb47741cff93fa5f9d798c def test_fourth_changeset_diff(self): revs = self.repo.revisions - assert self.repo.get_diff(revs[2], revs[3]) == r'''diff --git a/README{ b/README{ + assert self.repo.get_diff(revs[2], revs[3]) == br'''diff --git a/README{ b/README{ new file mode 100644 index 0000000000000000000000000000000000000000..cdc0c1b5d234feedb37bbac19cd1b6442061102d --- /dev/null @@ -189,7 +189,7 @@ class TestHgRepositoryGetDiff(Repository def test_initial_commit_diff(self): initial_rev = self.repo.revisions[0] - assert self.repo.get_diff(self.repo.EMPTY_CHANGESET, initial_rev) == r'''diff --git a/foobar b/foobar + assert self.repo.get_diff(self.repo.EMPTY_CHANGESET, initial_rev) == br'''diff --git a/foobar b/foobar new file mode 100644 --- /dev/null +++ b/foobar @@ -207,7 +207,7 @@ new file mode 100644 def test_second_changeset_diff(self): revs = self.repo.revisions - assert self.repo.get_diff(revs[0], revs[1]) == r'''diff --git a/foobar b/foobar + assert self.repo.get_diff(revs[0], revs[1]) == br'''diff --git a/foobar b/foobar --- a/foobar +++ b/foobar @@ -1,1 +1,1 @@ @@ -226,7 +226,7 @@ new file mode 100644 def test_third_changeset_diff(self): revs = self.repo.revisions - assert self.repo.get_diff(revs[1], revs[2]) == r'''diff --git a/foobar b/foobar + assert self.repo.get_diff(revs[1], revs[2]) == br'''diff --git a/foobar b/foobar deleted file mode 100644 --- a/foobar +++ /dev/null @@ -246,7 +246,7 @@ diff --git a/foobar3 b/foobar3 def test_fourth_changeset_diff(self): revs = self.repo.revisions - assert self.repo.get_diff(revs[2], revs[3]) == r'''diff --git a/README{ b/README{ + assert self.repo.get_diff(revs[2], revs[3]) == br'''diff --git a/README{ b/README{ new file mode 100644 --- /dev/null +++ b/README{