pythonw.exe or python.exe?
Asked Answered
G

5

206

Long story short: pythonw.exe does nothing, python.exe accepts nothing (which one should I use?)

test.py:

print "a"

CMD window:

C:\path>pythonw.exe test.py
<BLANK LINE>
C:\path>

C:\path>python.exe test.py
  File "C:\path\test.py", line 7
    print "a"
            ^
SyntaxError: invalid syntax

C:\path>

Please tell me what I'm doing terrible wrong.

Glossa answered 14/3, 2012 at 16:30 Comment(2)
unfortunately this intermixes the two aspects python vs pythonw (generally the more interesting aspect) and some basic syntax change from python2 to python3. no criticism of the OP who could not know beforehand, but nonetheless it taints the value of this question as the go-to resource about pythonw.Blalock
Since this was recently updated I should clarify: in Python 3, print 'x' fails now because parentheses are required. Must use print('x').Materials
L
193

If you don't want a terminal window to pop up when you run your program, use pythonw.exe;
Otherwise, use python.exe

Regarding the syntax error: print is now a function in 3.x
So use instead:

print("a")
Lamrert answered 14/3, 2012 at 16:33 Comment(1)
Running a .pyw file from Notepad++ I still get a console window. To prevent this I have to double-click the file name to open the app. Only then do I see just the GUI and no console.Cylindroid
G
364

To summarize and complement the existing answers:

  • python.exe is a console (terminal) application for launching CLI-type scripts (console applications).

    • Unless run from an existing console window, python.exe opens a new console window.

    • Standard streams sys.stdin, sys.stdout and sys.stderr are connected to the console window.

    • Execution is synchronous when launched from a cmd.exe or PowerShell console window: See eryksun's 1st comment below.

      • If a new console window was created, it stays open until the script terminates.
      • When invoked from an existing console window, the prompt is blocked until the script terminates.
  • pythonw.exe is a GUI app for launching GUI/no-UI-at-all scripts.

    • NO console window is opened.
    • Execution is asynchronous:
      • When invoked from a console window, the script is merely launched and the prompt returns right away, whether the script is still running or not.
    • Standard streams sys.stdin, sys.stdout and sys.stderr are NOT available.
      • Caution: Unless you take extra steps, this has potentially unexpected side effects:
        • Unhandled exceptions cause the script to abort silently.
        • In Python 2.x, simply trying to use print() can cause that to happen (in 3.x, print() simply has no effect).
          • To prevent that from within your script, and to learn more, see this answer of mine.
          • Ad-hoc, you can use output redirection:Thanks, @handle.
            pythonw.exe yourScript.pyw 1>stdout.txt 2>stderr.txt
            (from PowerShell:
            cmd /c pythonw.exe yourScript.pyw 1>stdout.txt 2>stderr.txt) to capture stdout and stderr output in files.
            If you're confident that use of print() is the only reason your script fails silently with pythonw.exe, and you're not interested in stdout output, use @handle's command from the comments:
            pythonw.exe yourScript.pyw 1>NUL 2>&1
            Caveat: This output redirection technique does not work when invoking *.pyw scripts directly (as opposed to by passing the script file path to pythonw.exe). See eryksun's 2nd comment and its follow-ups below.

You can control which of the executables runs your script by default - such as when opened from Explorer - by choosing the right filename extension:

  • *.py files are by default associated (invoked) with python.exe
  • *.pyw files are by default associated (invoked) with pythonw.exe
Gloucestershire answered 18/5, 2015 at 21:28 Comment(9)
This does not seem to be documented on docs.python.org/3/using/windows.html Also see anatoly techtonik's comment in jon's answer: pythonw.exe might fail silently for some reason (Exception, print() ?). I cannot get pythonw.exe to persist using bottle.py (quiet=True ) which uses docs.python.org/3/library/… by default.Waterfowl
PS: It does work when I pipe stdout and stderr somewhere: > pythonw ls.pyw >nul 2>&1 (even though nothing is written).Waterfowl
@handle: As the paragraph above starting with "Caution: Unless you take extra steps..." states, pythonw.exe aborts silently on unhandled exceptions, unless your script explicitly handles that situation; in Python 2.x, this includes something as trivial as a call to print(), which, due to the unavailability of stdout, causes an exception (this has been fixed in 3.x); the same paragraph contains a link to this answer, which shows you what to do.Gloucestershire
@handle: The ad-hoc workaround with output redirection (>) is useful, thanks - I've added it to the answer. It works, because it connects streams to sys.stdout and sys.stderr even when running with pythonw.exe, preventing print() from failing (2.x). If use of print() statements are your script's only problem, then redirecting both stdout and stderr to NUL is fine, but note that you'll miss true exceptions that way.Gloucestershire
This synchronous and asynchronous behavior is just from the cmd.exe interactive command prompt without using the start command. It actually inspects the PEB of the child process to determine whether it's a console process. The console host process (conhost.exe) doesn't care about this. If you use subprocess.Popen to attach another python.exe instance to the current console and don't wait on it, then you'll have a confusing mess of both processes racing to access the console simultaneously.Minesweeper
A user-mode process is created by the system call NtCreateUserProcess. If the target executable is a console program, the system unconditionally inherits the parent's standard handles. But for a non-console program it requires being explicitly told to inherit the parent's inheritable handles. To run a file based on a file association, cmd calls ShellExecuteEx, which does not explicitly inherit handles when it calls CreateProcess => NtCreateUserProcess. Consequently redirecting standard I/O works in cmd when starting console .py scripts but not non-console .pyw scripts.Minesweeper
@eryksun: Thanks; I've updated the answer to point to your comments in the appropriate places. Re your 2nd comment: so why does explicit invocation of pythonw.exe cause the handles to be inherited? Because pythonw.exe is both a GUI and a console application, and cmd.exe detects that?Gloucestershire
The cmd shell first tries CreateProcess with bInheritHandles passed as TRUE. It only falls back on ShellExecuteEx when CreateProcess fails because the target isn't a PE executable (e.g. it's a .py script) or requires elevation (e.g. osk.exe). So when you directly run pythonw.exe or pyw.exe, it will inherit cmd's StandardInput, StandardOutput, and StandardError, which cmd (actually the CRT) modifies via SetStdHandle before and after calling CreateProcess when standard I/O is redirected to a pipe, file, or device.Minesweeper
Note that cmd does not use the STARTUPINFO handles (hStdInput, hStdOutput, hStdErr), unlike Python's subprocess.Popen. It can get away with this because it's a single-threaded program. It's only due to this design that redirection works at all with ShellExecuteEx (just for console programs, as noted) because the GUI shell API otherwise has no support for standard I/O.Minesweeper
L
193

If you don't want a terminal window to pop up when you run your program, use pythonw.exe;
Otherwise, use python.exe

Regarding the syntax error: print is now a function in 3.x
So use instead:

print("a")
Lamrert answered 14/3, 2012 at 16:33 Comment(1)
Running a .pyw file from Notepad++ I still get a console window. To prevent this I have to double-click the file name to open the app. Only then do I see just the GUI and no console.Cylindroid
P
21

See here: http://docs.python.org/using/windows.html

pythonw.exe "This suppresses the terminal window on startup."

Plunkett answered 14/3, 2012 at 16:34 Comment(1)
pythonw.exe has side effects that your program may fail silenty if it writes to stdout/stderr stream - see bugs.python.org/issue706263Iodize
R
21

If you're going to call a python script from some other process (say, from the command line), use pythonw.exe. Otherwise, your user will continuously see a cmd window launching the python process. It'll still run your script just the same, but it won't intrude on the user experience.

An example might be sending an email; python.exe will pop up a CLI window, send the email, then close the window. It'll appear as a quick flash, and can be considered somewhat annoying. pythonw.exe avoids this, but still sends the email.

Ram answered 14/3, 2012 at 16:39 Comment(1)
True, but re "say, from the command line": If you already are in a console (terminal) window, then python.exe will not open another one.Gloucestershire
L
3

I was struggling to get this to work for a while. Once you change the extension to .pyw, make sure that you open properties of the file and direct the "open with" path to pythonw.exe.

Lecia answered 27/10, 2016 at 5:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.