codon/test/stdlib/re_test.codon

448 lines
17 KiB
Python
Raw Permalink Normal View History

import re
import string
@test
def test_search_star_plus():
assert re.search('x*', 'axx').span(0) == (0, 0)
assert re.search('x*', 'axx').span() == (0, 0)
assert re.search('x+', 'axx').span(0) == (1, 3)
assert re.search('x+', 'axx').span() == (1, 3)
assert re.search('x', 'aaa') is None
assert re.match('a*', 'xxx').span(0) == (0, 0)
assert re.match('a*', 'xxx').span() == (0, 0)
assert re.match('x*', 'xxxa').span(0) == (0, 3)
assert re.match('x*', 'xxxa').span() == (0, 3)
assert re.match('a+', 'xxx') is None
test_search_star_plus()
@test
def test_branching():
"""Test Branching
Test expressions using the OR ('|') operator."""
assert re.match('(ab|ba)', 'ab').span() == (0, 2)
assert re.match('(ab|ba)', 'ba').span() == (0, 2)
assert re.match('(abc|bac|ca|cb)', 'abc').span() == (0, 3)
assert re.match('(abc|bac|ca|cb)', 'bac').span() == (0, 3)
assert re.match('(abc|bac|ca|cb)', 'ca').span() == (0, 2)
assert re.match('(abc|bac|ca|cb)', 'cb').span() == (0, 2)
assert re.match('((a)|(b)|(c))', 'a').span() == (0, 1)
assert re.match('((a)|(b)|(c))', 'b').span() == (0, 1)
assert re.match('((a)|(b)|(c))', 'c').span() == (0, 1)
test_branching()
Typechecker refactoring (#20) * Initial refactor commit * Support external vars * Simplify refactor; Python scoping [wip] * Python scoping [wip] * Python scoping [fix loops; wip] * Fix lambdas * Python scoping [test fixes; wip] * Fix scoping [wip] * Fix basic tests [no-ci] * Fix tests * CallExpr refactoring [wip] * CallExpr refactoring [wip] * Remove activeUnbounds tracking * Add core.codon * Move Function and other core types to core.codon; Revamp Function and Callable types * Refactor IntExpr, FloatExpr and CallExpr * Refactor ClassStmt * Refactor context, IdExpr and DotExpr * Refactor DotExpr and AssignStmt * Refactor ImportStmt * Refactor FunctionStmt * Refactor * Remove UpdateStmt * Refactor AssignReplacementVisitor * Make SimplifyVisitor in-place * Fix new scoping * Fix import type alias handling * Add docstrings; Complete Simplify refactoring * Fixes for seqtest * Refactor typecheck [wip] * Refactor typecheck [wip] * Refactor typecheck/access; Remove void anduse NoneType; Fix #18 * Refactor typecheck/assign * clang-format and cmake-format * Fix none types in IR * Multi-error support in simplify * Fix IR tests for new void * Simplify ClassStmt * Refactor cond.cpp * Refactor error.cpp * Refactor function.cpp and simplify unbounds * Refactor op.cpp * Refactor call.cpp [wip] [no-ci] * seqassertn updates [noci] * Refactor call.cpp * Refactor call.cpp * Refactor call.cpp * Refactor typecheck * clang-tidy updates [noci] * Refactor infer.cpp [wip] * Refactor infer.cpp * Refactor wrapExpr * Remove visitedAsts * Remove old base logic * Refactor typecheck ctx * Fix JIT bug * Fix JIT tests * Scoping fixes [wip] [noci] * Fix ImperativeForFlow var store * Add newlines [noci] * Dump IR module with log flag * Fix scoping bugs; Add &, ^ and | static operations; Address stylistic review issues * Fix side effect analysis for for-loops * Add support for class variables and ClassVar * Refactor special dot-member cases * Add codon app tests * Fix class variables; clang-tidy * Fix __argv__ * Add datetime constants and update tests * Fix #25; Add Py_None, Py_True and Py_False; External var support [wip] * External var support [wip] * Dump LLVM IR when debug flags are active * clang-format * Fix arg var construction * Extern var fixes * Undo extern var changes related to stdout etc. * Fix tuple magics * Fix extern vars and tuple magics * Fix duplicate var name error * Fix extern vars * Fix #16 * Fix side-effect analysis for try-catch * Move test C var to test executable * Add staticmethod * Fix var status for try-catch * Fix tests * Fix shell var name * Fix test * Fix app test * Fix scoping issue (remove dominated identifier from stack) * Fix no-pie issue * Use PIC when building library object * Don't use -no-pie when building library [noci] * Use -relocation-model=pic in test * Fix lib build on Linux * Fix lib build * Update exceptions to use subclasses vs. header * Fix __repr__ * Fix tests * Fix exceptions test * Don't build docs Co-authored-by: A. R. Shajii <ars@ars.me>
2022-07-26 20:06:00 +00:00
@test
def test_basic_re_sub():
def bump_num(matchobj):
int_value = int(matchobj.group(0))
return str(int_value + 1)
assert re.sub('y', 'a', 'xyz') == 'xaz'
assert re.sub("(?i)b+", "x", "bbbb BBBB") == 'x x'
assert re.sub(r'\d+', bump_num, '08.2 -2 23x99y') == '9.3 -3 24x100y'
assert re.sub(r'\d+', bump_num, '08.2 -2 23x99y', 3) == '9.3 -3 23x99y'
assert re.sub(r'\d+', bump_num, '08.2 -2 23x99y', count=3) == '9.3 -3 23x99y'
assert re.sub('.', lambda m: r"\n", 'x') == '\\n'
assert re.sub('.', r"\n", 'x') == '\n'
s = r"\1\1"
assert re.sub('(.)', s, 'x') == 'xx'
assert re.sub('(.)', s.replace('\\', r'\\'), 'x') == s
assert re.sub('(.)', lambda m: s, 'x') == s
assert re.sub('(?P<a>x)', r'\g<a>\g<a>', 'xx') == 'xxxx'
assert re.sub('(?P<a>x)', r'\g<a>\g<1>', 'xx') == 'xxxx'
assert re.sub('(?P<unk>x)', r'\g<unk>\g<unk>', 'xx') == 'xxxx'
assert re.sub('(?P<unk>x)', r'\g<1>\g<1>', 'xx') == 'xxxx'
assert re.sub('()x', r'\g<0>\g<0>', 'xx') == 'xxxx'
assert re.sub('a', r'\t\n\v\r\f\a\b', 'a') == '\t\n\v\r\f\a\b'
assert re.sub('a', '\t\n\v\r\f\a\b', 'a') == '\t\n\v\r\f\a\b'
assert re.sub('a', '\t\n\v\r\f\a\b', 'a') == (chr(9)+chr(10)+chr(11)+chr(13)+chr(12)+chr(7)+chr(8))
for c in 'cdehijklmopqsuwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ':
try:
re.sub('a', '\\' + c, 'a')
assert False
except re.error:
pass
assert re.sub(r'^\s*', 'X', 'test') == 'Xtest'
test_basic_re_sub()
@test
def test_bug_449964():
assert re.sub(r'(?P<unk>x)', r'\g<1>\g<1>\b', 'xx') == 'xx\bxx\b'
test_bug_449964()
@test
def test_bug_449000():
# Test for sub() on escaped characters
assert re.sub(r'\r\n', r'\n', 'abc\r\ndef\r\n') == 'abc\ndef\n'
assert re.sub('\r\n', r'\n', 'abc\r\ndef\r\n') =='abc\ndef\n'
assert re.sub(r'\r\n', '\n', 'abc\r\ndef\r\n') == 'abc\ndef\n'
assert re.sub('\r\n', '\n', 'abc\r\ndef\r\n') == 'abc\ndef\n'
test_bug_449000()
@test
def test_sub_template_numeric_escape():
# bug 776311 and friends
assert re.sub('x', r'\0', 'x') == '\0'
assert re.sub('x', r'\000', 'x') == '\000'
assert re.sub('x', r'\001', 'x') == '\001'
assert re.sub('x', r'\008', 'x') == '\0' + '8'
assert re.sub('x', r'\009', 'x') == '\0' + '9'
assert re.sub('x', r'\111', 'x') == '\111'
assert re.sub('x', r'\117', 'x') == '\117'
assert re.sub('x', r'\377', 'x') == '\377'
assert re.sub('x', r'\1111', 'x'), '\1111'
assert re.sub('x', r'\1111', 'x'), '\111' + '1'
assert re.sub('x', r'\00', 'x') == '\x00'
assert re.sub('x', r'\07', 'x') == '\x07'
assert re.sub('x', r'\08', 'x') == '\0' + '8'
assert re.sub('x', r'\09', 'x') == '\0' + '9'
assert re.sub('x', r'\0a', 'x') == '\0' + 'a'
'''
self.checkTemplateError('x', r'\400', 'x',
r'octal escape value \400 outside of '
r'range 0-0o377', 0)
self.checkTemplateError('x', r'\777', 'x',
r'octal escape value \777 outside of '
r'range 0-0o377', 0)
self.checkTemplateError('x', r'\1', 'x', 'invalid group reference 1', 1)
self.checkTemplateError('x', r'\8', 'x', 'invalid group reference 8', 1)
self.checkTemplateError('x', r'\9', 'x', 'invalid group reference 9', 1)
self.checkTemplateError('x', r'\11', 'x', 'invalid group reference 11', 1)
self.checkTemplateError('x', r'\18', 'x', 'invalid group reference 18', 1)
self.checkTemplateError('x', r'\1a', 'x', 'invalid group reference 1', 1)
self.checkTemplateError('x', r'\90', 'x', 'invalid group reference 90', 1)
self.checkTemplateError('x', r'\99', 'x', 'invalid group reference 99', 1)
self.checkTemplateError('x', r'\118', 'x', 'invalid group reference 11', 1)
self.checkTemplateError('x', r'\11a', 'x', 'invalid group reference 11', 1)
self.checkTemplateError('x', r'\181', 'x', 'invalid group reference 18', 1)
self.checkTemplateError('x', r'\800', 'x', 'invalid group reference 80', 1)
self.checkTemplateError('x', r'\8', '', 'invalid group reference 8', 1)
'''
assert re.sub('(((((((((((x)))))))))))', r'\11', 'x') == 'x'
assert re.sub('((((((((((y))))))))))(.)', r'\118', 'xyz') == 'xz8'
assert re.sub('((((((((((y))))))))))(.)', r'\11a', 'xyz') == 'xza'
test_sub_template_numeric_escape()
@test
def test_qualified_re_sub():
assert re.sub('a', 'b', 'aaaaa') == 'bbbbb'
assert re.sub('a', 'b', 'aaaaa', 1) == 'baaaa'
assert re.sub('a', 'b', 'aaaaa', count=1) == 'baaaa'
test_qualified_re_sub()
@test
def test_bug_114660():
assert re.sub(r'(\S)\s+(\S)', r'\1 \2', 'hello there') == 'hello there'
test_bug_114660()
@test
def test_symbolic_refs():
assert re.sub('(?P<a>x)|(?P<b>y)', r'\g<b>', 'xx') == ''
assert re.sub('(?P<a>x)|(?P<b>y)', r'\2', 'xx') == ''
# Support > 100 groups.
pat = '|'.join(f'x(?P<a{i}>{hex(i)[2:]})y' for i in range(1, 200 + 1))
assert re.sub(pat, r'\g<200>', 'xc8yzxc8y') == 'c8zc8'
test_symbolic_refs()
@test
def test_re_subn():
assert re.subn("(?i)b+", "x", "bbbb BBBB") == ('x x', 2)
assert re.subn("b+", "x", "bbbb BBBB") == ('x BBBB', 1)
assert re.subn("b+", "x", "xyz") == ('xyz', 0)
assert re.subn("b*", "x", "xyz") == ('xxxyxzx', 4)
assert re.subn("b*", "x", "xyz", 2) == ('xxxyz', 2)
assert re.subn("b*", "x", "xyz", count=2) == ('xxxyz', 2)
test_re_subn()
# TODO: Current version does not allow None == None,
# so use this as a workaround.
def cmp_opt(x, y):
if x is None:
return y is None
elif y is None:
return x is None
else:
return unwrap(x) == unwrap(y)
def cmp_list(a, b):
if len(a) != len(b):
return False
for i in range(len(a)):
if not cmp_opt(a[i], b[i]):
return False
return True
def cmp_tuple(a, b):
if staticlen(a) != staticlen(b):
return False
elif staticlen(a) == 0:
return True
else:
if not cmp_opt(a[0], b[0]):
return False
return cmp_tuple(a[1:], b[1:])
@test
def test_re_split():
assert cmp_list(re.split(":", ":a:b::c"), ['', 'a', 'b', '', 'c'])
assert cmp_list(re.split(":+", ":a:b::c"), ['', 'a', 'b', 'c'])
assert cmp_list(re.split("(:+)", ":a:b::c"), ['', ':', 'a', ':', 'b', '::', 'c'])
assert cmp_list(re.split("(?::+)", ":a:b::c"), ['', 'a', 'b', 'c'])
assert cmp_list(re.split("(:)+", ":a:b::c"), ['', ':', 'a', ':', 'b', ':', 'c'])
assert cmp_list(re.split("([b:]+)", ":a:b::c"), ['', ':', 'a', ':b::', 'c'])
assert cmp_list(re.split("(b)|(:+)", ":a:b::c"), [None, '', None, ':', 'a', None, ':', '', 'b', None, '', None, '::', 'c'][1:])
assert cmp_list(re.split("(?:b)|(?::+)", ":a:b::c"), ['', 'a', '', '', 'c'])
for sep, expected in [
(':*', [None, '', '', 'a', '', 'b', '', 'c', ''][1:]),
('(?::*)', [None, '', '', 'a', '', 'b', '', 'c', ''][1:]),
('(:*)', [None, '', ':', '', '', 'a', ':', '', '', 'b', '::', '', '', 'c', '', ''][1:]),
('(:)*', [None, '', ':', '', None, 'a', ':', '', None, 'b', ':', '', None, 'c', None, ''][1:]),
]:
assert cmp_list(re.split(sep, ':a:b::c'), expected)
for sep, expected in [
('', ['', ':', 'a', ':', 'b', ':', ':', 'c', '']),
# (r'\b', [':', 'a', ':', 'b', '::', 'c', '']), # TODO: this fails; re2 difference maybe?
]:
assert cmp_list(re.split(sep, ':a:b::c'), expected)
test_re_split()
@test
def test_qualified_re_split():
assert cmp_list(re.split(":", ":a:b::c", 2), ['', 'a', 'b::c'])
assert cmp_list(re.split(":", ":a:b::c", maxsplit=2), ['', 'a', 'b::c'])
assert cmp_list(re.split(':', 'a:b:c:d', maxsplit=2), ['a', 'b', 'c:d'])
assert cmp_list(re.split("(:)", ":a:b::c", maxsplit=2), ['', ':', 'a', ':', 'b::c'])
assert cmp_list(re.split("(:+)", ":a:b::c", maxsplit=2), ['', ':', 'a', ':', 'b::c'])
assert cmp_list(re.split("(:*)", ":a:b::c", maxsplit=2), ['', ':', '', '', 'a:b::c'])
test_qualified_re_split()
@test
def test_re_findall():
assert re.findall(":+", "abc") == []
assert re.findall(":+", "a:b::c:::d") == [":", "::", ":::"]
assert re.findall("(:+)", "a:b::c:::d") == [":", "::", ":::"]
# (!) Note: this is different in Codon, as we always return the full match even
# if there are capturing groups.
assert re.findall("(:)(:*)", "a:b::c:::d") == [":", "::", ":::"]
x = "\xe0"
xx = x * 2
xxx = x * 3
string = f"a{x}b{xx}c{xxx}d"
assert re.findall(f"{x}+", string) == [x, xx, xxx]
assert re.findall(f"({x}+)", string) == [x, xx, xxx]
# (!) Note: same as above.
assert re.findall(f"({x})({x}*)", string) == [x, xx, xxx]
test_re_findall()
@test
def test_re_match():
assert cmp_list(re.match('a', 'a').groups(), List[Optional[str]]())
assert cmp_list(re.match('(a)', 'a').groups(), [None, 'a',][1:])
assert re.match('(a)', 'a').group(0).__val__() == 'a'
assert re.match('(a)', 'a').group(1).__val__() == 'a'
assert re.match('(a)', 'a').group(1, 1) == (Optional('a'), Optional('a'))
assert cmp_list(re.match('\xe0', '\xe0').groups(), List[Optional[str]]())
assert cmp_list(re.match('(\xe0)', '\xe0').groups(), ['\xe0'])
assert unwrap(re.match('(\xe0)', '\xe0').group(0)) == '\xe0'
assert unwrap(re.match('(\xe0)', '\xe0').group(1)) == '\xe0'
assert re.match('(\xe0)', '\xe0').group(1, 1) == (Optional('\xe0'), Optional('\xe0'))
pat = re.compile('((a)|(b))(c)?')
assert cmp_list(pat.match('a').groups(), [None, 'a', 'a', None, None][1:])
assert cmp_list(pat.match('b').groups(), [None, 'b', None, 'b', None][1:])
assert cmp_list(pat.match('ac').groups(), [None, 'a', 'a', None, 'c'][1:])
assert cmp_list(pat.match('bc').groups(), [None, 'b', None, 'b', 'c'][1:])
assert cmp_list(pat.match('bc').groups(""), [None, 'b', "", 'b', 'c'][1:])
pat = re.compile('(?:(?P<a1>a)|(?P<b2>b))(?P<c3>c)?')
assert cmp_tuple(pat.match('a').group(1, 2, 3), (Optional('a'), Optional[str](), Optional[str]()))
assert cmp_tuple(pat.match('b').group('a1', 'b2', 'c3'), (Optional[str](), Optional('b'), Optional[str]()))
assert cmp_tuple(pat.match('ac').group(1, 'b2', 3), (Optional('a'), Optional[str](), Optional('c')))
test_re_match()
def raises(exception: type, function, *args, **kwargs):
try:
function(*args, **kwargs)
except exception:
return True
except:
pass
return False
@test
def test_group():
class Index:
value: int
def __init__(self, value):
self.value = value
def __index__(self):
return self.value
# A single group
m = re.match('(a)(b)', 'ab')
assert m.group() == 'ab'
assert unwrap(m.group(0)) == 'ab'
assert unwrap(m.group(1)) == 'a'
assert unwrap(m.group(Index(1))) == 'a'
assert raises(IndexError, m.group, -1)
assert raises(IndexError, m.group, 3)
assert raises(IndexError, m.group, 1<<1000)
assert raises(IndexError, m.group, Index(1<<1000))
assert raises(IndexError, m.group, 'x')
# Multiple groups
assert cmp_tuple(m.group(2, 1), ('b', 'a'))
assert cmp_tuple(m.group(Index(2), Index(1)), ('b', 'a'))
test_group()
@test
def test_match_getitem():
pat = re.compile('(?:(?P<a1>a)|(?P<b2>b))(?P<c3>c)?')
m = pat.match('a')
assert unwrap(m['a1']) == 'a'
assert m['b2'] is None
assert m['c3'] is None
assert unwrap(m[0]) == 'a'
assert unwrap(m[1]) == 'a'
assert m[2] is None
assert m[3] is None
assert raises(IndexError, lambda i: m[i], 'X')
assert raises(IndexError, lambda i: m[i], -1)
assert raises(IndexError, lambda i: m[i], 4)
m = pat.match('ac')
assert unwrap(m['a1']) == 'a'
assert m['b2'] is None
assert unwrap(m['c3']) == 'c'
assert unwrap(m[0]) == 'ac'
assert unwrap(m[1]) == 'a'
assert m[2] is None
assert unwrap(m[3]) == 'c'
test_match_getitem()
@test
def test_re_fullmatch():
assert re.fullmatch(r"a", "a").span() == (0, 1)
assert re.fullmatch(r"a|ab", "ab").span() == (0, 2)
assert re.fullmatch("\xe0|\xe0\xdf", "\xe0\xdf").span() == (0, 2)
assert re.fullmatch(r".*?$", "abc").span() == (0, 3)
assert re.fullmatch(r".*?", "abc").span() == (0, 3)
assert re.fullmatch(r"a.*?b", "ab").span() == (0, 2)
assert re.fullmatch(r"a.*?b", "abb").span() == (0, 3)
assert re.fullmatch(r"a.*?b", "axxb").span() == (0, 4)
assert re.fullmatch(r"a+", "ab") is None
assert re.fullmatch(r"abc$", "abc\n") is None
assert re.fullmatch(r"(?m)abc$", "abc\n") is None
assert re.compile(r"bc").fullmatch("abcd", pos=1, endpos=3).span() == (1, 3)
# TODO: following fails; $ does not respect endpos in re2?
#assert re.compile(r".*?$").fullmatch("abcd", pos=1, endpos=3).span() == (1, 3)
assert re.compile(r".*?").fullmatch("abcd", pos=1, endpos=3).span() == (1, 3)
test_re_fullmatch()
@test
def test_finditer():
iter = re.finditer(r":+", "a:b::c:::d")
assert cmp_list([item.group(0) for item in iter], [":", "::", ":::"])
pat = re.compile(r":+")
iter = pat.finditer("a:b::c:::d", 1, 10)
assert cmp_list([item.group(0) for item in iter], [":", "::", ":::"])
pat = re.compile(r":+")
iter = pat.finditer("a:b::c:::d", pos=1, endpos=10)
assert cmp_list([item.group(0) for item in iter], [":", "::", ":::"])
pat = re.compile(r":+")
iter = pat.finditer("a:b::c:::d", endpos=10, pos=1)
assert cmp_list([item.group(0) for item in iter], [":", "::", ":::"])
pat = re.compile(r":+")
iter = pat.finditer("a:b::c:::d", pos=3, endpos=8)
assert cmp_list([item.group(0) for item in iter], ["::", "::"])
test_finditer()
@test
def test_constants():
assert re.I == re.IGNORECASE
assert re.L == re.LOCALE
assert re.M == re.MULTILINE
assert re.S == re.DOTALL
assert re.X == re.VERBOSE
test_constants()
@test
def test_anyall():
assert unwrap(re.match("a.b", "a\nb", re.DOTALL).group(0)) == "a\nb"
assert unwrap(re.match("a.*b", "a\n\nb", re.DOTALL).group(0)) == "a\n\nb"
test_anyall()
@test
def test_groupdict():
d = re.match('(?P<first>first) (?P<second>second)', 'first second').groupdict()
assert len(d) == 2 and unwrap(d['first']) == 'first' and unwrap(d['second']) == 'second'
test_groupdict()
@test
def test_expand():
assert re.match("(?P<first>first) (?P<second>second)", "first second").expand(r"\2 \1 \g<second> \g<first>") == "second first second first"
assert re.match("(?P<first>first)|(?P<second>second)", "first").expand(r"\2 \g<second>") == " "
test_expand()
@test
def test_getattr():
assert re.compile("(?i)(a)(b)").pattern == "(?i)(a)(b)"
# TODO: Codon does not support flags like this
# self.assertEqual(re.compile("(?i)(a)(b)").flags, re.I | re.U)
assert re.compile("(?i)(a)(b)").groups == 2
assert re.compile("(?i)(a)(b)").groupindex == {}
assert re.compile("(?i)(?P<first>a)(?P<other>b)").groupindex == {'first': 1, 'other': 2}
assert re.match("(a)", "a").pos == 0
assert re.match("(a)", "a").endpos == 1
assert re.match("(a)", "a").string == "a"
assert re.match("(a)", "a").re
test_getattr()
Typechecker refactoring (#20) * Initial refactor commit * Support external vars * Simplify refactor; Python scoping [wip] * Python scoping [wip] * Python scoping [fix loops; wip] * Fix lambdas * Python scoping [test fixes; wip] * Fix scoping [wip] * Fix basic tests [no-ci] * Fix tests * CallExpr refactoring [wip] * CallExpr refactoring [wip] * Remove activeUnbounds tracking * Add core.codon * Move Function and other core types to core.codon; Revamp Function and Callable types * Refactor IntExpr, FloatExpr and CallExpr * Refactor ClassStmt * Refactor context, IdExpr and DotExpr * Refactor DotExpr and AssignStmt * Refactor ImportStmt * Refactor FunctionStmt * Refactor * Remove UpdateStmt * Refactor AssignReplacementVisitor * Make SimplifyVisitor in-place * Fix new scoping * Fix import type alias handling * Add docstrings; Complete Simplify refactoring * Fixes for seqtest * Refactor typecheck [wip] * Refactor typecheck [wip] * Refactor typecheck/access; Remove void anduse NoneType; Fix #18 * Refactor typecheck/assign * clang-format and cmake-format * Fix none types in IR * Multi-error support in simplify * Fix IR tests for new void * Simplify ClassStmt * Refactor cond.cpp * Refactor error.cpp * Refactor function.cpp and simplify unbounds * Refactor op.cpp * Refactor call.cpp [wip] [no-ci] * seqassertn updates [noci] * Refactor call.cpp * Refactor call.cpp * Refactor call.cpp * Refactor typecheck * clang-tidy updates [noci] * Refactor infer.cpp [wip] * Refactor infer.cpp * Refactor wrapExpr * Remove visitedAsts * Remove old base logic * Refactor typecheck ctx * Fix JIT bug * Fix JIT tests * Scoping fixes [wip] [noci] * Fix ImperativeForFlow var store * Add newlines [noci] * Dump IR module with log flag * Fix scoping bugs; Add &, ^ and | static operations; Address stylistic review issues * Fix side effect analysis for for-loops * Add support for class variables and ClassVar * Refactor special dot-member cases * Add codon app tests * Fix class variables; clang-tidy * Fix __argv__ * Add datetime constants and update tests * Fix #25; Add Py_None, Py_True and Py_False; External var support [wip] * External var support [wip] * Dump LLVM IR when debug flags are active * clang-format * Fix arg var construction * Extern var fixes * Undo extern var changes related to stdout etc. * Fix tuple magics * Fix extern vars and tuple magics * Fix duplicate var name error * Fix extern vars * Fix #16 * Fix side-effect analysis for try-catch * Move test C var to test executable * Add staticmethod * Fix var status for try-catch * Fix tests * Fix shell var name * Fix test * Fix app test * Fix scoping issue (remove dominated identifier from stack) * Fix no-pie issue * Use PIC when building library object * Don't use -no-pie when building library [noci] * Use -relocation-model=pic in test * Fix lib build on Linux * Fix lib build * Update exceptions to use subclasses vs. header * Fix __repr__ * Fix tests * Fix exceptions test * Don't build docs Co-authored-by: A. R. Shajii <ars@ars.me>
2022-07-26 20:06:00 +00:00
def check_match(pattern, text, match: Optional[str] = None, span: Optional[re.Span] = None, matcher = re.fullmatch):
if match is None and span is None:
# the pattern matches the whole text
match = text
span = (0, len(text))
elif match is None or span is None:
raise ValueError('If match is not None, span should be specified '
'(and vice versa).')
m = matcher(pattern, text)
return bool(m) and m.group() == match and m.span() == span
LITERAL_CHARS = string.ascii_letters + string.digits
@test
def test_re_escape():
p = ''.join(chr(i) for i in range(256))
for c in p:
Typechecker refactoring (#20) * Initial refactor commit * Support external vars * Simplify refactor; Python scoping [wip] * Python scoping [wip] * Python scoping [fix loops; wip] * Fix lambdas * Python scoping [test fixes; wip] * Fix scoping [wip] * Fix basic tests [no-ci] * Fix tests * CallExpr refactoring [wip] * CallExpr refactoring [wip] * Remove activeUnbounds tracking * Add core.codon * Move Function and other core types to core.codon; Revamp Function and Callable types * Refactor IntExpr, FloatExpr and CallExpr * Refactor ClassStmt * Refactor context, IdExpr and DotExpr * Refactor DotExpr and AssignStmt * Refactor ImportStmt * Refactor FunctionStmt * Refactor * Remove UpdateStmt * Refactor AssignReplacementVisitor * Make SimplifyVisitor in-place * Fix new scoping * Fix import type alias handling * Add docstrings; Complete Simplify refactoring * Fixes for seqtest * Refactor typecheck [wip] * Refactor typecheck [wip] * Refactor typecheck/access; Remove void anduse NoneType; Fix #18 * Refactor typecheck/assign * clang-format and cmake-format * Fix none types in IR * Multi-error support in simplify * Fix IR tests for new void * Simplify ClassStmt * Refactor cond.cpp * Refactor error.cpp * Refactor function.cpp and simplify unbounds * Refactor op.cpp * Refactor call.cpp [wip] [no-ci] * seqassertn updates [noci] * Refactor call.cpp * Refactor call.cpp * Refactor call.cpp * Refactor typecheck * clang-tidy updates [noci] * Refactor infer.cpp [wip] * Refactor infer.cpp * Refactor wrapExpr * Remove visitedAsts * Remove old base logic * Refactor typecheck ctx * Fix JIT bug * Fix JIT tests * Scoping fixes [wip] [noci] * Fix ImperativeForFlow var store * Add newlines [noci] * Dump IR module with log flag * Fix scoping bugs; Add &, ^ and | static operations; Address stylistic review issues * Fix side effect analysis for for-loops * Add support for class variables and ClassVar * Refactor special dot-member cases * Add codon app tests * Fix class variables; clang-tidy * Fix __argv__ * Add datetime constants and update tests * Fix #25; Add Py_None, Py_True and Py_False; External var support [wip] * External var support [wip] * Dump LLVM IR when debug flags are active * clang-format * Fix arg var construction * Extern var fixes * Undo extern var changes related to stdout etc. * Fix tuple magics * Fix extern vars and tuple magics * Fix duplicate var name error * Fix extern vars * Fix #16 * Fix side-effect analysis for try-catch * Move test C var to test executable * Add staticmethod * Fix var status for try-catch * Fix tests * Fix shell var name * Fix test * Fix app test * Fix scoping issue (remove dominated identifier from stack) * Fix no-pie issue * Use PIC when building library object * Don't use -no-pie when building library [noci] * Use -relocation-model=pic in test * Fix lib build on Linux * Fix lib build * Update exceptions to use subclasses vs. header * Fix __repr__ * Fix tests * Fix exceptions test * Don't build docs Co-authored-by: A. R. Shajii <ars@ars.me>
2022-07-26 20:06:00 +00:00
assert check_match(re.escape(c), c)
assert check_match('[' + re.escape(c) + ']', c)
assert check_match(re.escape(p), p)
for c in '-.]{}':
assert re.escape(c)[:1] == '\\'
literal_chars = LITERAL_CHARS
assert re.escape(literal_chars) == literal_chars
test_re_escape()