According to Python 3.6 docs for Popen:
If preexec_fn is set to a callable object, this object will be called in the child process just before the child is executed. (POSIX only)
Then why does the parent process hang while the preexec_fn function is executed? If it is executed in the child process then the parent should be able to proceed.
Here is a small example of a program that creates a new "ls" process before which it sleeps for 4 seconds. Ideally "reached" should be printed immediately but that is not the case. "reached" in printed 4 seconds later.
import os
import subprocess
import sys
import tempfile
import time
def sleep_a_little():
time.sleep(4)
p = subprocess.Popen(["ls"], preexec_fn=sleep_a_little)
print("reached")