diff options
Diffstat (limited to 'Lib/test/test_re.py')
-rw-r--r-- | Lib/test/test_re.py | 671 |
1 files changed, 297 insertions, 374 deletions
diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index a20c82f..d116c6d 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1,392 +1,315 @@ import sys sys.path = ['.'] + sys.path -from test.test_support import verify, verbose, TestFailed +from test.test_support import verbose, run_suite import re import sys, os, traceback # Misc tests from Tim Peters' re.doc -if verbose: - print 'Running tests on re.search and re.match' - -try: - verify(re.search('x*', 'axx').span(0) == (0, 0)) - verify(re.search('x*', 'axx').span() == (0, 0)) - verify(re.search('x+', 'axx').span(0) == (1, 3)) - verify(re.search('x+', 'axx').span() == (1, 3)) - verify(re.search('x', 'aaa') is None) -except: - raise TestFailed, "re.search" - -try: - verify(re.match('a*', 'xxx').span(0) == (0, 0)) - verify(re.match('a*', 'xxx').span() == (0, 0)) - verify(re.match('x*', 'xxxa').span(0) == (0, 3)) - verify(re.match('x*', 'xxxa').span() == (0, 3)) - verify(re.match('a+', 'xxx') is None) -except: - raise TestFailed, "re.search" - -if verbose: - print 'Running tests on re.sub' - -try: - verify(re.sub("(?i)b+", "x", "bbbb BBBB") == 'x x') - - def bump_num(matchobj): +import unittest + +class ReTests(unittest.TestCase): + def test_search_star_plus(self): + self.assertEqual(re.search('x*', 'axx').span(0), (0, 0)) + self.assertEqual(re.search('x*', 'axx').span(), (0, 0)) + self.assertEqual(re.search('x+', 'axx').span(0), (1, 3)) + self.assertEqual(re.search('x+', 'axx').span(), (1, 3)) + self.assertEqual(re.search('x', 'aaa') is None, True) + self.assertEqual(re.match('a*', 'xxx').span(0), (0, 0)) + self.assertEqual(re.match('a*', 'xxx').span(), (0, 0)) + self.assertEqual(re.match('x*', 'xxxa').span(0), (0, 3)) + self.assertEqual(re.match('x*', 'xxxa').span(), (0, 3)) + self.assertEqual(re.match('a+', 'xxx') is None, True) + + def bump_num(self, matchobj): int_value = int(matchobj.group(0)) return str(int_value + 1) - verify(re.sub(r'\d+', bump_num, '08.2 -2 23x99y') == '9.3 -3 24x100y') - verify(re.sub(r'\d+', bump_num, '08.2 -2 23x99y', 3) == '9.3 -3 23x99y') - - verify(re.sub('.', lambda m: r"\n", 'x') == '\\n') - verify(re.sub('.', r"\n", 'x') == '\n') - - s = r"\1\1" - verify(re.sub('(.)', s, 'x') == 'xx') - verify(re.sub('(.)', re.escape(s), 'x') == s) - verify(re.sub('(.)', lambda m: s, 'x') == s) - - verify(re.sub('(?P<a>x)', '\g<a>\g<a>', 'xx') == 'xxxx') - verify(re.sub('(?P<a>x)', '\g<a>\g<1>', 'xx') == 'xxxx') - verify(re.sub('(?P<unk>x)', '\g<unk>\g<unk>', 'xx') == 'xxxx') - verify(re.sub('(?P<unk>x)', '\g<1>\g<1>', 'xx') == 'xxxx') - - verify(re.sub('a', r'\t\n\v\r\f\a\b\B\Z\a\A\w\W\s\S\d\D', 'a') == '\t\n\v\r\f\a\b\\B\\Z\a\\A\\w\\W\\s\\S\\d\\D') - verify(re.sub('a', '\t\n\v\r\f\a', 'a') == '\t\n\v\r\f\a') - verify(re.sub('a', '\t\n\v\r\f\a', 'a') == (chr(9)+chr(10)+chr(11)+chr(13)+chr(12)+chr(7))) - - verify(re.sub('^\s*', 'X', 'test') == 'Xtest') - - # Test for sub() on escaped characters, see SF bug #449000 - verify(re.sub(r'\r\n', r'\n', 'abc\r\ndef\r\n') == 'abc\ndef\n') - verify(re.sub('\r\n', r'\n', 'abc\r\ndef\r\n') == 'abc\ndef\n') - verify(re.sub(r'\r\n', '\n', 'abc\r\ndef\r\n') == 'abc\ndef\n') - verify(re.sub('\r\n', '\n', 'abc\r\ndef\r\n') == 'abc\ndef\n') -except AssertionError: - raise TestFailed, "re.sub" - - -try: - verify(re.sub('a', 'b', 'aaaaa') == 'bbbbb') - verify(re.sub('a', 'b', 'aaaaa', 1) == 'baaaa') -except AssertionError: - raise TestFailed, "qualified re.sub" - -if verbose: - print 'Running tests on symbolic references' - -try: - re.sub('(?P<a>x)', '\g<a', 'xx') -except re.error, reason: - pass -else: - raise TestFailed, "symbolic reference" - -try: - re.sub('(?P<a>x)', '\g<', 'xx') -except re.error, reason: - pass -else: - raise TestFailed, "symbolic reference" - -try: - re.sub('(?P<a>x)', '\g', 'xx') -except re.error, reason: - pass -else: - raise TestFailed, "symbolic reference" - -try: - re.sub('(?P<a>x)', '\g<a a>', 'xx') -except re.error, reason: - pass -else: - raise TestFailed, "symbolic reference" - -try: - re.sub('(?P<a>x)', '\g<1a1>', 'xx') -except re.error, reason: - pass -else: - raise TestFailed, "symbolic reference" - -try: - re.sub('(?P<a>x)', '\g<ab>', 'xx') -except IndexError, reason: - pass -else: - raise TestFailed, "symbolic reference" - -try: - re.sub('(?P<a>x)|(?P<b>y)', '\g<b>', 'xx') -except re.error, reason: - pass -else: - raise TestFailed, "symbolic reference" - -try: - re.sub('(?P<a>x)|(?P<b>y)', '\\2', 'xx') -except re.error, reason: - pass -else: - raise TestFailed, "symbolic reference" - -if verbose: - print 'Running tests on re.subn' - -try: - verify(re.subn("(?i)b+", "x", "bbbb BBBB") == ('x x', 2)) - verify(re.subn("b+", "x", "bbbb BBBB") == ('x BBBB', 1)) - verify(re.subn("b+", "x", "xyz") == ('xyz', 0)) - verify(re.subn("b*", "x", "xyz") == ('xxxyxzx', 4)) - verify(re.subn("b*", "x", "xyz", 2) == ('xxxyz', 2)) -except AssertionError: - raise TestFailed, "re.subn" - -if verbose: - print 'Running tests on re.split' - -try: - verify(re.split(":", ":a:b::c") == ['', 'a', 'b', '', 'c']) - verify(re.split(":*", ":a:b::c") == ['', 'a', 'b', 'c']) - verify(re.split("(:*)", ":a:b::c") == ['', ':', 'a', ':', 'b', '::', 'c']) - verify(re.split("(?::*)", ":a:b::c") == ['', 'a', 'b', 'c']) - verify(re.split("(:)*", ":a:b::c") == ['', ':', 'a', ':', 'b', ':', 'c']) - verify(re.split("([b:]+)", ":a:b::c") == ['', ':', 'a', ':b::', 'c']) - verify(re.split("(b)|(:+)", ":a:b::c") == \ - ['', None, ':', 'a', None, ':', '', 'b', None, '', None, '::', 'c'] ) - verify(re.split("(?:b)|(?::+)", ":a:b::c") == ['', 'a', '', '', 'c']) -except AssertionError: - raise TestFailed, "re.split" - -try: - verify(re.split(":", ":a:b::c", 2) == ['', 'a', 'b::c']) - verify(re.split(':', 'a:b:c:d', 2) == ['a', 'b', 'c:d']) - - verify(re.split("(:)", ":a:b::c", 2) == ['', ':', 'a', ':', 'b::c']) - verify(re.split("(:*)", ":a:b::c", 2) == ['', ':', 'a', ':', 'b::c']) -except AssertionError: - raise TestFailed, "qualified re.split" - -if verbose: - print "Running tests on re.findall" - -try: - verify(re.findall(":+", "abc") == []) - verify(re.findall(":+", "a:b::c:::d") == [":", "::", ":::"]) - verify(re.findall("(:+)", "a:b::c:::d") == [":", "::", ":::"]) - verify(re.findall("(:)(:*)", "a:b::c:::d") == [(":", ""), - (":", ":"), - (":", "::")] ) -except AssertionError: - raise TestFailed, "re.findall" - -if verbose: - print "Running tests on re.match" - -try: - # No groups at all - m = re.match('a', 'a') ; verify(m.groups() == ()) - # A single group - m = re.match('(a)', 'a') ; verify(m.groups() == ('a',)) - - pat = re.compile('((a)|(b))(c)?') - verify(pat.match('a').groups() == ('a', 'a', None, None)) - verify(pat.match('b').groups() == ('b', None, 'b', None)) - verify(pat.match('ac').groups() == ('a', 'a', None, 'c')) - verify(pat.match('bc').groups() == ('b', None, 'b', 'c')) - verify(pat.match('bc').groups("") == ('b', "", 'b', 'c')) -except AssertionError: - raise TestFailed, "match .groups() method" - -try: - # A single group - m = re.match('(a)', 'a') - verify(m.group(0) == 'a') - verify(m.group(0) == 'a') - verify(m.group(1) == 'a') - verify(m.group(1, 1) == ('a', 'a')) - - pat = re.compile('(?:(?P<a1>a)|(?P<b2>b))(?P<c3>c)?') - verify(pat.match('a').group(1, 2, 3) == ('a', None, None)) - verify(pat.match('b').group('a1', 'b2', 'c3') == (None, 'b', None)) - verify(pat.match('ac').group(1, 'b2', 3) == ('a', None, 'c')) -except AssertionError: - raise TestFailed, "match .group() method" - -if verbose: - print "Running tests on re.escape" - -try: - p="" - for i in range(0, 256): - p = p + chr(i) - verify(re.match(re.escape(chr(i)), chr(i)) is not None) - verify(re.match(re.escape(chr(i)), chr(i)).span() == (0,1)) - - pat=re.compile( re.escape(p) ) - verify(pat.match(p) is not None) - verify(pat.match(p).span() == (0,256)) -except AssertionError: - raise TestFailed, "re.escape" - - -if verbose: - print 'Pickling a RegexObject instance' - -import pickle -pat = re.compile('a(?:b|(c|e){1,2}?|d)+?(.)') -s = pickle.dumps(pat) -pat = pickle.loads(s) - -try: - verify(re.I == re.IGNORECASE) - verify(re.L == re.LOCALE) - verify(re.M == re.MULTILINE) - verify(re.S == re.DOTALL) - verify(re.X == re.VERBOSE) -except AssertionError: - raise TestFailed, 're module constants' - -for flags in [re.I, re.M, re.X, re.S, re.L]: - try: - r = re.compile('^pattern$', flags) - except: - print 'Exception raised on flag', flags - -if verbose: - print 'Test engine limitations' - -# Try nasty case that overflows the straightforward recursive -# implementation of repeated groups. -try: - verify(re.match('(x)*', 50000*'x').span() == (0, 50000)) -except RuntimeError, v: - print v - -from test.re_tests import * - -if verbose: - print 'Running re_tests test suite' -else: - # To save time, only run the first and last 10 tests - #tests = tests[:10] + tests[-10:] - pass - -for t in tests: - sys.stdout.flush() - pattern = s = outcome = repl = expected = None - if len(t) == 5: - pattern, s, outcome, repl, expected = t - elif len(t) == 3: - pattern, s, outcome = t + def test_basic_re_sub(self): + self.assertEqual(re.sub("(?i)b+", "x", "bbbb BBBB"), 'x x') + self.assertEqual(re.sub(r'\d+', self.bump_num, '08.2 -2 23x99y'), + '9.3 -3 24x100y') + self.assertEqual(re.sub(r'\d+', self.bump_num, '08.2 -2 23x99y', 3), + '9.3 -3 23x99y') + + self.assertEqual(re.sub('.', lambda m: r"\n", 'x'), '\\n') + self.assertEqual(re.sub('.', r"\n", 'x'), '\n') + + s = r"\1\1" + self.assertEqual(re.sub('(.)', s, 'x'), 'xx') + self.assertEqual(re.sub('(.)', re.escape(s), 'x'), s) + self.assertEqual(re.sub('(.)', lambda m: s, 'x'), s) + + self.assertEqual(re.sub('(?P<a>x)', '\g<a>\g<a>', 'xx'), 'xxxx') + self.assertEqual(re.sub('(?P<a>x)', '\g<a>\g<1>', 'xx'), 'xxxx') + self.assertEqual(re.sub('(?P<unk>x)', '\g<unk>\g<unk>', 'xx'), 'xxxx') + self.assertEqual(re.sub('(?P<unk>x)', '\g<1>\g<1>', 'xx'), 'xxxx') + + self.assertEqual(re.sub('a',r'\t\n\v\r\f\a\b\B\Z\a\A\w\W\s\S\d\D','a'), + '\t\n\v\r\f\a\b\\B\\Z\a\\A\\w\\W\\s\\S\\d\\D') + self.assertEqual(re.sub('a', '\t\n\v\r\f\a', 'a'), '\t\n\v\r\f\a') + self.assertEqual(re.sub('a', '\t\n\v\r\f\a', 'a'), + (chr(9)+chr(10)+chr(11)+chr(13)+chr(12)+chr(7))) + + self.assertEqual(re.sub('^\s*', 'X', 'test'), 'Xtest') + + def test_escaped_re_sub(self): + # Test for sub() on escaped characters, see SF bug #449000 + self.assertEqual(re.sub(r'\r\n', r'\n', 'abc\r\ndef\r\n'), + 'abc\ndef\n') + self.assertEqual(re.sub('\r\n', r'\n', 'abc\r\ndef\r\n'), + 'abc\ndef\n') + self.assertEqual(re.sub(r'\r\n', '\n', 'abc\r\ndef\r\n'), + 'abc\ndef\n') + self.assertEqual(re.sub('\r\n', '\n', 'abc\r\ndef\r\n'), + 'abc\ndef\n') + + def test_qualified_re_sub(self): + self.assertEqual(re.sub('a', 'b', 'aaaaa'), 'bbbbb') + self.assertEqual(re.sub('a', 'b', 'aaaaa', 1), 'baaaa') + + def test_symbolic_refs(self): + self.assertRaises(re.error, re.sub, '(?P<a>x)', '\g<a', 'xx') + self.assertRaises(re.error, re.sub, '(?P<a>x)', '\g<', 'xx') + self.assertRaises(re.error, re.sub, '(?P<a>x)', '\g', 'xx') + self.assertRaises(re.error, re.sub, '(?P<a>x)', '\g<a a>', 'xx') + self.assertRaises(re.error, re.sub, '(?P<a>x)', '\g<1a1>', 'xx') + self.assertRaises(IndexError, re.sub, '(?P<a>x)', '\g<ab>', 'xx') + self.assertRaises(re.error, re.sub, '(?P<a>x)|(?P<b>y)', '\g<b>', 'xx') + self.assertRaises(re.error, re.sub, '(?P<a>x)|(?P<b>y)', '\\2', 'xx') + + def test_re_subn(self): + self.assertEqual(re.subn("(?i)b+", "x", "bbbb BBBB"), ('x x', 2)) + self.assertEqual(re.subn("b+", "x", "bbbb BBBB"), ('x BBBB', 1)) + self.assertEqual(re.subn("b+", "x", "xyz"), ('xyz', 0)) + self.assertEqual(re.subn("b*", "x", "xyz"), ('xxxyxzx', 4)) + self.assertEqual(re.subn("b*", "x", "xyz", 2), ('xxxyz', 2)) + + def test_re_split(self): + self.assertEqual(re.split(":", ":a:b::c"), ['', 'a', 'b', '', 'c']) + self.assertEqual(re.split(":*", ":a:b::c"), ['', 'a', 'b', 'c']) + self.assertEqual(re.split("(:*)", ":a:b::c"), + ['', ':', 'a', ':', 'b', '::', 'c']) + self.assertEqual(re.split("(?::*)", ":a:b::c"), ['', 'a', 'b', 'c']) + self.assertEqual(re.split("(:)*", ":a:b::c"), + ['', ':', 'a', ':', 'b', ':', 'c']) + self.assertEqual(re.split("([b:]+)", ":a:b::c"), + ['', ':', 'a', ':b::', 'c']) + self.assertEqual(re.split("(b)|(:+)", ":a:b::c"), + ['', None, ':', 'a', None, ':', '', 'b', None, '', + None, '::', 'c']) + self.assertEqual(re.split("(?:b)|(?::+)", ":a:b::c"), + ['', 'a', '', '', 'c']) + + def test_qualified_re_split(self): + self.assertEqual(re.split(":", ":a:b::c", 2), ['', 'a', 'b::c']) + self.assertEqual(re.split(':', 'a:b:c:d', 2), ['a', 'b', 'c:d']) + self.assertEqual(re.split("(:)", ":a:b::c", 2), + ['', ':', 'a', ':', 'b::c']) + self.assertEqual(re.split("(:*)", ":a:b::c", 2), + ['', ':', 'a', ':', 'b::c']) + + def test_re_findall(self): + self.assertEqual(re.findall(":+", "abc"), []) + self.assertEqual(re.findall(":+", "a:b::c:::d"), [":", "::", ":::"]) + self.assertEqual(re.findall("(:+)", "a:b::c:::d"), [":", "::", ":::"]) + self.assertEqual(re.findall("(:)(:*)", "a:b::c:::d"), [(":", ""), + (":", ":"), + (":", "::")]) + + def test_re_match(self): + # No groups at all + m = re.match('a', 'a') + self.assertEqual(m.groups(), ()) + # A single group + m = re.match('(a)', 'a') + self.assertEqual(m.groups(), ('a',)) + + pat = re.compile('((a)|(b))(c)?') + self.assertEqual(pat.match('a').groups(), ('a', 'a', None, None)) + self.assertEqual(pat.match('b').groups(), ('b', None, 'b', None)) + self.assertEqual(pat.match('ac').groups(), ('a', 'a', None, 'c')) + self.assertEqual(pat.match('bc').groups(), ('b', None, 'b', 'c')) + self.assertEqual(pat.match('bc').groups(""), ('b', "", 'b', 'c')) + + # A single group + m = re.match('(a)', 'a') + self.assertEqual(m.group(0), 'a') + self.assertEqual(m.group(0), 'a') + self.assertEqual(m.group(1), 'a') + self.assertEqual(m.group(1, 1), ('a', 'a')) + + pat = re.compile('(?:(?P<a1>a)|(?P<b2>b))(?P<c3>c)?') + self.assertEqual(pat.match('a').group(1, 2, 3), ('a', None, None)) + self.assertEqual(pat.match('b').group('a1', 'b2', 'c3'), + (None, 'b', None)) + self.assertEqual(pat.match('ac').group(1, 'b2', 3), ('a', None, 'c')) + + def test_re_escape(self): + p="" + for i in range(0, 256): + p = p + chr(i) + self.assertEqual(re.match(re.escape(chr(i)), chr(i)) is not None, + True) + self.assertEqual(re.match(re.escape(chr(i)), chr(i)).span(), (0,1)) + + pat=re.compile( re.escape(p) ) + self.assertEqual(pat.match(p) is not None, True) + self.assertEqual(pat.match(p).span(), (0,256)) + + def test_pickling(self): + import pickle + oldpat = re.compile('a(?:b|(c|e){1,2}?|d)+?(.)') + s = pickle.dumps(oldpat) + newpat = pickle.loads(s) + self.assertEqual(oldpat, newpat) + + def test_constants(self): + self.assertEqual(re.I, re.IGNORECASE) + self.assertEqual(re.L, re.LOCALE) + self.assertEqual(re.M, re.MULTILINE) + self.assertEqual(re.S, re.DOTALL) + self.assertEqual(re.X, re.VERBOSE) + + def test_flags(self): + for flags in [re.I, re.M, re.X, re.S, re.L]: + r = re.compile('^pattern$', flags) + + def test_limitations(self): + # Try nasty case that overflows the straightforward recursive + # implementation of repeated groups. + self.assertEqual(re.match('(x)*', 50000*'x').span(), (0, 50000)) + +def run_re_tests(): + from test.re_tests import benchmarks, tests, SUCCEED, FAIL, SYNTAX_ERROR + if verbose: + print 'Running re_tests test suite' else: - raise ValueError, ('Test tuples should have 3 or 5 fields', t) - - try: - obj = re.compile(pattern) - except re.error: - if outcome == SYNTAX_ERROR: pass # Expected a syntax error + # To save time, only run the first and last 10 tests + #tests = tests[:10] + tests[-10:] + pass + + for t in tests: + sys.stdout.flush() + pattern = s = outcome = repl = expected = None + if len(t) == 5: + pattern, s, outcome, repl, expected = t + elif len(t) == 3: + pattern, s, outcome = t else: - print '=== Syntax error:', t - except KeyboardInterrupt: raise KeyboardInterrupt - except: - print '*** Unexpected error ***', t - if verbose: - traceback.print_exc(file=sys.stdout) - else: + raise ValueError, ('Test tuples should have 3 or 5 fields', t) + try: - result = obj.search(s) - except re.error, msg: - print '=== Unexpected exception', t, repr(msg) - if outcome == SYNTAX_ERROR: - # This should have been a syntax error; forget it. - pass - elif outcome == FAIL: - if result is None: pass # No match, as expected - else: print '=== Succeeded incorrectly', t - elif outcome == SUCCEED: - if result is not None: - # Matched, as expected, so now we compute the - # result string and compare it to our expected result. - start, end = result.span(0) - vardict={'found': result.group(0), - 'groups': result.group(), - 'flags': result.re.flags} - for i in range(1, 100): - try: - gi = result.group(i) - # Special hack because else the string concat fails: - if gi is None: - gi = "None" - except IndexError: - gi = "Error" - vardict['g%d' % i] = gi - for i in result.re.groupindex.keys(): - try: - gi = result.group(i) - if gi is None: - gi = "None" - except IndexError: - gi = "Error" - vardict[i] = gi - repl = eval(repl, vardict) - if repl != expected: - print '=== grouping error', t, - print repr(repl) + ' should be ' + repr(expected) + obj = re.compile(pattern) + except re.error: + if outcome == SYNTAX_ERROR: pass # Expected a syntax error else: - print '=== Failed incorrectly', t - - # Try the match on a unicode string, and check that it - # still succeeds. + print '=== Syntax error:', t + except KeyboardInterrupt: raise KeyboardInterrupt + except: + print '*** Unexpected error ***', t + if verbose: + traceback.print_exc(file=sys.stdout) + else: try: - result = obj.search(unicode(s, "latin-1")) + result = obj.search(s) + except re.error, msg: + print '=== Unexpected exception', t, repr(msg) + if outcome == SYNTAX_ERROR: + # This should have been a syntax error; forget it. + pass + elif outcome == FAIL: + if result is None: pass # No match, as expected + else: print '=== Succeeded incorrectly', t + elif outcome == SUCCEED: + if result is not None: + # Matched, as expected, so now we compute the + # result string and compare it to our expected result. + start, end = result.span(0) + vardict={'found': result.group(0), + 'groups': result.group(), + 'flags': result.re.flags} + for i in range(1, 100): + try: + gi = result.group(i) + # Special hack because else the string concat fails: + if gi is None: + gi = "None" + except IndexError: + gi = "Error" + vardict['g%d' % i] = gi + for i in result.re.groupindex.keys(): + try: + gi = result.group(i) + if gi is None: + gi = "None" + except IndexError: + gi = "Error" + vardict[i] = gi + repl = eval(repl, vardict) + if repl != expected: + print '=== grouping error', t, + print repr(repl) + ' should be ' + repr(expected) + else: + print '=== Failed incorrectly', t + + # Try the match on a unicode string, and check that it + # still succeeds. + try: + result = obj.search(unicode(s, "latin-1")) + if result is None: + print '=== Fails on unicode match', t + except NameError: + continue # 1.5.2 + except TypeError: + continue # unicode test case + + # Try the match on a unicode pattern, and check that it + # still succeeds. + obj=re.compile(unicode(pattern, "latin-1")) + result = obj.search(s) if result is None: - print '=== Fails on unicode match', t - except NameError: - continue # 1.5.2 - except TypeError: - continue # unicode test case - - # Try the match on a unicode pattern, and check that it - # still succeeds. - obj=re.compile(unicode(pattern, "latin-1")) - result = obj.search(s) - if result is None: - print '=== Fails on unicode pattern match', t - - # Try the match with the search area limited to the extent - # of the match and see if it still succeeds. \B will - # break (because it won't match at the end or start of a - # string), so we'll ignore patterns that feature it. - - if pattern[:2] != '\\B' and pattern[-2:] != '\\B' \ - and result is not None: - obj = re.compile(pattern) - result = obj.search(s, result.start(0), result.end(0) + 1) + print '=== Fails on unicode pattern match', t + + # Try the match with the search area limited to the extent + # of the match and see if it still succeeds. \B will + # break (because it won't match at the end or start of a + # string), so we'll ignore patterns that feature it. + + if pattern[:2] != '\\B' and pattern[-2:] != '\\B' \ + and result is not None: + obj = re.compile(pattern) + result = obj.search(s, result.start(0), result.end(0) + 1) + if result is None: + print '=== Failed on range-limited match', t + + # Try the match with IGNORECASE enabled, and check that it + # still succeeds. + obj = re.compile(pattern, re.IGNORECASE) + result = obj.search(s) if result is None: - print '=== Failed on range-limited match', t - - # Try the match with IGNORECASE enabled, and check that it - # still succeeds. - obj = re.compile(pattern, re.IGNORECASE) - result = obj.search(s) - if result is None: - print '=== Fails on case-insensitive match', t - - # Try the match with LOCALE enabled, and check that it - # still succeeds. - obj = re.compile(pattern, re.LOCALE) - result = obj.search(s) - if result is None: - print '=== Fails on locale-sensitive match', t - - # Try the match with UNICODE locale enabled, and check - # that it still succeeds. - obj = re.compile(pattern, re.UNICODE) - result = obj.search(s) - if result is None: - print '=== Fails on unicode-sensitive match', t + print '=== Fails on case-insensitive match', t + + # Try the match with LOCALE enabled, and check that it + # still succeeds. + obj = re.compile(pattern, re.LOCALE) + result = obj.search(s) + if result is None: + print '=== Fails on locale-sensitive match', t + + # Try the match with UNICODE locale enabled, and check + # that it still succeeds. + obj = re.compile(pattern, re.UNICODE) + result = obj.search(s) + if result is None: + print '=== Fails on unicode-sensitive match', t + +def test_main(): + run_re_tests() + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(ReTests)) + run_suite(suite) + +if __name__ == "__main__": + test_main() |