##// END OF EJS Templates
tests: convert the `root` arg of matchmod.match() to local path separators...
Matt Harbison -
r44416:8f677353 default
parent child Browse files
Show More
@@ -182,35 +182,38 b' def match('
182 the same directory
182 the same directory
183 '<something>' - a pattern of the specified default type
183 '<something>' - a pattern of the specified default type
184
184
185 >>> def _match(root, *args, **kwargs):
186 ... return match(util.localpath(root), *args, **kwargs)
187
185 Usually a patternmatcher is returned:
188 Usually a patternmatcher is returned:
186 >>> match(b'/foo', b'.', [b're:.*\.c$', b'path:foo/a', b'*.py'])
189 >>> _match(b'/foo', b'.', [b're:.*\.c$', b'path:foo/a', b'*.py'])
187 <patternmatcher patterns='.*\\.c$|foo/a(?:/|$)|[^/]*\\.py$'>
190 <patternmatcher patterns='.*\\.c$|foo/a(?:/|$)|[^/]*\\.py$'>
188
191
189 Combining 'patterns' with 'include' (resp. 'exclude') gives an
192 Combining 'patterns' with 'include' (resp. 'exclude') gives an
190 intersectionmatcher (resp. a differencematcher):
193 intersectionmatcher (resp. a differencematcher):
191 >>> type(match(b'/foo', b'.', [b're:.*\.c$'], include=[b'path:lib']))
194 >>> type(_match(b'/foo', b'.', [b're:.*\.c$'], include=[b'path:lib']))
192 <class 'mercurial.match.intersectionmatcher'>
195 <class 'mercurial.match.intersectionmatcher'>
193 >>> type(match(b'/foo', b'.', [b're:.*\.c$'], exclude=[b'path:build']))
196 >>> type(_match(b'/foo', b'.', [b're:.*\.c$'], exclude=[b'path:build']))
194 <class 'mercurial.match.differencematcher'>
197 <class 'mercurial.match.differencematcher'>
195
198
196 Notice that, if 'patterns' is empty, an alwaysmatcher is returned:
199 Notice that, if 'patterns' is empty, an alwaysmatcher is returned:
197 >>> match(b'/foo', b'.', [])
200 >>> _match(b'/foo', b'.', [])
198 <alwaysmatcher>
201 <alwaysmatcher>
199
202
200 The 'default' argument determines which kind of pattern is assumed if a
203 The 'default' argument determines which kind of pattern is assumed if a
201 pattern has no prefix:
204 pattern has no prefix:
202 >>> match(b'/foo', b'.', [b'.*\.c$'], default=b're')
205 >>> _match(b'/foo', b'.', [b'.*\.c$'], default=b're')
203 <patternmatcher patterns='.*\\.c$'>
206 <patternmatcher patterns='.*\\.c$'>
204 >>> match(b'/foo', b'.', [b'main.py'], default=b'relpath')
207 >>> _match(b'/foo', b'.', [b'main.py'], default=b'relpath')
205 <patternmatcher patterns='main\\.py(?:/|$)'>
208 <patternmatcher patterns='main\\.py(?:/|$)'>
206 >>> match(b'/foo', b'.', [b'main.py'], default=b're')
209 >>> _match(b'/foo', b'.', [b'main.py'], default=b're')
207 <patternmatcher patterns='main.py'>
210 <patternmatcher patterns='main.py'>
208
211
209 The primary use of matchers is to check whether a value (usually a file
212 The primary use of matchers is to check whether a value (usually a file
210 name) matches againset one of the patterns given at initialization. There
213 name) matches againset one of the patterns given at initialization. There
211 are two ways of doing this check.
214 are two ways of doing this check.
212
215
213 >>> m = match(b'/foo', b'', [b're:.*\.c$', b'relpath:a'])
216 >>> m = _match(b'/foo', b'', [b're:.*\.c$', b'relpath:a'])
214
217
215 1. Calling the matcher with a file name returns True if any pattern
218 1. Calling the matcher with a file name returns True if any pattern
216 matches that file name:
219 matches that file name:
@@ -942,7 +945,7 b' class subdirmatcher(basematcher):'
942 The paths are remapped to remove/insert the path as needed:
945 The paths are remapped to remove/insert the path as needed:
943
946
944 >>> from . import pycompat
947 >>> from . import pycompat
945 >>> m1 = match(b'/root', b'', [b'a.txt', b'sub/b.txt'])
948 >>> m1 = match(util.localpath(b'/root'), b'', [b'a.txt', b'sub/b.txt'])
946 >>> m2 = subdirmatcher(b'sub', m1)
949 >>> m2 = subdirmatcher(b'sub', m1)
947 >>> m2(b'a.txt')
950 >>> m2(b'a.txt')
948 False
951 False
@@ -9,6 +9,7 b' import zlib'
9 from mercurial import (
9 from mercurial import (
10 manifest as manifestmod,
10 manifest as manifestmod,
11 match as matchmod,
11 match as matchmod,
12 util,
12 )
13 )
13
14
14 EMTPY_MANIFEST = b''
15 EMTPY_MANIFEST = b''
@@ -169,7 +170,7 b' class basemanifesttests(object):'
169 m[b'foo'] = want + b'+'
170 m[b'foo'] = want + b'+'
170 self.assertEqual(want, m[b'foo'])
171 self.assertEqual(want, m[b'foo'])
171 # make sure the suffix survives a copy
172 # make sure the suffix survives a copy
172 match = matchmod.match(b'/repo', b'', [b're:foo'])
173 match = matchmod.match(util.localpath(b'/repo'), b'', [b're:foo'])
173 m2 = m.matches(match)
174 m2 = m.matches(match)
174 self.assertEqual(want, m2[b'foo'])
175 self.assertEqual(want, m2[b'foo'])
175 self.assertEqual(1, len(m2))
176 self.assertEqual(1, len(m2))
@@ -186,7 +187,7 b' class basemanifesttests(object):'
186
187
187 def testMatchException(self):
188 def testMatchException(self):
188 m = self.parsemanifest(A_SHORT_MANIFEST)
189 m = self.parsemanifest(A_SHORT_MANIFEST)
189 match = matchmod.match(b'/repo', b'', [b're:.*'])
190 match = matchmod.match(util.localpath(b'/repo'), b'', [b're:.*'])
190
191
191 def filt(path):
192 def filt(path):
192 if path == b'foo':
193 if path == b'foo':
@@ -328,7 +329,9 b' class basemanifesttests(object):'
328 actually exist.'''
329 actually exist.'''
329 m = self.parsemanifest(A_DEEPER_MANIFEST)
330 m = self.parsemanifest(A_DEEPER_MANIFEST)
330
331
331 match = matchmod.match(b'/repo', b'', [b'a/f'], default=b'relpath')
332 match = matchmod.match(
333 util.localpath(b'/repo'), b'', [b'a/f'], default=b'relpath'
334 )
332 m2 = m.matches(match)
335 m2 = m.matches(match)
333
336
334 self.assertEqual([], m2.keys())
337 self.assertEqual([], m2.keys())
@@ -348,7 +351,7 b' class basemanifesttests(object):'
348 '''Tests matches() for what should be a full match.'''
351 '''Tests matches() for what should be a full match.'''
349 m = self.parsemanifest(A_DEEPER_MANIFEST)
352 m = self.parsemanifest(A_DEEPER_MANIFEST)
350
353
351 match = matchmod.match(b'/repo', b'', [b''])
354 match = matchmod.match(util.localpath(b'/repo'), b'', [b''])
352 m2 = m.matches(match)
355 m2 = m.matches(match)
353
356
354 self.assertEqual(m.keys(), m2.keys())
357 self.assertEqual(m.keys(), m2.keys())
@@ -358,7 +361,9 b' class basemanifesttests(object):'
358 match against all files within said directory.'''
361 match against all files within said directory.'''
359 m = self.parsemanifest(A_DEEPER_MANIFEST)
362 m = self.parsemanifest(A_DEEPER_MANIFEST)
360
363
361 match = matchmod.match(b'/repo', b'', [b'a/b'], default=b'relpath')
364 match = matchmod.match(
365 util.localpath(b'/repo'), b'', [b'a/b'], default=b'relpath'
366 )
362 m2 = m.matches(match)
367 m2 = m.matches(match)
363
368
364 self.assertEqual(
369 self.assertEqual(
@@ -392,7 +397,9 b' class basemanifesttests(object):'
392 when not in the root directory.'''
397 when not in the root directory.'''
393 m = self.parsemanifest(A_DEEPER_MANIFEST)
398 m = self.parsemanifest(A_DEEPER_MANIFEST)
394
399
395 match = matchmod.match(b'/repo', b'a/b', [b'.'], default=b'relpath')
400 match = matchmod.match(
401 util.localpath(b'/repo'), b'a/b', [b'.'], default=b'relpath'
402 )
396 m2 = m.matches(match)
403 m2 = m.matches(match)
397
404
398 self.assertEqual(
405 self.assertEqual(
@@ -415,7 +422,7 b' class basemanifesttests(object):'
415 deeper than the specified directory.'''
422 deeper than the specified directory.'''
416 m = self.parsemanifest(A_DEEPER_MANIFEST)
423 m = self.parsemanifest(A_DEEPER_MANIFEST)
417
424
418 match = matchmod.match(b'/repo', b'', [b'a/b/*/*.txt'])
425 match = matchmod.match(util.localpath(b'/repo'), b'', [b'a/b/*/*.txt'])
419 m2 = m.matches(match)
426 m2 = m.matches(match)
420
427
421 self.assertEqual(
428 self.assertEqual(
@@ -467,7 +474,7 b' class testtreemanifest(unittest.TestCase'
467 sorted(dirs),
474 sorted(dirs),
468 )
475 )
469
476
470 match = matchmod.match(b'/repo', b'', [b'path:a/b/'])
477 match = matchmod.match(util.localpath(b'/repo'), b'', [b'path:a/b/'])
471 dirs = [s._dir for s in m.walksubtrees(matcher=match)]
478 dirs = [s._dir for s in m.walksubtrees(matcher=match)]
472 self.assertEqual(sorted([b'a/b/', b'a/b/c/', b'a/b/d/']), sorted(dirs))
479 self.assertEqual(sorted([b'a/b/', b'a/b/c/', b'a/b/d/']), sorted(dirs))
473
480
@@ -66,7 +66,9 b' class PredicateMatcherTests(unittest.Tes'
66
66
67 class PatternMatcherTests(unittest.TestCase):
67 class PatternMatcherTests(unittest.TestCase):
68 def testVisitdirPrefix(self):
68 def testVisitdirPrefix(self):
69 m = matchmod.match(b'/repo', b'', patterns=[b'path:dir/subdir'])
69 m = matchmod.match(
70 util.localpath(b'/repo'), b'', patterns=[b'path:dir/subdir']
71 )
70 assert isinstance(m, matchmod.patternmatcher)
72 assert isinstance(m, matchmod.patternmatcher)
71 self.assertTrue(m.visitdir(b''))
73 self.assertTrue(m.visitdir(b''))
72 self.assertTrue(m.visitdir(b'dir'))
74 self.assertTrue(m.visitdir(b'dir'))
@@ -76,7 +78,9 b' class PatternMatcherTests(unittest.TestC'
76 self.assertFalse(m.visitdir(b'folder'))
78 self.assertFalse(m.visitdir(b'folder'))
77
79
78 def testVisitchildrensetPrefix(self):
80 def testVisitchildrensetPrefix(self):
79 m = matchmod.match(b'/repo', b'', patterns=[b'path:dir/subdir'])
81 m = matchmod.match(
82 util.localpath(b'/repo'), b'', patterns=[b'path:dir/subdir']
83 )
80 assert isinstance(m, matchmod.patternmatcher)
84 assert isinstance(m, matchmod.patternmatcher)
81 self.assertEqual(m.visitchildrenset(b''), b'this')
85 self.assertEqual(m.visitchildrenset(b''), b'this')
82 self.assertEqual(m.visitchildrenset(b'dir'), b'this')
86 self.assertEqual(m.visitchildrenset(b'dir'), b'this')
@@ -86,7 +90,9 b' class PatternMatcherTests(unittest.TestC'
86 self.assertEqual(m.visitchildrenset(b'folder'), set())
90 self.assertEqual(m.visitchildrenset(b'folder'), set())
87
91
88 def testVisitdirRootfilesin(self):
92 def testVisitdirRootfilesin(self):
89 m = matchmod.match(b'/repo', b'', patterns=[b'rootfilesin:dir/subdir'])
93 m = matchmod.match(
94 util.localpath(b'/repo'), b'', patterns=[b'rootfilesin:dir/subdir'],
95 )
90 assert isinstance(m, matchmod.patternmatcher)
96 assert isinstance(m, matchmod.patternmatcher)
91 self.assertFalse(m.visitdir(b'dir/subdir/x'))
97 self.assertFalse(m.visitdir(b'dir/subdir/x'))
92 self.assertFalse(m.visitdir(b'folder'))
98 self.assertFalse(m.visitdir(b'folder'))
@@ -96,7 +102,9 b' class PatternMatcherTests(unittest.TestC'
96 self.assertFalse(m.visitdir(b'dir/subdir'))
102 self.assertFalse(m.visitdir(b'dir/subdir'))
97
103
98 def testVisitchildrensetRootfilesin(self):
104 def testVisitchildrensetRootfilesin(self):
99 m = matchmod.match(b'/repo', b'', patterns=[b'rootfilesin:dir/subdir'])
105 m = matchmod.match(
106 util.localpath(b'/repo'), b'', patterns=[b'rootfilesin:dir/subdir'],
107 )
100 assert isinstance(m, matchmod.patternmatcher)
108 assert isinstance(m, matchmod.patternmatcher)
101 self.assertEqual(m.visitchildrenset(b'dir/subdir/x'), set())
109 self.assertEqual(m.visitchildrenset(b'dir/subdir/x'), set())
102 self.assertEqual(m.visitchildrenset(b'folder'), set())
110 self.assertEqual(m.visitchildrenset(b'folder'), set())
@@ -107,7 +115,9 b' class PatternMatcherTests(unittest.TestC'
107 self.assertEqual(m.visitchildrenset(b'dir/subdir'), set())
115 self.assertEqual(m.visitchildrenset(b'dir/subdir'), set())
108
116
109 def testVisitdirGlob(self):
117 def testVisitdirGlob(self):
110 m = matchmod.match(b'/repo', b'', patterns=[b'glob:dir/z*'])
118 m = matchmod.match(
119 util.localpath(b'/repo'), b'', patterns=[b'glob:dir/z*']
120 )
111 assert isinstance(m, matchmod.patternmatcher)
121 assert isinstance(m, matchmod.patternmatcher)
112 self.assertTrue(m.visitdir(b''))
122 self.assertTrue(m.visitdir(b''))
113 self.assertTrue(m.visitdir(b'dir'))
123 self.assertTrue(m.visitdir(b'dir'))
@@ -117,7 +127,9 b' class PatternMatcherTests(unittest.TestC'
117 self.assertTrue(m.visitdir(b'dir/subdir/x'))
127 self.assertTrue(m.visitdir(b'dir/subdir/x'))
118
128
119 def testVisitchildrensetGlob(self):
129 def testVisitchildrensetGlob(self):
120 m = matchmod.match(b'/repo', b'', patterns=[b'glob:dir/z*'])
130 m = matchmod.match(
131 util.localpath(b'/repo'), b'', patterns=[b'glob:dir/z*']
132 )
121 assert isinstance(m, matchmod.patternmatcher)
133 assert isinstance(m, matchmod.patternmatcher)
122 self.assertEqual(m.visitchildrenset(b''), b'this')
134 self.assertEqual(m.visitchildrenset(b''), b'this')
123 self.assertEqual(m.visitchildrenset(b'folder'), set())
135 self.assertEqual(m.visitchildrenset(b'folder'), set())
@@ -129,7 +141,9 b' class PatternMatcherTests(unittest.TestC'
129
141
130 class IncludeMatcherTests(unittest.TestCase):
142 class IncludeMatcherTests(unittest.TestCase):
131 def testVisitdirPrefix(self):
143 def testVisitdirPrefix(self):
132 m = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
144 m = matchmod.match(
145 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
146 )
133 assert isinstance(m, matchmod.includematcher)
147 assert isinstance(m, matchmod.includematcher)
134 self.assertTrue(m.visitdir(b''))
148 self.assertTrue(m.visitdir(b''))
135 self.assertTrue(m.visitdir(b'dir'))
149 self.assertTrue(m.visitdir(b'dir'))
@@ -139,7 +153,9 b' class IncludeMatcherTests(unittest.TestC'
139 self.assertFalse(m.visitdir(b'folder'))
153 self.assertFalse(m.visitdir(b'folder'))
140
154
141 def testVisitchildrensetPrefix(self):
155 def testVisitchildrensetPrefix(self):
142 m = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
156 m = matchmod.match(
157 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
158 )
143 assert isinstance(m, matchmod.includematcher)
159 assert isinstance(m, matchmod.includematcher)
144 self.assertEqual(m.visitchildrenset(b''), {b'dir'})
160 self.assertEqual(m.visitchildrenset(b''), {b'dir'})
145 self.assertEqual(m.visitchildrenset(b'dir'), {b'subdir'})
161 self.assertEqual(m.visitchildrenset(b'dir'), {b'subdir'})
@@ -149,7 +165,9 b' class IncludeMatcherTests(unittest.TestC'
149 self.assertEqual(m.visitchildrenset(b'folder'), set())
165 self.assertEqual(m.visitchildrenset(b'folder'), set())
150
166
151 def testVisitdirRootfilesin(self):
167 def testVisitdirRootfilesin(self):
152 m = matchmod.match(b'/repo', b'', include=[b'rootfilesin:dir/subdir'])
168 m = matchmod.match(
169 util.localpath(b'/repo'), b'', include=[b'rootfilesin:dir/subdir']
170 )
153 assert isinstance(m, matchmod.includematcher)
171 assert isinstance(m, matchmod.includematcher)
154 self.assertTrue(m.visitdir(b''))
172 self.assertTrue(m.visitdir(b''))
155 self.assertTrue(m.visitdir(b'dir'))
173 self.assertTrue(m.visitdir(b'dir'))
@@ -158,7 +176,9 b' class IncludeMatcherTests(unittest.TestC'
158 self.assertFalse(m.visitdir(b'folder'))
176 self.assertFalse(m.visitdir(b'folder'))
159
177
160 def testVisitchildrensetRootfilesin(self):
178 def testVisitchildrensetRootfilesin(self):
161 m = matchmod.match(b'/repo', b'', include=[b'rootfilesin:dir/subdir'])
179 m = matchmod.match(
180 util.localpath(b'/repo'), b'', include=[b'rootfilesin:dir/subdir']
181 )
162 assert isinstance(m, matchmod.includematcher)
182 assert isinstance(m, matchmod.includematcher)
163 self.assertEqual(m.visitchildrenset(b''), {b'dir'})
183 self.assertEqual(m.visitchildrenset(b''), {b'dir'})
164 self.assertEqual(m.visitchildrenset(b'dir'), {b'subdir'})
184 self.assertEqual(m.visitchildrenset(b'dir'), {b'subdir'})
@@ -167,7 +187,9 b' class IncludeMatcherTests(unittest.TestC'
167 self.assertEqual(m.visitchildrenset(b'folder'), set())
187 self.assertEqual(m.visitchildrenset(b'folder'), set())
168
188
169 def testVisitdirGlob(self):
189 def testVisitdirGlob(self):
170 m = matchmod.match(b'/repo', b'', include=[b'glob:dir/z*'])
190 m = matchmod.match(
191 util.localpath(b'/repo'), b'', include=[b'glob:dir/z*']
192 )
171 assert isinstance(m, matchmod.includematcher)
193 assert isinstance(m, matchmod.includematcher)
172 self.assertTrue(m.visitdir(b''))
194 self.assertTrue(m.visitdir(b''))
173 self.assertTrue(m.visitdir(b'dir'))
195 self.assertTrue(m.visitdir(b'dir'))
@@ -177,7 +199,9 b' class IncludeMatcherTests(unittest.TestC'
177 self.assertTrue(m.visitdir(b'dir/subdir/x'))
199 self.assertTrue(m.visitdir(b'dir/subdir/x'))
178
200
179 def testVisitchildrensetGlob(self):
201 def testVisitchildrensetGlob(self):
180 m = matchmod.match(b'/repo', b'', include=[b'glob:dir/z*'])
202 m = matchmod.match(
203 util.localpath(b'/repo'), b'', include=[b'glob:dir/z*']
204 )
181 assert isinstance(m, matchmod.includematcher)
205 assert isinstance(m, matchmod.includematcher)
182 self.assertEqual(m.visitchildrenset(b''), {b'dir'})
206 self.assertEqual(m.visitchildrenset(b''), {b'dir'})
183 self.assertEqual(m.visitchildrenset(b'folder'), set())
207 self.assertEqual(m.visitchildrenset(b'folder'), set())
@@ -289,7 +313,9 b' class DifferenceMatcherTests(unittest.Te'
289
313
290 def testVisitdirM2SubdirPrefix(self):
314 def testVisitdirM2SubdirPrefix(self):
291 m1 = matchmod.alwaysmatcher()
315 m1 = matchmod.alwaysmatcher()
292 m2 = matchmod.match(b'/repo', b'', patterns=[b'path:dir/subdir'])
316 m2 = matchmod.match(
317 util.localpath(b'/repo'), b'', patterns=[b'path:dir/subdir']
318 )
293 dm = matchmod.differencematcher(m1, m2)
319 dm = matchmod.differencematcher(m1, m2)
294 self.assertEqual(dm.visitdir(b''), True)
320 self.assertEqual(dm.visitdir(b''), True)
295 self.assertEqual(dm.visitdir(b'dir'), True)
321 self.assertEqual(dm.visitdir(b'dir'), True)
@@ -304,7 +330,9 b' class DifferenceMatcherTests(unittest.Te'
304
330
305 def testVisitchildrensetM2SubdirPrefix(self):
331 def testVisitchildrensetM2SubdirPrefix(self):
306 m1 = matchmod.alwaysmatcher()
332 m1 = matchmod.alwaysmatcher()
307 m2 = matchmod.match(b'/repo', b'', patterns=[b'path:dir/subdir'])
333 m2 = matchmod.match(
334 util.localpath(b'/repo'), b'', patterns=[b'path:dir/subdir']
335 )
308 dm = matchmod.differencematcher(m1, m2)
336 dm = matchmod.differencematcher(m1, m2)
309 self.assertEqual(dm.visitchildrenset(b''), b'this')
337 self.assertEqual(dm.visitchildrenset(b''), b'this')
310 self.assertEqual(dm.visitchildrenset(b'dir'), b'this')
338 self.assertEqual(dm.visitchildrenset(b'dir'), b'this')
@@ -320,8 +348,12 b' class DifferenceMatcherTests(unittest.Te'
320 # We're using includematcher instead of patterns because it behaves slightly
348 # We're using includematcher instead of patterns because it behaves slightly
321 # better (giving narrower results) than patternmatcher.
349 # better (giving narrower results) than patternmatcher.
322 def testVisitdirIncludeInclude(self):
350 def testVisitdirIncludeInclude(self):
323 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
351 m1 = matchmod.match(
324 m2 = matchmod.match(b'/repo', b'', include=[b'rootfilesin:dir'])
352 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
353 )
354 m2 = matchmod.match(
355 util.localpath(b'/repo'), b'', include=[b'rootfilesin:dir']
356 )
325 dm = matchmod.differencematcher(m1, m2)
357 dm = matchmod.differencematcher(m1, m2)
326 self.assertEqual(dm.visitdir(b''), True)
358 self.assertEqual(dm.visitdir(b''), True)
327 self.assertEqual(dm.visitdir(b'dir'), True)
359 self.assertEqual(dm.visitdir(b'dir'), True)
@@ -335,8 +367,12 b' class DifferenceMatcherTests(unittest.Te'
335 self.assertEqual(dm.visitdir(b'dir/subdir/x'), True)
367 self.assertEqual(dm.visitdir(b'dir/subdir/x'), True)
336
368
337 def testVisitchildrensetIncludeInclude(self):
369 def testVisitchildrensetIncludeInclude(self):
338 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
370 m1 = matchmod.match(
339 m2 = matchmod.match(b'/repo', b'', include=[b'rootfilesin:dir'])
371 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
372 )
373 m2 = matchmod.match(
374 util.localpath(b'/repo'), b'', include=[b'rootfilesin:dir']
375 )
340 dm = matchmod.differencematcher(m1, m2)
376 dm = matchmod.differencematcher(m1, m2)
341 self.assertEqual(dm.visitchildrenset(b''), {b'dir'})
377 self.assertEqual(dm.visitchildrenset(b''), {b'dir'})
342 self.assertEqual(dm.visitchildrenset(b'dir'), {b'subdir'})
378 self.assertEqual(dm.visitchildrenset(b'dir'), {b'subdir'})
@@ -405,7 +441,9 b' class IntersectionMatcherTests(unittest.'
405
441
406 def testVisitdirM2SubdirPrefix(self):
442 def testVisitdirM2SubdirPrefix(self):
407 m1 = matchmod.alwaysmatcher()
443 m1 = matchmod.alwaysmatcher()
408 m2 = matchmod.match(b'/repo', b'', patterns=[b'path:dir/subdir'])
444 m2 = matchmod.match(
445 util.localpath(b'/repo'), b'', patterns=[b'path:dir/subdir']
446 )
409 im = matchmod.intersectmatchers(m1, m2)
447 im = matchmod.intersectmatchers(m1, m2)
410 self.assertEqual(im.visitdir(b''), True)
448 self.assertEqual(im.visitdir(b''), True)
411 self.assertEqual(im.visitdir(b'dir'), True)
449 self.assertEqual(im.visitdir(b'dir'), True)
@@ -420,7 +458,9 b' class IntersectionMatcherTests(unittest.'
420
458
421 def testVisitchildrensetM2SubdirPrefix(self):
459 def testVisitchildrensetM2SubdirPrefix(self):
422 m1 = matchmod.alwaysmatcher()
460 m1 = matchmod.alwaysmatcher()
423 m2 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
461 m2 = matchmod.match(
462 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
463 )
424 im = matchmod.intersectmatchers(m1, m2)
464 im = matchmod.intersectmatchers(m1, m2)
425 self.assertEqual(im.visitchildrenset(b''), {b'dir'})
465 self.assertEqual(im.visitchildrenset(b''), {b'dir'})
426 self.assertEqual(im.visitchildrenset(b'dir'), {b'subdir'})
466 self.assertEqual(im.visitchildrenset(b'dir'), {b'subdir'})
@@ -434,8 +474,12 b' class IntersectionMatcherTests(unittest.'
434 # We're using includematcher instead of patterns because it behaves slightly
474 # We're using includematcher instead of patterns because it behaves slightly
435 # better (giving narrower results) than patternmatcher.
475 # better (giving narrower results) than patternmatcher.
436 def testVisitdirIncludeInclude(self):
476 def testVisitdirIncludeInclude(self):
437 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
477 m1 = matchmod.match(
438 m2 = matchmod.match(b'/repo', b'', include=[b'rootfilesin:dir'])
478 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
479 )
480 m2 = matchmod.match(
481 util.localpath(b'/repo'), b'', include=[b'rootfilesin:dir']
482 )
439 im = matchmod.intersectmatchers(m1, m2)
483 im = matchmod.intersectmatchers(m1, m2)
440 self.assertEqual(im.visitdir(b''), True)
484 self.assertEqual(im.visitdir(b''), True)
441 self.assertEqual(im.visitdir(b'dir'), True)
485 self.assertEqual(im.visitdir(b'dir'), True)
@@ -446,8 +490,12 b' class IntersectionMatcherTests(unittest.'
446 self.assertFalse(im.visitdir(b'dir/subdir/x'))
490 self.assertFalse(im.visitdir(b'dir/subdir/x'))
447
491
448 def testVisitchildrensetIncludeInclude(self):
492 def testVisitchildrensetIncludeInclude(self):
449 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
493 m1 = matchmod.match(
450 m2 = matchmod.match(b'/repo', b'', include=[b'rootfilesin:dir'])
494 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
495 )
496 m2 = matchmod.match(
497 util.localpath(b'/repo'), b'', include=[b'rootfilesin:dir']
498 )
451 im = matchmod.intersectmatchers(m1, m2)
499 im = matchmod.intersectmatchers(m1, m2)
452 self.assertEqual(im.visitchildrenset(b''), {b'dir'})
500 self.assertEqual(im.visitchildrenset(b''), {b'dir'})
453 self.assertEqual(im.visitchildrenset(b'dir'), b'this')
501 self.assertEqual(im.visitchildrenset(b'dir'), b'this')
@@ -460,8 +508,12 b' class IntersectionMatcherTests(unittest.'
460 # We're using includematcher instead of patterns because it behaves slightly
508 # We're using includematcher instead of patterns because it behaves slightly
461 # better (giving narrower results) than patternmatcher.
509 # better (giving narrower results) than patternmatcher.
462 def testVisitdirIncludeInclude2(self):
510 def testVisitdirIncludeInclude2(self):
463 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
511 m1 = matchmod.match(
464 m2 = matchmod.match(b'/repo', b'', include=[b'path:folder'])
512 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
513 )
514 m2 = matchmod.match(
515 util.localpath(b'/repo'), b'', include=[b'path:folder']
516 )
465 im = matchmod.intersectmatchers(m1, m2)
517 im = matchmod.intersectmatchers(m1, m2)
466 # FIXME: is True correct here?
518 # FIXME: is True correct here?
467 self.assertEqual(im.visitdir(b''), True)
519 self.assertEqual(im.visitdir(b''), True)
@@ -473,8 +525,12 b' class IntersectionMatcherTests(unittest.'
473 self.assertFalse(im.visitdir(b'dir/subdir/x'))
525 self.assertFalse(im.visitdir(b'dir/subdir/x'))
474
526
475 def testVisitchildrensetIncludeInclude2(self):
527 def testVisitchildrensetIncludeInclude2(self):
476 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
528 m1 = matchmod.match(
477 m2 = matchmod.match(b'/repo', b'', include=[b'path:folder'])
529 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
530 )
531 m2 = matchmod.match(
532 util.localpath(b'/repo'), b'', include=[b'path:folder']
533 )
478 im = matchmod.intersectmatchers(m1, m2)
534 im = matchmod.intersectmatchers(m1, m2)
479 # FIXME: is set() correct here?
535 # FIXME: is set() correct here?
480 self.assertEqual(im.visitchildrenset(b''), set())
536 self.assertEqual(im.visitchildrenset(b''), set())
@@ -488,8 +544,12 b' class IntersectionMatcherTests(unittest.'
488 # We're using includematcher instead of patterns because it behaves slightly
544 # We're using includematcher instead of patterns because it behaves slightly
489 # better (giving narrower results) than patternmatcher.
545 # better (giving narrower results) than patternmatcher.
490 def testVisitdirIncludeInclude3(self):
546 def testVisitdirIncludeInclude3(self):
491 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir/x'])
547 m1 = matchmod.match(
492 m2 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
548 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir/x']
549 )
550 m2 = matchmod.match(
551 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
552 )
493 im = matchmod.intersectmatchers(m1, m2)
553 im = matchmod.intersectmatchers(m1, m2)
494 self.assertEqual(im.visitdir(b''), True)
554 self.assertEqual(im.visitdir(b''), True)
495 self.assertEqual(im.visitdir(b'dir'), True)
555 self.assertEqual(im.visitdir(b'dir'), True)
@@ -501,8 +561,12 b' class IntersectionMatcherTests(unittest.'
501 self.assertEqual(im.visitdir(b'dir/subdir/x'), True)
561 self.assertEqual(im.visitdir(b'dir/subdir/x'), True)
502
562
503 def testVisitchildrensetIncludeInclude3(self):
563 def testVisitchildrensetIncludeInclude3(self):
504 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir/x'])
564 m1 = matchmod.match(
505 m2 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
565 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir/x']
566 )
567 m2 = matchmod.match(
568 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
569 )
506 im = matchmod.intersectmatchers(m1, m2)
570 im = matchmod.intersectmatchers(m1, m2)
507 self.assertEqual(im.visitchildrenset(b''), {b'dir'})
571 self.assertEqual(im.visitchildrenset(b''), {b'dir'})
508 self.assertEqual(im.visitchildrenset(b'dir'), {b'subdir'})
572 self.assertEqual(im.visitchildrenset(b'dir'), {b'subdir'})
@@ -516,8 +580,12 b' class IntersectionMatcherTests(unittest.'
516 # We're using includematcher instead of patterns because it behaves slightly
580 # We're using includematcher instead of patterns because it behaves slightly
517 # better (giving narrower results) than patternmatcher.
581 # better (giving narrower results) than patternmatcher.
518 def testVisitdirIncludeInclude4(self):
582 def testVisitdirIncludeInclude4(self):
519 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir/x'])
583 m1 = matchmod.match(
520 m2 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir/z'])
584 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir/x']
585 )
586 m2 = matchmod.match(
587 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir/z']
588 )
521 im = matchmod.intersectmatchers(m1, m2)
589 im = matchmod.intersectmatchers(m1, m2)
522 # OPT: these next three could probably be False as well.
590 # OPT: these next three could probably be False as well.
523 self.assertEqual(im.visitdir(b''), True)
591 self.assertEqual(im.visitdir(b''), True)
@@ -529,8 +597,12 b' class IntersectionMatcherTests(unittest.'
529 self.assertFalse(im.visitdir(b'dir/subdir/x'))
597 self.assertFalse(im.visitdir(b'dir/subdir/x'))
530
598
531 def testVisitchildrensetIncludeInclude4(self):
599 def testVisitchildrensetIncludeInclude4(self):
532 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir/x'])
600 m1 = matchmod.match(
533 m2 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir/z'])
601 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir/x']
602 )
603 m2 = matchmod.match(
604 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir/z']
605 )
534 im = matchmod.intersectmatchers(m1, m2)
606 im = matchmod.intersectmatchers(m1, m2)
535 # OPT: these next two could probably be set() as well.
607 # OPT: these next two could probably be set() as well.
536 self.assertEqual(im.visitchildrenset(b''), {b'dir'})
608 self.assertEqual(im.visitchildrenset(b''), {b'dir'})
@@ -623,7 +695,9 b' class UnionMatcherTests(unittest.TestCas'
623
695
624 def testVisitdirM2SubdirPrefix(self):
696 def testVisitdirM2SubdirPrefix(self):
625 m1 = matchmod.alwaysmatcher()
697 m1 = matchmod.alwaysmatcher()
626 m2 = matchmod.match(b'/repo', b'', patterns=[b'path:dir/subdir'])
698 m2 = matchmod.match(
699 util.localpath(b'/repo'), b'', patterns=[b'path:dir/subdir']
700 )
627 um = matchmod.unionmatcher([m1, m2])
701 um = matchmod.unionmatcher([m1, m2])
628 self.assertEqual(um.visitdir(b''), b'all')
702 self.assertEqual(um.visitdir(b''), b'all')
629 self.assertEqual(um.visitdir(b'dir'), b'all')
703 self.assertEqual(um.visitdir(b'dir'), b'all')
@@ -635,7 +709,9 b' class UnionMatcherTests(unittest.TestCas'
635
709
636 def testVisitchildrensetM2SubdirPrefix(self):
710 def testVisitchildrensetM2SubdirPrefix(self):
637 m1 = matchmod.alwaysmatcher()
711 m1 = matchmod.alwaysmatcher()
638 m2 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
712 m2 = matchmod.match(
713 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
714 )
639 um = matchmod.unionmatcher([m1, m2])
715 um = matchmod.unionmatcher([m1, m2])
640 self.assertEqual(um.visitchildrenset(b''), b'all')
716 self.assertEqual(um.visitchildrenset(b''), b'all')
641 self.assertEqual(um.visitchildrenset(b'dir'), b'all')
717 self.assertEqual(um.visitchildrenset(b'dir'), b'all')
@@ -648,8 +724,12 b' class UnionMatcherTests(unittest.TestCas'
648 # We're using includematcher instead of patterns because it behaves slightly
724 # We're using includematcher instead of patterns because it behaves slightly
649 # better (giving narrower results) than patternmatcher.
725 # better (giving narrower results) than patternmatcher.
650 def testVisitdirIncludeInclude(self):
726 def testVisitdirIncludeInclude(self):
651 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
727 m1 = matchmod.match(
652 m2 = matchmod.match(b'/repo', b'', include=[b'rootfilesin:dir'])
728 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
729 )
730 m2 = matchmod.match(
731 util.localpath(b'/repo'), b'', include=[b'rootfilesin:dir']
732 )
653 um = matchmod.unionmatcher([m1, m2])
733 um = matchmod.unionmatcher([m1, m2])
654 self.assertEqual(um.visitdir(b''), True)
734 self.assertEqual(um.visitdir(b''), True)
655 self.assertEqual(um.visitdir(b'dir'), True)
735 self.assertEqual(um.visitdir(b'dir'), True)
@@ -661,8 +741,12 b' class UnionMatcherTests(unittest.TestCas'
661 self.assertEqual(um.visitdir(b'dir/subdir/x'), True)
741 self.assertEqual(um.visitdir(b'dir/subdir/x'), True)
662
742
663 def testVisitchildrensetIncludeInclude(self):
743 def testVisitchildrensetIncludeInclude(self):
664 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
744 m1 = matchmod.match(
665 m2 = matchmod.match(b'/repo', b'', include=[b'rootfilesin:dir'])
745 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
746 )
747 m2 = matchmod.match(
748 util.localpath(b'/repo'), b'', include=[b'rootfilesin:dir']
749 )
666 um = matchmod.unionmatcher([m1, m2])
750 um = matchmod.unionmatcher([m1, m2])
667 self.assertEqual(um.visitchildrenset(b''), {b'dir'})
751 self.assertEqual(um.visitchildrenset(b''), {b'dir'})
668 self.assertEqual(um.visitchildrenset(b'dir'), b'this')
752 self.assertEqual(um.visitchildrenset(b'dir'), b'this')
@@ -676,8 +760,12 b' class UnionMatcherTests(unittest.TestCas'
676 # We're using includematcher instead of patterns because it behaves slightly
760 # We're using includematcher instead of patterns because it behaves slightly
677 # better (giving narrower results) than patternmatcher.
761 # better (giving narrower results) than patternmatcher.
678 def testVisitdirIncludeInclude2(self):
762 def testVisitdirIncludeInclude2(self):
679 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
763 m1 = matchmod.match(
680 m2 = matchmod.match(b'/repo', b'', include=[b'path:folder'])
764 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
765 )
766 m2 = matchmod.match(
767 util.localpath(b'/repo'), b'', include=[b'path:folder']
768 )
681 um = matchmod.unionmatcher([m1, m2])
769 um = matchmod.unionmatcher([m1, m2])
682 self.assertEqual(um.visitdir(b''), True)
770 self.assertEqual(um.visitdir(b''), True)
683 self.assertEqual(um.visitdir(b'dir'), True)
771 self.assertEqual(um.visitdir(b'dir'), True)
@@ -689,8 +777,12 b' class UnionMatcherTests(unittest.TestCas'
689 self.assertEqual(um.visitdir(b'dir/subdir/x'), True)
777 self.assertEqual(um.visitdir(b'dir/subdir/x'), True)
690
778
691 def testVisitchildrensetIncludeInclude2(self):
779 def testVisitchildrensetIncludeInclude2(self):
692 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
780 m1 = matchmod.match(
693 m2 = matchmod.match(b'/repo', b'', include=[b'path:folder'])
781 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
782 )
783 m2 = matchmod.match(
784 util.localpath(b'/repo'), b'', include=[b'path:folder']
785 )
694 um = matchmod.unionmatcher([m1, m2])
786 um = matchmod.unionmatcher([m1, m2])
695 self.assertEqual(um.visitchildrenset(b''), {b'folder', b'dir'})
787 self.assertEqual(um.visitchildrenset(b''), {b'folder', b'dir'})
696 self.assertEqual(um.visitchildrenset(b'dir'), {b'subdir'})
788 self.assertEqual(um.visitchildrenset(b'dir'), {b'subdir'})
@@ -704,8 +796,12 b' class UnionMatcherTests(unittest.TestCas'
704 # We're using includematcher instead of patterns because it behaves slightly
796 # We're using includematcher instead of patterns because it behaves slightly
705 # better (giving narrower results) than patternmatcher.
797 # better (giving narrower results) than patternmatcher.
706 def testVisitdirIncludeInclude3(self):
798 def testVisitdirIncludeInclude3(self):
707 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir/x'])
799 m1 = matchmod.match(
708 m2 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
800 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir/x']
801 )
802 m2 = matchmod.match(
803 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
804 )
709 um = matchmod.unionmatcher([m1, m2])
805 um = matchmod.unionmatcher([m1, m2])
710 self.assertEqual(um.visitdir(b''), True)
806 self.assertEqual(um.visitdir(b''), True)
711 self.assertEqual(um.visitdir(b'dir'), True)
807 self.assertEqual(um.visitdir(b'dir'), True)
@@ -717,8 +813,12 b' class UnionMatcherTests(unittest.TestCas'
717 self.assertEqual(um.visitdir(b'dir/subdir/z'), True)
813 self.assertEqual(um.visitdir(b'dir/subdir/z'), True)
718
814
719 def testVisitchildrensetIncludeInclude3(self):
815 def testVisitchildrensetIncludeInclude3(self):
720 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir/x'])
816 m1 = matchmod.match(
721 m2 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
817 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir/x']
818 )
819 m2 = matchmod.match(
820 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
821 )
722 um = matchmod.unionmatcher([m1, m2])
822 um = matchmod.unionmatcher([m1, m2])
723 self.assertEqual(um.visitchildrenset(b''), {b'dir'})
823 self.assertEqual(um.visitchildrenset(b''), {b'dir'})
724 self.assertEqual(um.visitchildrenset(b'dir'), {b'subdir'})
824 self.assertEqual(um.visitchildrenset(b'dir'), {b'subdir'})
@@ -732,8 +832,12 b' class UnionMatcherTests(unittest.TestCas'
732 # We're using includematcher instead of patterns because it behaves slightly
832 # We're using includematcher instead of patterns because it behaves slightly
733 # better (giving narrower results) than patternmatcher.
833 # better (giving narrower results) than patternmatcher.
734 def testVisitdirIncludeInclude4(self):
834 def testVisitdirIncludeInclude4(self):
735 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir/x'])
835 m1 = matchmod.match(
736 m2 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir/z'])
836 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir/x']
837 )
838 m2 = matchmod.match(
839 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir/z']
840 )
737 um = matchmod.unionmatcher([m1, m2])
841 um = matchmod.unionmatcher([m1, m2])
738 # OPT: these next three could probably be False as well.
842 # OPT: these next three could probably be False as well.
739 self.assertEqual(um.visitdir(b''), True)
843 self.assertEqual(um.visitdir(b''), True)
@@ -745,8 +849,12 b' class UnionMatcherTests(unittest.TestCas'
745 self.assertEqual(um.visitdir(b'dir/subdir/x'), b'all')
849 self.assertEqual(um.visitdir(b'dir/subdir/x'), b'all')
746
850
747 def testVisitchildrensetIncludeInclude4(self):
851 def testVisitchildrensetIncludeInclude4(self):
748 m1 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir/x'])
852 m1 = matchmod.match(
749 m2 = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir/z'])
853 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir/x']
854 )
855 m2 = matchmod.match(
856 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir/z']
857 )
750 um = matchmod.unionmatcher([m1, m2])
858 um = matchmod.unionmatcher([m1, m2])
751 self.assertEqual(um.visitchildrenset(b''), {b'dir'})
859 self.assertEqual(um.visitchildrenset(b''), {b'dir'})
752 self.assertEqual(um.visitchildrenset(b'dir'), {b'subdir'})
860 self.assertEqual(um.visitchildrenset(b'dir'), {b'subdir'})
@@ -759,7 +867,9 b' class UnionMatcherTests(unittest.TestCas'
759
867
760 class SubdirMatcherTests(unittest.TestCase):
868 class SubdirMatcherTests(unittest.TestCase):
761 def testVisitdir(self):
869 def testVisitdir(self):
762 m = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
870 m = matchmod.match(
871 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
872 )
763 sm = matchmod.subdirmatcher(b'dir', m)
873 sm = matchmod.subdirmatcher(b'dir', m)
764
874
765 self.assertEqual(sm.visitdir(b''), True)
875 self.assertEqual(sm.visitdir(b''), True)
@@ -770,7 +880,9 b' class SubdirMatcherTests(unittest.TestCa'
770 self.assertFalse(sm.visitdir(b'foo'))
880 self.assertFalse(sm.visitdir(b'foo'))
771
881
772 def testVisitchildrenset(self):
882 def testVisitchildrenset(self):
773 m = matchmod.match(b'/repo', b'', include=[b'path:dir/subdir'])
883 m = matchmod.match(
884 util.localpath(b'/repo'), b'', include=[b'path:dir/subdir']
885 )
774 sm = matchmod.subdirmatcher(b'dir', m)
886 sm = matchmod.subdirmatcher(b'dir', m)
775
887
776 self.assertEqual(sm.visitchildrenset(b''), {b'subdir'})
888 self.assertEqual(sm.visitchildrenset(b''), {b'subdir'})
General Comments 0
You need to be logged in to leave comments. Login now