This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients gregory.p.smith, izbyshev, kevans, koobs, nanjekyejoannah, pablogsal, serhiy.storchaka, vstinner
Date 2019-01-17.10:00:47
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
Alexey Izbyshev
> So, if we can't change os.execvp() and/or current subprocess behavior, posix_spawnp seems to be ruled out.

My main motivation for using posix_spawn() is performance. An optimization should not justify to introduce a backward incompatible change. I agree wth posix_spawnp() cannot be used directly in subprocess because of that. But os.posix_spawnp() addition in Python 3.8 remains useful because it allows to use it directly (avoid subprocess).

> A naive emulation of posix_spawnp would be repeatedly calling posix_spawn for each PATH entry, but that's prohibitively expensive.

It should be compared to the current code. Currently, _posixsubprocess uses a loop calling execv(). I don't think that calling posix_spawn() in a loop until one doesn't fail is more inefficient.

The worst case would be when applying process attributes and run file actions would dominate performances... I don't think that such case exists. Syscalls like dup2() and close() should be way faster than the final successful execv() in the overall posix_spawn() call. I'm talking about the case when the program exists.

> Iterate over PATH entries and perform a quick check for common exec errors (ENOENT, ENOTDIR, EACCES) manually (e.g. by stat()).

I dislike this option. There is a high risk of race condition if the program is created, deleted or modified between the check and exec. It can cause subtle bugs, or worse: security vulnerabilities. IMHO the only valid check, to test if a program exists, is to call exec().

Alexey: Do you want to work on a PR to reimplement the "executable_list" and loop used by subprocess with _posixsubproces? You should keep the latest exception to re-raise it if no posix_spawn() successed. Don't forget to clear the exception on success, to not create a reference cycle:

commit acb9fa79fa6453c2bbe3ccfc9cad2837feb90093
Author: Victor Stinner <>
Date:   Wed Sep 13 10:10:10 2017 -0700

    bpo-31234, socket.create_connection(): Fix ref cycle (#3546)
Date User Action Args
2019-01-17 10:00:49vstinnersetrecipients: + vstinner, gregory.p.smith, serhiy.storchaka, koobs, izbyshev, pablogsal, nanjekyejoannah, kevans
2019-01-17 10:00:47vstinnersetmessageid: <>
2019-01-17 10:00:47vstinnerlinkissue35537 messages
2019-01-17 10:00:47vstinnercreate