I am aware that sys.stdout
is a Python object that wraps the output file handle but I am wondering if those file handles are "synced" and always the same?
For example, say sys.stdout.isatty()
is True. I call GetStdHandle(-11)
(-11 is STDOUT on Windows) and then some Windows Console API that fails and find that the error's errno is 6 (The handle is invalid). AFAIK, this means that the handle is not a valid console handle. In that case, they are not "synced". In other words, is it possible to redirect sys.stdout
while the STDOUT handle returned by GetStdHandle
is not redirected? My code uses GetStdHandle
so ultimately I should test for errno 6 but it would be nice if I could just rely on sys.stdout.isatty
.
Here is an example (I don't have access to a windows machine at the moment but hopefully the code is correct). Run with and without redirection (or normally and within a call to subprocess.check_output
.
import sys
from ctypes import WinError, wintypes
STDOUT = -11
ERROR_INVALID_HANDLE = 6
kernel32 = ctypes.WinDLL('kernel32', use_errno=True, use_last_error=True)
handle = kernel32.GetStdHandle(STDOUT)
# Assume we set argtypes/restype for all win api functions here
if handle == wintypes.HANDLE(-1).value:
raise WinError()
console_mode = wintypes.DWORD(0)
# We use GetConsoleMode here but it could be any function that expects a
# valid console handle
retval = kernel32.GetConsoleMode(handle, ctypes.byref(console_mode))
# Are the following assertions always true?
if retval == 0:
errno = ctypes.get_last_error()
if errno == ERROR_INVALID_HANDLE:
print('Invalid handle')
assert not sys.stdout.isatty()
else:
# Another error happened
raise WinError()
else:
assert sys.stdout.isatty()
I tried to scour the CPython source code but could not find anything that could confirm or deny this. Perhaps someone more experienced with the codebase could point me in the right direction?
EDIT: I know about the CONOUT$ + CreateFile
API. I am not interested in getting the input or output handle under redirection but in understanding the relationship between the Windows console handle APIs and sys.stdout
.