Eryk Sun <eryk...@gmail.com> added the comment:

Python uses the Windows C runtime to parse the command line into an argument 
array. By the CRT rules [1], you need to escape the embedded double quotes 
using backslashes. For example:

    PS C:\> python -c 's = \"fn main() {\"; s += \"\n\".join(\"let x = 0;\" for 
_ in range(2)); s+= \"}\"; print(s)'
    fn main() {let x = 0;
    let x = 0;}

In case you don't know already, PowerShell magically converts the single quotes 
in your command line to double quotes. It recognizes that most Windows programs 
parse the command line using the C runtime or WinAPI CommandLineToArgvW, which 
doesn't have any special handling for single quotes.

You can use ctypes to see how your original command line gets parsed via 
CommandLineToArgvW, which is functionally the same as what the C runtime does. 
For example (note the -i option to enter interactive mode):

    PS C:\> python -ic 's = "fn main() {"; s += "\n".join("let x = 0;" for _ in 
range(2)); s+= "}"; print(s)'
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    NameError: name 'fn' is not defined

    >>> import ctypes
    >>> kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
    >>> shell32 = ctypes.WinDLL('shell32', use_last_error=True)
    >>> kernel32.GetCommandLineW.restype = ctypes.c_wchar_p
    >>> shell32.CommandLineToArgvW.restype = ctypes.POINTER(ctypes.c_wchar_p)

    >>> cmd = kernel32.GetCommandLineW()
    >>> num = ctypes.c_int()
    >>> args = shell32.CommandLineToArgvW(cmd, ctypes.byref(num))

    >>> print(*zip(range(num.value), args[:num.value]), sep='\n')
    (0, 'C:\\Program Files\\Python39\\python.exe')
    (1, '-ic')
    (2, 's = fn')
    (3, 'main()')
    (4, '{; s += \\n.join(let')
    (5, 'x')
    (6, '=')
    (7, '0; for _ in range(2)); s+= }; print(s)')

As you can see, because the double quotes aren't escaped, they get consumed, 
combined with the rule for white space, to parse the command line after "-ic" 
into six arguments instead of just one argument.

---

[1] 
https://docs.microsoft.com/en-us/cpp/cpp/main-function-command-line-args?view=msvc-160#parsing-c-command-line-arguments

----------
nosy: +eryksun
resolution:  -> not a bug
stage:  -> resolved
status: open -> closed

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue42499>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to