Cache prevents re-enabling ANSI support when a subprocess has disabled it
Problem description
Using subprocess on Windows can break the colored output of coloredlogs if the new process modifies the console mode. Unfortunately, this seems to happen quite a lot, and the caching applied to enable_ansi_support() prevents the end-user from turning it back on using this function. The cache is effectively invalid after every subprocess.Popen because of this.
Reproduction program given below.
Possible fix
Python 3.8 adds audit hooks that would allow this cache to be invalidated whenever subprocess is being used on Windows. If the relevant ANSI functionality in humanfriendly called enable_ansi_support() before producing output, the reenable_ansi() function defined in the program below could be installed as an audit hook to automatically resolve the problem. Whether or not that's something humanfriendly would want to do is up to the maintainer(s), but if so I would be happy to submit a PR to do this. If not, hopefully this trick helps out any users who stub their toe on the same bug :slightly_smiling_face:
import sys
if sys.version_info > (3, 8):
def reenable_ansi_hook(event, args):
if event == "subprocess.Popen":
reenable_ansi() # defined below
sys.addaudithook(reenable_ansi_hook)
Reproduction program
import logging
import subprocess
import coloredlogs
logger = logging.getLogger(__name__)
coloredlogs.install()
logger.info(f"This line should have working ANSI")
subprocess.check_output(["echo"]) # changes the console mode on Windows 10
logger.info(f"This line should have broken ANSI")
subprocess.check_output(["echo"])
coloredlogs.enable_ansi_support() # does NOT enable ANSI support because the cache is now invalid
logger.info(f"This line should have working ANSI again")
def reenable_ansi():
try:
# invalidate the cache, if necessary
del coloredlogs.enable_ansi_support.cached_results
except NameError:
pass
coloredlogs.enable_ansi_support()
subprocess.check_output(["echo"])
reenable_ansi()
logger.info(f"This line should have working ANSI again")
Screenshot of Win10 output
