def test_simple_assign(self) -> None:
     wrapper = MetadataWrapper(parse_module("a = b"))
     wrapper.visit(
         DependentVisitor(
             test=self,
             name_to_context={
                 "a": ExpressionContext.STORE,
                 "b": ExpressionContext.LOAD,
             },
         ))
 def test_with_as(self) -> None:
     wrapper = MetadataWrapper(parse_module("with a() as b:\n    pass"))
     wrapper.visit(
         DependentVisitor(
             test=self,
             name_to_context={
                 "a": ExpressionContext.LOAD,
                 "b": ExpressionContext.STORE,
             },
         ))
 def test_except_as(self) -> None:
     wrapper = MetadataWrapper(
         parse_module("try:    ...\nexcept Exception as ex:\n    pass"))
     wrapper.visit(
         DependentVisitor(
             test=self,
             name_to_context={
                 "Exception": ExpressionContext.LOAD,
                 "ex": ExpressionContext.STORE,
             },
         ))
 def test_del_with_tuple(self) -> None:
     wrapper = MetadataWrapper(parse_module("del a, b"))
     wrapper.visit(
         DependentVisitor(
             test=self,
             name_to_context={
                 "a": ExpressionContext.DEL,
                 "b": ExpressionContext.DEL,
             },
             tuple_to_context={("a", "b"): ExpressionContext.DEL},
         ))
 def test_starred_element_with_assign(self) -> None:
     wrapper = MetadataWrapper(parse_module("*a = b"))
     wrapper.visit(
         DependentVisitor(
             test=self,
             name_to_context={
                 "a": ExpressionContext.LOAD,
                 "b": ExpressionContext.LOAD,
             },
             starred_element_to_context={"a": ExpressionContext.STORE},
         ))
 def test_del_with_subscript(self) -> None:
     wrapper = MetadataWrapper(parse_module("del a[b]"))
     wrapper.visit(
         DependentVisitor(
             test=self,
             name_to_context={
                 "a": ExpressionContext.LOAD,
                 "b": ExpressionContext.LOAD,
             },
             subscript_to_context={"a": ExpressionContext.DEL},
         ))
    def test_accesses(self) -> None:
        m, scopes = get_scope_metadata_provider("""
            foo = 'toplevel'
            fn1(foo)
            fn2(foo)
            def fn_def():
                foo = 'shadow'
                fn3(foo)
            """)
        scope_of_module = scopes[m]
        self.assertIsInstance(scope_of_module, GlobalScope)
        global_foo_assignments = scope_of_module["foo"]
        self.assertEqual(len(global_foo_assignments), 1)
        foo_assignment = global_foo_assignments[0]
        self.assertEqual(len(foo_assignment.accesses), 2)
        fn1_call_arg = ensure_type(
            ensure_type(
                ensure_type(m.body[1], cst.SimpleStatementLine).body[0],
                cst.Expr).value,
            cst.Call,
        ).args[0]
        self.assertEqual(foo_assignment.accesses[0].node, fn1_call_arg.value)
        fn2_call_arg = ensure_type(
            ensure_type(
                ensure_type(m.body[2], cst.SimpleStatementLine).body[0],
                cst.Expr).value,
            cst.Call,
        ).args[0]
        self.assertEqual(foo_assignment.accesses[1].node, fn2_call_arg.value)
        func_body = ensure_type(m.body[3], cst.FunctionDef).body
        func_foo_statement = func_body.body[0]
        scope_of_func_statement = scopes[func_foo_statement]
        self.assertIsInstance(scope_of_func_statement, FunctionScope)
        func_foo_assignments = scope_of_func_statement["foo"]
        self.assertEqual(len(func_foo_assignments), 1)
        foo_assignment = func_foo_assignments[0]
        self.assertEqual(len(foo_assignment.accesses), 1)
        fn3_call_arg = ensure_type(
            ensure_type(
                ensure_type(func_body.body[1],
                            cst.SimpleStatementLine).body[0],
                cst.Expr,
            ).value,
            cst.Call,
        ).args[0]
        self.assertEqual(foo_assignment.accesses[0].node, fn3_call_arg.value)

        wrapper = MetadataWrapper(cst.parse_module("from a import b\n"))
        wrapper.visit(DependentVisitor())

        wrapper = MetadataWrapper(
            cst.parse_module("def a():\n    from b import c\n\n"))
        wrapper.visit(DependentVisitor())
 def test_list_with_assing(self) -> None:
     wrapper = MetadataWrapper(parse_module("[a] = [b]"))
     wrapper.visit(
         DependentVisitor(
             test=self,
             name_to_context={
                 "a": ExpressionContext.STORE,
                 "b": ExpressionContext.LOAD,
             },
             list_to_context={
                 ("a", ): ExpressionContext.STORE,
                 ("b", ): ExpressionContext.LOAD,
             },
         ))
 def test_assign_with_subscript(self) -> None:
     wrapper = MetadataWrapper(parse_module("a[b] = c[d]"))
     wrapper.visit(
         DependentVisitor(
             test=self,
             name_to_context={
                 "a": ExpressionContext.LOAD,
                 "b": ExpressionContext.LOAD,
                 "c": ExpressionContext.LOAD,
                 "d": ExpressionContext.LOAD,
             },
             subscript_to_context={
                 "a": ExpressionContext.STORE,
                 "c": ExpressionContext.LOAD,
             },
         ))
 def test_assign_to_attribute(self) -> None:
     wrapper = MetadataWrapper(parse_module("a.b = c.d"))
     wrapper.visit(
         DependentVisitor(
             test=self,
             name_to_context={
                 "a": ExpressionContext.LOAD,
                 "b": ExpressionContext.STORE,
                 "c": ExpressionContext.LOAD,
                 "d": ExpressionContext.LOAD,
             },
             attribute_to_context={
                 "b": ExpressionContext.STORE,
                 "d": ExpressionContext.LOAD,
             },
         ))
    def test_visitor_provider(self) -> None:
        """
        Sets 2 metadata entries for every node:
            SimpleProvider -> 1
            DependentProvider - > 2
        """
        test = self

        class DependentVisitor(CSTTransformer):
            METADATA_DEPENDENCIES = (SyntacticPositionProvider,)

            def visit_Pass(self, node: cst.Pass) -> None:
                range = self.get_metadata(SyntacticPositionProvider, node)
                test.assertEqual(range, CodeRange((1, 0), (1, 4)))

        wrapper = MetadataWrapper(parse_module("pass"))
        wrapper.visit(DependentVisitor())
Exemple #12
0
    def visit(self: _ModuleSelfT,
              visitor: CSTVisitorT,
              use_compatible: bool = True) -> _ModuleSelfT:
        """
        Returns the result of running a visitor over this module.

        :class:`Module` overrides the default visitor entry point to resolve metadata
        dependencies declared by 'visitor'.
        """
        # TODO: remove compatibility hack
        if use_compatible:
            from libcst.metadata.wrapper import MetadataWrapper

            wrapper = MetadataWrapper(self)
            result = wrapper.visit(visitor)
        else:
            result = super(Module, self).visit(visitor)

        if isinstance(result, RemovalSentinel):
            return self.with_changes(body=(), header=(), footer=())
        else:  # is a Module
            return cast(_ModuleSelfT, result)
 def test_simple_load(self) -> None:
     wrapper = MetadataWrapper(parse_module("a"))
     wrapper.visit(
         DependentVisitor(test=self,
                          name_to_context={"a": ExpressionContext.LOAD}))
 def test_invalid_type_for_context(self) -> None:
     wrapper = MetadataWrapper(parse_module("a()"))
     wrapper.visit(
         DependentVisitor(test=self,
                          name_to_context={"a": ExpressionContext.LOAD}))