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