def test_gen_dotted_names(self) -> None:
        names = {name for name, node in _gen_dotted_names(cst.Name(value="a"))}
        self.assertEqual(names, {"a"})

        names = {
            name
            for name, node in _gen_dotted_names(
                cst.Attribute(value=cst.Name(value="a"),
                              attr=cst.Name(value="b")))
        }
        self.assertEqual(names, {"a.b", "a"})

        names = {
            name
            for name, node in _gen_dotted_names(
                cst.Attribute(
                    value=cst.Call(
                        func=cst.Attribute(
                            value=cst.Attribute(value=cst.Name(value="a"),
                                                attr=cst.Name(value="b")),
                            attr=cst.Name(value="c"),
                        ),
                        args=[],
                    ),
                    attr=cst.Name(value="d"),
                ))
        }
        self.assertEqual(names, {"a.b.c", "a.b", "a"})
    def is_in_use(self, scope: cst.metadata.Scope,
                  alias: cst.ImportAlias) -> bool:
        """
        Check if ``alias`` is in use in the given ``scope``.

        An alias is in use if it's directly referenced, exported, or appears in
        a string type annotation. Override this in a subclass for additional
        filtering.
        """
        asname = alias.asname
        names = _gen_dotted_names(
            cst.ensure_type(asname.name, cst.Name
                            ) if asname is not None else alias.name)

        for name_or_alias, _ in names:
            if (name_or_alias in self._exported_names
                    or name_or_alias in self._string_annotation_names):
                return True

            for assignment in scope[name_or_alias]:
                if (isinstance(assignment, cst.metadata.Assignment)
                        and isinstance(assignment.node,
                                       (cst.ImportFrom, cst.Import))
                        and len(assignment.references) > 0):
                    return True
        return False
Exemple #3
0
    def _is_in_use(self, scope: Scope, alias: cst.ImportAlias) -> bool:
        # Grab the string name of this alias from the point of view of this module.
        asname = alias.asname
        names = _gen_dotted_names(
            cst.ensure_type(asname.name, cst.Name
                            ) if asname is not None else alias.name)

        for name_or_alias, _ in names:
            if name_or_alias in self.exported_objects:
                return True

            for assignment in scope[name_or_alias]:
                if (isinstance(assignment, Assignment)
                        and isinstance(assignment.node,
                                       (cst.ImportFrom, cst.Import))
                        and len(assignment.references) > 0):
                    return True
        return False