Esempio n. 1
0
    def __init__(self, module_name, source_ref):
        ExpressionBase.__init__(self, source_ref=source_ref)

        self.module_name = resolveModuleName(module_name)

        self.finding = None

        # If not found, we import the package at least
        (
            self.found_module_name,
            self.found_module_filename,
            self.finding,
        ) = self._attemptFollow()
Esempio n. 2
0
    def computeExpression(self, trace_collection):
        # Attempt to recurse if not already done.
        if self.follow_attempted:
            if self.finding == "not-found":
                # Importing and not finding, may raise an exception obviously.
                trace_collection.onExceptionRaiseExit(BaseException)
            else:
                # If we know it exists, only RuntimeError shall occur.
                trace_collection.onExceptionRaiseExit(RuntimeError)

            # We stay here.
            return self, None, None

        module_name = self.subnode_name

        if module_name.isCompileTimeConstant():
            imported_module_name = module_name.getCompileTimeConstant()

            module_filename = self._attemptFollow(
                module_name=imported_module_name)

            self.follow_attempted = True

            if type(imported_module_name) in (str, unicode):
                imported_module_name = resolveModuleName(imported_module_name)

                if self.finding == "absolute" and imported_module_name in hard_modules:
                    if (isStandardLibraryPath(module_filename)
                            or imported_module_name == "pkg_resources"):
                        result = ExpressionImportModuleHard(
                            module_name=imported_module_name,
                            source_ref=self.source_ref)

                        return (
                            result,
                            "new_expression",
                            "Lowered import of standard library module '%s' to hard import."
                            % imported_module_name.asString(),
                        )
                    elif shallWarnUnusualCode():
                        unusual_logger.warning(
                            "%s: Standard library module '%s' used from outside path %r."
                            % (
                                self.source_ref.getAsString(),
                                imported_module_name.asString(),
                                self.module_filename,
                            ))

                if self.finding == "built-in":
                    if imported_module_name in hard_modules:
                        result = ExpressionImportModuleHard(
                            module_name=imported_module_name,
                            source_ref=self.source_ref)

                        return (
                            result,
                            "new_expression",
                            "Lowered import of built-in module '%s' to hard import."
                            % imported_module_name.asString(),
                        )

                    self.type_shape = tshape_module_builtin
                    self.builtin_module = __import__(imported_module_name)

            else:
                # TODO: This doesn't preserve side effects.

                # Non-strings is going to raise an error.
                (
                    new_node,
                    change_tags,
                    message,
                ) = trace_collection.getCompileTimeComputationResult(
                    node=self,
                    computation=lambda: __import__(module_name.
                                                   getCompileTimeConstant()),
                    description=
                    "Replaced '__import__' call with non-string module name argument.",
                )

                # Must fail, must not go on when it doesn't.
                assert change_tags == "new_raise", module_name

                return new_node, change_tags, message

        # Importing may raise an exception obviously, unless we know it will
        # not.
        if self.finding != "built-in":
            trace_collection.onExceptionRaiseExit(BaseException)

        # TODO: May return a module or module variable reference of some sort in
        # the future with embedded modules.
        return self, None, None
Esempio n. 3
0
    def _attemptFollow(self, module_name):
        # Complex stuff, pylint: disable=too-many-branches

        parent_module = self.getParentModule()

        parent_package = parent_module.getFullName()
        if not parent_module.isCompiledPythonPackage():
            parent_package = parent_package.getPackageName()

        level = self.subnode_level

        if level is None:
            level = 0 if parent_module.getFutureSpec().isAbsoluteImport(
            ) else -1
        elif not level.isCompileTimeConstant():
            return
        else:
            level = level.getCompileTimeConstant()

        # TODO: Catch this as a static error maybe.
        if type(level) not in (int, long):
            return None, None

        module_name, module_filename, self.finding = locateModule(
            module_name=resolveModuleName(module_name),
            parent_package=parent_package,
            level=level,
        )

        if self.finding != "not-found":
            self.used_modules = [(module_name, module_filename, self.finding,
                                  level)]
            import_list = self.subnode_fromlist

            if import_list is not None:
                if import_list.isCompileTimeConstant():
                    import_list = import_list.getCompileTimeConstant()

                if type(import_list) not in (tuple, list):
                    import_list = None

            if (module_filename is not None and import_list
                    and isPackageDir(module_filename)):
                for import_item in import_list:
                    if import_item == "*":
                        continue

                    (
                        name_import_module_name,
                        name_import_module_filename,
                        name_import_finding,
                    ) = locateModule(
                        module_name=ModuleName(import_item),
                        parent_package=module_name,
                        level=1,  # Relative import
                    )

                    if name_import_module_filename is not None:
                        self.used_modules.append((
                            name_import_module_name,
                            name_import_module_filename,
                            name_import_finding,
                            1,
                        ))

            return module_filename
        else:
            module_name = resolveModuleName(module_name)

            while True:
                module_name = module_name.getPackageName()

                if module_name is None:
                    break

                module_name_found, module_filename, finding = locateModule(
                    module_name=module_name,
                    parent_package=parent_package,
                    level=level,
                )

                if module_filename is not None:
                    self.used_modules = [(module_name_found, module_filename,
                                          finding, level)]

            return None