I support deprecating these legacy os APIs. Though we should try to do some research to figure out if anything remains that uses them first before deciding that.
We could also re-implement them on top of subprocess. But the potential for subtle behavior differences makes that even more painful, I’d rather reduce our maintenance burden and API surface and let people who do depend on subtle behaviors in their specific scenario discover that on their own during a deprecation period.
The os.spawn* API docstrings all use text of the form:
“Execute file with …”
“Execute file (which is looked for along $PATH) with …”
Those are accurate. The naming convention for the APIs with the ‘l’, ‘v’, ‘p’, and ‘e’ monikers all originate from the underlying C exec* APIs.
If you pass a fully specified path name to a p function it should just behave the same as its non-p variant that should cause the execp() variant under the hood to skip the $PATH check.
We cannot rename the arguments. Existing code may depend on them as keyword argument names. And changing the documentation to not match the argument name carries the burden to needing to explain in the documentation what the actual argument name is while not using that name in the docs so that people encountering a use of keyword arguments can make sense of things. A nice way to do that is a style question for docs folks to consider. This isn’t the only stdlib API with imperfect parameter names on things intended to be positional, and thus name unseen, but long predating positional-only arguments.
“cmd” is inaccurate as a “command” can be read to imply the use of a shell and potential additional parsing of an arbitrary string which these APIs not do. The existing “file” feels accurate enough as “file” is intentionally ambiguous as to whether or not it is fully specified and fully specified paths always work. Hindsight could prefer the name to be “executable”, but that isn’t going to happen because we’re not going to change the API.