comparison mercurial/match.py @ 42087:2e2699af5649

match: let regex match function return a boolean Match function for regex pattern kind is built through _buildregexmatch() and _buildmatch() using _rematcher() that returns a re.match function, which either returns a match object or None. This does not conform to Mercurial's matcher interface for __call__() or exact(), which are expected to return a boolean value. We fix this by building a lambda around _rematcher() in _buildregexmatch(). Accordingly, we update doctest examples to remove bool() calls that are now useless.
author Denis Laxalde <denis@laxalde.org>
date Sun, 07 Apr 2019 16:53:47 +0200
parents 1721b92f2b5e
children 5753e5949b51
comparison
equal deleted inserted replaced
42086:1721b92f2b5e 42087:2e2699af5649
179 179
180 >>> m = match('foo', '', ['re:.*\.c$', 'relpath:a']) 180 >>> m = match('foo', '', ['re:.*\.c$', 'relpath:a'])
181 181
182 1. Calling the matcher with a file name returns True if any pattern 182 1. Calling the matcher with a file name returns True if any pattern
183 matches that file name: 183 matches that file name:
184 >>> bool(m('a')) 184 >>> m('a')
185 True 185 True
186 >>> bool(m('main.c')) 186 >>> m('main.c')
187 True 187 True
188 >>> bool(m('test.py')) 188 >>> m('test.py')
189 False 189 False
190 190
191 2. Using the exact() method only returns True if the file name matches one 191 2. Using the exact() method only returns True if the file name matches one
192 of the exact patterns (i.e. not re: or glob: patterns): 192 of the exact patterns (i.e. not re: or glob: patterns):
193 >>> m.exact('a') 193 >>> m.exact('a')
488 ... ('path', 'foo/a', ''), 488 ... ('path', 'foo/a', ''),
489 ... ('relpath', 'b', ''), 489 ... ('relpath', 'b', ''),
490 ... ('glob', '*.h', ''), 490 ... ('glob', '*.h', ''),
491 ... ] 491 ... ]
492 >>> m = patternmatcher('foo', kindpats) 492 >>> m = patternmatcher('foo', kindpats)
493 >>> bool(m('main.c')) # matches re:.*\.c$ 493 >>> m('main.c') # matches re:.*\.c$
494 True 494 True
495 >>> bool(m('b.txt')) 495 >>> m('b.txt')
496 False 496 False
497 >>> bool(m('foo/a')) # matches path:foo/a 497 >>> m('foo/a') # matches path:foo/a
498 True 498 True
499 >>> bool(m('a')) # does not match path:b, since 'root' is 'foo' 499 >>> m('a') # does not match path:b, since 'root' is 'foo'
500 False 500 False
501 >>> bool(m('b')) # matches relpath:b, since 'root' is 'foo' 501 >>> m('b') # matches relpath:b, since 'root' is 'foo'
502 True 502 True
503 >>> bool(m('lib.h')) # matches glob:*.h 503 >>> m('lib.h') # matches glob:*.h
504 True 504 True
505 505
506 >>> m.files() 506 >>> m.files()
507 ['.', 'foo/a', 'b', '.'] 507 ['.', 'foo/a', 'b', '.']
508 >>> m.exact('foo/a') 508 >>> m.exact('foo/a')
869 The paths are remapped to remove/insert the path as needed: 869 The paths are remapped to remove/insert the path as needed:
870 870
871 >>> from . import pycompat 871 >>> from . import pycompat
872 >>> m1 = match(b'root', b'', [b'a.txt', b'sub/b.txt']) 872 >>> m1 = match(b'root', b'', [b'a.txt', b'sub/b.txt'])
873 >>> m2 = subdirmatcher(b'sub', m1) 873 >>> m2 = subdirmatcher(b'sub', m1)
874 >>> bool(m2(b'a.txt')) 874 >>> m2(b'a.txt')
875 False 875 False
876 >>> bool(m2(b'b.txt')) 876 >>> m2(b'b.txt')
877 True 877 True
878 >>> bool(m2.matchfn(b'a.txt')) 878 >>> m2.matchfn(b'a.txt')
879 False 879 False
880 >>> bool(m2.matchfn(b'b.txt')) 880 >>> m2.matchfn(b'b.txt')
881 True 881 True
882 >>> m2.files() 882 >>> m2.files()
883 ['b.txt'] 883 ['b.txt']
884 >>> m2.exact(b'b.txt') 884 >>> m2.exact(b'b.txt')
885 True 885 True
948 The prefix path should usually be the relative path from the root of 948 The prefix path should usually be the relative path from the root of
949 this matcher to the root of the wrapped matcher. 949 this matcher to the root of the wrapped matcher.
950 950
951 >>> m1 = match(util.localpath(b'root/d/e'), b'f', [b'../a.txt', b'b.txt']) 951 >>> m1 = match(util.localpath(b'root/d/e'), b'f', [b'../a.txt', b'b.txt'])
952 >>> m2 = prefixdirmatcher(b'd/e', m1) 952 >>> m2 = prefixdirmatcher(b'd/e', m1)
953 >>> bool(m2(b'a.txt'),) 953 >>> m2(b'a.txt')
954 False 954 False
955 >>> bool(m2(b'd/e/a.txt')) 955 >>> m2(b'd/e/a.txt')
956 True 956 True
957 >>> bool(m2(b'd/e/b.txt')) 957 >>> m2(b'd/e/b.txt')
958 False 958 False
959 >>> m2.files() 959 >>> m2.files()
960 ['d/e/a.txt', 'd/e/f/b.txt'] 960 ['d/e/a.txt', 'd/e/f/b.txt']
961 >>> m2.exact(b'd/e/a.txt') 961 >>> m2.exact(b'd/e/a.txt')
962 True 962 True
1285 startidx = idx 1285 startidx = idx
1286 groupsize = 0 1286 groupsize = 0
1287 groupsize += piecesize + 1 1287 groupsize += piecesize + 1
1288 1288
1289 if startidx == 0: 1289 if startidx == 0:
1290 func = _rematcher(fullregexp) 1290 matcher = _rematcher(fullregexp)
1291 func = lambda s: matcher(s) is not None
1291 else: 1292 else:
1292 group = regexps[startidx:] 1293 group = regexps[startidx:]
1293 allgroups.append(_joinregexes(group)) 1294 allgroups.append(_joinregexes(group))
1294 allmatchers = [_rematcher(g) for g in allgroups] 1295 allmatchers = [_rematcher(g) for g in allgroups]
1295 func = lambda s: any(m(s) for m in allmatchers) 1296 func = lambda s: any(m(s) for m in allmatchers)