diff -r 2372284d9457 -r 687b865b95ad mercurial/match.py --- a/mercurial/match.py Sun Oct 06 09:45:02 2019 -0400 +++ b/mercurial/match.py Sun Oct 06 09:48:39 2019 -0400 @@ -26,21 +26,21 @@ rustmod = policy.importrust(r'filepatterns') allpatternkinds = ( - 're', - 'glob', - 'path', - 'relglob', - 'relpath', - 'relre', - 'rootglob', - 'listfile', - 'listfile0', - 'set', - 'include', - 'subinclude', - 'rootfilesin', + b're', + b'glob', + b'path', + b'relglob', + b'relpath', + b'relre', + b'rootglob', + b'listfile', + b'listfile0', + b'set', + b'include', + b'subinclude', + b'rootfilesin', ) -cwdrelativepatternkinds = ('relpath', 'glob') +cwdrelativepatternkinds = (b'relpath', b'glob') propertycache = util.propertycache @@ -62,10 +62,10 @@ other = [] for kind, pat, source in kindpats: - if kind == 'set': + if kind == b'set': if ctx is None: raise error.ProgrammingError( - "fileset expression with no " "context" + b"fileset expression with no " b"context" ) matchers.append(ctx.matchfileset(pat, badfn=badfn)) @@ -87,17 +87,17 @@ other = [] for kind, pat, source in kindpats: - if kind == 'subinclude': + if kind == b'subinclude': sourceroot = pathutil.dirname(util.normpath(source)) pat = util.pconvert(pat) path = pathutil.join(sourceroot, pat) newroot = pathutil.dirname(path) - matcherargs = (newroot, '', [], ['include:%s' % path]) + matcherargs = (newroot, b'', [], [b'include:%s' % path]) prefix = pathutil.canonpath(root, root, newroot) if prefix: - prefix += '/' + prefix += b'/' relmatchers.append((prefix, matcherargs)) else: other.append((kind, pat, source)) @@ -110,7 +110,7 @@ 'relpath:.' does. """ for kind, pat, source in kindpats: - if pat != '' or kind not in ['relpath', 'glob']: + if pat != b'' or kind not in [b'relpath', b'glob']: return False return True @@ -140,7 +140,7 @@ patterns=None, include=None, exclude=None, - default='glob', + default=b'glob', auditor=None, ctx=None, listsubrepos=False, @@ -236,7 +236,7 @@ kp = _donormalize(patterns, default, root, cwd, auditor, warn) kindpats = [] for kind, pats, source in kp: - if kind not in ('re', 'relre'): # regex can't be normalized + if kind not in (b're', b'relre'): # regex can't be normalized p = pats pats = dsnormalize(pats) @@ -266,7 +266,7 @@ m = alwaysmatcher(badfn) if include: - kindpats = normalize(include, 'glob', root, cwd, auditor, warn) + kindpats = normalize(include, b'glob', root, cwd, auditor, warn) im = _buildkindpatsmatcher( includematcher, root, @@ -277,7 +277,7 @@ ) m = intersectmatchers(m, im) if exclude: - kindpats = normalize(exclude, 'glob', root, cwd, auditor, warn) + kindpats = normalize(exclude, b'glob', root, cwd, auditor, warn) em = _buildkindpatsmatcher( includematcher, root, @@ -318,24 +318,24 @@ for kind, pat in [_patsplit(p, default) for p in patterns]: if kind in cwdrelativepatternkinds: pat = pathutil.canonpath(root, cwd, pat, auditor=auditor) - elif kind in ('relglob', 'path', 'rootfilesin', 'rootglob'): + elif kind in (b'relglob', b'path', b'rootfilesin', b'rootglob'): pat = util.normpath(pat) - elif kind in ('listfile', 'listfile0'): + elif kind in (b'listfile', b'listfile0'): try: files = util.readfile(pat) - if kind == 'listfile0': - files = files.split('\0') + if kind == b'listfile0': + files = files.split(b'\0') else: files = files.splitlines() files = [f for f in files if f] except EnvironmentError: - raise error.Abort(_("unable to read file list (%s)") % pat) + raise error.Abort(_(b"unable to read file list (%s)") % pat) for k, p, source in _donormalize( files, default, root, cwd, auditor, warn ): kindpats.append((k, p, pat)) continue - elif kind == 'include': + elif kind == b'include': try: fullpath = os.path.join(root, util.localpath(pat)) includepats = readpatternfile(fullpath, warn) @@ -344,16 +344,16 @@ ): kindpats.append((k, p, source or pat)) except error.Abort as inst: - raise error.Abort('%s: %s' % (pat, inst[0])) + raise error.Abort(b'%s: %s' % (pat, inst[0])) except IOError as inst: if warn: warn( - _("skipping unreadable pattern file '%s': %s\n") + _(b"skipping unreadable pattern file '%s': %s\n") % (pat, stringutil.forcebytestr(inst.strerror)) ) continue # else: re or relre - which cannot be normalized - kindpats.append((kind, pat, '')) + kindpats.append((kind, pat, b'')) return kindpats @@ -454,7 +454,7 @@ equivalently that if there are files to investigate in 'dir' that it will always return 'this'). ''' - return 'this' + return b'this' def always(self): '''Matcher will match everything and .files() will be empty -- @@ -490,10 +490,10 @@ return True def visitdir(self, dir): - return 'all' + return b'all' def visitchildrenset(self, dir): - return 'all' + return b'all' def __repr__(self): return r'' @@ -539,16 +539,16 @@ s = stringutil.buildrepr(self._predrepr) or pycompat.byterepr( self.matchfn ) - return '' % s + return b'' % s def normalizerootdir(dir, funcname): - if dir == '.': + if dir == b'.': util.nouideprecwarn( - "match.%s() no longer accepts " "'.', use '' instead." % funcname, - '5.1', + b"match.%s() no longer accepts " b"'.', use '' instead." % funcname, + b'5.1', ) - return '' + return b'' return dir @@ -590,16 +590,16 @@ self._files = _explicitfiles(kindpats) self._prefix = _prefix(kindpats) - self._pats, self.matchfn = _buildmatch(kindpats, '$', root) + self._pats, self.matchfn = _buildmatch(kindpats, b'$', root) @propertycache def _dirs(self): return set(util.dirs(self._fileset)) def visitdir(self, dir): - dir = normalizerootdir(dir, 'visitdir') + dir = normalizerootdir(dir, b'visitdir') if self._prefix and dir in self._fileset: - return 'all' + return b'all' return ( dir in self._fileset or dir in self._dirs @@ -611,18 +611,18 @@ def visitchildrenset(self, dir): ret = self.visitdir(dir) if ret is True: - return 'this' + return b'this' elif not ret: return set() - assert ret == 'all' - return 'all' + assert ret == b'all' + return b'all' def prefix(self): return self._prefix @encoding.strmethod def __repr__(self): - return '' % pycompat.bytestr(self._pats) + return b'' % pycompat.bytestr(self._pats) # This is basically a reimplementation of util.dirs that stores the children @@ -637,7 +637,7 @@ addpath(f) def addpath(self, path): - if path == '': + if path == b'': return dirs = self._dirs findsplitdirs = _dirchildren._findsplitdirs @@ -654,12 +654,12 @@ # Unlike manifest._splittopdir, this does not suffix `dirname` with a # slash. oldpos = len(path) - pos = path.rfind('/') + pos = path.rfind(b'/') while pos != -1: yield path[:pos], path[pos + 1 : oldpos] oldpos = pos - pos = path.rfind('/', 0, pos) - yield '', path[:oldpos] + pos = path.rfind(b'/', 0, pos) + yield b'', path[:oldpos] def get(self, path): return self._dirs.get(path, set()) @@ -669,7 +669,7 @@ def __init__(self, root, kindpats, badfn=None): super(includematcher, self).__init__(badfn) - self._pats, self.matchfn = _buildmatch(kindpats, '(?:/|$)', root) + self._pats, self.matchfn = _buildmatch(kindpats, b'(?:/|$)', root) self._prefix = _prefix(kindpats) roots, dirs, parents = _rootsdirsandparents(kindpats) # roots are directories which are recursively included. @@ -681,9 +681,9 @@ self._parents = parents def visitdir(self, dir): - dir = normalizerootdir(dir, 'visitdir') + dir = normalizerootdir(dir, b'visitdir') if self._prefix and dir in self._roots: - return 'all' + return b'all' return ( dir in self._roots or dir in self._dirs @@ -706,16 +706,16 @@ def visitchildrenset(self, dir): if self._prefix and dir in self._roots: - return 'all' + return b'all' # Note: this does *not* include the 'dir in self._parents' case from # visitdir, that's handled below. if ( - '' in self._roots + b'' in self._roots or dir in self._roots or dir in self._dirs or any(parentdir in self._roots for parentdir in util.finddirs(dir)) ): - return 'this' + return b'this' if dir in self._parents: return self._allparentschildren.get(dir) or set() @@ -723,7 +723,7 @@ @encoding.strmethod def __repr__(self): - return '' % pycompat.bytestr(self._pats) + return b'' % pycompat.bytestr(self._pats) class exactmatcher(basematcher): @@ -762,25 +762,25 @@ return set(util.dirs(self._fileset)) def visitdir(self, dir): - dir = normalizerootdir(dir, 'visitdir') + dir = normalizerootdir(dir, b'visitdir') return dir in self._dirs def visitchildrenset(self, dir): - dir = normalizerootdir(dir, 'visitchildrenset') + dir = normalizerootdir(dir, b'visitchildrenset') if not self._fileset or dir not in self._dirs: return set() - candidates = self._fileset | self._dirs - {''} - if dir != '': - d = dir + '/' + candidates = self._fileset | self._dirs - {b''} + if dir != b'': + d = dir + b'/' candidates = set(c[len(d) :] for c in candidates if c.startswith(d)) # self._dirs includes all of the directories, recursively, so if # we're attempting to match foo/bar/baz.txt, it'll have '', 'foo', # 'foo/bar' in it. Thus we can safely ignore a candidate that has a # '/' in it, indicating a it's for a subdir-of-a-subdir; the # immediate subdir will be in there without a slash. - ret = {c for c in candidates if '/' not in c} + ret = {c for c in candidates if b'/' not in c} # We really do not expect ret to be empty, since that would imply that # there's something in _dirs that didn't have a file in _fileset. assert ret @@ -791,7 +791,7 @@ @encoding.strmethod def __repr__(self): - return '' % self._files + return b'' % self._files class differencematcher(basematcher): @@ -825,7 +825,7 @@ return self._m1.files() def visitdir(self, dir): - if self._m2.visitdir(dir) == 'all': + if self._m2.visitdir(dir) == b'all': return False elif not self._m2.visitdir(dir): # m2 does not match dir, we can return 'all' here if possible @@ -834,7 +834,7 @@ def visitchildrenset(self, dir): m2_set = self._m2.visitchildrenset(dir) - if m2_set == 'all': + if m2_set == b'all': return set() m1_set = self._m1.visitchildrenset(dir) # Possible values for m1: 'all', 'this', set(...), set() @@ -844,11 +844,11 @@ # return True, not 'all', for some reason. if not m2_set: return m1_set - if m1_set in ['all', 'this']: + if m1_set in [b'all', b'this']: # Never return 'all' here if m2_set is any kind of non-empty (either # 'this' or set(foo)), since m2 might return set() for a # subdirectory. - return 'this' + return b'this' # Possible values for m1: set(...), set() # Possible values for m2: 'this', set(...) # We ignore m2's set results. They're possibly incorrect: @@ -862,7 +862,7 @@ @encoding.strmethod def __repr__(self): - return '' % (self._m1, self._m2) + return b'' % (self._m1, self._m2) def intersectmatchers(m1, m2): @@ -914,7 +914,7 @@ def visitdir(self, dir): visit1 = self._m1.visitdir(dir) - if visit1 == 'all': + if visit1 == b'all': return self._m2.visitdir(dir) # bool() because visit1=True + visit2='all' should not be 'all' return bool(visit1 and self._m2.visitdir(dir)) @@ -927,13 +927,13 @@ if not m2_set: return set() - if m1_set == 'all': + if m1_set == b'all': return m2_set - elif m2_set == 'all': + elif m2_set == b'all': return m1_set - if m1_set == 'this' or m2_set == 'this': - return 'this' + if m1_set == b'this' or m2_set == b'this': + return b'this' assert isinstance(m1_set, set) and isinstance(m2_set, set) return m1_set.intersection(m2_set) @@ -946,7 +946,7 @@ @encoding.strmethod def __repr__(self): - return '' % (self._m1, self._m2) + return b'' % (self._m1, self._m2) class subdirmatcher(basematcher): @@ -985,7 +985,7 @@ self._files = [ f[len(path) + 1 :] for f in matcher._files - if f.startswith(path + "/") + if f.startswith(path + b"/") ] # If the parent repo had a path to this subrepo and the matcher is @@ -994,29 +994,29 @@ self._always = any(f == path for f in matcher._files) def bad(self, f, msg): - self._matcher.bad(self._path + "/" + f, msg) + self._matcher.bad(self._path + b"/" + f, msg) def matchfn(self, f): # Some information is lost in the superclass's constructor, so we # can not accurately create the matching function for the subdirectory # from the inputs. Instead, we override matchfn() and visitdir() to # call the original matcher with the subdirectory path prepended. - return self._matcher.matchfn(self._path + "/" + f) + return self._matcher.matchfn(self._path + b"/" + f) def visitdir(self, dir): - dir = normalizerootdir(dir, 'visitdir') - if dir == '': + dir = normalizerootdir(dir, b'visitdir') + if dir == b'': dir = self._path else: - dir = self._path + "/" + dir + dir = self._path + b"/" + dir return self._matcher.visitdir(dir) def visitchildrenset(self, dir): - dir = normalizerootdir(dir, 'visitchildrenset') - if dir == '': + dir = normalizerootdir(dir, b'visitchildrenset') + if dir == b'': dir = self._path else: - dir = self._path + "/" + dir + dir = self._path + b"/" + dir return self._matcher.visitchildrenset(dir) def always(self): @@ -1027,7 +1027,7 @@ @encoding.strmethod def __repr__(self): - return '' % ( + return b'' % ( self._path, self._matcher, ) @@ -1069,9 +1069,9 @@ def __init__(self, path, matcher, badfn=None): super(prefixdirmatcher, self).__init__(badfn) if not path: - raise error.ProgrammingError('prefix path must not be empty') + raise error.ProgrammingError(b'prefix path must not be empty') self._path = path - self._pathprefix = path + '/' + self._pathprefix = path + b'/' self._matcher = matcher @propertycache @@ -1089,18 +1089,18 @@ def visitdir(self, dir): if dir == self._path: - return self._matcher.visitdir('') + return self._matcher.visitdir(b'') if dir.startswith(self._pathprefix): return self._matcher.visitdir(dir[len(self._pathprefix) :]) return dir in self._pathdirs def visitchildrenset(self, dir): if dir == self._path: - return self._matcher.visitchildrenset('') + return self._matcher.visitchildrenset(b'') if dir.startswith(self._pathprefix): return self._matcher.visitchildrenset(dir[len(self._pathprefix) :]) if dir in self._pathdirs: - return 'this' + return b'this' return set() def isexact(self): @@ -1111,7 +1111,7 @@ @encoding.strmethod def __repr__(self): - return '' % ( + return b'' % ( pycompat.bytestr(self._path), self._matcher, ) @@ -1141,7 +1141,7 @@ r = False for m in self._matchers: v = m.visitdir(dir) - if v == 'all': + if v == b'all': return v r |= v return r @@ -1153,21 +1153,21 @@ v = m.visitchildrenset(dir) if not v: continue - if v == 'all': + if v == b'all': return v - if this or v == 'this': + if this or v == b'this': this = True # don't break, we might have an 'all' in here. continue assert isinstance(v, set) r = r.union(v) if this: - return 'this' + return b'this' return r @encoding.strmethod def __repr__(self): - return '' % self._matchers + return b'' % self._matchers def patkind(pattern, default=None): @@ -1189,8 +1189,8 @@ def _patsplit(pattern, default): """Split a string into the optional pattern kind prefix and the actual pattern.""" - if ':' in pattern: - kind, pat = pattern.split(':', 1) + if b':' in pattern: + kind, pat = pattern.split(b':', 1) if kind in allpatternkinds: return kind, pat return default, pattern @@ -1220,7 +1220,7 @@ \.\*\? ''' i, n = 0, len(pat) - res = '' + res = b'' group = 0 escape = util.stringutil.regexbytesescapemap.get @@ -1230,45 +1230,45 @@ while i < n: c = pat[i : i + 1] i += 1 - if c not in '*?[{},\\': + if c not in b'*?[{},\\': res += escape(c, c) - elif c == '*': - if peek() == '*': + elif c == b'*': + if peek() == b'*': i += 1 - if peek() == '/': + if peek() == b'/': i += 1 - res += '(?:.*/)?' + res += b'(?:.*/)?' else: - res += '.*' + res += b'.*' else: - res += '[^/]*' - elif c == '?': - res += '.' - elif c == '[': + res += b'[^/]*' + elif c == b'?': + res += b'.' + elif c == b'[': j = i - if j < n and pat[j : j + 1] in '!]': + if j < n and pat[j : j + 1] in b'!]': j += 1 - while j < n and pat[j : j + 1] != ']': + while j < n and pat[j : j + 1] != b']': j += 1 if j >= n: - res += '\\[' + res += b'\\[' else: - stuff = pat[i:j].replace('\\', '\\\\') + stuff = pat[i:j].replace(b'\\', b'\\\\') i = j + 1 - if stuff[0:1] == '!': - stuff = '^' + stuff[1:] - elif stuff[0:1] == '^': - stuff = '\\' + stuff - res = '%s[%s]' % (res, stuff) - elif c == '{': + if stuff[0:1] == b'!': + stuff = b'^' + stuff[1:] + elif stuff[0:1] == b'^': + stuff = b'\\' + stuff + res = b'%s[%s]' % (res, stuff) + elif c == b'{': group += 1 - res += '(?:' - elif c == '}' and group: - res += ')' + res += b'(?:' + elif c == b'}' and group: + res += b')' group -= 1 - elif c == ',' and group: - res += '|' - elif c == '\\': + elif c == b',' and group: + res += b'|' + elif c == b'\\': p = peek() if p: i += 1 @@ -1290,39 +1290,39 @@ return rustmod.build_single_regex(kind, pat, globsuffix) except rustmod.PatternError: raise error.ProgrammingError( - 'not a regex pattern: %s:%s' % (kind, pat) + b'not a regex pattern: %s:%s' % (kind, pat) ) - if not pat and kind in ('glob', 'relpath'): - return '' - if kind == 're': + if not pat and kind in (b'glob', b'relpath'): + return b'' + if kind == b're': return pat - if kind in ('path', 'relpath'): - if pat == '.': - return '' - return util.stringutil.reescape(pat) + '(?:/|$)' - if kind == 'rootfilesin': - if pat == '.': - escaped = '' + if kind in (b'path', b'relpath'): + if pat == b'.': + return b'' + return util.stringutil.reescape(pat) + b'(?:/|$)' + if kind == b'rootfilesin': + if pat == b'.': + escaped = b'' else: # Pattern is a directory name. - escaped = util.stringutil.reescape(pat) + '/' + escaped = util.stringutil.reescape(pat) + b'/' # Anything after the pattern must be a non-directory. - return escaped + '[^/]+$' - if kind == 'relglob': + return escaped + b'[^/]+$' + if kind == b'relglob': globre = _globre(pat) - if globre.startswith('[^/]*'): + if globre.startswith(b'[^/]*'): # When pat has the form *XYZ (common), make the returned regex more # legible by returning the regex for **XYZ instead of **/*XYZ. - return '.*' + globre[len('[^/]*') :] + globsuffix - return '(?:|.*/)' + globre + globsuffix - if kind == 'relre': - if pat.startswith('^'): + return b'.*' + globre[len(b'[^/]*') :] + globsuffix + return b'(?:|.*/)' + globre + globsuffix + if kind == b'relre': + if pat.startswith(b'^'): return pat - return '.*' + pat - if kind in ('glob', 'rootglob'): + return b'.*' + pat + if kind in (b'glob', b'rootglob'): return _globre(pat) + globsuffix - raise error.ProgrammingError('not a regex pattern: %s:%s' % (kind, pat)) + raise error.ProgrammingError(b'not a regex pattern: %s:%s' % (kind, pat)) def _buildmatch(kindpats, globsuffix, root): @@ -1348,17 +1348,17 @@ matchfuncs.append(matchsubinclude) - regex = '' + regex = b'' if kindpats: - if all(k == 'rootfilesin' for k, p, s in kindpats): + if all(k == b'rootfilesin' for k, p, s in kindpats): dirs = {p for k, p, s in kindpats} def mf(f): - i = f.rfind('/') + i = f.rfind(b'/') if i >= 0: dir = f[:i] else: - dir = '.' + dir = b'.' return dir in dirs regex = b'rootfilesin: %s' % stringutil.pprint(list(sorted(dirs))) @@ -1378,7 +1378,7 @@ def _joinregexes(regexps): """gather multiple regular expressions into a single one""" - return '|'.join(regexps) + return b'|'.join(regexps) def _buildregexmatch(kindpats, globsuffix): @@ -1403,7 +1403,7 @@ for idx, r in enumerate(regexps): piecesize = len(r) if piecesize > MAX_RE_SIZE: - msg = _("matcher pattern is too long (%d bytes)") % piecesize + msg = _(b"matcher pattern is too long (%d bytes)") % piecesize raise error.Abort(msg) elif (groupsize + piecesize) > MAX_RE_SIZE: group = regexps[startidx:idx] @@ -1428,11 +1428,11 @@ except re.error: if s: raise error.Abort( - _("%s: invalid pattern (%s): %s") % (s, k, p) + _(b"%s: invalid pattern (%s): %s") % (s, k, p) ) else: - raise error.Abort(_("invalid pattern (%s): %s") % (k, p)) - raise error.Abort(_("invalid pattern")) + raise error.Abort(_(b"invalid pattern (%s): %s") % (k, p)) + raise error.Abort(_(b"invalid pattern")) def _patternrootsanddirs(kindpats): @@ -1446,23 +1446,23 @@ r = [] d = [] for kind, pat, source in kindpats: - if kind in ('glob', 'rootglob'): # find the non-glob prefix + if kind in (b'glob', b'rootglob'): # find the non-glob prefix root = [] - for p in pat.split('/'): - if '[' in p or '{' in p or '*' in p or '?' in p: + for p in pat.split(b'/'): + if b'[' in p or b'{' in p or b'*' in p or b'?' in p: break root.append(p) - r.append('/'.join(root)) - elif kind in ('relpath', 'path'): - if pat == '.': - pat = '' + r.append(b'/'.join(root)) + elif kind in (b'relpath', b'path'): + if pat == b'.': + pat = b'' r.append(pat) - elif kind in ('rootfilesin',): - if pat == '.': - pat = '' + elif kind in (b'rootfilesin',): + if pat == b'.': + pat = b'' d.append(pat) else: # relglob, re, relre - r.append('') + r.append(b'') return r, d @@ -1526,14 +1526,14 @@ ''' # Keep only the pattern kinds where one can specify filenames (vs only # directory names). - filable = [kp for kp in kindpats if kp[0] not in ('rootfilesin',)] + filable = [kp for kp in kindpats if kp[0] not in (b'rootfilesin',)] return _roots(filable) def _prefix(kindpats): '''Whether all the patterns match a prefix (i.e. recursively)''' for kind, pat, source in kindpats: - if kind not in ('path', 'relpath'): + if kind not in (b'path', b'relpath'): return False return True @@ -1573,24 +1573,24 @@ for warning_params in warnings: # Can't be easily emitted from Rust, because it would require # a mechanism for both gettext and calling the `warn` function. - warn(_("%s: ignoring invalid syntax '%s'\n") % warning_params) + warn(_(b"%s: ignoring invalid syntax '%s'\n") % warning_params) return result syntaxes = { - 're': 'relre:', - 'regexp': 'relre:', - 'glob': 'relglob:', - 'rootglob': 'rootglob:', - 'include': 'include', - 'subinclude': 'subinclude', + b're': b'relre:', + b'regexp': b'relre:', + b'glob': b'relglob:', + b'rootglob': b'rootglob:', + b'include': b'include', + b'subinclude': b'subinclude', } - syntax = 'relre:' + syntax = b'relre:' patterns = [] - fp = open(filepath, 'rb') + fp = open(filepath, b'rb') for lineno, line in enumerate(util.iterfile(fp), start=1): - if "#" in line: + if b"#" in line: global _commentre if not _commentre: _commentre = util.re.compile(br'((?:^|[^\\])(?:\\\\)*)#.*') @@ -1599,19 +1599,19 @@ if m: line = line[: m.end(1)] # fixup properly escaped comments that survived the above - line = line.replace("\\#", "#") + line = line.replace(b"\\#", b"#") line = line.rstrip() if not line: continue - if line.startswith('syntax:'): + if line.startswith(b'syntax:'): s = line[7:].strip() try: syntax = syntaxes[s] except KeyError: if warn: warn( - _("%s: ignoring invalid syntax '%s'\n") % (filepath, s) + _(b"%s: ignoring invalid syntax '%s'\n") % (filepath, s) ) continue @@ -1621,7 +1621,7 @@ linesyntax = rels line = line[len(rels) :] break - elif line.startswith(s + ':'): + elif line.startswith(s + b':'): linesyntax = rels line = line[len(s) + 1 :] break