--- a/mercurial/revset.py Fri Oct 26 12:02:58 2012 -0700
+++ b/mercurial/revset.py Tue Oct 30 18:48:44 2012 -0500
@@ -105,6 +105,15 @@
keywords = set(['and', 'or', 'not'])
def tokenize(program):
+ '''
+ Parse a revset statement into a stream of tokens
+
+ Check that @ is a valid unquoted token character (issue3686):
+ >>> list(tokenize("@::"))
+ [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)]
+
+ '''
+
pos, l = 0, len(program)
while pos < l:
c = program[pos]
@@ -140,12 +149,12 @@
else:
raise error.ParseError(_("unterminated string"), s)
# gather up a symbol/keyword
- elif c.isalnum() or c in '._' or ord(c) > 127:
+ elif c.isalnum() or c in '._@' or ord(c) > 127:
s = pos
pos += 1
while pos < l: # find end of symbol
d = program[pos]
- if not (d.isalnum() or d in "._/" or ord(d) > 127):
+ if not (d.isalnum() or d in "._/@" or ord(d) > 127):
break
if d == '.' and program[pos - 1] == '.': # special case for ..
pos -= 1