classification
Title: subprocess.list2cmdline() does not allow running some commands.
Type: behavior Stage: resolved
Components: IO, Library (Lib), Windows Versions: Python 3.7, Python 3.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Roffild, eryksun, paul.moore, steve.dower, tim.golden, zach.ware
Priority: normal Keywords:

Created on 2018-11-03 20:55 by Roffild, last changed 2018-11-05 19:43 by Roffild. This issue is now closed.

Messages (5)
msg329207 - (view) Author: Roffild (Roffild) Date: 2018-11-03 20:55
This issue has already been discussed in #23862

Have to use this hack:

import subprocess

def list2cmdlineHack(seq):
    return " ".join(seq)

subprocess.list2cmdline = list2cmdlineHack

There must be an argument in subprocess.run() to disable subprocess.list2cmdline(). Let the programmer set the start line of the command himself.
msg329217 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2018-11-04 02:48
In case you don't know, on Windows an args sequence has to be converted to a command line that's compatible with CreateProcess[AsUser]. If the executable path isn't passed separately, the system has to parse it from the command line, and in this case paths with spaces need to be quoted in double quotes. That's the extent of what the system needs to see. Parsing the rest is the responsibility of the program itself once it's running. Most follow common rules. In particular, the C runtime library parses the command line into a Unix-style argv array, and the shell32 API provides a nearly identical implementation as CommandLineToArgvW. subprocess.list2cmdline is intended for this common case. Other cases, which are rare with the exception of the CMD shell, require manually processing an args sequence into a compatible command line.
msg329253 - (view) Author: Roffild (Roffild) Date: 2018-11-04 20:02
Yes, the string with spaces must be enclosed in double quotes. But when a programmer calls CreateProcess(), he himself puts double quotes or calls CommandLineToArgvW().

subprocess.list2cmdline() is always called and can spoil the launch string.

I propose to add an additional argument list2cmdline=False in subprocess.run() to disable this function.

subprocess.run(['"program path"', '/param="space space"'], list2cmdline=False)

subprocess.run('"program path" /param="space space"', list2cmdline=False)
msg329256 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2018-11-04 20:39
> he himself puts double quotes or calls CommandLineToArgvW

CommandLineToArgvW has nothing to do with creating a command line for use with CreateProcess. It's used by a process to parse its own command line using the common VC++ rules.

> subprocess.list2cmdline() is always called

No, it's only called for an args sequence, not a command-line string. If you have your own function to convert a sequence to a command-line, then call it explicitly, e.g. subprocess.run(mylist2cmdline(args)).
msg329314 - (view) Author: Roffild (Roffild) Date: 2018-11-05 19:43
Yes, my mistake.

Lib/subprocess.py:970
History
Date User Action Args
2018-11-05 19:43:12Roffildsetstatus: open -> closed
resolution: not a bug
messages: + msg329314

stage: resolved
2018-11-04 20:39:02eryksunsetmessages: + msg329256
2018-11-04 20:02:43Roffildsetmessages: + msg329253
2018-11-04 02:48:47eryksunsetnosy: + eryksun
messages: + msg329217
2018-11-03 20:55:53Roffildcreate