##// END OF EJS Templates
doctest: bulk-replace string literals with b'' for Python 3...
Yuya Nishihara -
r34133:0fa78132 default
parent child Browse files
Show More
@@ -59,18 +59,18 b' def recode(s):'
59
59
60 def mapbranch(branch, branchmap):
60 def mapbranch(branch, branchmap):
61 '''
61 '''
62 >>> bmap = {'default': 'branch1'}
62 >>> bmap = {b'default': b'branch1'}
63 >>> for i in ['', None]:
63 >>> for i in [b'', None]:
64 ... mapbranch(i, bmap)
64 ... mapbranch(i, bmap)
65 'branch1'
65 'branch1'
66 'branch1'
66 'branch1'
67 >>> bmap = {'None': 'branch2'}
67 >>> bmap = {b'None': b'branch2'}
68 >>> for i in ['', None]:
68 >>> for i in [b'', None]:
69 ... mapbranch(i, bmap)
69 ... mapbranch(i, bmap)
70 'branch2'
70 'branch2'
71 'branch2'
71 'branch2'
72 >>> bmap = {'None': 'branch3', 'default': 'branch4'}
72 >>> bmap = {b'None': b'branch3', b'default': b'branch4'}
73 >>> for i in ['None', '', None, 'default', 'branch5']:
73 >>> for i in [b'None', b'', None, b'default', b'branch5']:
74 ... mapbranch(i, bmap)
74 ... mapbranch(i, bmap)
75 'branch3'
75 'branch3'
76 'branch4'
76 'branch4'
@@ -54,23 +54,23 b' class logerror(Exception):'
54 def getrepopath(cvspath):
54 def getrepopath(cvspath):
55 """Return the repository path from a CVS path.
55 """Return the repository path from a CVS path.
56
56
57 >>> getrepopath('/foo/bar')
57 >>> getrepopath(b'/foo/bar')
58 '/foo/bar'
58 '/foo/bar'
59 >>> getrepopath('c:/foo/bar')
59 >>> getrepopath(b'c:/foo/bar')
60 '/foo/bar'
60 '/foo/bar'
61 >>> getrepopath(':pserver:10/foo/bar')
61 >>> getrepopath(b':pserver:10/foo/bar')
62 '/foo/bar'
62 '/foo/bar'
63 >>> getrepopath(':pserver:10c:/foo/bar')
63 >>> getrepopath(b':pserver:10c:/foo/bar')
64 '/foo/bar'
64 '/foo/bar'
65 >>> getrepopath(':pserver:/foo/bar')
65 >>> getrepopath(b':pserver:/foo/bar')
66 '/foo/bar'
66 '/foo/bar'
67 >>> getrepopath(':pserver:c:/foo/bar')
67 >>> getrepopath(b':pserver:c:/foo/bar')
68 '/foo/bar'
68 '/foo/bar'
69 >>> getrepopath(':pserver:truc@foo.bar:/foo/bar')
69 >>> getrepopath(b':pserver:truc@foo.bar:/foo/bar')
70 '/foo/bar'
70 '/foo/bar'
71 >>> getrepopath(':pserver:truc@foo.bar:c:/foo/bar')
71 >>> getrepopath(b':pserver:truc@foo.bar:c:/foo/bar')
72 '/foo/bar'
72 '/foo/bar'
73 >>> getrepopath('user@server/path/to/repository')
73 >>> getrepopath(b'user@server/path/to/repository')
74 '/path/to/repository'
74 '/path/to/repository'
75 """
75 """
76 # According to CVS manual, CVS paths are expressed like:
76 # According to CVS manual, CVS paths are expressed like:
@@ -18,7 +18,7 b' SKIPREV = common.SKIPREV'
18 def rpairs(path):
18 def rpairs(path):
19 '''Yield tuples with path split at '/', starting with the full path.
19 '''Yield tuples with path split at '/', starting with the full path.
20 No leading, trailing or double '/', please.
20 No leading, trailing or double '/', please.
21 >>> for x in rpairs('foo/bar/baz'): print x
21 >>> for x in rpairs(b'foo/bar/baz'): print x
22 ('foo/bar/baz', '')
22 ('foo/bar/baz', '')
23 ('foo/bar', 'baz')
23 ('foo/bar', 'baz')
24 ('foo', 'bar/baz')
24 ('foo', 'bar/baz')
@@ -32,9 +32,9 b' def decodefilename(filename):'
32 """Perforce escapes special characters @, #, *, or %
32 """Perforce escapes special characters @, #, *, or %
33 with %40, %23, %2A, or %25 respectively
33 with %40, %23, %2A, or %25 respectively
34
34
35 >>> decodefilename('portable-net45%252Bnetcore45%252Bwp8%252BMonoAndroid')
35 >>> decodefilename(b'portable-net45%252Bnetcore45%252Bwp8%252BMonoAndroid')
36 'portable-net45%2Bnetcore45%2Bwp8%2BMonoAndroid'
36 'portable-net45%2Bnetcore45%2Bwp8%2BMonoAndroid'
37 >>> decodefilename('//Depot/Directory/%2525/%2523/%23%40.%2A')
37 >>> decodefilename(b'//Depot/Directory/%2525/%2523/%23%40.%2A')
38 '//Depot/Directory/%25/%23/#@.*'
38 '//Depot/Directory/%25/%23/#@.*'
39 """
39 """
40 replacements = [('%2A', '*'), ('%23', '#'), ('%40', '@'), ('%25', '%')]
40 replacements = [('%2A', '*'), ('%23', '#'), ('%40', '@'), ('%25', '%')]
@@ -61,16 +61,16 b' class SvnPathNotFound(Exception):'
61
61
62 def revsplit(rev):
62 def revsplit(rev):
63 """Parse a revision string and return (uuid, path, revnum).
63 """Parse a revision string and return (uuid, path, revnum).
64 >>> revsplit('svn:a2147622-4a9f-4db4-a8d3-13562ff547b2'
64 >>> revsplit(b'svn:a2147622-4a9f-4db4-a8d3-13562ff547b2'
65 ... '/proj%20B/mytrunk/mytrunk@1')
65 ... b'/proj%20B/mytrunk/mytrunk@1')
66 ('a2147622-4a9f-4db4-a8d3-13562ff547b2', '/proj%20B/mytrunk/mytrunk', 1)
66 ('a2147622-4a9f-4db4-a8d3-13562ff547b2', '/proj%20B/mytrunk/mytrunk', 1)
67 >>> revsplit('svn:8af66a51-67f5-4354-b62c-98d67cc7be1d@1')
67 >>> revsplit(b'svn:8af66a51-67f5-4354-b62c-98d67cc7be1d@1')
68 ('', '', 1)
68 ('', '', 1)
69 >>> revsplit('@7')
69 >>> revsplit(b'@7')
70 ('', '', 7)
70 ('', '', 7)
71 >>> revsplit('7')
71 >>> revsplit(b'7')
72 ('', '', 0)
72 ('', '', 0)
73 >>> revsplit('bad')
73 >>> revsplit(b'bad')
74 ('', '', 0)
74 ('', '', 0)
75 """
75 """
76 parts = rev.rsplit('@', 1)
76 parts = rev.rsplit('@', 1)
@@ -154,23 +154,25 b' PLAINHEADERS = {'
154
154
155 def inserthgheader(lines, header, value):
155 def inserthgheader(lines, header, value):
156 """Assuming lines contains a HG patch header, add a header line with value.
156 """Assuming lines contains a HG patch header, add a header line with value.
157 >>> try: inserthgheader([], '# Date ', 'z')
157 >>> try: inserthgheader([], b'# Date ', b'z')
158 ... except ValueError, inst: print "oops"
158 ... except ValueError, inst: print "oops"
159 oops
159 oops
160 >>> inserthgheader(['# HG changeset patch'], '# Date ', 'z')
160 >>> inserthgheader([b'# HG changeset patch'], b'# Date ', b'z')
161 ['# HG changeset patch', '# Date z']
161 ['# HG changeset patch', '# Date z']
162 >>> inserthgheader(['# HG changeset patch', ''], '# Date ', 'z')
162 >>> inserthgheader([b'# HG changeset patch', b''], b'# Date ', b'z')
163 ['# HG changeset patch', '# Date z', '']
163 ['# HG changeset patch', '# Date z', '']
164 >>> inserthgheader(['# HG changeset patch', '# User y'], '# Date ', 'z')
164 >>> inserthgheader([b'# HG changeset patch', b'# User y'], b'# Date ', b'z')
165 ['# HG changeset patch', '# User y', '# Date z']
165 ['# HG changeset patch', '# User y', '# Date z']
166 >>> inserthgheader(['# HG changeset patch', '# Date x', '# User y'],
166 >>> inserthgheader([b'# HG changeset patch', b'# Date x', b'# User y'],
167 ... '# User ', 'z')
167 ... b'# User ', b'z')
168 ['# HG changeset patch', '# Date x', '# User z']
168 ['# HG changeset patch', '# Date x', '# User z']
169 >>> inserthgheader(['# HG changeset patch', '# Date y'], '# Date ', 'z')
169 >>> inserthgheader([b'# HG changeset patch', b'# Date y'], b'# Date ', b'z')
170 ['# HG changeset patch', '# Date z']
170 ['# HG changeset patch', '# Date z']
171 >>> inserthgheader(['# HG changeset patch', '', '# Date y'], '# Date ', 'z')
171 >>> inserthgheader([b'# HG changeset patch', b'', b'# Date y'],
172 ... b'# Date ', b'z')
172 ['# HG changeset patch', '# Date z', '', '# Date y']
173 ['# HG changeset patch', '# Date z', '', '# Date y']
173 >>> inserthgheader(['# HG changeset patch', '# Parent y'], '# Date ', 'z')
174 >>> inserthgheader([b'# HG changeset patch', b'# Parent y'],
175 ... b'# Date ', b'z')
174 ['# HG changeset patch', '# Date z', '# Parent y']
176 ['# HG changeset patch', '# Date z', '# Parent y']
175 """
177 """
176 start = lines.index('# HG changeset patch') + 1
178 start = lines.index('# HG changeset patch') + 1
@@ -194,19 +196,19 b' def inserthgheader(lines, header, value)'
194
196
195 def insertplainheader(lines, header, value):
197 def insertplainheader(lines, header, value):
196 """For lines containing a plain patch header, add a header line with value.
198 """For lines containing a plain patch header, add a header line with value.
197 >>> insertplainheader([], 'Date', 'z')
199 >>> insertplainheader([], b'Date', b'z')
198 ['Date: z']
200 ['Date: z']
199 >>> insertplainheader([''], 'Date', 'z')
201 >>> insertplainheader([b''], b'Date', b'z')
200 ['Date: z', '']
202 ['Date: z', '']
201 >>> insertplainheader(['x'], 'Date', 'z')
203 >>> insertplainheader([b'x'], b'Date', b'z')
202 ['Date: z', '', 'x']
204 ['Date: z', '', 'x']
203 >>> insertplainheader(['From: y', 'x'], 'Date', 'z')
205 >>> insertplainheader([b'From: y', b'x'], b'Date', b'z')
204 ['From: y', 'Date: z', '', 'x']
206 ['From: y', 'Date: z', '', 'x']
205 >>> insertplainheader([' date : x', ' from : y', ''], 'From', 'z')
207 >>> insertplainheader([b' date : x', b' from : y', b''], b'From', b'z')
206 [' date : x', 'From: z', '']
208 [' date : x', 'From: z', '']
207 >>> insertplainheader(['', 'Date: y'], 'Date', 'z')
209 >>> insertplainheader([b'', b'Date: y'], b'Date', b'z')
208 ['Date: z', '', 'Date: y']
210 ['Date: z', '', 'Date: y']
209 >>> insertplainheader(['foo: bar', 'DATE: z', 'x'], 'From', 'y')
211 >>> insertplainheader([b'foo: bar', b'DATE: z', b'x'], b'From', b'y')
210 ['From: y', 'foo: bar', 'DATE: z', '', 'x']
212 ['From: y', 'foo: bar', 'DATE: z', '', 'x']
211 """
213 """
212 newprio = PLAINHEADERS[header.lower()]
214 newprio = PLAINHEADERS[header.lower()]
@@ -91,7 +91,7 b' class RangeableFileObject(object):'
91 Examples:
91 Examples:
92 # expose 10 bytes, starting at byte position 20, from
92 # expose 10 bytes, starting at byte position 20, from
93 # /etc/aliases.
93 # /etc/aliases.
94 >>> fo = RangeableFileObject(file('/etc/passwd', 'r'), (20,30))
94 >>> fo = RangeableFileObject(file(b'/etc/passwd', b'r'), (20,30))
95 # seek seeks within the range (to position 23 in this case)
95 # seek seeks within the range (to position 23 in this case)
96 >>> fo.seek(3)
96 >>> fo.seek(3)
97 # tell tells where your at _within the range_ (position 3 in
97 # tell tells where your at _within the range_ (position 3 in
@@ -27,8 +27,8 b' from . import ('
27
27
28 def _string_escape(text):
28 def _string_escape(text):
29 """
29 """
30 >>> d = {'nl': chr(10), 'bs': chr(92), 'cr': chr(13), 'nul': chr(0)}
30 >>> d = {b'nl': chr(10), b'bs': chr(92), b'cr': chr(13), b'nul': chr(0)}
31 >>> s = "ab%(nl)scd%(bs)s%(bs)sn%(nul)sab%(cr)scd%(bs)s%(nl)s" % d
31 >>> s = b"ab%(nl)scd%(bs)s%(bs)sn%(nul)sab%(cr)scd%(bs)s%(nl)s" % d
32 >>> s
32 >>> s
33 'ab\\ncd\\\\\\\\n\\x00ab\\rcd\\\\\\n'
33 'ab\\ncd\\\\\\\\n\\x00ab\\rcd\\\\\\n'
34 >>> res = _string_escape(s)
34 >>> res = _string_escape(s)
@@ -41,11 +41,11 b' def _string_escape(text):'
41
41
42 def decodeextra(text):
42 def decodeextra(text):
43 """
43 """
44 >>> sorted(decodeextra(encodeextra({'foo': 'bar', 'baz': chr(0) + '2'})
44 >>> sorted(decodeextra(encodeextra({b'foo': b'bar', b'baz': chr(0) + b'2'})
45 ... ).iteritems())
45 ... ).iteritems())
46 [('baz', '\\x002'), ('branch', 'default'), ('foo', 'bar')]
46 [('baz', '\\x002'), ('branch', 'default'), ('foo', 'bar')]
47 >>> sorted(decodeextra(encodeextra({'foo': 'bar',
47 >>> sorted(decodeextra(encodeextra({b'foo': b'bar',
48 ... 'baz': chr(92) + chr(0) + '2'})
48 ... b'baz': chr(92) + chr(0) + b'2'})
49 ... ).iteritems())
49 ... ).iteritems())
50 [('baz', '\\\\\\x002'), ('branch', 'default'), ('foo', 'bar')]
50 [('baz', '\\\\\\x002'), ('branch', 'default'), ('foo', 'bar')]
51 """
51 """
@@ -320,10 +320,10 b' def _effect_str(ui, effect):'
320 def _mergeeffects(text, start, stop):
320 def _mergeeffects(text, start, stop):
321 """Insert start sequence at every occurrence of stop sequence
321 """Insert start sequence at every occurrence of stop sequence
322
322
323 >>> s = _mergeeffects('cyan', '[C]', '|')
323 >>> s = _mergeeffects(b'cyan', b'[C]', b'|')
324 >>> s = _mergeeffects(s + 'yellow', '[Y]', '|')
324 >>> s = _mergeeffects(s + b'yellow', b'[Y]', b'|')
325 >>> s = _mergeeffects('ma' + s + 'genta', '[M]', '|')
325 >>> s = _mergeeffects(b'ma' + s + b'genta', b'[M]', b'|')
326 >>> s = _mergeeffects('red' + s, '[R]', '|')
326 >>> s = _mergeeffects(b'red' + s, b'[R]', b'|')
327 >>> s
327 >>> s
328 '[R]red[M]ma[Y][C]cyan|[R][M][Y]yellow|[R][M]genta|'
328 '[R]red[M]ma[Y][C]cyan|[R][M][Y]yellow|[R][M]genta|'
329 """
329 """
@@ -183,7 +183,7 b' class config(object):'
183 def parselist(value):
183 def parselist(value):
184 """parse a configuration value as a list of comma/space separated strings
184 """parse a configuration value as a list of comma/space separated strings
185
185
186 >>> parselist('this,is "a small" ,test')
186 >>> parselist(b'this,is "a small" ,test')
187 ['this', 'is', 'a small', 'test']
187 ['this', 'is', 'a small', 'test']
188 """
188 """
189
189
@@ -1112,16 +1112,16 b' def _annotatepair(parents, childfctx, ch'
1112 Additionally, if `skipchild` is True, replace all other lines with parent
1112 Additionally, if `skipchild` is True, replace all other lines with parent
1113 annotate data as well such that child is never blamed for any lines.
1113 annotate data as well such that child is never blamed for any lines.
1114
1114
1115 >>> oldfctx = 'old'
1115 >>> oldfctx = b'old'
1116 >>> p1fctx, p2fctx, childfctx = 'p1', 'p2', 'c'
1116 >>> p1fctx, p2fctx, childfctx = b'p1', b'p2', b'c'
1117 >>> olddata = 'a\nb\n'
1117 >>> olddata = b'a\nb\n'
1118 >>> p1data = 'a\nb\nc\n'
1118 >>> p1data = b'a\nb\nc\n'
1119 >>> p2data = 'a\nc\nd\n'
1119 >>> p2data = b'a\nc\nd\n'
1120 >>> childdata = 'a\nb2\nc\nc2\nd\n'
1120 >>> childdata = b'a\nb2\nc\nc2\nd\n'
1121 >>> diffopts = mdiff.diffopts()
1121 >>> diffopts = mdiff.diffopts()
1122
1122
1123 >>> def decorate(text, rev):
1123 >>> def decorate(text, rev):
1124 ... return ([(rev, i) for i in xrange(1, text.count('\n') + 1)], text)
1124 ... return ([(rev, i) for i in xrange(1, text.count(b'\n') + 1)], text)
1125
1125
1126 Basic usage:
1126 Basic usage:
1127
1127
@@ -54,7 +54,7 b' def parsedag(desc):'
54
54
55 Example of a complex graph (output not shown for brevity):
55 Example of a complex graph (output not shown for brevity):
56
56
57 >>> len(list(parsedag("""
57 >>> len(list(parsedag(b"""
58 ...
58 ...
59 ... +3 # 3 nodes in linear run
59 ... +3 # 3 nodes in linear run
60 ... :forkhere # a label for the last of the 3 nodes from above
60 ... :forkhere # a label for the last of the 3 nodes from above
@@ -74,88 +74,88 b' def parsedag(desc):'
74
74
75 Empty list:
75 Empty list:
76
76
77 >>> list(parsedag(""))
77 >>> list(parsedag(b""))
78 []
78 []
79
79
80 A simple linear run:
80 A simple linear run:
81
81
82 >>> list(parsedag("+3"))
82 >>> list(parsedag(b"+3"))
83 [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
83 [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
84
84
85 Some non-standard ways to define such runs:
85 Some non-standard ways to define such runs:
86
86
87 >>> list(parsedag("+1+2"))
87 >>> list(parsedag(b"+1+2"))
88 [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
88 [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
89
89
90 >>> list(parsedag("+1*1*"))
90 >>> list(parsedag(b"+1*1*"))
91 [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
91 [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
92
92
93 >>> list(parsedag("*"))
93 >>> list(parsedag(b"*"))
94 [('n', (0, [-1]))]
94 [('n', (0, [-1]))]
95
95
96 >>> list(parsedag("..."))
96 >>> list(parsedag(b"..."))
97 [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
97 [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [1]))]
98
98
99 A fork and a join, using numeric back references:
99 A fork and a join, using numeric back references:
100
100
101 >>> list(parsedag("+2*2*/2"))
101 >>> list(parsedag(b"+2*2*/2"))
102 [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [0])), ('n', (3, [2, 1]))]
102 [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [0])), ('n', (3, [2, 1]))]
103
103
104 >>> list(parsedag("+2<2+1/2"))
104 >>> list(parsedag(b"+2<2+1/2"))
105 [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [0])), ('n', (3, [2, 1]))]
105 [('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [0])), ('n', (3, [2, 1]))]
106
106
107 Placing a label:
107 Placing a label:
108
108
109 >>> list(parsedag("+1 :mylabel +1"))
109 >>> list(parsedag(b"+1 :mylabel +1"))
110 [('n', (0, [-1])), ('l', (0, 'mylabel')), ('n', (1, [0]))]
110 [('n', (0, [-1])), ('l', (0, 'mylabel')), ('n', (1, [0]))]
111
111
112 An empty label (silly, really):
112 An empty label (silly, really):
113
113
114 >>> list(parsedag("+1:+1"))
114 >>> list(parsedag(b"+1:+1"))
115 [('n', (0, [-1])), ('l', (0, '')), ('n', (1, [0]))]
115 [('n', (0, [-1])), ('l', (0, '')), ('n', (1, [0]))]
116
116
117 Fork and join, but with labels instead of numeric back references:
117 Fork and join, but with labels instead of numeric back references:
118
118
119 >>> list(parsedag("+1:f +1:p2 *f */p2"))
119 >>> list(parsedag(b"+1:f +1:p2 *f */p2"))
120 [('n', (0, [-1])), ('l', (0, 'f')), ('n', (1, [0])), ('l', (1, 'p2')),
120 [('n', (0, [-1])), ('l', (0, 'f')), ('n', (1, [0])), ('l', (1, 'p2')),
121 ('n', (2, [0])), ('n', (3, [2, 1]))]
121 ('n', (2, [0])), ('n', (3, [2, 1]))]
122
122
123 >>> list(parsedag("+1:f +1:p2 <f +1 /p2"))
123 >>> list(parsedag(b"+1:f +1:p2 <f +1 /p2"))
124 [('n', (0, [-1])), ('l', (0, 'f')), ('n', (1, [0])), ('l', (1, 'p2')),
124 [('n', (0, [-1])), ('l', (0, 'f')), ('n', (1, [0])), ('l', (1, 'p2')),
125 ('n', (2, [0])), ('n', (3, [2, 1]))]
125 ('n', (2, [0])), ('n', (3, [2, 1]))]
126
126
127 Restarting from the root:
127 Restarting from the root:
128
128
129 >>> list(parsedag("+1 $ +1"))
129 >>> list(parsedag(b"+1 $ +1"))
130 [('n', (0, [-1])), ('n', (1, [-1]))]
130 [('n', (0, [-1])), ('n', (1, [-1]))]
131
131
132 Annotations, which are meant to introduce sticky state for subsequent nodes:
132 Annotations, which are meant to introduce sticky state for subsequent nodes:
133
133
134 >>> list(parsedag("+1 @ann +1"))
134 >>> list(parsedag(b"+1 @ann +1"))
135 [('n', (0, [-1])), ('a', 'ann'), ('n', (1, [0]))]
135 [('n', (0, [-1])), ('a', 'ann'), ('n', (1, [0]))]
136
136
137 >>> list(parsedag('+1 @"my annotation" +1'))
137 >>> list(parsedag(b'+1 @"my annotation" +1'))
138 [('n', (0, [-1])), ('a', 'my annotation'), ('n', (1, [0]))]
138 [('n', (0, [-1])), ('a', 'my annotation'), ('n', (1, [0]))]
139
139
140 Commands, which are meant to operate on the most recently created node:
140 Commands, which are meant to operate on the most recently created node:
141
141
142 >>> list(parsedag("+1 !cmd +1"))
142 >>> list(parsedag(b"+1 !cmd +1"))
143 [('n', (0, [-1])), ('c', 'cmd'), ('n', (1, [0]))]
143 [('n', (0, [-1])), ('c', 'cmd'), ('n', (1, [0]))]
144
144
145 >>> list(parsedag('+1 !"my command" +1'))
145 >>> list(parsedag(b'+1 !"my command" +1'))
146 [('n', (0, [-1])), ('c', 'my command'), ('n', (1, [0]))]
146 [('n', (0, [-1])), ('c', 'my command'), ('n', (1, [0]))]
147
147
148 >>> list(parsedag('+1 !!my command line\\n +1'))
148 >>> list(parsedag(b'+1 !!my command line\\n +1'))
149 [('n', (0, [-1])), ('C', 'my command line'), ('n', (1, [0]))]
149 [('n', (0, [-1])), ('C', 'my command line'), ('n', (1, [0]))]
150
150
151 Comments, which extend to the end of the line:
151 Comments, which extend to the end of the line:
152
152
153 >>> list(parsedag('+1 # comment\\n+1'))
153 >>> list(parsedag(b'+1 # comment\\n+1'))
154 [('n', (0, [-1])), ('n', (1, [0]))]
154 [('n', (0, [-1])), ('n', (1, [0]))]
155
155
156 Error:
156 Error:
157
157
158 >>> try: list(parsedag('+1 bad'))
158 >>> try: list(parsedag(b'+1 bad'))
159 ... except Exception, e: print(e)
159 ... except Exception, e: print(e)
160 invalid character in dag description: bad...
160 invalid character in dag description: bad...
161
161
@@ -413,52 +413,54 b' def dagtext(dag,'
413
413
414 Linear run:
414 Linear run:
415
415
416 >>> dagtext([('n', (0, [-1])), ('n', (1, [0]))])
416 >>> dagtext([(b'n', (0, [-1])), (b'n', (1, [0]))])
417 '+2'
417 '+2'
418
418
419 Two roots:
419 Two roots:
420
420
421 >>> dagtext([('n', (0, [-1])), ('n', (1, [-1]))])
421 >>> dagtext([(b'n', (0, [-1])), (b'n', (1, [-1]))])
422 '+1 $ +1'
422 '+1 $ +1'
423
423
424 Fork and join:
424 Fork and join:
425
425
426 >>> dagtext([('n', (0, [-1])), ('n', (1, [0])), ('n', (2, [0])),
426 >>> dagtext([(b'n', (0, [-1])), (b'n', (1, [0])), (b'n', (2, [0])),
427 ... ('n', (3, [2, 1]))])
427 ... (b'n', (3, [2, 1]))])
428 '+2 *2 */2'
428 '+2 *2 */2'
429
429
430 Fork and join with labels:
430 Fork and join with labels:
431
431
432 >>> dagtext([('n', (0, [-1])), ('l', (0, 'f')), ('n', (1, [0])),
432 >>> dagtext([(b'n', (0, [-1])), (b'l', (0, b'f')), (b'n', (1, [0])),
433 ... ('l', (1, 'p2')), ('n', (2, [0])), ('n', (3, [2, 1]))])
433 ... (b'l', (1, b'p2')), (b'n', (2, [0])), (b'n', (3, [2, 1]))])
434 '+1 :f +1 :p2 *f */p2'
434 '+1 :f +1 :p2 *f */p2'
435
435
436 Annotations:
436 Annotations:
437
437
438 >>> dagtext([('n', (0, [-1])), ('a', 'ann'), ('n', (1, [0]))])
438 >>> dagtext([(b'n', (0, [-1])), (b'a', b'ann'), (b'n', (1, [0]))])
439 '+1 @ann +1'
439 '+1 @ann +1'
440
440
441 >>> dagtext([('n', (0, [-1])),
441 >>> dagtext([(b'n', (0, [-1])),
442 ... ('a', 'my annotation'),
442 ... (b'a', b'my annotation'),
443 ... ('n', (1, [0]))])
443 ... (b'n', (1, [0]))])
444 '+1 @"my annotation" +1'
444 '+1 @"my annotation" +1'
445
445
446 Commands:
446 Commands:
447
447
448 >>> dagtext([('n', (0, [-1])), ('c', 'cmd'), ('n', (1, [0]))])
448 >>> dagtext([(b'n', (0, [-1])), (b'c', b'cmd'), (b'n', (1, [0]))])
449 '+1 !cmd +1'
449 '+1 !cmd +1'
450
450
451 >>> dagtext([('n', (0, [-1])), ('c', 'my command'), ('n', (1, [0]))])
451 >>> dagtext([(b'n', (0, [-1])),
452 ... (b'c', b'my command'),
453 ... (b'n', (1, [0]))])
452 '+1 !"my command" +1'
454 '+1 !"my command" +1'
453
455
454 >>> dagtext([('n', (0, [-1])),
456 >>> dagtext([(b'n', (0, [-1])),
455 ... ('C', 'my command line'),
457 ... (b'C', b'my command line'),
456 ... ('n', (1, [0]))])
458 ... (b'n', (1, [0]))])
457 '+1 !!my command line\\n+1'
459 '+1 !!my command line\\n+1'
458
460
459 Comments:
461 Comments:
460
462
461 >>> dagtext([('n', (0, [-1])), ('#', ' comment'), ('n', (1, [0]))])
463 >>> dagtext([(b'n', (0, [-1])), (b'#', b' comment'), (b'n', (1, [0]))])
462 '+1 # comment\\n+1'
464 '+1 # comment\\n+1'
463
465
464 >>> dagtext([])
466 >>> dagtext([])
@@ -466,7 +468,7 b' def dagtext(dag,'
466
468
467 Combining parsedag and dagtext:
469 Combining parsedag and dagtext:
468
470
469 >>> dagtext(parsedag('+1 :f +1 :p2 *f */p2'))
471 >>> dagtext(parsedag(b'+1 :f +1 :p2 *f */p2'))
470 '+1 :f +1 :p2 *f */p2'
472 '+1 :f +1 :p2 *f */p2'
471
473
472 '''
474 '''
@@ -607,20 +607,20 b' def _earlygetopt(aliases, args):'
607 The values are listed in the order they appear in args.
607 The values are listed in the order they appear in args.
608 The options and values are removed from args.
608 The options and values are removed from args.
609
609
610 >>> args = ['x', '--cwd', 'foo', 'y']
610 >>> args = [b'x', b'--cwd', b'foo', b'y']
611 >>> _earlygetopt(['--cwd'], args), args
611 >>> _earlygetopt([b'--cwd'], args), args
612 (['foo'], ['x', 'y'])
612 (['foo'], ['x', 'y'])
613
613
614 >>> args = ['x', '--cwd=bar', 'y']
614 >>> args = [b'x', b'--cwd=bar', b'y']
615 >>> _earlygetopt(['--cwd'], args), args
615 >>> _earlygetopt([b'--cwd'], args), args
616 (['bar'], ['x', 'y'])
616 (['bar'], ['x', 'y'])
617
617
618 >>> args = ['x', '-R', 'foo', 'y']
618 >>> args = [b'x', b'-R', b'foo', b'y']
619 >>> _earlygetopt(['-R'], args), args
619 >>> _earlygetopt([b'-R'], args), args
620 (['foo'], ['x', 'y'])
620 (['foo'], ['x', 'y'])
621
621
622 >>> args = ['x', '-Rbar', 'y']
622 >>> args = [b'x', b'-Rbar', b'y']
623 >>> _earlygetopt(['-R'], args), args
623 >>> _earlygetopt([b'-R'], args), args
624 (['bar'], ['x', 'y'])
624 (['bar'], ['x', 'y'])
625 """
625 """
626 try:
626 try:
@@ -108,19 +108,19 b' def tolocal(s):'
108 strings next to their local representation to allow lossless
108 strings next to their local representation to allow lossless
109 round-trip conversion back to UTF-8.
109 round-trip conversion back to UTF-8.
110
110
111 >>> u = 'foo: \\xc3\\xa4' # utf-8
111 >>> u = b'foo: \\xc3\\xa4' # utf-8
112 >>> l = tolocal(u)
112 >>> l = tolocal(u)
113 >>> l
113 >>> l
114 'foo: ?'
114 'foo: ?'
115 >>> fromlocal(l)
115 >>> fromlocal(l)
116 'foo: \\xc3\\xa4'
116 'foo: \\xc3\\xa4'
117 >>> u2 = 'foo: \\xc3\\xa1'
117 >>> u2 = b'foo: \\xc3\\xa1'
118 >>> d = { l: 1, tolocal(u2): 2 }
118 >>> d = { l: 1, tolocal(u2): 2 }
119 >>> len(d) # no collision
119 >>> len(d) # no collision
120 2
120 2
121 >>> 'foo: ?' in d
121 >>> b'foo: ?' in d
122 False
122 False
123 >>> l1 = 'foo: \\xe4' # historical latin1 fallback
123 >>> l1 = b'foo: \\xe4' # historical latin1 fallback
124 >>> l = tolocal(l1)
124 >>> l = tolocal(l1)
125 >>> l
125 >>> l
126 'foo: ?'
126 'foo: ?'
@@ -247,10 +247,10 b" def trim(s, width, ellipsis='', leftside"
247 If 'leftside' is True, left side of string 's' is trimmed.
247 If 'leftside' is True, left side of string 's' is trimmed.
248 'ellipsis' is always placed at trimmed side.
248 'ellipsis' is always placed at trimmed side.
249
249
250 >>> ellipsis = '+++'
250 >>> ellipsis = b'+++'
251 >>> from . import encoding
251 >>> from . import encoding
252 >>> encoding.encoding = 'utf-8'
252 >>> encoding.encoding = b'utf-8'
253 >>> t= '1234567890'
253 >>> t = b'1234567890'
254 >>> print trim(t, 12, ellipsis=ellipsis)
254 >>> print trim(t, 12, ellipsis=ellipsis)
255 1234567890
255 1234567890
256 >>> print trim(t, 10, ellipsis=ellipsis)
256 >>> print trim(t, 10, ellipsis=ellipsis)
@@ -285,7 +285,7 b" def trim(s, width, ellipsis='', leftside"
285 +++
285 +++
286 >>> print trim(t, 4, ellipsis=ellipsis, leftside=True)
286 >>> print trim(t, 4, ellipsis=ellipsis, leftside=True)
287 +++
287 +++
288 >>> t = '\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa' # invalid byte sequence
288 >>> t = b'\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa' # invalid byte sequence
289 >>> print trim(t, 12, ellipsis=ellipsis)
289 >>> print trim(t, 12, ellipsis=ellipsis)
290 \x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa
290 \x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa
291 >>> print trim(t, 10, ellipsis=ellipsis)
291 >>> print trim(t, 10, ellipsis=ellipsis)
@@ -406,35 +406,35 b' def jsonescape(s, paranoid=False):'
406
406
407 (escapes are doubled in these tests)
407 (escapes are doubled in these tests)
408
408
409 >>> jsonescape('this is a test')
409 >>> jsonescape(b'this is a test')
410 'this is a test'
410 'this is a test'
411 >>> jsonescape('escape characters: \\0 \\x0b \\x7f')
411 >>> jsonescape(b'escape characters: \\0 \\x0b \\x7f')
412 'escape characters: \\\\u0000 \\\\u000b \\\\u007f'
412 'escape characters: \\\\u0000 \\\\u000b \\\\u007f'
413 >>> jsonescape('escape characters: \\b \\t \\n \\f \\r \\" \\\\')
413 >>> jsonescape(b'escape characters: \\b \\t \\n \\f \\r \\" \\\\')
414 'escape characters: \\\\b \\\\t \\\\n \\\\f \\\\r \\\\" \\\\\\\\'
414 'escape characters: \\\\b \\\\t \\\\n \\\\f \\\\r \\\\" \\\\\\\\'
415 >>> jsonescape('a weird byte: \\xdd')
415 >>> jsonescape(b'a weird byte: \\xdd')
416 'a weird byte: \\xed\\xb3\\x9d'
416 'a weird byte: \\xed\\xb3\\x9d'
417 >>> jsonescape('utf-8: caf\\xc3\\xa9')
417 >>> jsonescape(b'utf-8: caf\\xc3\\xa9')
418 'utf-8: caf\\xc3\\xa9'
418 'utf-8: caf\\xc3\\xa9'
419 >>> jsonescape('')
419 >>> jsonescape(b'')
420 ''
420 ''
421
421
422 If paranoid, non-ascii and common troublesome characters are also escaped.
422 If paranoid, non-ascii and common troublesome characters are also escaped.
423 This is suitable for web output.
423 This is suitable for web output.
424
424
425 >>> s = 'escape characters: \\0 \\x0b \\x7f'
425 >>> s = b'escape characters: \\0 \\x0b \\x7f'
426 >>> assert jsonescape(s) == jsonescape(s, paranoid=True)
426 >>> assert jsonescape(s) == jsonescape(s, paranoid=True)
427 >>> s = 'escape characters: \\b \\t \\n \\f \\r \\" \\\\'
427 >>> s = b'escape characters: \\b \\t \\n \\f \\r \\" \\\\'
428 >>> assert jsonescape(s) == jsonescape(s, paranoid=True)
428 >>> assert jsonescape(s) == jsonescape(s, paranoid=True)
429 >>> jsonescape('escape boundary: \\x7e \\x7f \\xc2\\x80', paranoid=True)
429 >>> jsonescape(b'escape boundary: \\x7e \\x7f \\xc2\\x80', paranoid=True)
430 'escape boundary: ~ \\\\u007f \\\\u0080'
430 'escape boundary: ~ \\\\u007f \\\\u0080'
431 >>> jsonescape('a weird byte: \\xdd', paranoid=True)
431 >>> jsonescape(b'a weird byte: \\xdd', paranoid=True)
432 'a weird byte: \\\\udcdd'
432 'a weird byte: \\\\udcdd'
433 >>> jsonescape('utf-8: caf\\xc3\\xa9', paranoid=True)
433 >>> jsonescape(b'utf-8: caf\\xc3\\xa9', paranoid=True)
434 'utf-8: caf\\\\u00e9'
434 'utf-8: caf\\\\u00e9'
435 >>> jsonescape('non-BMP: \\xf0\\x9d\\x84\\x9e', paranoid=True)
435 >>> jsonescape(b'non-BMP: \\xf0\\x9d\\x84\\x9e', paranoid=True)
436 'non-BMP: \\\\ud834\\\\udd1e'
436 'non-BMP: \\\\ud834\\\\udd1e'
437 >>> jsonescape('<foo@example.org>', paranoid=True)
437 >>> jsonescape(b'<foo@example.org>', paranoid=True)
438 '\\\\u003cfoo@example.org\\\\u003e'
438 '\\\\u003cfoo@example.org\\\\u003e'
439 '''
439 '''
440
440
@@ -531,18 +531,18 b' def fromutf8b(s):'
531 that's was passed through tolocal will remain in UTF-8.
531 that's was passed through tolocal will remain in UTF-8.
532
532
533 >>> roundtrip = lambda x: fromutf8b(toutf8b(x)) == x
533 >>> roundtrip = lambda x: fromutf8b(toutf8b(x)) == x
534 >>> m = "\\xc3\\xa9\\x99abcd"
534 >>> m = b"\\xc3\\xa9\\x99abcd"
535 >>> toutf8b(m)
535 >>> toutf8b(m)
536 '\\xc3\\xa9\\xed\\xb2\\x99abcd'
536 '\\xc3\\xa9\\xed\\xb2\\x99abcd'
537 >>> roundtrip(m)
537 >>> roundtrip(m)
538 True
538 True
539 >>> roundtrip("\\xc2\\xc2\\x80")
539 >>> roundtrip(b"\\xc2\\xc2\\x80")
540 True
540 True
541 >>> roundtrip("\\xef\\xbf\\xbd")
541 >>> roundtrip(b"\\xef\\xbf\\xbd")
542 True
542 True
543 >>> roundtrip("\\xef\\xef\\xbf\\xbd")
543 >>> roundtrip(b"\\xef\\xef\\xbf\\xbd")
544 True
544 True
545 >>> roundtrip("\\xf1\\x80\\x80\\x80\\x80")
545 >>> roundtrip(b"\\xf1\\x80\\x80\\x80\\x80")
546 True
546 True
547 '''
547 '''
548
548
@@ -52,14 +52,14 b' Doctest helper:'
52 Basic example:
52 Basic example:
53
53
54 >>> def files(ui, fm):
54 >>> def files(ui, fm):
55 ... files = [('foo', 123, (0, 0)), ('bar', 456, (1, 0))]
55 ... files = [(b'foo', 123, (0, 0)), (b'bar', 456, (1, 0))]
56 ... for f in files:
56 ... for f in files:
57 ... fm.startitem()
57 ... fm.startitem()
58 ... fm.write('path', '%s', f[0])
58 ... fm.write(b'path', b'%s', f[0])
59 ... fm.condwrite(ui.verbose, 'date', ' %s',
59 ... fm.condwrite(ui.verbose, b'date', b' %s',
60 ... fm.formatdate(f[2], '%Y-%m-%d %H:%M:%S'))
60 ... fm.formatdate(f[2], b'%Y-%m-%d %H:%M:%S'))
61 ... fm.data(size=f[1])
61 ... fm.data(size=f[1])
62 ... fm.plain('\\n')
62 ... fm.plain(b'\\n')
63 ... fm.end()
63 ... fm.end()
64 >>> show(files)
64 >>> show(files)
65 foo
65 foo
@@ -67,7 +67,7 b' bar'
67 >>> show(files, verbose=True)
67 >>> show(files, verbose=True)
68 foo 1970-01-01 00:00:00
68 foo 1970-01-01 00:00:00
69 bar 1970-01-01 00:00:01
69 bar 1970-01-01 00:00:01
70 >>> show(files, template='json')
70 >>> show(files, template=b'json')
71 [
71 [
72 {
72 {
73 "date": [0, 0],
73 "date": [0, 0],
@@ -80,7 +80,7 b' bar 1970-01-01 00:00:01'
80 "size": 456
80 "size": 456
81 }
81 }
82 ]
82 ]
83 >>> show(files, template='path: {path}\\ndate: {date|rfc3339date}\\n')
83 >>> show(files, template=b'path: {path}\\ndate: {date|rfc3339date}\\n')
84 path: foo
84 path: foo
85 date: 1970-01-01T00:00:00+00:00
85 date: 1970-01-01T00:00:00+00:00
86 path: bar
86 path: bar
@@ -90,14 +90,14 b' Nested example:'
90
90
91 >>> def subrepos(ui, fm):
91 >>> def subrepos(ui, fm):
92 ... fm.startitem()
92 ... fm.startitem()
93 ... fm.write('repo', '[%s]\\n', 'baz')
93 ... fm.write(b'repo', b'[%s]\\n', b'baz')
94 ... files(ui, fm.nested('files'))
94 ... files(ui, fm.nested(b'files'))
95 ... fm.end()
95 ... fm.end()
96 >>> show(subrepos)
96 >>> show(subrepos)
97 [baz]
97 [baz]
98 foo
98 foo
99 bar
99 bar
100 >>> show(subrepos, template='{repo}: {join(files % "{path}", ", ")}\\n')
100 >>> show(subrepos, template=b'{repo}: {join(files % "{path}", ", ")}\\n')
101 baz: foo, bar
101 baz: foo, bar
102 """
102 """
103
103
@@ -180,17 +180,17 b' def peer(uiorrepo, opts, path, create=Fa'
180 def defaultdest(source):
180 def defaultdest(source):
181 '''return default destination of clone if none is given
181 '''return default destination of clone if none is given
182
182
183 >>> defaultdest('foo')
183 >>> defaultdest(b'foo')
184 'foo'
184 'foo'
185 >>> defaultdest('/foo/bar')
185 >>> defaultdest(b'/foo/bar')
186 'bar'
186 'bar'
187 >>> defaultdest('/')
187 >>> defaultdest(b'/')
188 ''
188 ''
189 >>> defaultdest('')
189 >>> defaultdest(b'')
190 ''
190 ''
191 >>> defaultdest('http://example.org/')
191 >>> defaultdest(b'http://example.org/')
192 ''
192 ''
193 >>> defaultdest('http://example.org/foo/')
193 >>> defaultdest(b'http://example.org/foo/')
194 'foo'
194 'foo'
195 '''
195 '''
196 path = util.url(source).path
196 path = util.url(source).path
@@ -70,9 +70,9 b' def urlrepos(prefix, roothead, paths):'
70 """yield url paths and filesystem paths from a list of repo paths
70 """yield url paths and filesystem paths from a list of repo paths
71
71
72 >>> conv = lambda seq: [(v, util.pconvert(p)) for v,p in seq]
72 >>> conv = lambda seq: [(v, util.pconvert(p)) for v,p in seq]
73 >>> conv(urlrepos('hg', '/opt', ['/opt/r', '/opt/r/r', '/opt']))
73 >>> conv(urlrepos(b'hg', b'/opt', [b'/opt/r', b'/opt/r/r', b'/opt']))
74 [('hg/r', '/opt/r'), ('hg/r/r', '/opt/r/r'), ('hg', '/opt')]
74 [('hg/r', '/opt/r'), ('hg/r/r', '/opt/r/r'), ('hg', '/opt')]
75 >>> conv(urlrepos('', '/opt', ['/opt/r', '/opt/r/r', '/opt']))
75 >>> conv(urlrepos(b'', b'/opt', [b'/opt/r', b'/opt/r/r', b'/opt']))
76 [('r', '/opt/r'), ('r/r', '/opt/r/r'), ('', '/opt')]
76 [('r', '/opt/r'), ('r/r', '/opt/r/r'), ('', '/opt')]
77 """
77 """
78 for path in paths:
78 for path in paths:
@@ -84,17 +84,17 b' def geturlcgivars(baseurl, port):'
84 """
84 """
85 Extract CGI variables from baseurl
85 Extract CGI variables from baseurl
86
86
87 >>> geturlcgivars("http://host.org/base", "80")
87 >>> geturlcgivars(b"http://host.org/base", b"80")
88 ('host.org', '80', '/base')
88 ('host.org', '80', '/base')
89 >>> geturlcgivars("http://host.org:8000/base", "80")
89 >>> geturlcgivars(b"http://host.org:8000/base", b"80")
90 ('host.org', '8000', '/base')
90 ('host.org', '8000', '/base')
91 >>> geturlcgivars('/base', 8000)
91 >>> geturlcgivars(b'/base', 8000)
92 ('', '8000', '/base')
92 ('', '8000', '/base')
93 >>> geturlcgivars("base", '8000')
93 >>> geturlcgivars(b"base", b'8000')
94 ('', '8000', '/base')
94 ('', '8000', '/base')
95 >>> geturlcgivars("http://host", '8000')
95 >>> geturlcgivars(b"http://host", b'8000')
96 ('host', '8000', '/')
96 ('host', '8000', '/')
97 >>> geturlcgivars("http://host/", '8000')
97 >>> geturlcgivars(b"http://host/", b'8000')
98 ('host', '8000', '/')
98 ('host', '8000', '/')
99 """
99 """
100 u = util.url(baseurl)
100 u = util.url(baseurl)
@@ -580,28 +580,28 b' class subdirmatcher(basematcher):'
580
580
581 The paths are remapped to remove/insert the path as needed:
581 The paths are remapped to remove/insert the path as needed:
582
582
583 >>> m1 = match('root', '', ['a.txt', 'sub/b.txt'])
583 >>> m1 = match(b'root', b'', [b'a.txt', b'sub/b.txt'])
584 >>> m2 = subdirmatcher('sub', m1)
584 >>> m2 = subdirmatcher(b'sub', m1)
585 >>> bool(m2('a.txt'))
585 >>> bool(m2(b'a.txt'))
586 False
586 False
587 >>> bool(m2('b.txt'))
587 >>> bool(m2(b'b.txt'))
588 True
588 True
589 >>> bool(m2.matchfn('a.txt'))
589 >>> bool(m2.matchfn(b'a.txt'))
590 False
590 False
591 >>> bool(m2.matchfn('b.txt'))
591 >>> bool(m2.matchfn(b'b.txt'))
592 True
592 True
593 >>> m2.files()
593 >>> m2.files()
594 ['b.txt']
594 ['b.txt']
595 >>> m2.exact('b.txt')
595 >>> m2.exact(b'b.txt')
596 True
596 True
597 >>> util.pconvert(m2.rel('b.txt'))
597 >>> util.pconvert(m2.rel(b'b.txt'))
598 'sub/b.txt'
598 'sub/b.txt'
599 >>> def bad(f, msg):
599 >>> def bad(f, msg):
600 ... print "%s: %s" % (f, msg)
600 ... print b"%s: %s" % (f, msg)
601 >>> m1.bad = bad
601 >>> m1.bad = bad
602 >>> m2.bad('x.txt', 'No such file')
602 >>> m2.bad(b'x.txt', b'No such file')
603 sub/x.txt: No such file
603 sub/x.txt: No such file
604 >>> m2.abs('c.txt')
604 >>> m2.abs(b'c.txt')
605 'sub/c.txt'
605 'sub/c.txt'
606 """
606 """
607
607
@@ -703,21 +703,21 b' def _patsplit(pattern, default):'
703 def _globre(pat):
703 def _globre(pat):
704 r'''Convert an extended glob string to a regexp string.
704 r'''Convert an extended glob string to a regexp string.
705
705
706 >>> print _globre(r'?')
706 >>> print _globre(br'?')
707 .
707 .
708 >>> print _globre(r'*')
708 >>> print _globre(br'*')
709 [^/]*
709 [^/]*
710 >>> print _globre(r'**')
710 >>> print _globre(br'**')
711 .*
711 .*
712 >>> print _globre(r'**/a')
712 >>> print _globre(br'**/a')
713 (?:.*/)?a
713 (?:.*/)?a
714 >>> print _globre(r'a/**/b')
714 >>> print _globre(br'a/**/b')
715 a\/(?:.*/)?b
715 a\/(?:.*/)?b
716 >>> print _globre(r'[a*?!^][^b][!c]')
716 >>> print _globre(br'[a*?!^][^b][!c]')
717 [a*?!^][\^b][^c]
717 [a*?!^][\^b][^c]
718 >>> print _globre(r'{a,b}')
718 >>> print _globre(br'{a,b}')
719 (?:a|b)
719 (?:a|b)
720 >>> print _globre(r'.\*\?')
720 >>> print _globre(br'.\*\?')
721 \.\*\?
721 \.\*\?
722 '''
722 '''
723 i, n = 0, len(pat)
723 i, n = 0, len(pat)
@@ -910,17 +910,20 b' def _rootsanddirs(kindpats):'
910 include directories that need to be implicitly considered as either, such as
910 include directories that need to be implicitly considered as either, such as
911 parent directories.
911 parent directories.
912
912
913 >>> _rootsanddirs(\
913 >>> _rootsanddirs(
914 [('glob', 'g/h/*', ''), ('glob', 'g/h', ''), ('glob', 'g*', '')])
914 ... [(b'glob', b'g/h/*', b''), (b'glob', b'g/h', b''),
915 ... (b'glob', b'g*', b'')])
915 (['g/h', 'g/h', '.'], ['g', '.'])
916 (['g/h', 'g/h', '.'], ['g', '.'])
916 >>> _rootsanddirs(\
917 >>> _rootsanddirs(
917 [('rootfilesin', 'g/h', ''), ('rootfilesin', '', '')])
918 ... [(b'rootfilesin', b'g/h', b''), (b'rootfilesin', b'', b'')])
918 ([], ['g/h', '.', 'g', '.'])
919 ([], ['g/h', '.', 'g', '.'])
919 >>> _rootsanddirs(\
920 >>> _rootsanddirs(
920 [('relpath', 'r', ''), ('path', 'p/p', ''), ('path', '', '')])
921 ... [(b'relpath', b'r', b''), (b'path', b'p/p', b''),
922 ... (b'path', b'', b'')])
921 (['r', 'p/p', '.'], ['p', '.'])
923 (['r', 'p/p', '.'], ['p', '.'])
922 >>> _rootsanddirs(\
924 >>> _rootsanddirs(
923 [('relglob', 'rg*', ''), ('re', 're/', ''), ('relre', 'rr', '')])
925 ... [(b'relglob', b'rg*', b''), (b're', b're/', b''),
926 ... (b'relre', b'rr', b'')])
924 (['.', '.', '.'], ['.'])
927 (['.', '.', '.'], ['.'])
925 '''
928 '''
926 r, d = _patternrootsanddirs(kindpats)
929 r, d = _patternrootsanddirs(kindpats)
@@ -937,9 +940,9 b' def _rootsanddirs(kindpats):'
937 def _explicitfiles(kindpats):
940 def _explicitfiles(kindpats):
938 '''Returns the potential explicit filenames from the patterns.
941 '''Returns the potential explicit filenames from the patterns.
939
942
940 >>> _explicitfiles([('path', 'foo/bar', '')])
943 >>> _explicitfiles([(b'path', b'foo/bar', b'')])
941 ['foo/bar']
944 ['foo/bar']
942 >>> _explicitfiles([('rootfilesin', 'foo/bar', '')])
945 >>> _explicitfiles([(b'rootfilesin', b'foo/bar', b'')])
943 []
946 []
944 '''
947 '''
945 # Keep only the pattern kinds where one can specify filenames (vs only
948 # Keep only the pattern kinds where one can specify filenames (vs only
@@ -46,13 +46,13 b' def replace(text, substs):'
46 '''
46 '''
47 Apply a list of (find, replace) pairs to a text.
47 Apply a list of (find, replace) pairs to a text.
48
48
49 >>> replace("foo bar", [('f', 'F'), ('b', 'B')])
49 >>> replace(b"foo bar", [(b'f', b'F'), (b'b', b'B')])
50 'Foo Bar'
50 'Foo Bar'
51 >>> encoding.encoding = 'latin1'
51 >>> encoding.encoding = b'latin1'
52 >>> replace('\\x81\\\\', [('\\\\', '/')])
52 >>> replace(b'\\x81\\\\', [(b'\\\\', b'/')])
53 '\\x81/'
53 '\\x81/'
54 >>> encoding.encoding = 'shiftjis'
54 >>> encoding.encoding = b'shiftjis'
55 >>> replace('\\x81\\\\', [('\\\\', '/')])
55 >>> replace(b'\\x81\\\\', [(b'\\\\', b'/')])
56 '\\x81\\\\'
56 '\\x81\\\\'
57 '''
57 '''
58
58
@@ -97,15 +97,15 b' class parser(object):'
97 def splitargspec(spec):
97 def splitargspec(spec):
98 """Parse spec of function arguments into (poskeys, varkey, keys, optkey)
98 """Parse spec of function arguments into (poskeys, varkey, keys, optkey)
99
99
100 >>> splitargspec('')
100 >>> splitargspec(b'')
101 ([], None, [], None)
101 ([], None, [], None)
102 >>> splitargspec('foo bar')
102 >>> splitargspec(b'foo bar')
103 ([], None, ['foo', 'bar'], None)
103 ([], None, ['foo', 'bar'], None)
104 >>> splitargspec('foo *bar baz **qux')
104 >>> splitargspec(b'foo *bar baz **qux')
105 (['foo'], 'bar', ['baz'], 'qux')
105 (['foo'], 'bar', ['baz'], 'qux')
106 >>> splitargspec('*foo')
106 >>> splitargspec(b'*foo')
107 ([], 'foo', [], None)
107 ([], 'foo', [], None)
108 >>> splitargspec('**foo')
108 >>> splitargspec(b'**foo')
109 ([], None, [], 'foo')
109 ([], None, [], 'foo')
110 """
110 """
111 optkey = None
111 optkey = None
@@ -221,39 +221,39 b' def simplifyinfixops(tree, targetnodes):'
221 """Flatten chained infix operations to reduce usage of Python stack
221 """Flatten chained infix operations to reduce usage of Python stack
222
222
223 >>> def f(tree):
223 >>> def f(tree):
224 ... print prettyformat(simplifyinfixops(tree, ('or',)), ('symbol',))
224 ... print prettyformat(simplifyinfixops(tree, (b'or',)), (b'symbol',))
225 >>> f(('or',
225 >>> f((b'or',
226 ... ('or',
226 ... (b'or',
227 ... ('symbol', '1'),
227 ... (b'symbol', b'1'),
228 ... ('symbol', '2')),
228 ... (b'symbol', b'2')),
229 ... ('symbol', '3')))
229 ... (b'symbol', b'3')))
230 (or
230 (or
231 (symbol '1')
231 (symbol '1')
232 (symbol '2')
232 (symbol '2')
233 (symbol '3'))
233 (symbol '3'))
234 >>> f(('func',
234 >>> f((b'func',
235 ... ('symbol', 'p1'),
235 ... (b'symbol', b'p1'),
236 ... ('or',
236 ... (b'or',
237 ... ('or',
237 ... (b'or',
238 ... ('func',
238 ... (b'func',
239 ... ('symbol', 'sort'),
239 ... (b'symbol', b'sort'),
240 ... ('list',
240 ... (b'list',
241 ... ('or',
241 ... (b'or',
242 ... ('or',
242 ... (b'or',
243 ... ('symbol', '1'),
243 ... (b'symbol', b'1'),
244 ... ('symbol', '2')),
244 ... (b'symbol', b'2')),
245 ... ('symbol', '3')),
245 ... (b'symbol', b'3')),
246 ... ('negate',
246 ... (b'negate',
247 ... ('symbol', 'rev')))),
247 ... (b'symbol', b'rev')))),
248 ... ('and',
248 ... (b'and',
249 ... ('symbol', '4'),
249 ... (b'symbol', b'4'),
250 ... ('group',
250 ... (b'group',
251 ... ('or',
251 ... (b'or',
252 ... ('or',
252 ... (b'or',
253 ... ('symbol', '5'),
253 ... (b'symbol', b'5'),
254 ... ('symbol', '6')),
254 ... (b'symbol', b'6')),
255 ... ('symbol', '7'))))),
255 ... (b'symbol', b'7'))))),
256 ... ('symbol', '8'))))
256 ... (b'symbol', b'8'))))
257 (func
257 (func
258 (symbol 'p1')
258 (symbol 'p1')
259 (or
259 (or
@@ -304,13 +304,13 b' def _buildtree(template, placeholder, re'
304 def buildtree(template, placeholder, *repls):
304 def buildtree(template, placeholder, *repls):
305 """Create new tree by substituting placeholders by replacements
305 """Create new tree by substituting placeholders by replacements
306
306
307 >>> _ = ('symbol', '_')
307 >>> _ = (b'symbol', b'_')
308 >>> def f(template, *repls):
308 >>> def f(template, *repls):
309 ... return buildtree(template, _, *repls)
309 ... return buildtree(template, _, *repls)
310 >>> f(('func', ('symbol', 'only'), ('list', _, _)),
310 >>> f((b'func', (b'symbol', b'only'), (b'list', _, _)),
311 ... ('symbol', '1'), ('symbol', '2'))
311 ... ('symbol', '1'), ('symbol', '2'))
312 ('func', ('symbol', 'only'), ('list', ('symbol', '1'), ('symbol', '2')))
312 ('func', ('symbol', 'only'), ('list', ('symbol', '1'), ('symbol', '2')))
313 >>> f(('and', _, ('not', _)), ('symbol', '1'), ('symbol', '2'))
313 >>> f((b'and', _, (b'not', _)), (b'symbol', b'1'), (b'symbol', b'2'))
314 ('and', ('symbol', '1'), ('not', ('symbol', '2')))
314 ('and', ('symbol', '1'), ('not', ('symbol', '2')))
315 """
315 """
316 if not isinstance(placeholder, tuple):
316 if not isinstance(placeholder, tuple):
@@ -339,34 +339,34 b' def matchtree(pattern, tree, placeholder'
339 matched with the placeholder; Otherwise None
339 matched with the placeholder; Otherwise None
340
340
341 >>> def f(pattern, tree):
341 >>> def f(pattern, tree):
342 ... m = matchtree(pattern, tree, _, {'keyvalue', 'list'})
342 ... m = matchtree(pattern, tree, _, {b'keyvalue', b'list'})
343 ... if m:
343 ... if m:
344 ... return m[1:]
344 ... return m[1:]
345
345
346 >>> _ = ('symbol', '_')
346 >>> _ = (b'symbol', b'_')
347 >>> f(('func', ('symbol', 'ancestors'), _),
347 >>> f((b'func', (b'symbol', b'ancestors'), _),
348 ... ('func', ('symbol', 'ancestors'), ('symbol', '1')))
348 ... (b'func', (b'symbol', b'ancestors'), (b'symbol', b'1')))
349 [('symbol', '1')]
349 [('symbol', '1')]
350 >>> f(('func', ('symbol', 'ancestors'), _),
350 >>> f((b'func', (b'symbol', b'ancestors'), _),
351 ... ('func', ('symbol', 'ancestors'), None))
351 ... (b'func', (b'symbol', b'ancestors'), None))
352 >>> f(('range', ('dagrange', _, _), _),
352 >>> f((b'range', (b'dagrange', _, _), _),
353 ... ('range',
353 ... (b'range',
354 ... ('dagrange', ('symbol', '1'), ('symbol', '2')),
354 ... (b'dagrange', (b'symbol', b'1'), (b'symbol', b'2')),
355 ... ('symbol', '3')))
355 ... (b'symbol', b'3')))
356 [('symbol', '1'), ('symbol', '2'), ('symbol', '3')]
356 [('symbol', '1'), ('symbol', '2'), ('symbol', '3')]
357
357
358 The placeholder does not match the specified incomplete nodes because
358 The placeholder does not match the specified incomplete nodes because
359 an incomplete node (e.g. argument list) cannot construct an expression.
359 an incomplete node (e.g. argument list) cannot construct an expression.
360
360
361 >>> f(('func', ('symbol', 'ancestors'), _),
361 >>> f((b'func', (b'symbol', b'ancestors'), _),
362 ... ('func', ('symbol', 'ancestors'),
362 ... (b'func', (b'symbol', b'ancestors'),
363 ... ('list', ('symbol', '1'), ('symbol', '2'))))
363 ... (b'list', (b'symbol', b'1'), (b'symbol', b'2'))))
364
364
365 The placeholder may be omitted, but which shouldn't match a None node.
365 The placeholder may be omitted, but which shouldn't match a None node.
366
366
367 >>> _ = None
367 >>> _ = None
368 >>> f(('func', ('symbol', 'ancestors'), None),
368 >>> f((b'func', (b'symbol', b'ancestors'), None),
369 ... ('func', ('symbol', 'ancestors'), ('symbol', '0')))
369 ... (b'func', (b'symbol', b'ancestors'), (b'symbol', b'0')))
370 """
370 """
371 if placeholder is not None and not isinstance(placeholder, tuple):
371 if placeholder is not None and not isinstance(placeholder, tuple):
372 raise error.ProgrammingError('placeholder must be a node tuple')
372 raise error.ProgrammingError('placeholder must be a node tuple')
@@ -436,27 +436,27 b' class basealiasrules(object):'
436 - ``args``: list of argument names (or None for symbol declaration)
436 - ``args``: list of argument names (or None for symbol declaration)
437 - ``errorstr``: detail about detected error (or None)
437 - ``errorstr``: detail about detected error (or None)
438
438
439 >>> sym = lambda x: ('symbol', x)
439 >>> sym = lambda x: (b'symbol', x)
440 >>> symlist = lambda *xs: ('list',) + tuple(sym(x) for x in xs)
440 >>> symlist = lambda *xs: (b'list',) + tuple(sym(x) for x in xs)
441 >>> func = lambda n, a: ('func', sym(n), a)
441 >>> func = lambda n, a: (b'func', sym(n), a)
442 >>> parsemap = {
442 >>> parsemap = {
443 ... 'foo': sym('foo'),
443 ... b'foo': sym(b'foo'),
444 ... '$foo': sym('$foo'),
444 ... b'$foo': sym(b'$foo'),
445 ... 'foo::bar': ('dagrange', sym('foo'), sym('bar')),
445 ... b'foo::bar': (b'dagrange', sym(b'foo'), sym(b'bar')),
446 ... 'foo()': func('foo', None),
446 ... b'foo()': func(b'foo', None),
447 ... '$foo()': func('$foo', None),
447 ... b'$foo()': func(b'$foo', None),
448 ... 'foo($1, $2)': func('foo', symlist('$1', '$2')),
448 ... b'foo($1, $2)': func(b'foo', symlist(b'$1', b'$2')),
449 ... 'foo(bar_bar, baz.baz)':
449 ... b'foo(bar_bar, baz.baz)':
450 ... func('foo', symlist('bar_bar', 'baz.baz')),
450 ... func(b'foo', symlist(b'bar_bar', b'baz.baz')),
451 ... 'foo(bar($1, $2))':
451 ... b'foo(bar($1, $2))':
452 ... func('foo', func('bar', symlist('$1', '$2'))),
452 ... func(b'foo', func(b'bar', symlist(b'$1', b'$2'))),
453 ... 'foo($1, $2, nested($1, $2))':
453 ... b'foo($1, $2, nested($1, $2))':
454 ... func('foo', (symlist('$1', '$2') +
454 ... func(b'foo', (symlist(b'$1', b'$2') +
455 ... (func('nested', symlist('$1', '$2')),))),
455 ... (func(b'nested', symlist(b'$1', b'$2')),))),
456 ... 'foo("bar")': func('foo', ('string', 'bar')),
456 ... b'foo("bar")': func(b'foo', (b'string', b'bar')),
457 ... 'foo($1, $2': error.ParseError('unexpected token: end', 10),
457 ... b'foo($1, $2': error.ParseError(b'unexpected token: end', 10),
458 ... 'foo("bar': error.ParseError('unterminated string', 5),
458 ... b'foo("bar': error.ParseError(b'unterminated string', 5),
459 ... 'foo($1, $2, $1)': func('foo', symlist('$1', '$2', '$1')),
459 ... b'foo($1, $2, $1)': func(b'foo', symlist(b'$1', b'$2', b'$1')),
460 ... }
460 ... }
461 >>> def parse(expr):
461 >>> def parse(expr):
462 ... x = parsemap[expr]
462 ... x = parsemap[expr]
@@ -464,42 +464,42 b' class basealiasrules(object):'
464 ... raise x
464 ... raise x
465 ... return x
465 ... return x
466 >>> def trygetfunc(tree):
466 >>> def trygetfunc(tree):
467 ... if not tree or tree[0] != 'func' or tree[1][0] != 'symbol':
467 ... if not tree or tree[0] != b'func' or tree[1][0] != b'symbol':
468 ... return None
468 ... return None
469 ... if not tree[2]:
469 ... if not tree[2]:
470 ... return tree[1][1], []
470 ... return tree[1][1], []
471 ... if tree[2][0] == 'list':
471 ... if tree[2][0] == b'list':
472 ... return tree[1][1], list(tree[2][1:])
472 ... return tree[1][1], list(tree[2][1:])
473 ... return tree[1][1], [tree[2]]
473 ... return tree[1][1], [tree[2]]
474 >>> class aliasrules(basealiasrules):
474 >>> class aliasrules(basealiasrules):
475 ... _parse = staticmethod(parse)
475 ... _parse = staticmethod(parse)
476 ... _trygetfunc = staticmethod(trygetfunc)
476 ... _trygetfunc = staticmethod(trygetfunc)
477 >>> builddecl = aliasrules._builddecl
477 >>> builddecl = aliasrules._builddecl
478 >>> builddecl('foo')
478 >>> builddecl(b'foo')
479 ('foo', None, None)
479 ('foo', None, None)
480 >>> builddecl('$foo')
480 >>> builddecl(b'$foo')
481 ('$foo', None, "invalid symbol '$foo'")
481 ('$foo', None, "invalid symbol '$foo'")
482 >>> builddecl('foo::bar')
482 >>> builddecl(b'foo::bar')
483 ('foo::bar', None, 'invalid format')
483 ('foo::bar', None, 'invalid format')
484 >>> builddecl('foo()')
484 >>> builddecl(b'foo()')
485 ('foo', [], None)
485 ('foo', [], None)
486 >>> builddecl('$foo()')
486 >>> builddecl(b'$foo()')
487 ('$foo()', None, "invalid function '$foo'")
487 ('$foo()', None, "invalid function '$foo'")
488 >>> builddecl('foo($1, $2)')
488 >>> builddecl(b'foo($1, $2)')
489 ('foo', ['$1', '$2'], None)
489 ('foo', ['$1', '$2'], None)
490 >>> builddecl('foo(bar_bar, baz.baz)')
490 >>> builddecl(b'foo(bar_bar, baz.baz)')
491 ('foo', ['bar_bar', 'baz.baz'], None)
491 ('foo', ['bar_bar', 'baz.baz'], None)
492 >>> builddecl('foo($1, $2, nested($1, $2))')
492 >>> builddecl(b'foo($1, $2, nested($1, $2))')
493 ('foo($1, $2, nested($1, $2))', None, 'invalid argument list')
493 ('foo($1, $2, nested($1, $2))', None, 'invalid argument list')
494 >>> builddecl('foo(bar($1, $2))')
494 >>> builddecl(b'foo(bar($1, $2))')
495 ('foo(bar($1, $2))', None, 'invalid argument list')
495 ('foo(bar($1, $2))', None, 'invalid argument list')
496 >>> builddecl('foo("bar")')
496 >>> builddecl(b'foo("bar")')
497 ('foo("bar")', None, 'invalid argument list')
497 ('foo("bar")', None, 'invalid argument list')
498 >>> builddecl('foo($1, $2')
498 >>> builddecl(b'foo($1, $2')
499 ('foo($1, $2', None, 'at 10: unexpected token: end')
499 ('foo($1, $2', None, 'at 10: unexpected token: end')
500 >>> builddecl('foo("bar')
500 >>> builddecl(b'foo("bar')
501 ('foo("bar', None, 'at 5: unterminated string')
501 ('foo("bar', None, 'at 5: unterminated string')
502 >>> builddecl('foo($1, $2, $1)')
502 >>> builddecl(b'foo($1, $2, $1)')
503 ('foo', None, 'argument names collide with each other')
503 ('foo', None, 'argument names collide with each other')
504 """
504 """
505 try:
505 try:
@@ -556,33 +556,36 b' class basealiasrules(object):'
556 is declared as a symbol.
556 is declared as a symbol.
557
557
558 >>> parsemap = {
558 >>> parsemap = {
559 ... '$1 or foo': ('or', ('symbol', '$1'), ('symbol', 'foo')),
559 ... b'$1 or foo': (b'or', (b'symbol', b'$1'), (b'symbol', b'foo')),
560 ... '$1 or $bar': ('or', ('symbol', '$1'), ('symbol', '$bar')),
560 ... b'$1 or $bar':
561 ... '$10 or baz': ('or', ('symbol', '$10'), ('symbol', 'baz')),
561 ... (b'or', (b'symbol', b'$1'), (b'symbol', b'$bar')),
562 ... '"$1" or "foo"': ('or', ('string', '$1'), ('string', 'foo')),
562 ... b'$10 or baz':
563 ... (b'or', (b'symbol', b'$10'), (b'symbol', b'baz')),
564 ... b'"$1" or "foo"':
565 ... (b'or', (b'string', b'$1'), (b'string', b'foo')),
563 ... }
566 ... }
564 >>> class aliasrules(basealiasrules):
567 >>> class aliasrules(basealiasrules):
565 ... _parse = staticmethod(parsemap.__getitem__)
568 ... _parse = staticmethod(parsemap.__getitem__)
566 ... _trygetfunc = staticmethod(lambda x: None)
569 ... _trygetfunc = staticmethod(lambda x: None)
567 >>> builddefn = aliasrules._builddefn
570 >>> builddefn = aliasrules._builddefn
568 >>> def pprint(tree):
571 >>> def pprint(tree):
569 ... print prettyformat(tree, ('_aliasarg', 'string', 'symbol'))
572 ... print prettyformat(tree, (b'_aliasarg', b'string', b'symbol'))
570 >>> args = ['$1', '$2', 'foo']
573 >>> args = [b'$1', b'$2', b'foo']
571 >>> pprint(builddefn('$1 or foo', args))
574 >>> pprint(builddefn(b'$1 or foo', args))
572 (or
575 (or
573 (_aliasarg '$1')
576 (_aliasarg '$1')
574 (_aliasarg 'foo'))
577 (_aliasarg 'foo'))
575 >>> try:
578 >>> try:
576 ... builddefn('$1 or $bar', args)
579 ... builddefn(b'$1 or $bar', args)
577 ... except error.ParseError as inst:
580 ... except error.ParseError as inst:
578 ... print parseerrordetail(inst)
581 ... print parseerrordetail(inst)
579 invalid symbol '$bar'
582 invalid symbol '$bar'
580 >>> args = ['$1', '$10', 'foo']
583 >>> args = [b'$1', b'$10', b'foo']
581 >>> pprint(builddefn('$10 or baz', args))
584 >>> pprint(builddefn(b'$10 or baz', args))
582 (or
585 (or
583 (_aliasarg '$10')
586 (_aliasarg '$10')
584 (symbol 'baz'))
587 (symbol 'baz'))
585 >>> pprint(builddefn('"$1" or "foo"', args))
588 >>> pprint(builddefn(b'"$1" or "foo"', args))
586 (or
589 (or
587 (string '$1')
590 (string '$1')
588 (string 'foo'))
591 (string 'foo'))
@@ -1479,7 +1479,7 b' def reversehunks(hunks):'
1479 This function operates on hunks coming out of patch.filterpatch, that is
1479 This function operates on hunks coming out of patch.filterpatch, that is
1480 a list of the form: [header1, hunk1, hunk2, header2...]. Example usage:
1480 a list of the form: [header1, hunk1, hunk2, header2...]. Example usage:
1481
1481
1482 >>> rawpatch = """diff --git a/folder1/g b/folder1/g
1482 >>> rawpatch = b"""diff --git a/folder1/g b/folder1/g
1483 ... --- a/folder1/g
1483 ... --- a/folder1/g
1484 ... +++ b/folder1/g
1484 ... +++ b/folder1/g
1485 ... @@ -1,7 +1,7 @@
1485 ... @@ -1,7 +1,7 @@
@@ -1541,7 +1541,7 b' def parsepatch(originalchunks, maxcontex'
1541
1541
1542 If maxcontext is not None, trim context lines if necessary.
1542 If maxcontext is not None, trim context lines if necessary.
1543
1543
1544 >>> rawpatch = '''diff --git a/folder1/g b/folder1/g
1544 >>> rawpatch = b'''diff --git a/folder1/g b/folder1/g
1545 ... --- a/folder1/g
1545 ... --- a/folder1/g
1546 ... +++ b/folder1/g
1546 ... +++ b/folder1/g
1547 ... @@ -1,8 +1,10 @@
1547 ... @@ -1,8 +1,10 @@
@@ -1667,17 +1667,17 b' def pathtransform(path, strip, prefix):'
1667
1667
1668 Returns (stripped components, path in repository).
1668 Returns (stripped components, path in repository).
1669
1669
1670 >>> pathtransform('a/b/c', 0, '')
1670 >>> pathtransform(b'a/b/c', 0, b'')
1671 ('', 'a/b/c')
1671 ('', 'a/b/c')
1672 >>> pathtransform(' a/b/c ', 0, '')
1672 >>> pathtransform(b' a/b/c ', 0, b'')
1673 ('', ' a/b/c')
1673 ('', ' a/b/c')
1674 >>> pathtransform(' a/b/c ', 2, '')
1674 >>> pathtransform(b' a/b/c ', 2, b'')
1675 ('a/b/', 'c')
1675 ('a/b/', 'c')
1676 >>> pathtransform('a/b/c', 0, 'd/e/')
1676 >>> pathtransform(b'a/b/c', 0, b'd/e/')
1677 ('', 'd/e/a/b/c')
1677 ('', 'd/e/a/b/c')
1678 >>> pathtransform(' a//b/c ', 2, 'd/e/')
1678 >>> pathtransform(b' a//b/c ', 2, b'd/e/')
1679 ('a//b/', 'd/e/c')
1679 ('a//b/', 'd/e/c')
1680 >>> pathtransform('a/b/c', 3, '')
1680 >>> pathtransform(b'a/b/c', 3, b'')
1681 Traceback (most recent call last):
1681 Traceback (most recent call last):
1682 PatchError: unable to strip away 1 of 3 dirs from a/b/c
1682 PatchError: unable to strip away 1 of 3 dirs from a/b/c
1683 '''
1683 '''
@@ -203,9 +203,9 b' def normasprefix(path):'
203
203
204 See also issue3033 for detail about need of this function.
204 See also issue3033 for detail about need of this function.
205
205
206 >>> normasprefix('/foo/bar').replace(os.sep, '/')
206 >>> normasprefix(b'/foo/bar').replace(os.sep, b'/')
207 '/foo/bar/'
207 '/foo/bar/'
208 >>> normasprefix('/').replace(os.sep, '/')
208 >>> normasprefix(b'/').replace(os.sep, b'/')
209 '/'
209 '/'
210 '''
210 '''
211 d, p = os.path.splitdrive(path)
211 d, p = os.path.splitdrive(path)
@@ -52,14 +52,14 b' def split(p):'
52 '''Same as posixpath.split, but faster
52 '''Same as posixpath.split, but faster
53
53
54 >>> import posixpath
54 >>> import posixpath
55 >>> for f in ['/absolute/path/to/file',
55 >>> for f in [b'/absolute/path/to/file',
56 ... 'relative/path/to/file',
56 ... b'relative/path/to/file',
57 ... 'file_alone',
57 ... b'file_alone',
58 ... 'path/to/directory/',
58 ... b'path/to/directory/',
59 ... '/multiple/path//separators',
59 ... b'/multiple/path//separators',
60 ... '/file_at_root',
60 ... b'/file_at_root',
61 ... '///multiple_leading_separators_at_root',
61 ... b'///multiple_leading_separators_at_root',
62 ... '']:
62 ... b'']:
63 ... assert split(f) == posixpath.split(f), f
63 ... assert split(f) == posixpath.split(f), f
64 '''
64 '''
65 ht = p.rsplit('/', 1)
65 ht = p.rsplit('/', 1)
@@ -342,13 +342,13 b" if pycompat.sysplatform == 'darwin':"
342 - lowercase
342 - lowercase
343 - omit ignored characters [200c-200f, 202a-202e, 206a-206f,feff]
343 - omit ignored characters [200c-200f, 202a-202e, 206a-206f,feff]
344
344
345 >>> normcase('UPPER')
345 >>> normcase(b'UPPER')
346 'upper'
346 'upper'
347 >>> normcase('Caf\xc3\xa9')
347 >>> normcase(b'Caf\xc3\xa9')
348 'cafe\\xcc\\x81'
348 'cafe\\xcc\\x81'
349 >>> normcase('\xc3\x89')
349 >>> normcase(b'\xc3\x89')
350 'e\\xcc\\x81'
350 'e\\xcc\\x81'
351 >>> normcase('\xb8\xca\xc3\xca\xbe\xc8.JPG') # issue3918
351 >>> normcase(b'\xb8\xca\xc3\xca\xbe\xc8.JPG') # issue3918
352 '%b8%ca%c3\\xca\\xbe%c8.jpg'
352 '%b8%ca%c3\\xca\\xbe%c8.jpg'
353 '''
353 '''
354
354
@@ -78,7 +78,7 b' def tokenize(program, lookup=None, symin'
78 letters of symbols, if ``c.isalnum() or c in '-._/@' or ord(c) > 127``.
78 letters of symbols, if ``c.isalnum() or c in '-._/@' or ord(c) > 127``.
79
79
80 Check that @ is a valid unquoted token character (issue3686):
80 Check that @ is a valid unquoted token character (issue3686):
81 >>> list(tokenize("@::"))
81 >>> list(tokenize(b"@::"))
82 [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)]
82 [('symbol', '@', 0), ('::', None, 1), ('end', None, 3)]
83
83
84 '''
84 '''
@@ -252,7 +252,7 b' def _cachedtree(spec):'
252 def _build(tmplspec, *repls):
252 def _build(tmplspec, *repls):
253 """Create raw parsed tree from a template revset statement
253 """Create raw parsed tree from a template revset statement
254
254
255 >>> _build('f(_) and _', ('string', '1'), ('symbol', '2'))
255 >>> _build(b'f(_) and _', (b'string', b'1'), (b'symbol', b'2'))
256 ('and', ('func', ('symbol', 'f'), ('string', '1')), ('symbol', '2'))
256 ('and', ('func', ('symbol', 'f'), ('string', '1')), ('symbol', '2'))
257 """
257 """
258 template = _cachedtree(tmplspec)
258 template = _cachedtree(tmplspec)
@@ -261,10 +261,10 b' def _build(tmplspec, *repls):'
261 def _match(patspec, tree):
261 def _match(patspec, tree):
262 """Test if a tree matches the given pattern statement; return the matches
262 """Test if a tree matches the given pattern statement; return the matches
263
263
264 >>> _match('f(_)', parse('f()'))
264 >>> _match(b'f(_)', parse(b'f()'))
265 >>> _match('f(_)', parse('f(1)'))
265 >>> _match(b'f(_)', parse(b'f(1)'))
266 [('func', ('symbol', 'f'), ('symbol', '1')), ('symbol', '1')]
266 [('func', ('symbol', 'f'), ('symbol', '1')), ('symbol', '1')]
267 >>> _match('f(_)', parse('f(1, 2)'))
267 >>> _match(b'f(_)', parse(b'f(1, 2)'))
268 """
268 """
269 pattern = _cachedtree(patspec)
269 pattern = _cachedtree(patspec)
270 return parser.matchtree(pattern, tree, ('symbol', '_'),
270 return parser.matchtree(pattern, tree, ('symbol', '_'),
@@ -478,13 +478,13 b' def optimize(tree):'
478 def _parsewith(spec, lookup=None, syminitletters=None):
478 def _parsewith(spec, lookup=None, syminitletters=None):
479 """Generate a parse tree of given spec with given tokenizing options
479 """Generate a parse tree of given spec with given tokenizing options
480
480
481 >>> _parsewith('foo($1)', syminitletters=_aliassyminitletters)
481 >>> _parsewith(b'foo($1)', syminitletters=_aliassyminitletters)
482 ('func', ('symbol', 'foo'), ('symbol', '$1'))
482 ('func', ('symbol', 'foo'), ('symbol', '$1'))
483 >>> _parsewith('$1')
483 >>> _parsewith(b'$1')
484 Traceback (most recent call last):
484 Traceback (most recent call last):
485 ...
485 ...
486 ParseError: ("syntax error in revset '$1'", 0)
486 ParseError: ("syntax error in revset '$1'", 0)
487 >>> _parsewith('foo bar')
487 >>> _parsewith(b'foo bar')
488 Traceback (most recent call last):
488 Traceback (most recent call last):
489 ...
489 ...
490 ParseError: ('invalid token', 4)
490 ParseError: ('invalid token', 4)
@@ -554,11 +554,11 b' def parse(spec, lookup=None):'
554 def _quote(s):
554 def _quote(s):
555 r"""Quote a value in order to make it safe for the revset engine.
555 r"""Quote a value in order to make it safe for the revset engine.
556
556
557 >>> _quote('asdf')
557 >>> _quote(b'asdf')
558 "'asdf'"
558 "'asdf'"
559 >>> _quote("asdf'\"")
559 >>> _quote(b"asdf'\"")
560 '\'asdf\\\'"\''
560 '\'asdf\\\'"\''
561 >>> _quote('asdf\'')
561 >>> _quote(b'asdf\'')
562 "'asdf\\''"
562 "'asdf\\''"
563 >>> _quote(1)
563 >>> _quote(1)
564 "'1'"
564 "'1'"
@@ -582,19 +582,19 b' def formatspec(expr, *args):'
582
582
583 Prefixing the type with 'l' specifies a parenthesized list of that type.
583 Prefixing the type with 'l' specifies a parenthesized list of that type.
584
584
585 >>> formatspec('%r:: and %lr', '10 or 11', ("this()", "that()"))
585 >>> formatspec(b'%r:: and %lr', b'10 or 11', (b"this()", b"that()"))
586 '(10 or 11):: and ((this()) or (that()))'
586 '(10 or 11):: and ((this()) or (that()))'
587 >>> formatspec('%d:: and not %d::', 10, 20)
587 >>> formatspec(b'%d:: and not %d::', 10, 20)
588 '10:: and not 20::'
588 '10:: and not 20::'
589 >>> formatspec('%ld or %ld', [], [1])
589 >>> formatspec(b'%ld or %ld', [], [1])
590 "_list('') or 1"
590 "_list('') or 1"
591 >>> formatspec('keyword(%s)', 'foo\\xe9')
591 >>> formatspec(b'keyword(%s)', b'foo\\xe9')
592 "keyword('foo\\\\xe9')"
592 "keyword('foo\\\\xe9')"
593 >>> b = lambda: 'default'
593 >>> b = lambda: b'default'
594 >>> b.branch = b
594 >>> b.branch = b
595 >>> formatspec('branch(%b)', b)
595 >>> formatspec(b'branch(%b)', b)
596 "branch('default')"
596 "branch('default')"
597 >>> formatspec('root(%ls)', ['a', 'b', 'c', 'd'])
597 >>> formatspec(b'root(%ls)', [b'a', b'b', b'c', b'd'])
598 "root(_list('a\\x00b\\x00c\\x00d'))"
598 "root(_list('a\\x00b\\x00c\\x00d'))"
599 '''
599 '''
600
600
@@ -27,13 +27,13 b" parsers = policy.importmod(r'parsers')"
27 # foo.i or foo.d
27 # foo.i or foo.d
28 def _encodedir(path):
28 def _encodedir(path):
29 '''
29 '''
30 >>> _encodedir('data/foo.i')
30 >>> _encodedir(b'data/foo.i')
31 'data/foo.i'
31 'data/foo.i'
32 >>> _encodedir('data/foo.i/bla.i')
32 >>> _encodedir(b'data/foo.i/bla.i')
33 'data/foo.i.hg/bla.i'
33 'data/foo.i.hg/bla.i'
34 >>> _encodedir('data/foo.i.hg/bla.i')
34 >>> _encodedir(b'data/foo.i.hg/bla.i')
35 'data/foo.i.hg.hg/bla.i'
35 'data/foo.i.hg.hg/bla.i'
36 >>> _encodedir('data/foo.i\\ndata/foo.i/bla.i\\ndata/foo.i.hg/bla.i\\n')
36 >>> _encodedir(b'data/foo.i\\ndata/foo.i/bla.i\\ndata/foo.i.hg/bla.i\\n')
37 'data/foo.i\\ndata/foo.i.hg/bla.i\\ndata/foo.i.hg.hg/bla.i\\n'
37 'data/foo.i\\ndata/foo.i.hg/bla.i\\ndata/foo.i.hg.hg/bla.i\\n'
38 '''
38 '''
39 return (path
39 return (path
@@ -45,11 +45,11 b" encodedir = getattr(parsers, 'encodedir'"
45
45
46 def decodedir(path):
46 def decodedir(path):
47 '''
47 '''
48 >>> decodedir('data/foo.i')
48 >>> decodedir(b'data/foo.i')
49 'data/foo.i'
49 'data/foo.i'
50 >>> decodedir('data/foo.i.hg/bla.i')
50 >>> decodedir(b'data/foo.i.hg/bla.i')
51 'data/foo.i/bla.i'
51 'data/foo.i/bla.i'
52 >>> decodedir('data/foo.i.hg.hg/bla.i')
52 >>> decodedir(b'data/foo.i.hg.hg/bla.i')
53 'data/foo.i.hg/bla.i'
53 'data/foo.i.hg/bla.i'
54 '''
54 '''
55 if ".hg/" not in path:
55 if ".hg/" not in path:
@@ -80,24 +80,24 b' def _buildencodefun():'
80 '''
80 '''
81 >>> enc, dec = _buildencodefun()
81 >>> enc, dec = _buildencodefun()
82
82
83 >>> enc('nothing/special.txt')
83 >>> enc(b'nothing/special.txt')
84 'nothing/special.txt'
84 'nothing/special.txt'
85 >>> dec('nothing/special.txt')
85 >>> dec(b'nothing/special.txt')
86 'nothing/special.txt'
86 'nothing/special.txt'
87
87
88 >>> enc('HELLO')
88 >>> enc(b'HELLO')
89 '_h_e_l_l_o'
89 '_h_e_l_l_o'
90 >>> dec('_h_e_l_l_o')
90 >>> dec(b'_h_e_l_l_o')
91 'HELLO'
91 'HELLO'
92
92
93 >>> enc('hello:world?')
93 >>> enc(b'hello:world?')
94 'hello~3aworld~3f'
94 'hello~3aworld~3f'
95 >>> dec('hello~3aworld~3f')
95 >>> dec(b'hello~3aworld~3f')
96 'hello:world?'
96 'hello:world?'
97
97
98 >>> enc('the\x07quick\xADshot')
98 >>> enc(b'the\x07quick\xADshot')
99 'the~07quick~adshot'
99 'the~07quick~adshot'
100 >>> dec('the~07quick~adshot')
100 >>> dec(b'the~07quick~adshot')
101 'the\\x07quick\\xadshot'
101 'the\\x07quick\\xadshot'
102 '''
102 '''
103 e = '_'
103 e = '_'
@@ -133,14 +133,14 b' def _buildencodefun():'
133
133
134 def encodefilename(s):
134 def encodefilename(s):
135 '''
135 '''
136 >>> encodefilename('foo.i/bar.d/bla.hg/hi:world?/HELLO')
136 >>> encodefilename(b'foo.i/bar.d/bla.hg/hi:world?/HELLO')
137 'foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o'
137 'foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o'
138 '''
138 '''
139 return _encodefname(encodedir(s))
139 return _encodefname(encodedir(s))
140
140
141 def decodefilename(s):
141 def decodefilename(s):
142 '''
142 '''
143 >>> decodefilename('foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o')
143 >>> decodefilename(b'foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o')
144 'foo.i/bar.d/bla.hg/hi:world?/HELLO'
144 'foo.i/bar.d/bla.hg/hi:world?/HELLO'
145 '''
145 '''
146 return decodedir(_decodefname(s))
146 return decodedir(_decodefname(s))
@@ -148,13 +148,13 b' def decodefilename(s):'
148 def _buildlowerencodefun():
148 def _buildlowerencodefun():
149 '''
149 '''
150 >>> f = _buildlowerencodefun()
150 >>> f = _buildlowerencodefun()
151 >>> f('nothing/special.txt')
151 >>> f(b'nothing/special.txt')
152 'nothing/special.txt'
152 'nothing/special.txt'
153 >>> f('HELLO')
153 >>> f(b'HELLO')
154 'hello'
154 'hello'
155 >>> f('hello:world?')
155 >>> f(b'hello:world?')
156 'hello~3aworld~3f'
156 'hello~3aworld~3f'
157 >>> f('the\x07quick\xADshot')
157 >>> f(b'the\x07quick\xADshot')
158 'the~07quick~adshot'
158 'the~07quick~adshot'
159 '''
159 '''
160 cmap = dict([(chr(x), chr(x)) for x in xrange(127)])
160 cmap = dict([(chr(x), chr(x)) for x in xrange(127)])
@@ -180,15 +180,15 b' def _auxencode(path, dotencode):'
180 basename (e.g. "aux", "aux.foo"). A directory or file named "foo.aux"
180 basename (e.g. "aux", "aux.foo"). A directory or file named "foo.aux"
181 doesn't need encoding.
181 doesn't need encoding.
182
182
183 >>> s = '.foo/aux.txt/txt.aux/con/prn/nul/foo.'
183 >>> s = b'.foo/aux.txt/txt.aux/con/prn/nul/foo.'
184 >>> _auxencode(s.split('/'), True)
184 >>> _auxencode(s.split(b'/'), True)
185 ['~2efoo', 'au~78.txt', 'txt.aux', 'co~6e', 'pr~6e', 'nu~6c', 'foo~2e']
185 ['~2efoo', 'au~78.txt', 'txt.aux', 'co~6e', 'pr~6e', 'nu~6c', 'foo~2e']
186 >>> s = '.com1com2/lpt9.lpt4.lpt1/conprn/com0/lpt0/foo.'
186 >>> s = b'.com1com2/lpt9.lpt4.lpt1/conprn/com0/lpt0/foo.'
187 >>> _auxencode(s.split('/'), False)
187 >>> _auxencode(s.split(b'/'), False)
188 ['.com1com2', 'lp~749.lpt4.lpt1', 'conprn', 'com0', 'lpt0', 'foo~2e']
188 ['.com1com2', 'lp~749.lpt4.lpt1', 'conprn', 'com0', 'lpt0', 'foo~2e']
189 >>> _auxencode(['foo. '], True)
189 >>> _auxencode([b'foo. '], True)
190 ['foo.~20']
190 ['foo.~20']
191 >>> _auxencode([' .foo'], True)
191 >>> _auxencode([b' .foo'], True)
192 ['~20.foo']
192 ['~20.foo']
193 '''
193 '''
194 for i, n in enumerate(path):
194 for i, n in enumerate(path):
@@ -1388,23 +1388,23 b' class gitsubrepo(abstractsubrepo):'
1388 '''ensure git version is new enough
1388 '''ensure git version is new enough
1389
1389
1390 >>> _checkversion = gitsubrepo._checkversion
1390 >>> _checkversion = gitsubrepo._checkversion
1391 >>> _checkversion('git version 1.6.0')
1391 >>> _checkversion(b'git version 1.6.0')
1392 'ok'
1392 'ok'
1393 >>> _checkversion('git version 1.8.5')
1393 >>> _checkversion(b'git version 1.8.5')
1394 'ok'
1394 'ok'
1395 >>> _checkversion('git version 1.4.0')
1395 >>> _checkversion(b'git version 1.4.0')
1396 'abort'
1396 'abort'
1397 >>> _checkversion('git version 1.5.0')
1397 >>> _checkversion(b'git version 1.5.0')
1398 'warning'
1398 'warning'
1399 >>> _checkversion('git version 1.9-rc0')
1399 >>> _checkversion(b'git version 1.9-rc0')
1400 'ok'
1400 'ok'
1401 >>> _checkversion('git version 1.9.0.265.g81cdec2')
1401 >>> _checkversion(b'git version 1.9.0.265.g81cdec2')
1402 'ok'
1402 'ok'
1403 >>> _checkversion('git version 1.9.0.GIT')
1403 >>> _checkversion(b'git version 1.9.0.GIT')
1404 'ok'
1404 'ok'
1405 >>> _checkversion('git version 12345')
1405 >>> _checkversion(b'git version 12345')
1406 'unknown'
1406 'unknown'
1407 >>> _checkversion('no')
1407 >>> _checkversion(b'no')
1408 'unknown'
1408 'unknown'
1409 '''
1409 '''
1410 version = gitsubrepo._gitversion(out)
1410 version = gitsubrepo._gitversion(out)
@@ -275,19 +275,19 b' def person(author):'
275 """Any text. Returns the name before an email address,
275 """Any text. Returns the name before an email address,
276 interpreting it as per RFC 5322.
276 interpreting it as per RFC 5322.
277
277
278 >>> person('foo@bar')
278 >>> person(b'foo@bar')
279 'foo'
279 'foo'
280 >>> person('Foo Bar <foo@bar>')
280 >>> person(b'Foo Bar <foo@bar>')
281 'Foo Bar'
281 'Foo Bar'
282 >>> person('"Foo Bar" <foo@bar>')
282 >>> person(b'"Foo Bar" <foo@bar>')
283 'Foo Bar'
283 'Foo Bar'
284 >>> person('"Foo \"buz\" Bar" <foo@bar>')
284 >>> person(b'"Foo \"buz\" Bar" <foo@bar>')
285 'Foo "buz" Bar'
285 'Foo "buz" Bar'
286 >>> # The following are invalid, but do exist in real-life
286 >>> # The following are invalid, but do exist in real-life
287 ...
287 ...
288 >>> person('Foo "buz" Bar <foo@bar>')
288 >>> person(b'Foo "buz" Bar <foo@bar>')
289 'Foo "buz" Bar'
289 'Foo "buz" Bar'
290 >>> person('"Foo Bar <foo@bar>')
290 >>> person(b'"Foo Bar <foo@bar>')
291 'Foo Bar'
291 'Foo Bar'
292 """
292 """
293 if '@' not in author:
293 if '@' not in author:
@@ -147,15 +147,15 b' def tokenize(program, start, end, term=N'
147
147
148 def _parsetemplate(tmpl, start, stop, quote=''):
148 def _parsetemplate(tmpl, start, stop, quote=''):
149 r"""
149 r"""
150 >>> _parsetemplate('foo{bar}"baz', 0, 12)
150 >>> _parsetemplate(b'foo{bar}"baz', 0, 12)
151 ([('string', 'foo'), ('symbol', 'bar'), ('string', '"baz')], 12)
151 ([('string', 'foo'), ('symbol', 'bar'), ('string', '"baz')], 12)
152 >>> _parsetemplate('foo{bar}"baz', 0, 12, quote='"')
152 >>> _parsetemplate(b'foo{bar}"baz', 0, 12, quote=b'"')
153 ([('string', 'foo'), ('symbol', 'bar')], 9)
153 ([('string', 'foo'), ('symbol', 'bar')], 9)
154 >>> _parsetemplate('foo"{bar}', 0, 9, quote='"')
154 >>> _parsetemplate(b'foo"{bar}', 0, 9, quote=b'"')
155 ([('string', 'foo')], 4)
155 ([('string', 'foo')], 4)
156 >>> _parsetemplate(r'foo\"bar"baz', 0, 12, quote='"')
156 >>> _parsetemplate(br'foo\"bar"baz', 0, 12, quote=b'"')
157 ([('string', 'foo"'), ('string', 'bar')], 9)
157 ([('string', 'foo"'), ('string', 'bar')], 9)
158 >>> _parsetemplate(r'foo\\"bar', 0, 10, quote='"')
158 >>> _parsetemplate(br'foo\\"bar', 0, 10, quote=b'"')
159 ([('string', 'foo\\')], 6)
159 ([('string', 'foo\\')], 6)
160 """
160 """
161 parsed = []
161 parsed = []
@@ -193,18 +193,18 b' def _unnesttemplatelist(tree):'
193
193
194 >>> def f(tree):
194 >>> def f(tree):
195 ... print prettyformat(_unnesttemplatelist(tree))
195 ... print prettyformat(_unnesttemplatelist(tree))
196 >>> f(('template', []))
196 >>> f((b'template', []))
197 (string '')
197 (string '')
198 >>> f(('template', [('string', 'foo')]))
198 >>> f((b'template', [(b'string', b'foo')]))
199 (string 'foo')
199 (string 'foo')
200 >>> f(('template', [('string', 'foo'), ('symbol', 'rev')]))
200 >>> f((b'template', [(b'string', b'foo'), (b'symbol', b'rev')]))
201 (template
201 (template
202 (string 'foo')
202 (string 'foo')
203 (symbol 'rev'))
203 (symbol 'rev'))
204 >>> f(('template', [('symbol', 'rev')])) # template(rev) -> str
204 >>> f((b'template', [(b'symbol', b'rev')])) # template(rev) -> str
205 (template
205 (template
206 (symbol 'rev'))
206 (symbol 'rev'))
207 >>> f(('template', [('template', [('string', 'foo')])]))
207 >>> f((b'template', [(b'template', [(b'string', b'foo')])]))
208 (string 'foo')
208 (string 'foo')
209 """
209 """
210 if not isinstance(tree, tuple):
210 if not isinstance(tree, tuple):
@@ -231,15 +231,15 b' def parse(tmpl):'
231 def _parseexpr(expr):
231 def _parseexpr(expr):
232 """Parse a template expression into tree
232 """Parse a template expression into tree
233
233
234 >>> _parseexpr('"foo"')
234 >>> _parseexpr(b'"foo"')
235 ('string', 'foo')
235 ('string', 'foo')
236 >>> _parseexpr('foo(bar)')
236 >>> _parseexpr(b'foo(bar)')
237 ('func', ('symbol', 'foo'), ('symbol', 'bar'))
237 ('func', ('symbol', 'foo'), ('symbol', 'bar'))
238 >>> _parseexpr('foo(')
238 >>> _parseexpr(b'foo(')
239 Traceback (most recent call last):
239 Traceback (most recent call last):
240 ...
240 ...
241 ParseError: ('not a prefix: end', 4)
241 ParseError: ('not a prefix: end', 4)
242 >>> _parseexpr('"foo" "bar"')
242 >>> _parseexpr(b'"foo" "bar"')
243 Traceback (most recent call last):
243 Traceback (most recent call last):
244 ...
244 ...
245 ParseError: ('invalid token', 7)
245 ParseError: ('invalid token', 7)
@@ -489,10 +489,10 b' def _buildfuncargs(exp, context, curmeth'
489 ... x = _parseexpr(expr)
489 ... x = _parseexpr(expr)
490 ... n = getsymbol(x[1])
490 ... n = getsymbol(x[1])
491 ... return _buildfuncargs(x[2], context, exprmethods, n, argspec)
491 ... return _buildfuncargs(x[2], context, exprmethods, n, argspec)
492 >>> fargs('a(l=1, k=2)', 'k l m').keys()
492 >>> fargs(b'a(l=1, k=2)', b'k l m').keys()
493 ['l', 'k']
493 ['l', 'k']
494 >>> args = fargs('a(opts=1, k=2)', '**opts')
494 >>> args = fargs(b'a(opts=1, k=2)', b'**opts')
495 >>> args.keys(), args['opts'].keys()
495 >>> args.keys(), args[b'opts'].keys()
496 (['opts'], ['opts', 'k'])
496 (['opts'], ['opts', 'k'])
497 """
497 """
498 def compiledict(xs):
498 def compiledict(xs):
@@ -531,19 +531,19 b' class ui(object):'
531 def configbool(self, section, name, default=_unset, untrusted=False):
531 def configbool(self, section, name, default=_unset, untrusted=False):
532 """parse a configuration element as a boolean
532 """parse a configuration element as a boolean
533
533
534 >>> u = ui(); s = 'foo'
534 >>> u = ui(); s = b'foo'
535 >>> u.setconfig(s, 'true', 'yes')
535 >>> u.setconfig(s, b'true', b'yes')
536 >>> u.configbool(s, 'true')
536 >>> u.configbool(s, b'true')
537 True
537 True
538 >>> u.setconfig(s, 'false', 'no')
538 >>> u.setconfig(s, b'false', b'no')
539 >>> u.configbool(s, 'false')
539 >>> u.configbool(s, b'false')
540 False
540 False
541 >>> u.configbool(s, 'unknown')
541 >>> u.configbool(s, b'unknown')
542 False
542 False
543 >>> u.configbool(s, 'unknown', True)
543 >>> u.configbool(s, b'unknown', True)
544 True
544 True
545 >>> u.setconfig(s, 'invalid', 'somevalue')
545 >>> u.setconfig(s, b'invalid', b'somevalue')
546 >>> u.configbool(s, 'invalid')
546 >>> u.configbool(s, b'invalid')
547 Traceback (most recent call last):
547 Traceback (most recent call last):
548 ...
548 ...
549 ConfigError: foo.invalid is not a boolean ('somevalue')
549 ConfigError: foo.invalid is not a boolean ('somevalue')
@@ -568,21 +568,21 b' class ui(object):'
568 desc=None, untrusted=False):
568 desc=None, untrusted=False):
569 """parse a configuration element with a conversion function
569 """parse a configuration element with a conversion function
570
570
571 >>> u = ui(); s = 'foo'
571 >>> u = ui(); s = b'foo'
572 >>> u.setconfig(s, 'float1', '42')
572 >>> u.setconfig(s, b'float1', b'42')
573 >>> u.configwith(float, s, 'float1')
573 >>> u.configwith(float, s, b'float1')
574 42.0
574 42.0
575 >>> u.setconfig(s, 'float2', '-4.25')
575 >>> u.setconfig(s, b'float2', b'-4.25')
576 >>> u.configwith(float, s, 'float2')
576 >>> u.configwith(float, s, b'float2')
577 -4.25
577 -4.25
578 >>> u.configwith(float, s, 'unknown', 7)
578 >>> u.configwith(float, s, b'unknown', 7)
579 7.0
579 7.0
580 >>> u.setconfig(s, 'invalid', 'somevalue')
580 >>> u.setconfig(s, b'invalid', b'somevalue')
581 >>> u.configwith(float, s, 'invalid')
581 >>> u.configwith(float, s, b'invalid')
582 Traceback (most recent call last):
582 Traceback (most recent call last):
583 ...
583 ...
584 ConfigError: foo.invalid is not a valid float ('somevalue')
584 ConfigError: foo.invalid is not a valid float ('somevalue')
585 >>> u.configwith(float, s, 'invalid', desc='womble')
585 >>> u.configwith(float, s, b'invalid', desc=b'womble')
586 Traceback (most recent call last):
586 Traceback (most recent call last):
587 ...
587 ...
588 ConfigError: foo.invalid is not a valid womble ('somevalue')
588 ConfigError: foo.invalid is not a valid womble ('somevalue')
@@ -602,17 +602,17 b' class ui(object):'
602 def configint(self, section, name, default=_unset, untrusted=False):
602 def configint(self, section, name, default=_unset, untrusted=False):
603 """parse a configuration element as an integer
603 """parse a configuration element as an integer
604
604
605 >>> u = ui(); s = 'foo'
605 >>> u = ui(); s = b'foo'
606 >>> u.setconfig(s, 'int1', '42')
606 >>> u.setconfig(s, b'int1', b'42')
607 >>> u.configint(s, 'int1')
607 >>> u.configint(s, b'int1')
608 42
608 42
609 >>> u.setconfig(s, 'int2', '-42')
609 >>> u.setconfig(s, b'int2', b'-42')
610 >>> u.configint(s, 'int2')
610 >>> u.configint(s, b'int2')
611 -42
611 -42
612 >>> u.configint(s, 'unknown', 7)
612 >>> u.configint(s, b'unknown', 7)
613 7
613 7
614 >>> u.setconfig(s, 'invalid', 'somevalue')
614 >>> u.setconfig(s, b'invalid', b'somevalue')
615 >>> u.configint(s, 'invalid')
615 >>> u.configint(s, b'invalid')
616 Traceback (most recent call last):
616 Traceback (most recent call last):
617 ...
617 ...
618 ConfigError: foo.invalid is not a valid integer ('somevalue')
618 ConfigError: foo.invalid is not a valid integer ('somevalue')
@@ -627,17 +627,17 b' class ui(object):'
627 Units can be specified as b (bytes), k or kb (kilobytes), m or
627 Units can be specified as b (bytes), k or kb (kilobytes), m or
628 mb (megabytes), g or gb (gigabytes).
628 mb (megabytes), g or gb (gigabytes).
629
629
630 >>> u = ui(); s = 'foo'
630 >>> u = ui(); s = b'foo'
631 >>> u.setconfig(s, 'val1', '42')
631 >>> u.setconfig(s, b'val1', b'42')
632 >>> u.configbytes(s, 'val1')
632 >>> u.configbytes(s, b'val1')
633 42
633 42
634 >>> u.setconfig(s, 'val2', '42.5 kb')
634 >>> u.setconfig(s, b'val2', b'42.5 kb')
635 >>> u.configbytes(s, 'val2')
635 >>> u.configbytes(s, b'val2')
636 43520
636 43520
637 >>> u.configbytes(s, 'unknown', '7 MB')
637 >>> u.configbytes(s, b'unknown', b'7 MB')
638 7340032
638 7340032
639 >>> u.setconfig(s, 'invalid', 'somevalue')
639 >>> u.setconfig(s, b'invalid', b'somevalue')
640 >>> u.configbytes(s, 'invalid')
640 >>> u.configbytes(s, b'invalid')
641 Traceback (most recent call last):
641 Traceback (most recent call last):
642 ...
642 ...
643 ConfigError: foo.invalid is not a byte quantity ('somevalue')
643 ConfigError: foo.invalid is not a byte quantity ('somevalue')
@@ -660,9 +660,9 b' class ui(object):'
660 """parse a configuration element as a list of comma/space separated
660 """parse a configuration element as a list of comma/space separated
661 strings
661 strings
662
662
663 >>> u = ui(); s = 'foo'
663 >>> u = ui(); s = b'foo'
664 >>> u.setconfig(s, 'list1', 'this,is "a small" ,test')
664 >>> u.setconfig(s, b'list1', b'this,is "a small" ,test')
665 >>> u.configlist(s, 'list1')
665 >>> u.configlist(s, b'list1')
666 ['this', 'is', 'a small', 'test']
666 ['this', 'is', 'a small', 'test']
667 """
667 """
668 # default is not always a list
668 # default is not always a list
@@ -677,9 +677,9 b' class ui(object):'
677 def configdate(self, section, name, default=_unset, untrusted=False):
677 def configdate(self, section, name, default=_unset, untrusted=False):
678 """parse a configuration element as a tuple of ints
678 """parse a configuration element as a tuple of ints
679
679
680 >>> u = ui(); s = 'foo'
680 >>> u = ui(); s = b'foo'
681 >>> u.setconfig(s, 'date', '0 0')
681 >>> u.setconfig(s, b'date', b'0 0')
682 >>> u.configdate(s, 'date')
682 >>> u.configdate(s, b'date')
683 (0, 0)
683 (0, 0)
684 """
684 """
685 if self.config(section, name, default, untrusted):
685 if self.config(section, name, default, untrusted):
@@ -1256,11 +1256,11 b' class ui(object):'
1256 This returns tuple "(message, choices)", and "choices" is the
1256 This returns tuple "(message, choices)", and "choices" is the
1257 list of tuple "(response character, text without &)".
1257 list of tuple "(response character, text without &)".
1258
1258
1259 >>> ui.extractchoices("awake? $$ &Yes $$ &No")
1259 >>> ui.extractchoices(b"awake? $$ &Yes $$ &No")
1260 ('awake? ', [('y', 'Yes'), ('n', 'No')])
1260 ('awake? ', [('y', 'Yes'), ('n', 'No')])
1261 >>> ui.extractchoices("line\\nbreak? $$ &Yes $$ &No")
1261 >>> ui.extractchoices(b"line\\nbreak? $$ &Yes $$ &No")
1262 ('line\\nbreak? ', [('y', 'Yes'), ('n', 'No')])
1262 ('line\\nbreak? ', [('y', 'Yes'), ('n', 'No')])
1263 >>> ui.extractchoices("want lots of $$money$$?$$Ye&s$$N&o")
1263 >>> ui.extractchoices(b"want lots of $$money$$?$$Ye&s$$N&o")
1264 ('want lots of $$money$$?', [('s', 'Yes'), ('o', 'No')])
1264 ('want lots of $$money$$?', [('s', 'Yes'), ('o', 'No')])
1265 """
1265 """
1266
1266
@@ -227,15 +227,15 b' class digester(object):'
227
227
228 This helper can be used to compute one or more digests given their name.
228 This helper can be used to compute one or more digests given their name.
229
229
230 >>> d = digester(['md5', 'sha1'])
230 >>> d = digester([b'md5', b'sha1'])
231 >>> d.update('foo')
231 >>> d.update(b'foo')
232 >>> [k for k in sorted(d)]
232 >>> [k for k in sorted(d)]
233 ['md5', 'sha1']
233 ['md5', 'sha1']
234 >>> d['md5']
234 >>> d[b'md5']
235 'acbd18db4cc2f85cedef654fccc4a4d8'
235 'acbd18db4cc2f85cedef654fccc4a4d8'
236 >>> d['sha1']
236 >>> d[b'sha1']
237 '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
237 '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33'
238 >>> digester.preferred(['md5', 'sha1'])
238 >>> digester.preferred([b'md5', b'sha1'])
239 'sha1'
239 'sha1'
240 """
240 """
241
241
@@ -448,7 +448,7 b' def versiontuple(v=None, n=4):'
448 ``n`` can be 2, 3, or 4. Here is how some version strings map to
448 ``n`` can be 2, 3, or 4. Here is how some version strings map to
449 returned values:
449 returned values:
450
450
451 >>> v = '3.6.1+190-df9b73d2d444'
451 >>> v = b'3.6.1+190-df9b73d2d444'
452 >>> versiontuple(v, 2)
452 >>> versiontuple(v, 2)
453 (3, 6)
453 (3, 6)
454 >>> versiontuple(v, 3)
454 >>> versiontuple(v, 3)
@@ -456,10 +456,10 b' def versiontuple(v=None, n=4):'
456 >>> versiontuple(v, 4)
456 >>> versiontuple(v, 4)
457 (3, 6, 1, '190-df9b73d2d444')
457 (3, 6, 1, '190-df9b73d2d444')
458
458
459 >>> versiontuple('3.6.1+190-df9b73d2d444+20151118')
459 >>> versiontuple(b'3.6.1+190-df9b73d2d444+20151118')
460 (3, 6, 1, '190-df9b73d2d444+20151118')
460 (3, 6, 1, '190-df9b73d2d444+20151118')
461
461
462 >>> v = '3.6'
462 >>> v = b'3.6'
463 >>> versiontuple(v, 2)
463 >>> versiontuple(v, 2)
464 (3, 6)
464 (3, 6)
465 >>> versiontuple(v, 3)
465 >>> versiontuple(v, 3)
@@ -467,7 +467,7 b' def versiontuple(v=None, n=4):'
467 >>> versiontuple(v, 4)
467 >>> versiontuple(v, 4)
468 (3, 6, None, None)
468 (3, 6, None, None)
469
469
470 >>> v = '3.9-rc'
470 >>> v = b'3.9-rc'
471 >>> versiontuple(v, 2)
471 >>> versiontuple(v, 2)
472 (3, 9)
472 (3, 9)
473 >>> versiontuple(v, 3)
473 >>> versiontuple(v, 3)
@@ -475,7 +475,7 b' def versiontuple(v=None, n=4):'
475 >>> versiontuple(v, 4)
475 >>> versiontuple(v, 4)
476 (3, 9, None, 'rc')
476 (3, 9, None, 'rc')
477
477
478 >>> v = '3.9-rc+2-02a8fea4289b'
478 >>> v = b'3.9-rc+2-02a8fea4289b'
479 >>> versiontuple(v, 2)
479 >>> versiontuple(v, 2)
480 (3, 9)
480 (3, 9)
481 >>> versiontuple(v, 3)
481 >>> versiontuple(v, 3)
@@ -579,11 +579,11 b' def cachefunc(func):'
579 class sortdict(collections.OrderedDict):
579 class sortdict(collections.OrderedDict):
580 '''a simple sorted dictionary
580 '''a simple sorted dictionary
581
581
582 >>> d1 = sortdict([('a', 0), ('b', 1)])
582 >>> d1 = sortdict([(b'a', 0), (b'b', 1)])
583 >>> d2 = d1.copy()
583 >>> d2 = d1.copy()
584 >>> d2
584 >>> d2
585 sortdict([('a', 0), ('b', 1)])
585 sortdict([('a', 0), ('b', 1)])
586 >>> d2.update([('a', 2)])
586 >>> d2.update([(b'a', 2)])
587 >>> d2.keys() # should still be in last-set order
587 >>> d2.keys() # should still be in last-set order
588 ['b', 'a']
588 ['b', 'a']
589 '''
589 '''
@@ -1240,24 +1240,24 b' def checkwinfilename(path):'
1240 r'''Check that the base-relative path is a valid filename on Windows.
1240 r'''Check that the base-relative path is a valid filename on Windows.
1241 Returns None if the path is ok, or a UI string describing the problem.
1241 Returns None if the path is ok, or a UI string describing the problem.
1242
1242
1243 >>> checkwinfilename("just/a/normal/path")
1243 >>> checkwinfilename(b"just/a/normal/path")
1244 >>> checkwinfilename("foo/bar/con.xml")
1244 >>> checkwinfilename(b"foo/bar/con.xml")
1245 "filename contains 'con', which is reserved on Windows"
1245 "filename contains 'con', which is reserved on Windows"
1246 >>> checkwinfilename("foo/con.xml/bar")
1246 >>> checkwinfilename(b"foo/con.xml/bar")
1247 "filename contains 'con', which is reserved on Windows"
1247 "filename contains 'con', which is reserved on Windows"
1248 >>> checkwinfilename("foo/bar/xml.con")
1248 >>> checkwinfilename(b"foo/bar/xml.con")
1249 >>> checkwinfilename("foo/bar/AUX/bla.txt")
1249 >>> checkwinfilename(b"foo/bar/AUX/bla.txt")
1250 "filename contains 'AUX', which is reserved on Windows"
1250 "filename contains 'AUX', which is reserved on Windows"
1251 >>> checkwinfilename("foo/bar/bla:.txt")
1251 >>> checkwinfilename(b"foo/bar/bla:.txt")
1252 "filename contains ':', which is reserved on Windows"
1252 "filename contains ':', which is reserved on Windows"
1253 >>> checkwinfilename("foo/bar/b\07la.txt")
1253 >>> checkwinfilename(b"foo/bar/b\07la.txt")
1254 "filename contains '\\x07', which is invalid on Windows"
1254 "filename contains '\\x07', which is invalid on Windows"
1255 >>> checkwinfilename("foo/bar/bla ")
1255 >>> checkwinfilename(b"foo/bar/bla ")
1256 "filename ends with ' ', which is not allowed on Windows"
1256 "filename ends with ' ', which is not allowed on Windows"
1257 >>> checkwinfilename("../bar")
1257 >>> checkwinfilename(b"../bar")
1258 >>> checkwinfilename("foo\\")
1258 >>> checkwinfilename(b"foo\\")
1259 "filename ends with '\\', which is invalid on Windows"
1259 "filename ends with '\\', which is invalid on Windows"
1260 >>> checkwinfilename("foo\\/bar")
1260 >>> checkwinfilename(b"foo\\/bar")
1261 "directory name ends with '\\', which is invalid on Windows"
1261 "directory name ends with '\\', which is invalid on Windows"
1262 '''
1262 '''
1263 if path.endswith('\\'):
1263 if path.endswith('\\'):
@@ -1994,15 +1994,15 b' def parsedate(date, formats=None, bias=N'
1994 The date may be a "unixtime offset" string or in one of the specified
1994 The date may be a "unixtime offset" string or in one of the specified
1995 formats. If the date already is a (unixtime, offset) tuple, it is returned.
1995 formats. If the date already is a (unixtime, offset) tuple, it is returned.
1996
1996
1997 >>> parsedate(' today ') == parsedate(\
1997 >>> parsedate(b' today ') == parsedate(\
1998 datetime.date.today().strftime('%b %d'))
1998 datetime.date.today().strftime('%b %d'))
1999 True
1999 True
2000 >>> parsedate( 'yesterday ') == parsedate((datetime.date.today() -\
2000 >>> parsedate(b'yesterday ') == parsedate((datetime.date.today() -\
2001 datetime.timedelta(days=1)\
2001 datetime.timedelta(days=1)\
2002 ).strftime('%b %d'))
2002 ).strftime('%b %d'))
2003 True
2003 True
2004 >>> now, tz = makedate()
2004 >>> now, tz = makedate()
2005 >>> strnow, strtz = parsedate('now')
2005 >>> strnow, strtz = parsedate(b'now')
2006 >>> (strnow - now) < 1
2006 >>> (strnow - now) < 1
2007 True
2007 True
2008 >>> tz == strtz
2008 >>> tz == strtz
@@ -2076,12 +2076,12 b' def matchdate(date):'
2076
2076
2077 '>{date}' on or after a given date
2077 '>{date}' on or after a given date
2078
2078
2079 >>> p1 = parsedate("10:29:59")
2079 >>> p1 = parsedate(b"10:29:59")
2080 >>> p2 = parsedate("10:30:00")
2080 >>> p2 = parsedate(b"10:30:00")
2081 >>> p3 = parsedate("10:30:59")
2081 >>> p3 = parsedate(b"10:30:59")
2082 >>> p4 = parsedate("10:31:00")
2082 >>> p4 = parsedate(b"10:31:00")
2083 >>> p5 = parsedate("Sep 15 10:30:00 1999")
2083 >>> p5 = parsedate(b"Sep 15 10:30:00 1999")
2084 >>> f = matchdate("10:30")
2084 >>> f = matchdate(b"10:30")
2085 >>> f(p1[0])
2085 >>> f(p1[0])
2086 False
2086 False
2087 >>> f(p2[0])
2087 >>> f(p2[0])
@@ -2156,27 +2156,27 b' def stringmatcher(pattern, casesensitive'
2156 ... return (kind, pattern, [bool(matcher(t)) for t in tests])
2156 ... return (kind, pattern, [bool(matcher(t)) for t in tests])
2157
2157
2158 exact matching (no prefix):
2158 exact matching (no prefix):
2159 >>> test('abcdefg', 'abc', 'def', 'abcdefg')
2159 >>> test(b'abcdefg', b'abc', b'def', b'abcdefg')
2160 ('literal', 'abcdefg', [False, False, True])
2160 ('literal', 'abcdefg', [False, False, True])
2161
2161
2162 regex matching ('re:' prefix)
2162 regex matching ('re:' prefix)
2163 >>> test('re:a.+b', 'nomatch', 'fooadef', 'fooadefbar')
2163 >>> test(b're:a.+b', b'nomatch', b'fooadef', b'fooadefbar')
2164 ('re', 'a.+b', [False, False, True])
2164 ('re', 'a.+b', [False, False, True])
2165
2165
2166 force exact matches ('literal:' prefix)
2166 force exact matches ('literal:' prefix)
2167 >>> test('literal:re:foobar', 'foobar', 're:foobar')
2167 >>> test(b'literal:re:foobar', b'foobar', b're:foobar')
2168 ('literal', 're:foobar', [False, True])
2168 ('literal', 're:foobar', [False, True])
2169
2169
2170 unknown prefixes are ignored and treated as literals
2170 unknown prefixes are ignored and treated as literals
2171 >>> test('foo:bar', 'foo', 'bar', 'foo:bar')
2171 >>> test(b'foo:bar', b'foo', b'bar', b'foo:bar')
2172 ('literal', 'foo:bar', [False, False, True])
2172 ('literal', 'foo:bar', [False, False, True])
2173
2173
2174 case insensitive regex matches
2174 case insensitive regex matches
2175 >>> itest('re:A.+b', 'nomatch', 'fooadef', 'fooadefBar')
2175 >>> itest(b're:A.+b', b'nomatch', b'fooadef', b'fooadefBar')
2176 ('re', 'A.+b', [False, False, True])
2176 ('re', 'A.+b', [False, False, True])
2177
2177
2178 case insensitive literal matches
2178 case insensitive literal matches
2179 >>> itest('ABCDEFG', 'abc', 'def', 'abcdefg')
2179 >>> itest(b'ABCDEFG', b'abc', b'def', b'abcdefg')
2180 ('literal', 'ABCDEFG', [False, False, True])
2180 ('literal', 'ABCDEFG', [False, False, True])
2181 """
2181 """
2182 if pattern.startswith('re:'):
2182 if pattern.startswith('re:'):
@@ -2649,55 +2649,55 b' class url(object):'
2649
2649
2650 Examples:
2650 Examples:
2651
2651
2652 >>> url('http://www.ietf.org/rfc/rfc2396.txt')
2652 >>> url(b'http://www.ietf.org/rfc/rfc2396.txt')
2653 <url scheme: 'http', host: 'www.ietf.org', path: 'rfc/rfc2396.txt'>
2653 <url scheme: 'http', host: 'www.ietf.org', path: 'rfc/rfc2396.txt'>
2654 >>> url('ssh://[::1]:2200//home/joe/repo')
2654 >>> url(b'ssh://[::1]:2200//home/joe/repo')
2655 <url scheme: 'ssh', host: '[::1]', port: '2200', path: '/home/joe/repo'>
2655 <url scheme: 'ssh', host: '[::1]', port: '2200', path: '/home/joe/repo'>
2656 >>> url('file:///home/joe/repo')
2656 >>> url(b'file:///home/joe/repo')
2657 <url scheme: 'file', path: '/home/joe/repo'>
2657 <url scheme: 'file', path: '/home/joe/repo'>
2658 >>> url('file:///c:/temp/foo/')
2658 >>> url(b'file:///c:/temp/foo/')
2659 <url scheme: 'file', path: 'c:/temp/foo/'>
2659 <url scheme: 'file', path: 'c:/temp/foo/'>
2660 >>> url('bundle:foo')
2660 >>> url(b'bundle:foo')
2661 <url scheme: 'bundle', path: 'foo'>
2661 <url scheme: 'bundle', path: 'foo'>
2662 >>> url('bundle://../foo')
2662 >>> url(b'bundle://../foo')
2663 <url scheme: 'bundle', path: '../foo'>
2663 <url scheme: 'bundle', path: '../foo'>
2664 >>> url(r'c:\foo\bar')
2664 >>> url(br'c:\foo\bar')
2665 <url path: 'c:\\foo\\bar'>
2665 <url path: 'c:\\foo\\bar'>
2666 >>> url(r'\\blah\blah\blah')
2666 >>> url(br'\\blah\blah\blah')
2667 <url path: '\\\\blah\\blah\\blah'>
2667 <url path: '\\\\blah\\blah\\blah'>
2668 >>> url(r'\\blah\blah\blah#baz')
2668 >>> url(br'\\blah\blah\blah#baz')
2669 <url path: '\\\\blah\\blah\\blah', fragment: 'baz'>
2669 <url path: '\\\\blah\\blah\\blah', fragment: 'baz'>
2670 >>> url(r'file:///C:\users\me')
2670 >>> url(br'file:///C:\users\me')
2671 <url scheme: 'file', path: 'C:\\users\\me'>
2671 <url scheme: 'file', path: 'C:\\users\\me'>
2672
2672
2673 Authentication credentials:
2673 Authentication credentials:
2674
2674
2675 >>> url('ssh://joe:xyz@x/repo')
2675 >>> url(b'ssh://joe:xyz@x/repo')
2676 <url scheme: 'ssh', user: 'joe', passwd: 'xyz', host: 'x', path: 'repo'>
2676 <url scheme: 'ssh', user: 'joe', passwd: 'xyz', host: 'x', path: 'repo'>
2677 >>> url('ssh://joe@x/repo')
2677 >>> url(b'ssh://joe@x/repo')
2678 <url scheme: 'ssh', user: 'joe', host: 'x', path: 'repo'>
2678 <url scheme: 'ssh', user: 'joe', host: 'x', path: 'repo'>
2679
2679
2680 Query strings and fragments:
2680 Query strings and fragments:
2681
2681
2682 >>> url('http://host/a?b#c')
2682 >>> url(b'http://host/a?b#c')
2683 <url scheme: 'http', host: 'host', path: 'a', query: 'b', fragment: 'c'>
2683 <url scheme: 'http', host: 'host', path: 'a', query: 'b', fragment: 'c'>
2684 >>> url('http://host/a?b#c', parsequery=False, parsefragment=False)
2684 >>> url(b'http://host/a?b#c', parsequery=False, parsefragment=False)
2685 <url scheme: 'http', host: 'host', path: 'a?b#c'>
2685 <url scheme: 'http', host: 'host', path: 'a?b#c'>
2686
2686
2687 Empty path:
2687 Empty path:
2688
2688
2689 >>> url('')
2689 >>> url(b'')
2690 <url path: ''>
2690 <url path: ''>
2691 >>> url('#a')
2691 >>> url(b'#a')
2692 <url path: '', fragment: 'a'>
2692 <url path: '', fragment: 'a'>
2693 >>> url('http://host/')
2693 >>> url(b'http://host/')
2694 <url scheme: 'http', host: 'host', path: ''>
2694 <url scheme: 'http', host: 'host', path: ''>
2695 >>> url('http://host/#a')
2695 >>> url(b'http://host/#a')
2696 <url scheme: 'http', host: 'host', path: '', fragment: 'a'>
2696 <url scheme: 'http', host: 'host', path: '', fragment: 'a'>
2697
2697
2698 Only scheme:
2698 Only scheme:
2699
2699
2700 >>> url('http:')
2700 >>> url(b'http:')
2701 <url scheme: 'http'>
2701 <url scheme: 'http'>
2702 """
2702 """
2703
2703
@@ -2812,33 +2812,33 b' class url(object):'
2812
2812
2813 Examples:
2813 Examples:
2814
2814
2815 >>> str(url('http://user:pw@host:80/c:/bob?fo:oo#ba:ar'))
2815 >>> str(url(b'http://user:pw@host:80/c:/bob?fo:oo#ba:ar'))
2816 'http://user:pw@host:80/c:/bob?fo:oo#ba:ar'
2816 'http://user:pw@host:80/c:/bob?fo:oo#ba:ar'
2817 >>> str(url('http://user:pw@host:80/?foo=bar&baz=42'))
2817 >>> str(url(b'http://user:pw@host:80/?foo=bar&baz=42'))
2818 'http://user:pw@host:80/?foo=bar&baz=42'
2818 'http://user:pw@host:80/?foo=bar&baz=42'
2819 >>> str(url('http://user:pw@host:80/?foo=bar%3dbaz'))
2819 >>> str(url(b'http://user:pw@host:80/?foo=bar%3dbaz'))
2820 'http://user:pw@host:80/?foo=bar%3dbaz'
2820 'http://user:pw@host:80/?foo=bar%3dbaz'
2821 >>> str(url('ssh://user:pw@[::1]:2200//home/joe#'))
2821 >>> str(url(b'ssh://user:pw@[::1]:2200//home/joe#'))
2822 'ssh://user:pw@[::1]:2200//home/joe#'
2822 'ssh://user:pw@[::1]:2200//home/joe#'
2823 >>> str(url('http://localhost:80//'))
2823 >>> str(url(b'http://localhost:80//'))
2824 'http://localhost:80//'
2824 'http://localhost:80//'
2825 >>> str(url('http://localhost:80/'))
2825 >>> str(url(b'http://localhost:80/'))
2826 'http://localhost:80/'
2826 'http://localhost:80/'
2827 >>> str(url('http://localhost:80'))
2827 >>> str(url(b'http://localhost:80'))
2828 'http://localhost:80/'
2828 'http://localhost:80/'
2829 >>> str(url('bundle:foo'))
2829 >>> str(url(b'bundle:foo'))
2830 'bundle:foo'
2830 'bundle:foo'
2831 >>> str(url('bundle://../foo'))
2831 >>> str(url(b'bundle://../foo'))
2832 'bundle:../foo'
2832 'bundle:../foo'
2833 >>> str(url('path'))
2833 >>> str(url(b'path'))
2834 'path'
2834 'path'
2835 >>> str(url('file:///tmp/foo/bar'))
2835 >>> str(url(b'file:///tmp/foo/bar'))
2836 'file:///tmp/foo/bar'
2836 'file:///tmp/foo/bar'
2837 >>> str(url('file:///c:/tmp/foo/bar'))
2837 >>> str(url(b'file:///c:/tmp/foo/bar'))
2838 'file:///c:/tmp/foo/bar'
2838 'file:///c:/tmp/foo/bar'
2839 >>> print url(r'bundle:foo\bar')
2839 >>> print url(br'bundle:foo\bar')
2840 bundle:foo\bar
2840 bundle:foo\bar
2841 >>> print url(r'file:///D:\data\hg')
2841 >>> print url(br'file:///D:\data\hg')
2842 file:///D:\data\hg
2842 file:///D:\data\hg
2843 """
2843 """
2844 if self._localpath:
2844 if self._localpath:
@@ -3017,11 +3017,11 b' def timed(func):'
3017 def sizetoint(s):
3017 def sizetoint(s):
3018 '''Convert a space specifier to a byte count.
3018 '''Convert a space specifier to a byte count.
3019
3019
3020 >>> sizetoint('30')
3020 >>> sizetoint(b'30')
3021 30
3021 30
3022 >>> sizetoint('2.2kb')
3022 >>> sizetoint(b'2.2kb')
3023 2252
3023 2252
3024 >>> sizetoint('6M')
3024 >>> sizetoint(b'6M')
3025 6291456
3025 6291456
3026 '''
3026 '''
3027 t = s.strip().lower()
3027 t = s.strip().lower()
@@ -267,15 +267,15 b' def samestat(s1, s2):'
267 _needsshellquote = None
267 _needsshellquote = None
268 def shellquote(s):
268 def shellquote(s):
269 r"""
269 r"""
270 >>> shellquote(r'C:\Users\xyz')
270 >>> shellquote(br'C:\Users\xyz')
271 '"C:\\Users\\xyz"'
271 '"C:\\Users\\xyz"'
272 >>> shellquote(r'C:\Users\xyz/mixed')
272 >>> shellquote(br'C:\Users\xyz/mixed')
273 '"C:\\Users\\xyz/mixed"'
273 '"C:\\Users\\xyz/mixed"'
274 >>> # Would be safe not to quote too, since it is all double backslashes
274 >>> # Would be safe not to quote too, since it is all double backslashes
275 >>> shellquote(r'C:\\Users\\xyz')
275 >>> shellquote(br'C:\\Users\\xyz')
276 '"C:\\\\Users\\\\xyz"'
276 '"C:\\\\Users\\\\xyz"'
277 >>> # But this must be quoted
277 >>> # But this must be quoted
278 >>> shellquote(r'C:\\Users\\xyz/abc')
278 >>> shellquote(br'C:\\Users\\xyz/abc')
279 '"C:\\\\Users\\\\xyz/abc"'
279 '"C:\\\\Users\\\\xyz/abc"'
280 """
280 """
281 global _quotere
281 global _quotere
General Comments 0
You need to be logged in to leave comments. Login now