def test_variable(self):
     expected = definitions.Variable(name="x",
                                     source="",
                                     lineno=1,
                                     col_offset=0)
     actual = utils.var_from_source("x")
     self.assertEqual(expected, actual)
Exemple #2
0
 def visit_alias(self, node: ast3.alias):
     # Aliases are the "name as other_name" in "import name as other_name".
     return definitions.Variable(
         name=node.asname if node.asname else node.name,
         source=self._source,
         # These must be filled in later.
         lineno=-1,
         col_offset=-1)
Exemple #3
0
    def visit_Attribute(self, node: ast3.Attribute):
        # If this Attribute isn't being used on the left-hand side of an assignment
        # statement, the visitor doesn't need to save it.
        if not self._is_store(node):
            return

        if self._in_class:
            # If in a class, only save "self.attr" expressions.
            if isinstance(node.value, ast3.Name) and node.value.id == "self":
                self._namespace[node.attr].append(
                    definitions.Variable(name=node.attr,
                                         source=self._source,
                                         lineno=node.lineno,
                                         col_offset=node.col_offset))
        else:
            # Outside of a class, an expression like "a.b.c" is stored as
            # Variable(name = "a"). When parsed, "a.b.c" becomes
            # Attribute(Attribute(Name("a"), "b"), "c"). Since only "a" needs to be
            # saved, proceed with the visit as normal so visit_Name handles "a".
            # However, "a" and "b" are considered Loads, not Stores, so we need to
            # update the node.
            node.value.ctx = ast3.Store()
            self.generic_visit(node)
 def test_class_members(self):
     # Classes are generated by the DefinitionFinder visitor passing in the
     # class def, the list of methods, the list of fields and any nested classes.
     # This test represents this by generating each piece separately.
     class_stmt = textwrap.dedent("""\
   class A:
     class_field = 3
     def __init__(self, arg):
       self.instance_field = arg
     def a_method(self, arg):
       return self.instance_field + arg
     class _simple_nested_cls:
       pass
   """)
     expected_methods = {
         "__init__":
         utils.make_func(name="__init__",
                         lineno=3,
                         col_offset=2,
                         params=[
                             utils.make_arg("self", lineno=3,
                                            col_offset=15),
                             utils.make_arg("arg", lineno=3, col_offset=21)
                         ]),
         "a_method":
         utils.make_func(name="a_method",
                         lineno=5,
                         col_offset=2,
                         params=[
                             utils.make_arg("self", lineno=5,
                                            col_offset=15),
                             utils.make_arg("arg", lineno=5, col_offset=21)
                         ]),
     }
     expected_fields = {
         "class_field":
         definitions.Variable("class_field",
                              source="",
                              lineno=2,
                              col_offset=2),
         "instance_field":
         definitions.Variable("instance_field",
                              source="",
                              lineno=4,
                              col_offset=4)
     }
     expected_nests = {
         "_simple_nested_cls":
         definitions.Class(name="_simple_nested_cls",
                           source="",
                           lineno=7,
                           col_offset=2,
                           bases=[],
                           keyword_bases=[],
                           decorators=[],
                           fields={},
                           methods={},
                           nested_classes={})
     }
     expected_class = definitions.Class(name="A",
                                        source="",
                                        lineno=1,
                                        col_offset=0,
                                        bases=[],
                                        keyword_bases=[],
                                        decorators=[],
                                        fields=expected_fields,
                                        methods=expected_methods,
                                        nested_classes=expected_nests)
     # We have to pull apart the parsed class by hand.
     node = utils.parse_stmt(class_stmt)
     classfield, init, method, nested = node.body
     # init.body[0] is an ast3.Attribute, and for class fields, there needs to
     # be a definition for the attr instead of the value. So the Variable
     # definition isn't created with from_node, because attr is a str.
     instance_field = init.body[0].targets[0]
     actual_fields = {
         "class_field":
         definitions.Variable.from_node(classfield.targets[0]),
         "instance_field":
         definitions.Variable(instance_field.attr, "",
                              instance_field.lineno,
                              instance_field.col_offset),
     }
     actual_methods = {
         "__init__": definitions.Function.from_node(init),
         "a_method": definitions.Function.from_node(method),
     }
     actual_nests = {
         "_simple_nested_cls":
         definitions.Class.from_node(nested, {}, {}, {}),
     }
     actual_class = definitions.Class.from_node(node, actual_fields,
                                                actual_methods,
                                                actual_nests)
     self.assertEqual(expected_class, actual_class)