I want to use logging, but with stderr redirection to stdout, as in:
import logging
import sys
logging.basicConfig(stream=sys.stdout)
for i in range(1, 100):
logging.warning("foo") # this should go to stdout
However, this setup is insufficient: if I run this script with grep -q foo, for instance, it will fail with BrokenPipeError: [Errno 32] Broken pipe.
Even if I wrap the whole for block around a try ... except, the error still happens.
As mentioned in this question, solutions such as sys.stderr.close() are not ideal, since they mask useful errors.
The solution from the question above (wrap a try ... except and then do sys.stdout = None) does not work in the case of the logging setup above. Neither does calling logging.shutdown() in the except block.
This logging-related question about redirecting stdout and stderr to a logger seems to indicate that it is necessary to write a class and several methods. Is it necessary even in my case? One of the answers suggests that using contextlib.redirect_stderr might help, but I tried and the error still happens (it happens inside the TextIOWrapper used by the logger, so it seems I cannot catch it).
Finally, when googling the "exception ignored message" sent by the logger, I find this SO question, but its solution is specific to the az command mentioned in the question.
So, I still couldn't find a workable solution: what's the simplest, correct way to setup a logger which sends warnings and errors to stdout?
Edit: on Windows, it's even worse: the broken pipe error may become an EINVAL (OSError: [Errno 22] Invalid argument). Apparently the only way to prevent it would be to code a custom stream (via TextIOBase) and then use that stream in a StreamHandler. So, replacing sys.stdout with something very similar, but which allows me to ignore the broken pipe error (possibly quitting execution if needed).