Пример #1
0
def checkPythonVersionFromCode(source_code):
    # There is a lot of cases to consider, pylint: disable=too-many-branches

    shebang = getShebangFromSource(source_code)

    if shebang is not None:
        binary, _args = parseShebang(shebang)

        if getOS() != "Windows":
            try:
                if os.path.samefile(sys.executable, binary):
                    return True
            except OSError: # Might not exist
                pass

        basename = os.path.basename(binary)

        # Not sure if we should do that.
        if basename == "python":
            result = python_version < 300
        elif basename == "python3":
            result = python_version > 300
        elif basename == "python2":
            result = python_version < 300
        elif basename == "python2.7":
            result = python_version < 300
        elif basename == "python2.6":
            result = python_version < 270
        elif basename == "python3.2":
            result = python_version < 330 and python_version >= 300
        elif basename == "python3.3":
            result = python_version < 340 and python_version >= 330
        elif basename == "python3.4":
            result = python_version < 350 and python_version >= 340
        elif basename == "python3.5":
            result = python_version < 360 and python_version >= 350
        elif basename == "python3.6":
            result = python_version < 370 and python_version >= 360
        else:
            result = None

        if result is False and Options.getIntendedPythonVersion() is None:
            sys.exit("""\
The program you compiled wants to be run with: %s.

Nuitka is currently running with Python version '%s', which seems to not
match that. Nuitka cannot guess the Python version of your source code. You
therefore might want to specify: '%s -m nuitka'.

That will make use the correct Python version for Nuitka.
""" % (shebang, python_version_str, binary)
            )
Пример #2
0
def main():
    # PyLint for Python3 thinks we import from ourselves if we really
    # import from package, pylint:disable=I0021,no-name-in-module

    # Also high complexity.
    # pylint: disable=too-many-branches,too-many-locals,too-many-statements

    if "NUITKA_BINARY_NAME" in os.environ:
        sys.argv[0] = os.environ["NUITKA_BINARY_NAME"]

    if "NUITKA_PYTHONPATH" in os.environ:
        # Restore the PYTHONPATH gained from the site module, that we chose not
        # to have imported. pylint: disable=eval-used
        sys.path = eval(os.environ["NUITKA_PYTHONPATH"])
        del os.environ["NUITKA_PYTHONPATH"]
    else:
        # Remove path element added for being called via "__main__.py", this can
        # only lead to trouble, having e.g. a "distutils" in sys.path that comes
        # from "nuitka.distutils".
        sys.path = [
            path_element
            for path_element in sys.path
            if os.path.dirname(os.path.abspath(__file__)) != path_element
        ]

    # For re-execution, we might not have done this.
    from nuitka import Options                  # isort:skip
    Options.parseArgs()

    from nuitka.utils import Utils, Execution   # isort:skip

    import logging # isort:skip
    logging.basicConfig(format = "Nuitka:%(levelname)s:%(message)s")

    # We don't care, and these are triggered by run time calculations of "range" and
    # others, while on python2.7 they are disabled by default.

    warnings.simplefilter("ignore", DeprecationWarning)

    # We will run with the Python configuration as specified by the user, if it does
    # not match, we restart ourselves with matching configuration.
    needs_reexec = False

    current_version = "%d.%d" % (sys.version_info[0], sys.version_info[1])

    # We support to execute with a specified version.
    intended_version = Options.getIntendedPythonVersion()
    if intended_version is None:
        intended_version = current_version

    # If it's a different version, we find it by guessing it, otherwise we use the
    # one previously used.
    if current_version != intended_version:
        if Utils.getOS() == "Windows":
            python_binary = Execution.getPythonExePathWindows(
                intended_version,
                Options.getIntendedPythonArch()
            )
        else:
            python_binary = Execution.getExecutablePath("python" + intended_version)

        if python_binary is None:
            sys.exit(
                "Error, cannot find Python %s binary in PATH (%s)." % (
                    intended_version,
                    os.environ.get("PATH", "")
                )
            )

        needs_reexec = True
    else:
        python_binary = sys.executable

    if sys.flags.no_site == 0:
        needs_reexec = True

    # The hash randomization totally changes the created source code created,
    # changing it every single time Nuitka is run. This kills any attempt at
    # caching it, and comparing generated source code. While the created binary
    # actually may still use it, during compilation we don't want to. So lets
    # disable it.
    if os.environ.get("PYTHONHASHSEED", "-1") != '0':
        needs_reexec = True

    # In case we need to re-execute.
    if needs_reexec:
        if not Options.isAllowedToReexecute():
            sys.exit("Error, not allowed to re-execute, but that would be needed.")

        our_filename = sys.modules[__name__].__file__

        # Workaround for --python-version which will choke on existing, but
        # not matching .pyc files.
        if current_version != intended_version:
            pyc_filename = our_filename[:-2] + ".pyc"

            if os.path.exists(pyc_filename):
                try:
                    os.unlink(pyc_filename)
                except OSError:
                    pass

        # Execute with full path as the process name, so it can find itself and its
        # libraries.
        args = [
            python_binary,
            python_binary,
            "-S",
            our_filename,
        ]

        os.environ["NUITKA_BINARY_NAME"] = sys.modules["__main__"].__file__

        if Options.is_nuitka_run:
            args.append("--run")

        # Same arguments as before.
        args += sys.argv[1:] + list(Options.getMainArgs())

        if current_version == intended_version:
            os.environ["NUITKA_PYTHONPATH"] = repr(
                sys.path
            )

            from nuitka.importing.PreloadedPackages import detectPreLoadedPackagePaths, detectPthImportedPackages
            os.environ["NUITKA_NAMESPACES"] = repr(
                detectPreLoadedPackagePaths()
            )

            if "site" in sys.modules:
                os.environ["NUITKA_SITE_FILENAME"] = sys.modules["site"].__file__

                os.environ["NUITKA_PTH_IMPORTED"] = repr(detectPthImportedPackages())


        os.environ["NUITKA_SITE_FLAG"] = str(sys.flags.no_site) \
                                           if "no_site" not in Options.getPythonFlags() \
                                         else '1'

        os.environ["PYTHONHASHSEED"] = '0'

        Execution.callExec(args)

    if Options.isShowMemory():
        from nuitka.utils import MemoryUsage
        MemoryUsage.startMemoryTracing()

    # Inform the user about potential issues.
    if current_version not in Options.getSupportedPythonVersions():

        # Do not disturb run of automatic tests, detected from the presence of
        # that environment variable.
        if "PYTHON" not in os.environ:
            logging.warning(
                "The version '%s' is not currently supported. Expect problems.",
                current_version
            )

    if "NUITKA_NAMESPACES" in os.environ:
        # Restore the detected name space packages, that were force loaded in
        # site.py, and will need a free pass later on. pylint: disable=eval-used

        from nuitka.importing.PreloadedPackages import setPreloadedPackagePaths

        setPreloadedPackagePaths(eval(os.environ["NUITKA_NAMESPACES"]))
        del os.environ["NUITKA_NAMESPACES"]

    if "NUITKA_PTH_IMPORTED" in os.environ:
        # Restore the packages that the ".pth" files asked to import.
        # pylint: disable=eval-used

        from nuitka.importing.PreloadedPackages import setPthImportedPackages

        setPthImportedPackages(eval(os.environ["NUITKA_PTH_IMPORTED"]))
        del os.environ["NUITKA_PTH_IMPORTED"]

    # Now the real main program of Nuitka can take over.
    from nuitka import MainControl  # isort:skip
    MainControl.main()

    if Options.isShowMemory():
        MemoryUsage.showMemoryTrace()
Пример #3
0
import logging # isort:skip
logging.basicConfig(format = "Nuitka:%(levelname)s:%(message)s")

# We don't care, and these are triggered by run time calculations of "range" and
# others, while on python2.7 they are disabled by default.

warnings.simplefilter("ignore", DeprecationWarning)

# We will run with the Python configuration as specified by the user, if it does
# not match, we restart ourselves with matching configuration.
needs_reexec = False

current_version = "%d.%d" % (sys.version_info[0], sys.version_info[1])

# We support to execute with a specified version.
intended_version = Options.getIntendedPythonVersion()
if intended_version is None:
    intended_version = current_version

# If it's a different version, we find it by guessing it, otherwise we use the
# one previously used.
if current_version != intended_version:
    if Utils.getOS() == "Windows":
        python_binary = Execution.getPythonExePathWindows(
            intended_version,
            Options.getIntendedPythonArch()
        )
    else:
        python_binary = Execution.getExecutablePath("python" + intended_version)

    if python_binary is None: