- Core Concepts & Mnemonic: python.exe vs pythonw.exe
- Windows Subsystems and I/O Stream Internals
- Common Gotchas: Subprocesses and « stderr duplication failed »
- Decision Matrix: When to Use Which
Core Concepts & Mnemonic: python.exe vs pythonw.exe
– A strictly Windows-specific distinction:
Under Linux and macOS (POSIX systems), there is only python3. Running a background script or GUI without a blocking terminal is handled by the shell (e.g. nohup, &, or process managers).
Under Windows, the operating system requires every executable file (PE header) to explicitly declare its target subsystem upon compilation: Console or GUI.
– The Mnemonic rule (Moyen mnémotechnique):
– python.exe = Console (Standard mode). Always allocates or attaches to a terminal window (CMD/PowerShell) with active input/output streams.
– pythonw.exe = Windowless / Windows GUI. The « w » stands for Windowing: it suppresses the console window entirely so no black terminal rectangle appears on screen.
Windows Subsystems and I/O Stream Internals
– Binary compilation flags:
Windows handles process creation differently based on the executable’s subsystem flag:
– python.exe is compiled with /SUBSYSTEM:CONSOLE. The Windows Kernel automatically allocates a new console window if launched from the File Explorer, or reuses the current terminal session.
– pythonw.exe is compiled with /SUBSYSTEM:WINDOWS. Windows initializes the process as a pure GUI application without allocating any console handle.
– Standard streams behavior (sys.stdout, sys.stderr, sys.stdin):
In a standard python.exe process, the three standard streams are bound to file descriptors (0, 1, 2).
In a pythonw.exe process, Windows assigns NULL (or INVALID_HANDLE_VALUE) to standard descriptors:
# When executed with pythonw.exe: import sys print(sys.stdout) # Returns None (or an unusable dummy stream in older versions) print(sys.stderr) # Returns None print(sys.stdin) # Returns None # Calling print() or logging to stdout directly can raise an OSError or fail silently: sys.stdout.write("Hello") # AttributeError: 'NoneType' object has no attribute 'write' |
Decision Matrix: When to Use Which
– Recommended usage mapping:
Select the binary according to the operational context of the script:
+------------------------------------------+-------------------+--------------------+ | Use Case / Workload | Executable Target | File Extension | +------------------------------------------+-------------------+--------------------+ | Web APIs (FastAPI, Flask, Django) | python.exe | .py | | IDE, CLI tools, scripts, pytest, etc... | python.exe | .py | | Desktop GUI Apps (Tkinter, PyQt, Kivy) | pythonw.exe | .pyw (or .py) | | Background agents / System tray widgets | pythonw.exe | .pyw | | Windows Scheduled Tasks (silent mode) | pythonw.exe | .pyw | +------------------------------------------+-------------------+--------------------+ |