Mercurial > public > mercurial-scm > hg-stable
diff mercurial/revsetlang.py @ 43077:687b865b95ad
formatting: byteify all mercurial/ and hgext/ string literals
Done with
python3.7 contrib/byteify-strings.py -i $(hg files 'set:mercurial/**.py - mercurial/thirdparty/** + hgext/**.py - hgext/fsmonitor/pywatchman/** - mercurial/__init__.py')
black -l 80 -t py33 -S $(hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**" - hgext/fsmonitor/pywatchman/**')
# skip-blame mass-reformatting only
Differential Revision: https://phab.mercurial-scm.org/D6972
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:48:39 -0400 |
parents | 2372284d9457 |
children | c59eb1560c44 |
line wrap: on
line diff
--- a/mercurial/revsetlang.py Sun Oct 06 09:45:02 2019 -0400 +++ b/mercurial/revsetlang.py Sun Oct 06 09:48:39 2019 -0400 @@ -22,63 +22,63 @@ elements = { # token-type: binding-strength, primary, prefix, infix, suffix - "(": (21, None, ("group", 1, ")"), ("func", 1, ")"), None), - "[": (21, None, None, ("subscript", 1, "]"), None), - "#": (21, None, None, ("relation", 21), None), - "##": (20, None, None, ("_concat", 20), None), - "~": (18, None, None, ("ancestor", 18), None), - "^": (18, None, None, ("parent", 18), "parentpost"), - "-": (5, None, ("negate", 19), ("minus", 5), None), - "::": ( + b"(": (21, None, (b"group", 1, b")"), (b"func", 1, b")"), None), + b"[": (21, None, None, (b"subscript", 1, b"]"), None), + b"#": (21, None, None, (b"relation", 21), None), + b"##": (20, None, None, (b"_concat", 20), None), + b"~": (18, None, None, (b"ancestor", 18), None), + b"^": (18, None, None, (b"parent", 18), b"parentpost"), + b"-": (5, None, (b"negate", 19), (b"minus", 5), None), + b"::": ( 17, - "dagrangeall", - ("dagrangepre", 17), - ("dagrange", 17), - "dagrangepost", + b"dagrangeall", + (b"dagrangepre", 17), + (b"dagrange", 17), + b"dagrangepost", ), - "..": ( + b"..": ( 17, - "dagrangeall", - ("dagrangepre", 17), - ("dagrange", 17), - "dagrangepost", + b"dagrangeall", + (b"dagrangepre", 17), + (b"dagrange", 17), + b"dagrangepost", ), - ":": (15, "rangeall", ("rangepre", 15), ("range", 15), "rangepost"), - "not": (10, None, ("not", 10), None, None), - "!": (10, None, ("not", 10), None, None), - "and": (5, None, None, ("and", 5), None), - "&": (5, None, None, ("and", 5), None), - "%": (5, None, None, ("only", 5), "onlypost"), - "or": (4, None, None, ("or", 4), None), - "|": (4, None, None, ("or", 4), None), - "+": (4, None, None, ("or", 4), None), - "=": (3, None, None, ("keyvalue", 3), None), - ",": (2, None, None, ("list", 2), None), - ")": (0, None, None, None, None), - "]": (0, None, None, None, None), - "symbol": (0, "symbol", None, None, None), - "string": (0, "string", None, None, None), - "end": (0, None, None, None, None), + b":": (15, b"rangeall", (b"rangepre", 15), (b"range", 15), b"rangepost"), + b"not": (10, None, (b"not", 10), None, None), + b"!": (10, None, (b"not", 10), None, None), + b"and": (5, None, None, (b"and", 5), None), + b"&": (5, None, None, (b"and", 5), None), + b"%": (5, None, None, (b"only", 5), b"onlypost"), + b"or": (4, None, None, (b"or", 4), None), + b"|": (4, None, None, (b"or", 4), None), + b"+": (4, None, None, (b"or", 4), None), + b"=": (3, None, None, (b"keyvalue", 3), None), + b",": (2, None, None, (b"list", 2), None), + b")": (0, None, None, None, None), + b"]": (0, None, None, None, None), + b"symbol": (0, b"symbol", None, None, None), + b"string": (0, b"string", None, None, None), + b"end": (0, None, None, None, None), } -keywords = {'and', 'or', 'not'} +keywords = {b'and', b'or', b'not'} symbols = {} -_quoteletters = {'"', "'"} -_simpleopletters = set(pycompat.iterbytestr("()[]#:=,-|&+!~^%")) +_quoteletters = {b'"', b"'"} +_simpleopletters = set(pycompat.iterbytestr(b"()[]#:=,-|&+!~^%")) # default set of valid characters for the initial letter of symbols _syminitletters = set( pycompat.iterbytestr( pycompat.sysbytes(string.ascii_letters) + pycompat.sysbytes(string.digits) - + '._@' + + b'._@' ) ) | set(map(pycompat.bytechr, pycompat.xrange(128, 256))) # default set of valid characters for non-initial letters of symbols -_symletters = _syminitletters | set(pycompat.iterbytestr('-/')) +_symletters = _syminitletters | set(pycompat.iterbytestr(b'-/')) def tokenize(program, lookup=None, syminitletters=None, symletters=None): @@ -104,7 +104,7 @@ ''' if not isinstance(program, bytes): raise error.ProgrammingError( - 'revset statement must be bytes, got %r' % program + b'revset statement must be bytes, got %r' % program ) program = pycompat.bytestr(program) if syminitletters is None: @@ -115,16 +115,16 @@ if program and lookup: # attempt to parse old-style ranges first to deal with # things like old-tag which contain query metacharacters - parts = program.split(':', 1) + parts = program.split(b':', 1) if all(lookup(sym) for sym in parts if sym): if parts[0]: - yield ('symbol', parts[0], 0) + yield (b'symbol', parts[0], 0) if len(parts) > 1: s = len(parts[0]) - yield (':', None, s) + yield (b':', None, s) if parts[1]: - yield ('symbol', parts[1], s + 1) - yield ('end', None, len(program)) + yield (b'symbol', parts[1], s + 1) + yield (b'end', None, len(program)) return pos, l = 0, len(program) @@ -133,28 +133,28 @@ if c.isspace(): # skip inter-token whitespace pass elif ( - c == ':' and program[pos : pos + 2] == '::' + c == b':' and program[pos : pos + 2] == b'::' ): # look ahead carefully - yield ('::', None, pos) + yield (b'::', None, pos) pos += 1 # skip ahead elif ( - c == '.' and program[pos : pos + 2] == '..' + c == b'.' and program[pos : pos + 2] == b'..' ): # look ahead carefully - yield ('..', None, pos) + yield (b'..', None, pos) pos += 1 # skip ahead elif ( - c == '#' and program[pos : pos + 2] == '##' + c == b'#' and program[pos : pos + 2] == b'##' ): # look ahead carefully - yield ('##', None, pos) + yield (b'##', None, pos) pos += 1 # skip ahead elif c in _simpleopletters: # handle simple operators yield (c, None, pos) elif ( c in _quoteletters - or c == 'r' - and program[pos : pos + 2] in ("r'", 'r"') + or c == b'r' + and program[pos : pos + 2] in (b"r'", b'r"') ): # handle quoted strings - if c == 'r': + if c == b'r': pos += 1 c = program[pos] decode = lambda x: x @@ -164,15 +164,15 @@ s = pos while pos < l: # find closing quote d = program[pos] - if d == '\\': # skip over escaped characters + if d == b'\\': # skip over escaped characters pos += 2 continue if d == c: - yield ('string', decode(program[s:pos]), s) + yield (b'string', decode(program[s:pos]), s) break pos += 1 else: - raise error.ParseError(_("unterminated string"), s) + raise error.ParseError(_(b"unterminated string"), s) # gather up a symbol/keyword elif c in syminitletters: s = pos @@ -181,38 +181,40 @@ d = program[pos] if d not in symletters: break - if d == '.' and program[pos - 1] == '.': # special case for .. + if ( + d == b'.' and program[pos - 1] == b'.' + ): # special case for .. pos -= 1 break pos += 1 sym = program[s:pos] if sym in keywords: # operator keywords yield (sym, None, s) - elif '-' in sym: + elif b'-' in sym: # some jerk gave us foo-bar-baz, try to check if it's a symbol if lookup and lookup(sym): # looks like a real symbol - yield ('symbol', sym, s) + yield (b'symbol', sym, s) else: # looks like an expression - parts = sym.split('-') + parts = sym.split(b'-') for p in parts[:-1]: if p: # possible consecutive - - yield ('symbol', p, s) + yield (b'symbol', p, s) s += len(p) - yield ('-', None, s) + yield (b'-', None, s) s += 1 if parts[-1]: # possible trailing - - yield ('symbol', parts[-1], s) + yield (b'symbol', parts[-1], s) else: - yield ('symbol', sym, s) + yield (b'symbol', sym, s) pos -= 1 else: raise error.ParseError( - _("syntax error in revset '%s'") % program, pos + _(b"syntax error in revset '%s'") % program, pos ) pos += 1 - yield ('end', None, pos) + yield (b'end', None, pos) # helpers @@ -221,13 +223,13 @@ def getsymbol(x): - if x and x[0] == 'symbol': + if x and x[0] == b'symbol': return x[1] - raise error.ParseError(_('not a symbol')) + raise error.ParseError(_(b'not a symbol')) def getstring(x, err): - if x and (x[0] == 'string' or x[0] == 'symbol'): + if x and (x[0] == b'string' or x[0] == b'symbol'): return x[1] raise error.ParseError(err) @@ -251,7 +253,7 @@ def getlist(x): if not x: return [] - if x[0] == 'list': + if x[0] == b'list': return list(x[1:]) return [x] @@ -260,13 +262,13 @@ if not x: raise error.ParseError(err) op = x[0] - if op == 'range': + if op == b'range': return x[1], x[2] - elif op == 'rangepre': + elif op == b'rangepre': return None, x[1] - elif op == 'rangepost': + elif op == b'rangepost': return x[1], None - elif op == 'rangeall': + elif op == b'rangeall': return None, None raise error.ParseError(err) @@ -277,7 +279,7 @@ If any of the sides omitted, and if no default provided, ParseError will be raised. """ - if x and (x[0] == 'string' or x[0] == 'symbol'): + if x and (x[0] == b'string' or x[0] == b'symbol'): n = getinteger(x, err1) return n, n a, b = getrange(x, err1) @@ -296,8 +298,8 @@ getlist(x), funcname, parser.splitargspec(keys), - keyvaluenode='keyvalue', - keynode='symbol', + keyvaluenode=b'keyvalue', + keynode=b'symbol', ) @@ -320,7 +322,7 @@ ('and', ('func', ('symbol', 'f'), ('string', '1')), ('symbol', '2')) """ template = _cachedtree(tmplspec) - return parser.buildtree(template, ('symbol', '_'), *repls) + return parser.buildtree(template, (b'symbol', b'_'), *repls) def _match(patspec, tree): @@ -333,12 +335,12 @@ """ pattern = _cachedtree(patspec) return parser.matchtree( - pattern, tree, ('symbol', '_'), {'keyvalue', 'list'} + pattern, tree, (b'symbol', b'_'), {b'keyvalue', b'list'} ) def _matchonly(revs, bases): - return _match('ancestors(_) and not ancestors(_)', ('and', revs, bases)) + return _match(b'ancestors(_) and not ancestors(_)', (b'and', revs, bases)) def _fixops(x): @@ -348,25 +350,25 @@ return x op = x[0] - if op == 'parent': + if op == b'parent': # x^:y means (x^) : y, not x ^ (:y) # x^: means (x^) :, not x ^ (:) - post = ('parentpost', x[1]) - if x[2][0] == 'dagrangepre': - return _fixops(('dagrange', post, x[2][1])) - elif x[2][0] == 'dagrangeall': - return _fixops(('dagrangepost', post)) - elif x[2][0] == 'rangepre': - return _fixops(('range', post, x[2][1])) - elif x[2][0] == 'rangeall': - return _fixops(('rangepost', post)) - elif op == 'or': + post = (b'parentpost', x[1]) + if x[2][0] == b'dagrangepre': + return _fixops((b'dagrange', post, x[2][1])) + elif x[2][0] == b'dagrangeall': + return _fixops((b'dagrangepost', post)) + elif x[2][0] == b'rangepre': + return _fixops((b'range', post, x[2][1])) + elif x[2][0] == b'rangeall': + return _fixops((b'rangepost', post)) + elif op == b'or': # make number of arguments deterministic: # x + y + z -> (or x y z) -> (or (list x y z)) - return (op, _fixops(('list',) + x[1:])) - elif op == 'subscript' and x[1][0] == 'relation': + return (op, _fixops((b'list',) + x[1:])) + elif op == b'subscript' and x[1][0] == b'relation': # x#y[z] ternary - return _fixops(('relsubscript', x[1][1], x[1][2], x[2])) + return _fixops((b'relsubscript', x[1][1], x[1][2], x[2])) return (op,) + tuple(_fixops(y) for y in x[1:]) @@ -376,53 +378,53 @@ return x op = x[0] - if op == 'minus': - return _analyze(_build('_ and not _', *x[1:])) - elif op == 'only': - return _analyze(_build('only(_, _)', *x[1:])) - elif op == 'onlypost': - return _analyze(_build('only(_)', x[1])) - elif op == 'dagrangeall': - raise error.ParseError(_("can't use '::' in this context")) - elif op == 'dagrangepre': - return _analyze(_build('ancestors(_)', x[1])) - elif op == 'dagrangepost': - return _analyze(_build('descendants(_)', x[1])) - elif op == 'negate': - s = getstring(x[1], _("can't negate that")) - return _analyze(('string', '-' + s)) - elif op in ('string', 'symbol', 'smartset'): + if op == b'minus': + return _analyze(_build(b'_ and not _', *x[1:])) + elif op == b'only': + return _analyze(_build(b'only(_, _)', *x[1:])) + elif op == b'onlypost': + return _analyze(_build(b'only(_)', x[1])) + elif op == b'dagrangeall': + raise error.ParseError(_(b"can't use '::' in this context")) + elif op == b'dagrangepre': + return _analyze(_build(b'ancestors(_)', x[1])) + elif op == b'dagrangepost': + return _analyze(_build(b'descendants(_)', x[1])) + elif op == b'negate': + s = getstring(x[1], _(b"can't negate that")) + return _analyze((b'string', b'-' + s)) + elif op in (b'string', b'symbol', b'smartset'): return x - elif op == 'rangeall': + elif op == b'rangeall': return (op, None) - elif op in {'or', 'not', 'rangepre', 'rangepost', 'parentpost'}: + elif op in {b'or', b'not', b'rangepre', b'rangepost', b'parentpost'}: return (op, _analyze(x[1])) - elif op == 'group': + elif op == b'group': return _analyze(x[1]) elif op in { - 'and', - 'dagrange', - 'range', - 'parent', - 'ancestor', - 'relation', - 'subscript', + b'and', + b'dagrange', + b'range', + b'parent', + b'ancestor', + b'relation', + b'subscript', }: ta = _analyze(x[1]) tb = _analyze(x[2]) return (op, ta, tb) - elif op == 'relsubscript': + elif op == b'relsubscript': ta = _analyze(x[1]) tb = _analyze(x[2]) tc = _analyze(x[3]) return (op, ta, tb, tc) - elif op == 'list': + elif op == b'list': return (op,) + tuple(_analyze(y) for y in x[1:]) - elif op == 'keyvalue': + elif op == b'keyvalue': return (op, x[1], _analyze(x[2])) - elif op == 'func': + elif op == b'func': return (op, x[1], _analyze(x[2])) - raise ValueError('invalid operator %r' % op) + raise ValueError(b'invalid operator %r' % op) def analyze(x): @@ -440,30 +442,30 @@ return 0, x op = x[0] - if op in ('string', 'symbol', 'smartset'): + if op in (b'string', b'symbol', b'smartset'): return 0.5, x # single revisions are small - elif op == 'and': + elif op == b'and': wa, ta = _optimize(x[1]) wb, tb = _optimize(x[2]) w = min(wa, wb) # (draft/secret/_notpublic() & ::x) have a fast path - m = _match('_() & ancestors(_)', ('and', ta, tb)) - if m and getsymbol(m[1]) in {'draft', 'secret', '_notpublic'}: - return w, _build('_phaseandancestors(_, _)', m[1], m[2]) + m = _match(b'_() & ancestors(_)', (b'and', ta, tb)) + if m and getsymbol(m[1]) in {b'draft', b'secret', b'_notpublic'}: + return w, _build(b'_phaseandancestors(_, _)', m[1], m[2]) # (::x and not ::y)/(not ::y and ::x) have a fast path m = _matchonly(ta, tb) or _matchonly(tb, ta) if m: - return w, _build('only(_, _)', *m[1:]) + return w, _build(b'only(_, _)', *m[1:]) - m = _match('not _', tb) + m = _match(b'not _', tb) if m: - return wa, ('difference', ta, m[1]) + return wa, (b'difference', ta, m[1]) if wa > wb: - op = 'andsmally' + op = b'andsmally' return w, (op, ta, tb) - elif op == 'or': + elif op == b'or': # fast path for machine-generated expression, that is likely to have # lots of trivial revisions: 'a + b + c()' to '_list(a b) + c()' ws, ts, ss = [], [], [] @@ -474,8 +476,8 @@ if len(ss) == 1: w, t = ss[0] else: - s = '\0'.join(t[1] for w, t in ss) - y = _build('_list(_)', ('string', s)) + s = b'\0'.join(t[1] for w, t in ss) + y = _build(b'_list(_)', (b'string', s)) w, t = _optimize(y) ws.append(w) ts.append(t) @@ -483,7 +485,7 @@ for y in getlist(x[1]): w, t = _optimize(y) - if t is not None and (t[0] == 'string' or t[0] == 'symbol'): + if t is not None and (t[0] == b'string' or t[0] == b'symbol'): ss.append((w, t)) continue flushss() @@ -492,48 +494,48 @@ flushss() if len(ts) == 1: return ws[0], ts[0] # 'or' operation is fully optimized out - return max(ws), (op, ('list',) + tuple(ts)) - elif op == 'not': + return max(ws), (op, (b'list',) + tuple(ts)) + elif op == b'not': # Optimize not public() to _notpublic() because we have a fast version - if _match('public()', x[1]): - o = _optimize(_build('_notpublic()')) + if _match(b'public()', x[1]): + o = _optimize(_build(b'_notpublic()')) return o[0], o[1] else: o = _optimize(x[1]) return o[0], (op, o[1]) - elif op == 'rangeall': + elif op == b'rangeall': return 1, x - elif op in ('rangepre', 'rangepost', 'parentpost'): + elif op in (b'rangepre', b'rangepost', b'parentpost'): o = _optimize(x[1]) return o[0], (op, o[1]) - elif op in ('dagrange', 'range'): + elif op in (b'dagrange', b'range'): wa, ta = _optimize(x[1]) wb, tb = _optimize(x[2]) return wa + wb, (op, ta, tb) - elif op in ('parent', 'ancestor', 'relation', 'subscript'): + elif op in (b'parent', b'ancestor', b'relation', b'subscript'): w, t = _optimize(x[1]) return w, (op, t, x[2]) - elif op == 'relsubscript': + elif op == b'relsubscript': w, t = _optimize(x[1]) return w, (op, t, x[2], x[3]) - elif op == 'list': + elif op == b'list': ws, ts = zip(*(_optimize(y) for y in x[1:])) return sum(ws), (op,) + ts - elif op == 'keyvalue': + elif op == b'keyvalue': w, t = _optimize(x[2]) return w, (op, x[1], t) - elif op == 'func': + elif op == b'func': f = getsymbol(x[1]) wa, ta = _optimize(x[2]) w = getattr(symbols.get(f), '_weight', 1) - m = _match('commonancestors(_)', ta) + m = _match(b'commonancestors(_)', ta) # Optimize heads(commonancestors(_)) because we have a fast version - if f == 'heads' and m: - return w + wa, _build('_commonancestorheads(_)', m[1]) + if f == b'heads' and m: + return w + wa, _build(b'_commonancestorheads(_)', m[1]) return w + wa, (op, x[1], ta) - raise ValueError('invalid operator %r' % op) + raise ValueError(b'invalid operator %r' % op) def optimize(tree): @@ -547,7 +549,7 @@ # the set of valid characters for the initial letter of symbols in # alias declarations and definitions -_aliassyminitletters = _syminitletters | {'$'} +_aliassyminitletters = _syminitletters | {b'$'} def _parsewith(spec, lookup=None, syminitletters=None): @@ -564,21 +566,21 @@ ... ParseError: ('invalid token', 4) """ - if lookup and spec.startswith('revset(') and spec.endswith(')'): + if lookup and spec.startswith(b'revset(') and spec.endswith(b')'): lookup = None p = parser.parser(elements) tree, pos = p.parse( tokenize(spec, lookup=lookup, syminitletters=syminitletters) ) if pos != len(spec): - raise error.ParseError(_('invalid token'), pos) - return _fixops(parser.simplifyinfixops(tree, ('list', 'or'))) + raise error.ParseError(_(b'invalid token'), pos) + return _fixops(parser.simplifyinfixops(tree, (b'list', b'or'))) class _aliasrules(parser.basealiasrules): """Parsing and expansion rule set of revset aliases""" - _section = _('revset alias') + _section = _(b'revset alias') @staticmethod def _parse(spec): @@ -592,7 +594,7 @@ @staticmethod def _trygetfunc(tree): - if tree[0] == 'func' and tree[1][0] == 'symbol': + if tree[0] == b'func' and tree[1][0] == b'symbol': return tree[1][1], getlist(tree[2]) @@ -604,7 +606,7 @@ if warn is not None: for name, alias in sorted(aliases.iteritems()): if alias.error and not alias.warned: - warn(_('warning: %s\n') % (alias.error)) + warn(_(b'warning: %s\n') % (alias.error)) alias.warned = True return tree @@ -613,24 +615,24 @@ """Fold elements to be concatenated by `##` """ if not isinstance(tree, tuple) or tree[0] in ( - 'string', - 'symbol', - 'smartset', + b'string', + b'symbol', + b'smartset', ): return tree - if tree[0] == '_concat': + if tree[0] == b'_concat': pending = [tree] l = [] while pending: e = pending.pop() - if e[0] == '_concat': + if e[0] == b'_concat': pending.extend(reversed(e[1:])) - elif e[0] in ('string', 'symbol'): + elif e[0] in (b'string', b'symbol'): l.append(e[1]) else: - msg = _("\"##\" can't concatenate \"%s\" element") % (e[0]) + msg = _(b"\"##\" can't concatenate \"%s\" element") % (e[0]) raise error.ParseError(msg) - return ('string', ''.join(l)) + return (b'string', b''.join(l)) else: return tuple(foldconcat(t) for t in tree) @@ -642,12 +644,12 @@ if len(inst.args) > 1: # has location loc = inst.args[1] # Remove newlines -- spaces are equivalent whitespace. - spec = spec.replace('\n', ' ') + spec = spec.replace(b'\n', b' ') # We want the caret to point to the place in the template that # failed to parse, but in a hint we get a open paren at the # start. Therefore, we print "loc + 1" spaces (instead of "loc") # to line up the caret with the location of the error. - inst.hint = spec + '\n' + ' ' * (loc + 1) + '^ ' + _('here') + inst.hint = spec + b'\n' + b' ' * (loc + 1) + b'^ ' + _(b'here') raise @@ -663,70 +665,70 @@ >>> _quote(1) "'1'" """ - return "'%s'" % stringutil.escapestr(pycompat.bytestr(s)) + return b"'%s'" % stringutil.escapestr(pycompat.bytestr(s)) def _formatargtype(c, arg): - if c == 'd': - return '_rev(%d)' % int(arg) - elif c == 's': + if c == b'd': + return b'_rev(%d)' % int(arg) + elif c == b's': return _quote(arg) - elif c == 'r': + elif c == b'r': if not isinstance(arg, bytes): raise TypeError parse(arg) # make sure syntax errors are confined - return '(%s)' % arg - elif c == 'n': + return b'(%s)' % arg + elif c == b'n': return _quote(node.hex(arg)) - elif c == 'b': + elif c == b'b': try: return _quote(arg.branch()) except AttributeError: raise TypeError - raise error.ParseError(_('unexpected revspec format character %s') % c) + raise error.ParseError(_(b'unexpected revspec format character %s') % c) def _formatlistexp(s, t): l = len(s) if l == 0: - return "_list('')" + return b"_list('')" elif l == 1: return _formatargtype(t, s[0]) - elif t == 'd': + elif t == b'd': return _formatintlist(s) - elif t == 's': - return "_list(%s)" % _quote("\0".join(s)) - elif t == 'n': - return "_hexlist('%s')" % "\0".join(node.hex(a) for a in s) - elif t == 'b': + elif t == b's': + return b"_list(%s)" % _quote(b"\0".join(s)) + elif t == b'n': + return b"_hexlist('%s')" % b"\0".join(node.hex(a) for a in s) + elif t == b'b': try: - return "_list('%s')" % "\0".join(a.branch() for a in s) + return b"_list('%s')" % b"\0".join(a.branch() for a in s) except AttributeError: raise TypeError m = l // 2 - return '(%s or %s)' % (_formatlistexp(s[:m], t), _formatlistexp(s[m:], t)) + return b'(%s or %s)' % (_formatlistexp(s[:m], t), _formatlistexp(s[m:], t)) def _formatintlist(data): try: l = len(data) if l == 0: - return "_list('')" + return b"_list('')" elif l == 1: - return _formatargtype('d', data[0]) - return "_intlist('%s')" % "\0".join('%d' % int(a) for a in data) + return _formatargtype(b'd', data[0]) + return b"_intlist('%s')" % b"\0".join(b'%d' % int(a) for a in data) except (TypeError, ValueError): - raise error.ParseError(_('invalid argument for revspec')) + raise error.ParseError(_(b'invalid argument for revspec')) def _formatparamexp(args, t): - return ', '.join(_formatargtype(t, a) for a in args) + return b', '.join(_formatargtype(t, a) for a in args) _formatlistfuncs = { - 'l': _formatlistexp, - 'p': _formatparamexp, + b'l': _formatlistexp, + b'p': _formatparamexp, } @@ -772,12 +774,12 @@ for t, arg in parsed: if t is None: ret.append(arg) - elif t == 'baseset': + elif t == b'baseset': if isinstance(arg, set): arg = sorted(arg) ret.append(_formatintlist(list(arg))) else: - raise error.ProgrammingError("unknown revspec item type: %r" % t) + raise error.ProgrammingError(b"unknown revspec item type: %r" % t) return b''.join(ret) @@ -789,15 +791,15 @@ for t, arg in parsed: if t is None: ret.append(arg) - elif t == 'baseset': - newtree = ('smartset', smartset.baseset(arg)) + elif t == b'baseset': + newtree = (b'smartset', smartset.baseset(arg)) inputs.append(newtree) - ret.append("$") + ret.append(b"$") else: - raise error.ProgrammingError("unknown revspec item type: %r" % t) + raise error.ProgrammingError(b"unknown revspec item type: %r" % t) expr = b''.join(ret) tree = _parsewith(expr, syminitletters=_aliassyminitletters) - tree = parser.buildtree(tree, ('symbol', '$'), *inputs) + tree = parser.buildtree(tree, (b'symbol', b'$'), *inputs) tree = foldconcat(tree) tree = analyze(tree) tree = optimize(tree) @@ -818,7 +820,7 @@ ret = [] pos = 0 while pos < len(expr): - q = expr.find('%', pos) + q = expr.find(b'%', pos) if q < 0: ret.append((None, expr[pos:])) break @@ -827,8 +829,8 @@ try: d = expr[pos] except IndexError: - raise error.ParseError(_('incomplete revspec format character')) - if d == '%': + raise error.ParseError(_(b'incomplete revspec format character')) + if d == b'%': ret.append((None, d)) pos += 1 continue @@ -836,45 +838,47 @@ try: arg = next(argiter) except StopIteration: - raise error.ParseError(_('missing argument for revspec')) + raise error.ParseError(_(b'missing argument for revspec')) f = _formatlistfuncs.get(d) if f: # a list of some type, might be expensive, do not replace pos += 1 - islist = d == 'l' + islist = d == b'l' try: d = expr[pos] except IndexError: - raise error.ParseError(_('incomplete revspec format character')) - if islist and d == 'd' and arg: + raise error.ParseError( + _(b'incomplete revspec format character') + ) + if islist and d == b'd' and arg: # we don't create a baseset yet, because it come with an # extra cost. If we are going to serialize it we better # skip it. - ret.append(('baseset', arg)) + ret.append((b'baseset', arg)) pos += 1 continue try: ret.append((None, f(list(arg), d))) except (TypeError, ValueError): - raise error.ParseError(_('invalid argument for revspec')) + raise error.ParseError(_(b'invalid argument for revspec')) else: # a single entry, not expensive, replace try: ret.append((None, _formatargtype(d, arg))) except (TypeError, ValueError): - raise error.ParseError(_('invalid argument for revspec')) + raise error.ParseError(_(b'invalid argument for revspec')) pos += 1 try: next(argiter) - raise error.ParseError(_('too many revspec arguments specified')) + raise error.ParseError(_(b'too many revspec arguments specified')) except StopIteration: pass return ret def prettyformat(tree): - return parser.prettyformat(tree, ('string', 'symbol')) + return parser.prettyformat(tree, (b'string', b'symbol')) def depth(tree): @@ -885,18 +889,18 @@ def funcsused(tree): - if not isinstance(tree, tuple) or tree[0] in ('string', 'symbol'): + if not isinstance(tree, tuple) or tree[0] in (b'string', b'symbol'): return set() else: funcs = set() for s in tree[1:]: funcs |= funcsused(s) - if tree[0] == 'func': + if tree[0] == b'func': funcs.add(tree[1][1]) return funcs -_hashre = util.re.compile('[0-9a-fA-F]{1,40}$') +_hashre = util.re.compile(b'[0-9a-fA-F]{1,40}$') def _ishashlikesymbol(symbol): @@ -919,7 +923,7 @@ if not tree: return [] - if tree[0] == "symbol": + if tree[0] == b"symbol": if _ishashlikesymbol(tree[1]): return [tree[1]] elif len(tree) >= 3: