Eryk Sun firstname.lastname@example.org added the comment:
Python is conceptually multi-platform, so its behavior on Linux and Windows should be as much consistent as possible.
It's not expected for the behavior of all Popen() parameters to be the same on all platforms. For example, the behavior and capabilities of shell=True are different in Windows vs POSIX. But I think a basic set of parameters should have been singled out for cross-platform consistency -- at least in the default case. Unfortunately it wasn't designed that way. New behavior that's consistent with POSIX can be implemented, but at this point it would have to be enabled by a parameter.
"In particular, the function looks for executable (or for the first item in args) relative to cwd if the executable path is a relative path."
For POSIX, this should be stated as a "relative path without a slash in it" or a "relative path without a directory in it". An unqualified filename is a relative path that won't be resolved against `cwd`, unless there's a "." entry in PATH.
For Windows, the use of CreateProcess() is documented. It could be stated more explicitly that `executable`, `args` / list2cmdline(args), `env`, and `cwd` are passed directly to CreateProcess() as lpApplicationName, lpCommandLine, lpEnvironment, and lpCurrentDirectory.
Here are some notes and corrections about the documentation of lpCommandLine, in particular the following paragraph:
If the file name does not contain an extension, .exe is appended. Therefore, if the file name extension is .com, this parameter must include the .com extension. If the file name ends in a period (.) with no extension, or if the file name contains a path, .exe is not appended. If the file name does not contain a directory path, the system searches for the executable file in the following sequence :
* %__APPDIR__% * %__CD__%  * %SystemRoot%\System32 * %SystemRoot%\System * %SystemRoot% * %PATH% (machine/user extended search sequence)
 The search sequence is rewritten here succinctly using environment variables in the current process, including the virtual variables __APPDIR__ (application directory) and __CD__ (current directory), which are supported by WinAPI GetEnvironmentVariableW().
 A path name is resolved by searching for it if it isn't fully qualified and doesn't explicitly begin with the current directory (".") or its parent (".."). Note that, unlike POSIX, a relative path name is resolved by searching for it even if it contains a directory component (i.e. a slash or backslash). For example, "spam\eggs.exe" is resolved by looking for r"%__APPDIR__%\spam\eggs.exe" and so on.
 If a path name has to be resolved by searching, and its final component does not contain a "." character, then ".exe" is appended to the name. On the other hand, if a path name does not need to be resolved by searching, because it's fully qualified or the first component is "." or "..", then if the given path name doesn't exist, it also looks for the name with ".exe" appended, even if the final component of the path name contains a "." character.
 If "NoDefaultCurrentDirectoryInExePath" is defined in the environment and the path name does not contain a directory component (i.e. no slash or backslash), then the current directory is excluded from the search sequence.
That %__APPDIR__% always takes precedence means that subprocess.Popen(['python']) runs the Python version of the current process, regardless of PATH, unless shell=True is used.
The implementation of lpApplicationName (executable) and lpCurrentDirectory (cwd) means that argv in the child process, as parsed from its command line, does not necessarily resolve to a name in the filesystem. Windows supports GetModuleFileNameW(NULL, ...) to get the path of the application executable.
---------- versions: +Python 3.10, Python 3.9 -Python 3.6, Python 3.7