Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pyinstaller, every joblib Parallel call creates a new tkinter window on MacOS

Here is the code which can reproduce the problem (it is just for reproducing the problem, so what it does is a bit meaningless):

from joblib import Parallel, delayed
import tkinter as tk


def f():
    print('func call')


if __name__ == '__main__':
    root = tk.Tk()

    button = tk.Button(root,
                       command=lambda: Parallel(n_jobs=-1, backend='threading')(delayed(f)() for _ in range(1)),
                       text='func')
    button.pack()

    root.mainloop()

The above code can run perfectly in my IDE, but once I create an executable with Pyinstaller, it bugs. The command line to create the executable is as below:

pyinstaller -F main.py

The excepted behavior is that, every time when presses the button in the tkinter window, a func call string should be printed in the terminal. But when I use the executable file to run, every time I press the button, besides the printing in the terminal, a new tkinter window is created.

I have also tried to build the executable in Windows with the same command. The executable file runs fine in Windows (No new tkinter window is created when pressing the button). Only the MacOS platform has this problem.

How should I fix this?

Here is the platform that I have the problem:

  • CPU: ARM64 (M1)
  • Python: 3.10
  • joblib: 1.1.0
  • pyinstaller 5.0.1
like image 720
Gordon Hui Avatar asked Oct 20 '25 17:10

Gordon Hui


1 Answers

The problem is solved by adding multiprocessing.freeze_support() to the code. The fixed version of code is as below:

import multiprocessing
multiprocessing.freeze_support()

from joblib import Parallel, delayed
import tkinter as tk


def f():
    print('func called')


if __name__ == '__main__':
    root = tk.Tk()

    button = tk.Button(root,
                       command=lambda: Parallel(n_jobs=-1, backend='threading')(delayed(f)() for _ in range(1)),
                       text='func')
    button.pack()

    root.mainloop()

Thank you rokm for answering my question on GitHub, here is the URL to rokm's answer: https://github.com/pyinstaller/pyinstaller/issues/6852#issuecomment-1138269358.

like image 69
Gordon Hui Avatar answered Oct 23 '25 07:10

Gordon Hui



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!