PythonCall.jl icon indicating copy to clipboard operation
PythonCall.jl copied to clipboard

error when executing a executable builded by pyinstaller

Open timacro opened this issue 3 years ago • 7 comments

I'm trying to use pyinstaller to build a executable with juliacall , here is my code:

from juliacall import Main as jl

def hello(u = "world"):
    jl.println(f"hello {u}!")

hello()

This works good in REPL, but runs into a error after pack it into a executable using pyinstaller:

Querying Julia versions from https://julialang-s3.julialang.org/bin/versions.json
Found Julia 1.7.1 at 'C:\\Users\\ash\\.julia\\pythoncall\\julia-1.7.1\\bin\\julia.exe'
isdev: False
JULIA_PYTHONCALL_LIBPTR: 140717263618048
JULIA_PYTHONCALL_EXE: D:\codehub\Instrument.jl\EC22.jl\temp\dist\hello\hello.exe
script:

        try
            if ENV["JULIA_PYTHONCALL_EXE"] != "" && get(ENV, "PYTHON", "") == ""
                # Ensures PyCall uses the same Python executable
                ENV["PYTHON"] = ENV["JULIA_PYTHONCALL_EXE"]
            end
            import Pkg
            Pkg.activate(raw"C:\Users\ash\.julia\environments\PythonCall", io=devnull)
            Pkg.add([Pkg.PackageSpec(name="PythonCall", uuid="6099a3de-0909-46bc-b1f4-468b9a2dfc0d")])
            import PythonCall
        catch err
            @error "Error loading PythonCall.jl" err=err
            rethrow()
        end


    Updating registry at `C:\Users\ash\.julia\registries\General.toml`
   Resolving package versions...
    Updating `C:\Users\ash\.julia\environments\PythonCall\Project.toml`
  [6099a3de] + PythonCall v0.4.3
    Updating `C:\Users\ash\.julia\environments\PythonCall\Manifest.toml`
  [8f4d0f93] + Conda v1.6.0
  [9a962f9c] + DataAPI v1.9.0
  [e2d170a0] + DataValueInterfaces v1.0.0
  [82899510] + IteratorInterfaceExtensions v1.0.0
  [682c06a0] + JSON v0.21.2
  [1914dd2f] + MacroTools v0.5.9
  [69de0a69] + Parsers v2.1.3
  [6099a3de] + PythonCall v0.4.3
  [ae029012] + Requires v1.2.0
  [3783bdb8] + TableTraits v1.0.1
  [bd369af6] + Tables v1.6.1
  [e17b2a0c] + UnsafePointers v1.0.0
  [81def892] + VersionParsing v1.2.1
  [0dad84c5] + ArgTools
  [56f22d72] + Artifacts
  [2a0f44e3] + Base64
  [ade2ca70] + Dates
  [f43a241f] + Downloads
  [b77e0a4c] + InteractiveUtils
  [b27032c2] + LibCURL
  [76f85450] + LibGit2
  [8f399da3] + Libdl
  [37e2e46d] + LinearAlgebra
  [56ddb016] + Logging
  [d6f4376e] + Markdown
  [a63ad114] + Mmap
  [ca575930] + NetworkOptions
  [44cfe95a] + Pkg
  [de0858da] + Printf
  [3fa0cd96] + REPL
  [9a3f8284] + Random
  [ea8e919c] + SHA
  [9e88b42a] + Serialization
  [6462fe0b] + Sockets
  [fa267f1f] + TOML
  [a4e569a6] + Tar
  [8dfed614] + Test
  [cf7118a7] + UUIDs
  [4ec0a83e] + Unicode
  [e66e0078] + CompilerSupportLibraries_jll
  [deac9b47] + LibCURL_jll
  [29816b5a] + LibSSH2_jll
  [c8ffd9c3] + MbedTLS_jll
  [14a3606d] + MozillaCACerts_jll
  [4536629a] + OpenBLAS_jll
  [83775a58] + Zlib_jll
  [8e850b90] + libblastrampoline_jll
  [8e850ede] + nghttp2_jll
  [3f19e933] + p7zip_jll
Precompiling project...
  1 dependency successfully precompiled in 15 seconds (18 already precompiled)
res: None

Traceback (most recent call last):
  File "hello.py", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "PyInstaller\loader\pyimod03_importers.py", line 476, in exec_module
  File "juliacall\__init__.py", line 4, in <module>
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "PyInstaller\loader\pyimod03_importers.py", line 476, in exec_module
  File "juliacall\init.py", line 167, in <module>
Exception: PythonCall.jl did not start properly
[6060] Failed to execute script 'hello' due to unhandled exception!

I installed juliacall by pip install -e . in order to do some modification with juliacall/init.py to print some info. here is my modification with juliacall/init.py

    ...
    script = '''
        try
            if ENV["JULIA_PYTHONCALL_EXE"] != "" && get(ENV, "PYTHON", "") == ""
                # Ensures PyCall uses the same Python executable
                ENV["PYTHON"] = ENV["JULIA_PYTHONCALL_EXE"]
            end
            import Pkg
            Pkg.activate(raw"{}", io=devnull)
            {}
            import PythonCall
        catch err
            @error "Error loading PythonCall.jl" err=err
            rethrow()
        end
        '''.format(jlenv, install, c.pythonapi._handle)

   # print some info
    print(f"isdev: {isdev}")
    print(f"JULIA_PYTHONCALL_LIBPTR: {os.environ['JULIA_PYTHONCALL_LIBPTR']}")
    print(f"JULIA_PYTHONCALL_EXE: {os.environ['JULIA_PYTHONCALL_EXE']}")
    print(f"script:\n{script}\n")
    res = lib.jl_eval_string(script.encode('utf8'))
    print(f"res: {res}\n")

   ...

timacro avatar Jan 05 '22 02:01 timacro

Can you inset the following into the catch block, so we can see what's going on?

Base.showerror(stdout, err)
Base.show_backtrace(stdout, Base.catch_backtrace())

cjdoris avatar Jan 07 '22 11:01 cjdoris

Here I got

PS D:\codehub\Instrument.jl\EC22.jl\temp> .\dist\hello\hello.exe
Querying Julia versions from https://julialang-s3.julialang.org/bin/versions.json
Found Julia 1.7.1 at 'C:\\Users\\ash\\.julia\\pythoncall\\julia-1.7.1\\bin\\julia.exe'
isdev: False
JULIA_PYTHONCALL_LIBPTR: 140715030020096
JULIA_PYTHONCALL_EXE: D:\codehub\Instrument.jl\EC22.jl\temp\dist\hello\hello.exe
script:

        try
            if ENV["JULIA_PYTHONCALL_EXE"] != "" && get(ENV, "PYTHON", "") == ""
                # Ensures PyCall uses the same Python executable
                ENV["PYTHON"] = ENV["JULIA_PYTHONCALL_EXE"]
            end
            println(ENV["PYTHON"])
            import Pkg
            Pkg.activate(raw"C:\Users\ash\.julia\environments\PythonCall", io=devnull)
            Pkg.add([Pkg.PackageSpec(name="PythonCall", uuid="6099a3de-0909-46bc-b1f4-468b9a2dfc0d")])
            import PythonCall
        catch err
            Base.showerror(stdout, err)
            Base.show_backtrace(stdout, Base.catch_backtrace())
            @error "Error loading PythonCall.jl" err=err
            rethrow()
        end


D:\codehub\Instrument.jl\EC22.jl\temp\dist\hello\hello.exe
    Updating registry at `C:\Users\ash\.julia\registries\General.toml`
   Resolving package versions...
    Updating `C:\Users\ash\.julia\environments\PythonCall\Project.toml`
  [6099a3de] + PythonCall v0.4.3
    Updating `C:\Users\ash\.julia\environments\PythonCall\Manifest.toml`
  [8f4d0f93] + Conda v1.6.0
  [9a962f9c] + DataAPI v1.9.0
  [e2d170a0] + DataValueInterfaces v1.0.0
  [82899510] + IteratorInterfaceExtensions v1.0.0
  [682c06a0] + JSON v0.21.2
  [1914dd2f] + MacroTools v0.5.9
  [69de0a69] + Parsers v2.1.3
  [6099a3de] + PythonCall v0.4.3
  [ae029012] + Requires v1.2.0
  [3783bdb8] + TableTraits v1.0.1
  [bd369af6] + Tables v1.6.1
  [e17b2a0c] + UnsafePointers v1.0.0
  [81def892] + VersionParsing v1.2.1
  [0dad84c5] + ArgTools
  [56f22d72] + Artifacts
  [2a0f44e3] + Base64
  [ade2ca70] + Dates
  [f43a241f] + Downloads
  [b77e0a4c] + InteractiveUtils
  [b27032c2] + LibCURL
  [76f85450] + LibGit2
  [8f399da3] + Libdl
  [37e2e46d] + LinearAlgebra
  [56ddb016] + Logging
  [d6f4376e] + Markdown
  [a63ad114] + Mmap
  [ca575930] + NetworkOptions
  [44cfe95a] + Pkg
  [de0858da] + Printf
  [3fa0cd96] + REPL
  [9a3f8284] + Random
  [ea8e919c] + SHA
  [9e88b42a] + Serialization
  [6462fe0b] + Sockets
  [fa267f1f] + TOML
  [a4e569a6] + Tar
  [8dfed614] + Test
  [cf7118a7] + UUIDs
  [4ec0a83e] + Unicode
  [e66e0078] + CompilerSupportLibraries_jll
  [deac9b47] + LibCURL_jll
  [29816b5a] + LibSSH2_jll
  [c8ffd9c3] + MbedTLS_jll
  [14a3606d] + MozillaCACerts_jll
  [4536629a] + OpenBLAS_jll
  [83775a58] + Zlib_jll
  [8e850b90] + libblastrampoline_jll
  [8e850ede] + nghttp2_jll
  [3f19e933] + p7zip_jll
InitError: Python: res: None

Traceback (most recent call last):
  File "hello.py", line 1, in <module>
    from juliacall import Main as jl
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "PyInstaller\loader\pyimod03_importers.py", line 476, in exec_module
  File "juliacall\__init__.py", line 4, in <module>
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "PyInstaller\loader\pyimod03_importers.py", line 476, in exec_module
  File "juliacall\init.py", line 170, in <module>
Exception: PythonCall.jl did not start properly
[7912] Failed to execute script 'hello' due to unhandled exception!

timacro avatar Jan 07 '22 11:01 timacro

It's not showing the error. Can you also flush(stdout) or use stderr instead?

cjdoris avatar Jan 07 '22 13:01 cjdoris

  1. with stderr:
    script = '''
        try
            if ENV["JULIA_PYTHONCALL_EXE"] != "" && get(ENV, "PYTHON", "") == ""
                # Ensures PyCall uses the same Python executable
                ENV["PYTHON"] = ENV["JULIA_PYTHONCALL_EXE"]
            end
            println(ENV["PYTHON"])
            import Pkg
            Pkg.activate(raw"{}", io=devnull)
            {}
            import PythonCall
        catch err
            Base.showerror(stderr, err)
            Base.show_backtrace(stderr, Base.catch_backtrace())
            flush(stderr)
            @error "Error loading PythonCall.jl" err=err
            rethrow()
        end
        '''.format(jlenv, install, c.pythonapi._handle)

still no extra information :

...
InitError: Python: res: None

Traceback (most recent call last):
  File "hello.py", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "PyInstaller\loader\pyimod03_importers.py", line 476, in exec_module
  File "juliacall\__init__.py", line 4, in <module>
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "PyInstaller\loader\pyimod03_importers.py", line 476, in exec_module
  File "juliacall\init.py", line 171, in <module>
Exception: PythonCall.jl did not start properly
[14784] Failed to execute script 'hello' due to unhandled exception!
  1. with flush(stdout), and println a split line:
    script = '''
        try
            if ENV["JULIA_PYTHONCALL_EXE"] != "" && get(ENV, "PYTHON", "") == ""
                # Ensures PyCall uses the same Python executable
                ENV["PYTHON"] = ENV["JULIA_PYTHONCALL_EXE"]
            end
            println(ENV["PYTHON"])
            import Pkg
            Pkg.activate(raw"{}", io=devnull)
            {}
            import PythonCall
        catch err
            println("-------------------------------------------------------")
            Base.showerror(stdout, err)
            Base.show_backtrace(stdout, Base.catch_backtrace())
            flush(stdout)
            @error "Error loading PythonCall.jl" err=err
            rethrow()
        end
        '''.format(jlenv, install, c.pythonapi._handle)

It's weird, still has no extra output,

...
-------------------------------------------------------
InitError: Python: res: None

Traceback (most recent call last):
  File "hello.py", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "PyInstaller\loader\pyimod03_importers.py", line 476, in exec_module
  File "juliacall\__init__.py", line 4, in <module>
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "PyInstaller\loader\pyimod03_importers.py", line 476, in exec_module
  File "juliacall\init.py", line 172, in <module>
Exception: PythonCall.jl did not start properly
[15796] Failed to execute script 'hello' due to unhandled exception!

timacro avatar Jan 07 '22 14:01 timacro

Interesting, I remove Base.showerror(stdout, err), and got them :

    script = '''
        try
            if ENV["JULIA_PYTHONCALL_EXE"] != "" && get(ENV, "PYTHON", "") == ""
                # Ensures PyCall uses the same Python executable
                ENV["PYTHON"] = ENV["JULIA_PYTHONCALL_EXE"]
            end
            println(ENV["PYTHON"])
            import Pkg
            Pkg.activate(raw"{}", io=devnull)
            {}
            import PythonCall
        catch err
            println("-------------------------------------------------------")
            Base.show_backtrace(stdout, Base.catch_backtrace())
            @error "Error loading PythonCall.jl" err=err
            rethrow()
        end
        '''.format(jlenv, install, c.pythonapi._handle)

got:

-------------------------------------------------------

Stacktrace:
  [1] pythrow()
    @ PythonCall C:\Users\ash\.julia\packages\PythonCall\zJpsh\src\err.jl:94
  [2] errcheck
    @ C:\Users\ash\.julia\packages\PythonCall\zJpsh\src\err.jl:10 [inlined]
  [3] pygetattr(x::PythonCall.Py, k::String)
    @ PythonCall C:\Users\ash\.julia\packages\PythonCall\zJpsh\src\abstract\object.jl:44
  [4] getproperty
    @ C:\Users\ash\.julia\packages\PythonCall\zJpsh\src\Py.jl:270 [inlined]
  [5] init_consts()
    @ PythonCall C:\Users\ash\.julia\packages\PythonCall\zJpsh\src\concrete\consts.jl:181    
  [6] (::PythonCall.var"#171#172")()
    @ PythonCall C:\Users\ash\.julia\packages\PythonCall\zJpsh\src\PythonCall.jl:84
  [7] with_gil
    @ C:\Users\ash\.julia\packages\PythonCall\zJpsh\src\cpython\gil.jl:14 [inlined]
  [8] with_gil
    @ C:\Users\ash\.julia\packages\PythonCall\zJpsh\src\cpython\gil.jl:9 [inlined]
  [9] __init__()
    @ PythonCall C:\Users\ash\.julia\packages\PythonCall\zJpsh\src\PythonCall.jl:83
 [10] _include_from_serialized(path::String, depmods::Vector{Any})
    @ Base .\loading.jl:768
 [11] _require_search_from_serialized(pkg::Base.PkgId, sourcepath::String)
    @ Base .\loading.jl:854
 [12] _require(pkg::Base.PkgId)
    @ Base .\loading.jl:1097
 [13] require(uuidkey::Base.PkgId)
    @ Base .\loading.jl:1013
 [14] require(into::Module, mod::Symbol)
    @ Base .\loading.jl:997
 [15] top-level scope
    @ none:11res: None

Traceback (most recent call last):
  File "hello.py", line 1, in <module>
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "PyInstaller\loader\pyimod03_importers.py", line 476, in exec_module
  File "juliacall\__init__.py", line 4, in <module>
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "PyInstaller\loader\pyimod03_importers.py", line 476, in exec_module
  File "juliacall\init.py", line 170, in <module>
Exception: PythonCall.jl did not start properly
[15224] Failed to execute script 'hello' due to unhandled exception!

timacro avatar Jan 07 '22 14:01 timacro

This issue has been marked as stale because it has been open for 30 days with no activity. If the issue is still relevant then please leave a comment, or else it will be closed in 7 days.

github-actions[bot] avatar Sep 13 '23 01:09 github-actions[bot]

This issue has been closed because it has been stale for 7 days. If it is still relevant, please re-open it.

github-actions[bot] avatar Sep 21 '23 01:09 github-actions[bot]