예제 #1
0
    def considerImplicitImports(self, module, signal_change):
        """Provide additional modules to import implicitly when encountering the module.

        Notes:
            Better do not overload this method.
            The standard plugin 'ImplicitImports.py' already contains MANY of these.
            If you do have a new candidate, consider a PR to get it included there.

        Args:
            module: the module object
            signal_change: bool
        Returns:
            None
        """
        from nuitka.importing.Importing import getModuleNameAndKindFromFilename

        for full_name in self.getImplicitImports(module):
            if type(full_name) in (tuple, list):
                raise NuitkaPluginError(
                    "Plugin %s needs to be change to only return modules names, not %r"
                    % (self, full_name))

            full_name = ModuleName(full_name)

            try:
                module_filename = self.locateModule(importing=module,
                                                    module_name=full_name)
            except Exception:
                self.warning("Problem locating '%s' implicit imports '%s'." %
                             (module.getFullName(), full_name))
                raise

            if module_filename is None:
                if Options.isShowInclusion():
                    self.info(
                        "Implicit module '%s' suggested by '%s' not found." %
                        (full_name, module.getFullName()))

                continue

            _module_name2, module_kind = getModuleNameAndKindFromFilename(
                module_filename)

            # TODO: This should get back to plug-ins, they should be allowed to
            # preempt or override the decision.
            decision, reason = self.decideRecursion(
                module_filename=module_filename,
                module_name=full_name,
                module_kind=module_kind,
            )

            if decision:
                self.recurseTo(
                    module_package=full_name.getPackageName(),
                    module_filename=module_filename,
                    module_kind=module_kind,
                    reason=reason,
                    signal_change=signal_change,
                )
예제 #2
0
    def considerImplicitImports(self, module, signal_change):
        """ Provide additional modules to import implicitly when encountering the module.

        Notes:
            Better do not overload this method.
            The standard plugin 'ImplicitImports.py' already contains MANY of these.
            If you do have a new candidate, consider a PR to get it included there.

        Args:
            module: the module object
            signal_change: bool
        Returns:
            None
        """
        from nuitka.importing.Importing import getModuleNameAndKindFromFilename

        for item in self.getImplicitImports(module):
            # TODO: Temporary, until all plugins are caught up, turn into an error later.
            if type(item) in (tuple, list):
                full_name, _required = item
            else:
                full_name = item

            full_name = ModuleName(full_name)

            module_filename = self.locateModule(importing=module,
                                                module_name=full_name)

            if module_filename is None:
                if Options.isShowInclusion():
                    self.info(
                        "Implicit module '%s' suggested by '%s' not found." %
                        (full_name, module.getFullName()))

                continue

            _module_name2, module_kind = getModuleNameAndKindFromFilename(
                module_filename)

            # TODO: This should get back to plug-ins, they should be allowed to
            # preempt or override the decision.
            decision, reason = self.decideRecursion(
                module_filename=module_filename,
                module_name=full_name,
                module_kind=module_kind,
            )

            if decision:
                self.recurseTo(
                    module_package=full_name.getPackageName(),
                    module_filename=module_filename,
                    module_kind=module_kind,
                    reason=reason,
                    signal_change=signal_change,
                )
예제 #3
0
파일: PluginBase.py 프로젝트: jonike/Nuitka
    def considerImplicitImports(self, module, signal_change):
        """ Provide additional modules to import implicitly when encountering the module.

        Notes:
            Better do not overload this method.
            The standard plugin 'ImplicitImports.py' already contains MANY of these.
            If you do have a new candidate, consider a PR to get it included there.

        Args:
            module: the module object
            signal_change: bool
        Returns:
            None
        """
        from nuitka.importing.Importing import getModuleNameAndKindFromFilename

        for full_name, required in self.getImplicitImports(module):
            full_name = ModuleName(full_name)

            module_filename = self.locateModule(
                importing=module, module_name=full_name, warn=required
            )

            if module_filename is None:
                if required:
                    sys.exit(
                        "Error, implicit module '%s' expected by '%s' not found."
                        % (full_name, module.getFullName())
                    )
                else:
                    continue

            _module_name2, module_kind = getModuleNameAndKindFromFilename(
                module_filename
            )

            # TODO: This should get back to plug-ins, they should be allowed to
            # preempt or override the decision.
            decision, reason = self.decideRecursion(
                module_filename=module_filename,
                module_name=full_name,
                module_kind=module_kind,
            )

            if decision:
                self.recurseTo(
                    module_package=full_name.getPackageName(),
                    module_filename=module_filename,
                    module_kind=module_kind,
                    reason=reason,
                    signal_change=signal_change,
                )
예제 #4
0
    def _attemptRecursion(self, trace_collection, 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

        module_package, self.module_filename, self.finding = findModule(
            importing=self,
            module_name=ModuleName(module_name),
            parent_package=parent_package,
            level=level,
            warn=True,
        )

        if self.module_filename is not None:
            imported_module = self._consider(
                trace_collection=trace_collection,
                module_filename=self.module_filename,
                module_package=module_package,
            )

            if imported_module is not None:
                self.imported_module_desc = (
                    imported_module.getFullName(),
                    imported_module.getFilename(),
                )

                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 import_list and imported_module.isCompiledPythonPackage():
                    for import_item in import_list:
                        if import_item == "*":
                            continue

                        module_package, module_filename, _finding = findModule(
                            importing=self,
                            module_name=ModuleName(import_item),
                            parent_package=imported_module.getFullName(),
                            level=-1,  # Relative import, so child is used.
                            warn=False,
                        )

                        if module_filename is not None:
                            sub_imported_module = self._consider(
                                trace_collection=trace_collection,
                                module_filename=module_filename,
                                module_package=module_package,
                            )

                            if sub_imported_module is not None:
                                self.import_list_modules_desc.append((
                                    sub_imported_module.getFullName(),
                                    sub_imported_module.getFilename(),
                                ))
        else:
            module_name = ModuleName(module_name)

            while True:
                module_name = module_name.getPackageName()

                if module_name is None:
                    break

                module_package, module_filename, _finding = findModule(
                    importing=self,
                    module_name=module_name,
                    parent_package=parent_package,
                    level=level,
                    warn=True,
                )

                if module_filename is not None:
                    package_module = self._consider(
                        trace_collection=trace_collection,
                        module_filename=module_filename,
                        module_package=module_package,
                    )

                    if package_module is not None:
                        if self.package_modules_desc is None:
                            self.package_modules_desc = []

                        self.package_modules_desc.append(
                            (package_module.getFullName(),
                             package_module.getFilename()))
예제 #5
0
def findModule(importing, module_name, parent_package, level, warn):
    """Find a module with given package name as parent.

    The package name can be None of course. Level is the same
    as with "__import__" built-in. Warnings are optional.

    Returns:
        Returns a triple of package name the module is in, filename of
        it, which can be a directory for packages, and the location
        method used.
    """
    # We have many branches here, because there are a lot of cases to try.
    # pylint: disable=too-many-branches

    assert type(module_name) is ModuleName, module_name

    if _debug_module_finding:
        print("findModule: Enter to search %r in package %r level %s." %
              (module_name, parent_package, level))

    # Do not allow star imports to get here. We just won't find modules with
    # that name, but it would be wasteful.
    assert module_name != "*"

    tried_names = []

    if level > 1:
        # TODO: Should give a warning and return not found if the levels
        # exceed the package name.
        if parent_package is not None:
            # TODO: This should be done with the API instead.
            parent_package = ModuleName(".".join(
                parent_package.asString().split(".")[:-level + 1]))

            if parent_package == "":
                parent_package = None
        else:
            return None, None, "not-found"

    # Try relative imports first if we have a parent package.
    if level != 0 and parent_package is not None:
        if module_name:
            full_name = ModuleName(parent_package + "." + module_name)
        else:
            full_name = ModuleName(parent_package)

        full_name = normalizePackageName(full_name)
        tried_names.append(full_name)

        try:
            module_filename = _findModule(module_name=full_name)
        except ImportError:
            # For relative import, that is OK, we will still try absolute.
            pass
        else:
            if _debug_module_finding:
                print(
                    "findModule: Relative imported module '%s' as '%s' in filename '%s':"
                    % (module_name, full_name, module_filename))

            return full_name.getPackageName(), module_filename, "relative"

    if level <= 1 and module_name != "":
        module_name = normalizePackageName(module_name)
        tried_names.append(module_name)

        package_name = module_name.getPackageName()

        # Built-in module names must not be searched any further.
        if module_name in sys.builtin_module_names:
            if _debug_module_finding:
                print(
                    "findModule: Absolute imported module '%s' in as built-in':"
                    % (module_name, ))
            return package_name, None, "built-in"

        try:
            module_filename = _findModule(module_name=module_name)
        except ImportError:
            # For relative import, that is OK, we will still try absolute.
            pass
        else:
            if _debug_module_finding:
                print(
                    "findModule: Found absolute imported module '%s' in filename '%s':"
                    % (module_name, module_filename))

            return package_name, module_filename, "absolute"

    if warn:
        warnAbout(
            importing=importing,
            module_name=module_name,
            parent_package=parent_package,
            tried_names=tried_names,
            level=level,
        )

    return None, None, "not-found"
예제 #6
0
def findModule(module_name, parent_package, level):
    """Find a module with given package name as parent.

    The package name can be None of course. Level is the same
    as with "__import__" built-in. Warnings are optional.

    Returns:
        Returns a triple of package name the module is in, filename of
        it, which can be a directory for packages, and the location
        method used.
    """
    # We have many branches here, because there are a lot of cases to try.
    # pylint: disable=too-many-branches,too-many-return-statements

    assert type(module_name) is ModuleName, module_name

    if _debug_module_finding:
        my_print(
            "findModule: Enter to search %r in package %r level %s."
            % (module_name, parent_package, level)
        )

    # Do not allow star imports to get here. We just won't find modules with
    # that name, but it would be wasteful.
    assert module_name != "*"

    if level > 1:
        # TODO: Should give a warning and return not found if the levels
        # exceed the package name.
        if parent_package is not None:
            parent_package = parent_package.getRelativePackageName(level)
        else:
            return None, None, "not-found"

    # Try relative imports first if we have a parent package.
    if level != 0 and parent_package is not None:
        if module_name:
            full_name = ModuleName(parent_package + "." + module_name)
        else:
            full_name = ModuleName(parent_package)

        full_name = normalizePackageName(full_name)

        preloaded_path = getPreloadedPackagePath(module_name)

        if preloaded_path is not None:
            for module_filename in preloaded_path:
                if os.path.exists(module_filename):
                    break
            else:
                module_filename = None

            return full_name.getPackageName(), module_filename, "pth"

        try:
            module_filename = _findModule(module_name=full_name)
        except ImportError:
            # For relative import, that is OK, we will still try absolute.
            pass
        else:
            if _debug_module_finding:
                my_print(
                    "findModule: Relative imported module '%s' as '%s' in filename '%s':"
                    % (module_name, full_name, module_filename)
                )

            return full_name.getPackageName(), module_filename, "relative"

    if level < 1 and module_name != "":
        module_name = normalizePackageName(module_name)

        package_name = module_name.getPackageName()

        # Built-in module names must not be searched any further.
        if module_name in sys.builtin_module_names:
            if _debug_module_finding:
                my_print(
                    "findModule: Absolute imported module '%s' in as built-in':"
                    % (module_name,)
                )
            return package_name, None, "built-in"

        # Frozen module names are similar to built-in, but there is no list of
        # them, therefore check loader name. Not useful at this time
        # to make a difference with built-in.
        if python_version >= 0x300 and module_name in sys.modules:
            loader = getattr(sys.modules[module_name], "__loader__", None)

            if (
                loader is not None
                and getattr(loader, "__name__", "") == "FrozenImporter"
            ):
                if _debug_module_finding:
                    my_print(
                        "findModule: Absolute imported module '%s' in as frozen':"
                        % (module_name,)
                    )
                return package_name, None, "built-in"

        preloaded_path = getPreloadedPackagePath(module_name)

        if preloaded_path is not None:
            for module_filename in preloaded_path:
                if os.path.exists(module_filename):
                    break
            else:
                module_filename = None

            return package_name, module_filename, "pth"

        try:
            module_filename = _findModule(module_name=module_name)
        except ImportError:
            # For relative import, that is OK, we will still try absolute.
            pass
        else:
            if _debug_module_finding:
                my_print(
                    "findModule: Found absolute imported module '%s' in filename '%s':"
                    % (module_name, module_filename)
                )

            return package_name, module_filename, "absolute"

    return None, None, "not-found"