Exemplo n.º 1
0
    def visit_ImportFrom_deep(self, node):
        # Is it relative?
        if node.level > 0:
            return self.handle_relative_import(node)
        # not relative
        for module in self.local_modules:
            if node.module == module[0]:
                if os.path.isdir(module[1]):
                    return self.from_directory_import(
                        module,
                        not_as_alias_handler(node.names),
                        as_alias_handler(node.names),
                    )
                return self.add_module(
                    module=module,
                    module_or_package_name=None,
                    local_names=as_alias_handler(node.names),
                    import_alias_mapping=retrieve_import_alias_mapping(
                        node.names),
                    from_from=True,
                )
        for module in self.project_modules:
            name = module[0]
            if node.level == 0:
                break
            if node.module == name:
                if os.path.isdir(module[1]):
                    if visited_module_paths.get(module[1]):
                        return IgnoredNode()
                    # Break recursion
                    visited_module_paths[module[1]] = True
                    return self.from_directory_import(
                        module,
                        not_as_alias_handler(node.names),
                        as_alias_handler(node.names),
                        retrieve_import_alias_mapping(node.names),
                    )
                return self.add_module(
                    module=module,
                    module_or_package_name=None,
                    local_names=as_alias_handler(node.names),
                    import_alias_mapping=retrieve_import_alias_mapping(
                        node.names),
                    from_from=True,
                )

        # Remember aliases for uninspectable modules such that we can label them fully qualified
        # e.g. we want a call to "os.system" be recognised, even if we do "from os import system"
        # from os import system as mysystem -> module=os, name=system, asname=mysystem
        for name in node.names:
            local_definitions = self.module_definitions_stack[-1]
            local_definitions.import_alias_mapping[
                name.asname
                or name.name] = "{}.{}".format(node.module, name.name)
        if node.module not in uninspectable_modules:
            uninspectable_modules.add(node.module)
        return IgnoredNode()
Exemplo n.º 2
0
    def handle_relative_import(self, node):
        """
        from A means node.level == 0
        from . import B means node.level == 1
        from .A means node.level == 1
        """
        no_file = os.path.abspath(os.path.join(self.filenames[-1], os.pardir))
        skip_init = False

        if node.level == 1:
            # Same directory as current file
            if node.module:
                name_with_dir = os.path.join(no_file,
                                             node.module.replace(".", "/"))
                if not os.path.isdir(name_with_dir):
                    name_with_dir = name_with_dir + ".py"
            # e.g. from . import X
            else:
                name_with_dir = no_file
                # We do not want to analyse the init file of the current directory
                skip_init = True
        else:
            parent = os.path.abspath(os.path.join(no_file, os.pardir))
            if node.level > 2:
                # Perform extra `cd ..` however many times
                for _ in range(0, node.level - 2):
                    parent = os.path.abspath(os.path.join(parent, os.pardir))
            if node.module:
                name_with_dir = os.path.join(parent,
                                             node.module.replace(".", "/"))
                if not os.path.isdir(name_with_dir):
                    name_with_dir = name_with_dir + ".py"
            # e.g. from .. import X
            else:
                name_with_dir = parent

        # Is it a file?
        if name_with_dir.endswith(".py"):
            if visited_module_paths.get(name_with_dir):
                return IgnoredNode()
            visited_module_paths[name_with_dir] = True
            return self.add_module(
                module=(node.module, name_with_dir),
                module_or_package_name=None,
                local_names=as_alias_handler(node.names),
                import_alias_mapping=retrieve_import_alias_mapping(node.names),
                from_from=True,
            )
        return self.from_directory_import(
            (node.module, name_with_dir),
            not_as_alias_handler(node.names),
            as_alias_handler(node.names),
            retrieve_import_alias_mapping(node.names),
            skip_init=skip_init,
        )