Pyinstaller with concurrent.futures executing function call on every process start

265 Views Asked by At

Edit: So I've been playing around with this; placing the getpass() call under the if name block, placing it in main, outside of main, the big issue is when it runs in the IDE or CLI normally it works as intended. But when I run it from frozen python, each process is calling all of the top level code and appears to be calling main again. I'm trying to figure out how to prevent the process.pool.executor from executing all of the code in main each time a new process starts. This doesn't seem to be an issue anywhere but frozen python.

I've been working on this project and nearly finished, except I encountered an issue with the program when I freeze it with pyinstaller.

The program starts by prompting the user for their password in the command line using getpass.getpass(). Then passes that value into the function called by the ProcessPoolExecutor. Problem is, each time the pool starts a new process, the CLI in the frozen python prompts for the password again. In the IDE and native python it only prompts once at the start and that value is stored and passed into each new process. I'm not sure what to do differently to fix this.

example code below:

import concurrent.futures
import getpass
from functools import partial

def multi_process_function(user, password, iterable):
     #do a thing 

def main():
     user = getpass.getuser()
     password = getpass.getpass('Please enter password')

     func = partial(multi_process_function, user, password)
     iterableThing = [1, 2, 3]
     output = {}

     with concurrent.futures.ProcessPoolExecutor as executor:
         results = executor.map(func, iterableThing)

         for result in results:
             output.update(result)

if __name__ == '__main__':
    main()

This is an example of the output:

enter image description here

1

There are 1 best solutions below

0
Rufom1 On

Ok so the answer was stupid simple, and practically a magic line of code.

multiprocessing.freeze_support()

before calling main under the if name block.

I saw this in some other SO posts but my code wasn't "crashing" it was just not running as expected when run from frozen. However, my guess is that the program never got to a point where it crashed since each process was stuck on the getpass() call at the top level of the code or main or wherever it was in the script.