def test_nonexpr_in_expr_context(self, template):
     parsed = matcher.parse_ast('[x]')
     m = base_matchers.Bind('bound', ast_matchers.Name())
     [matchinfo] = matcher.find_iter(m, parsed)
     with self.assertRaises(formatting.RewriteError):
         template.substitute_match(parsed, matchinfo.match,
                                   {'bound': matchinfo.match})
Exemple #2
0
 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, [])
Exemple #3
0
    def test_matches(self):
        parsed = matcher.parse_ast('var_hello = 42', '<string>')
        m = base_matchers.AllOf(base_matchers.FileMatchesRegex('hello'),
                                ast_matchers.Num())

        matches = list(matcher.find_iter(m, parsed))

        self.assertLen(matches, 1)
 def test_nonpython_dollars_source(self, src):
     parsed = matcher.parse_ast(src)
     m = base_matchers.Bind('bound', ast_matchers.Call())
     [matchinfo] = matcher.find_iter(m, parsed)
     self.assertEqual(
         src,
         syntactic_template.PythonExprTemplate('$bound').substitute_match(
             parsed, matchinfo.match, {'bound': matchinfo.match}))
Exemple #5
0
    def test_doesnt_match(self):
        parsed = matcher.parse_ast('hi = 42', '<string>')
        m = base_matchers.AllOf(base_matchers.FileMatchesRegex('hello'),
                                ast_matchers.Num())

        matches = list(matcher.find_iter(m, parsed))

        self.assertEqual(matches, [])
 def test_invalid_syntax(self):
     parsed = matcher.parse_ast('x')
     m = base_matchers.Bind('x', ast_matchers.Name())
     [matchinfo] = matcher.find_iter(m, parsed)
     template = syntactic_template.PythonTemplate('$x')
     with self.assertRaises(formatting.RewriteError):
         template.substitute_match(parsed, matchinfo.match,
                                   {'x': match.StringMatch('x  y')}),
Exemple #7
0
 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_nonpython_dollars_dest(self):
     src = 'f'
     parsed = matcher.parse_ast(src)
     m = base_matchers.Bind('bound', ast_matchers.Name())
     [matchinfo] = matcher.find_iter(m, parsed)
     self.assertEqual(
         'f("$x")',
         syntactic_template.PythonExprTemplate(
             '$bound("$x")').substitute_match(parsed, matchinfo.match,
                                              {'bound': matchinfo.match}))
 def test_autoparen_outer(self):
     parsed = matcher.parse_ast('x * 2')
     m = base_matchers.Bind('x', ast_matchers.Name())
     [matchinfo] = matcher.find_iter(m, parsed)
     template = syntactic_template.PythonTemplate('$x')
     self.assertEqual(
         template.substitute_match(parsed, matchinfo.match,
                                   {'x': match.StringMatch('x + y')}),
         '(x + y)',
     )
Exemple #10
0
 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))
Exemple #11
0
 def test_assignment(self, template):
     template = syntactic_template.PythonStmtTemplate(template)
     # Test with different values of `ctx` for the variable being substituted.
     for variable_source in 'a = 1', 'a':
         with self.subTest(variable_souce=variable_source):
             [matchinfo] = matcher.find_iter(
                 base_matchers.Bind('x', ast_matchers.Name()),
                 matcher.parse_ast(variable_source))
             substituted = template.substitute_match(
                 None, None, {'x': matchinfo.match})
             self.assertEqual(substituted,
                              template.template.replace('$x', 'a'))
Exemple #12
0
    def test_multi_regex(self):
        """Tests that the lazy dictionary doesn't walk over itself or something."""
        parsed = matcher.parse_ast('var_hello = 42', '<string>')
        m = base_matchers.AllOf(
            base_matchers.FileMatchesRegex('var'),
            base_matchers.FileMatchesRegex('hello'),
            base_matchers.FileMatchesRegex('42'),
            base_matchers.FileMatchesRegex(r'\Avar_hello = 42\Z'),
            ast_matchers.Num())

        matches = list(matcher.find_iter(m, parsed))

        self.assertLen(matches, 1)
Exemple #13
0
    def test_nonsingular_py_ok(self, template):
        """Tests non-singular PythonTemplate in a context where it's acceptable.

    If it is not being placed into a context where it's expected to parse as
    an expression, then '' and even 'a; b' are fine.

    Args:
      template: the template for this test.
    """
        parsed = matcher.parse_ast('x')
        m = base_matchers.Bind('bound', ast_matchers.Name())
        [matchinfo] = matcher.find_iter(m, parsed)
        self.assertEqual(
            template,
            syntactic_template.PythonTemplate(template).substitute_match(
                parsed, matchinfo.match, {'bound': matchinfo.match}))
Exemple #14
0
 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)
Exemple #15
0
    def find_dicts_parsed(
        self, parsed: _matcher.PythonParsedFile
    ) -> Iterable[Tuple[Mapping[MatchKey, match.Match], Mapping[
            MatchKey, formatting.Template]]]:

        # All node IDs that have been removed.
        removed_nodes = set([])
        # All node IDs in a suite that have been removed AND whose previous
        # siblings have all been removed, as well.
        removed_suite_prefix_nodes = set([])

        for result in _matcher.find_iter(self.matcher, parsed):
            matches = {
                bound_name: match.value
                for bound_name, match in result.bindings.items()
            }
            self._sanitize_removed_stmt(
                parsed,
                matches,
                result.replacements,
                removed_nodes,
                removed_suite_prefix_nodes,
            )
            yield (matches, result.replacements)
Exemple #16
0
 def test_matcherror(self):
     parsed = matcher.parse_ast('x+y')
     bind = base_matchers.Bind('var',
                               on_conflict=matcher.BindConflict.ERROR)
     m = ast_matchers.BinOp(left=bind, right=bind)
     self.assertEqual(list(matcher.find_iter(m, parsed)), [])
Exemple #17
0
 def get_all_match_strings(self, m, source_code):
     return [
         self._get_matchinfo_string(matchinfo, source_code)
         for matchinfo in matcher.find_iter(
             m, matcher.parse_ast(source_code, '<string>'))
     ]
Exemple #18
0
 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, [])