def test_cached(self): source = 'b\na\nb\n' m = base_matchers.AllOf( base_matchers.MatchesRegex(r'a|b'), base_matchers.Once(base_matchers.MatchesRegex(r'a')), ) self.assertEqual( self.get_all_match_strings(m, source), ['a', 'b'], )
def test_inner_nomatches(self): parsed = matcher.parse_ast('xy = 2', '<string>') matches = list( matcher.find_iter( base_matchers.MatchesRegex( r'', base_matchers.Unless(base_matchers.Anything())), parsed)) self.assertEqual(matches, [])
def test_fullmatch_semantics(self): """The regexp only matches the full expression.""" for var in ['x_', '_x']: with self.subTest(var=var): parsed = matcher.parse_ast(var, '<string>') self.assertEqual( list( matcher.find_iter(base_matchers.MatchesRegex(r'x'), parsed)), [])
def test_bindings(self): parsed = matcher.parse_ast('2', '<string>') matches = list( matcher.find_iter( base_matchers.MatchesRegex(r'(?P<var>.)', ast_matchers.Num()), parsed)) self.assertLen(matches, 1) [m] = matches self.assertIn('var', m.bindings) self.assertEqual(m.bindings['var'].value.span, (0, 1))
def test_matches(self): parsed = matcher.parse_ast('xy = 2', '<string>') matches = list( matcher.find_iter( base_matchers.MatchesRegex(r'^(?P<name>.)(.)$', base_matchers.Bind('inner')), parsed)) # There is only one AST node of length >= 2 (which the regex requires): xy. self.assertEqual(matches, [ matcher.MatchInfo( mock.ANY, { 'inner': mock.ANY, 'name': matcher.BoundValue(match.SpanMatch('x', (0, 1))), }) ]) [matchinfo] = matches self.assertEqual(matchinfo.match.span, (0, 2)) self.assertEqual(matchinfo.match, matchinfo.bindings['inner'].value)
category='pylint.dict-iter-method', # Must define manually due to the extra restrictions on the pattern. example_fragment='import six; x.{}()'.format(method_name), example_replacement='import six; six.{}(x)'.format(method_name), ) if six.PY2: SIMPLE_PYTHON_FIXERS.extend([ _HAS_KEY_FIXER, fixer.SimplePythonFixer( message=( 'long literals are deprecated and will not work in Python 3.' ' Regular int literals without the L suffix will generally' ' work just as well.'), matcher=base_matchers.MatchesRegex(r'(?P<num>.+)[lL]', ast_matchers.Num()), replacement=formatting.ShTemplate('$num'), url='https://www.python.org/doc/sunset-python-2/', category='pylint.long-suffix', example_fragment='42L', example_replacement='42', ), fixer.SimplePythonFixer( message=( 'Octal integer literals using 0NNN (with a leading 0) are' ' deprecated and will not work in Python 3. Instead, use the' ' 0oNNN syntax.'), # Have to be very careful here -- while 04 will not parse in Python 3, # expressions like 04.0 are valid in both 2 and 3 and not octal. matcher=base_matchers.MatchesRegex( r'(?P<prefix>[-+]?)0(?P<num>\d+)', ast_matchers.Num()),
import string import textwrap from refex import formatting from refex.fix import fixer from refex.python import matcher as matcher_ from refex.python import syntactic_template from refex.python.matchers import ast_matchers from refex.python.matchers import base_matchers from refex.python.matchers import syntax_matchers _MUTABLE_CONSTANT_CATEGORY = 'idioms.mutable-constant' _NONE_RETURNS_CATEGORY = 'idioms.none-return' _LOGGING_EXCEPTION_CATEGORY = 'idioms.logging.exception' _CONSTANT_MATCHER = base_matchers.MatchesRegex(r'[A-Z_\d]+') def idiom_fixer( old_expr, new_expr, category, url='https://refex.readthedocs.io/en/latest/guide/fixers/idiom.html', ): """Fixer for making expressions "clearer" / less convoluted. This also helps normalize them for other fixers to apply. Args: old_expr: An ExprPattern string for the expr to match. new_expr: A string.Template string for the replacement.
def test_bind_variables(self): self.assertEqual( base_matchers.MatchesRegex('(?P<name>x)(y)').bind_variables, {'name'})
def test_nomatches(self): parsed = matcher.parse_ast('xy = 2', '<string>') matches = list( matcher.find_iter(base_matchers.MatchesRegex(r'not found'), parsed)) self.assertEqual(matches, [])