123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
- import atexit
- import contextlib
- import sys
- from .ansitowin32 import AnsiToWin32
- def _wipe_internal_state_for_tests():
- global orig_stdout, orig_stderr
- orig_stdout = None
- orig_stderr = None
- global wrapped_stdout, wrapped_stderr
- wrapped_stdout = None
- wrapped_stderr = None
- global atexit_done
- atexit_done = False
- global fixed_windows_console
- fixed_windows_console = False
- try:
- # no-op if it wasn't registered
- atexit.unregister(reset_all)
- except AttributeError:
- # python 2: no atexit.unregister. Oh well, we did our best.
- pass
- def reset_all():
- if AnsiToWin32 is not None: # Issue #74: objects might become None at exit
- AnsiToWin32(orig_stdout).reset_all()
- def init(autoreset=False, convert=None, strip=None, wrap=True):
- if not wrap and any([autoreset, convert, strip]):
- raise ValueError('wrap=False conflicts with any other arg=True')
- global wrapped_stdout, wrapped_stderr
- global orig_stdout, orig_stderr
- orig_stdout = sys.stdout
- orig_stderr = sys.stderr
- if sys.stdout is None:
- wrapped_stdout = None
- else:
- sys.stdout = wrapped_stdout = \
- wrap_stream(orig_stdout, convert, strip, autoreset, wrap)
- if sys.stderr is None:
- wrapped_stderr = None
- else:
- sys.stderr = wrapped_stderr = \
- wrap_stream(orig_stderr, convert, strip, autoreset, wrap)
- global atexit_done
- if not atexit_done:
- atexit.register(reset_all)
- atexit_done = True
- def deinit():
- if orig_stdout is not None:
- sys.stdout = orig_stdout
- if orig_stderr is not None:
- sys.stderr = orig_stderr
- def just_fix_windows_console():
- global fixed_windows_console
- if sys.platform != "win32":
- return
- if fixed_windows_console:
- return
- if wrapped_stdout is not None or wrapped_stderr is not None:
- # Someone already ran init() and it did stuff, so we won't second-guess them
- return
- # On newer versions of Windows, AnsiToWin32.__init__ will implicitly enable the
- # native ANSI support in the console as a side-effect. We only need to actually
- # replace sys.stdout/stderr if we're in the old-style conversion mode.
- new_stdout = AnsiToWin32(sys.stdout, convert=None, strip=None, autoreset=False)
- if new_stdout.convert:
- sys.stdout = new_stdout
- new_stderr = AnsiToWin32(sys.stderr, convert=None, strip=None, autoreset=False)
- if new_stderr.convert:
- sys.stderr = new_stderr
- fixed_windows_console = True
- @contextlib.contextmanager
- def colorama_text(*args, **kwargs):
- init(*args, **kwargs)
- try:
- yield
- finally:
- deinit()
- def reinit():
- if wrapped_stdout is not None:
- sys.stdout = wrapped_stdout
- if wrapped_stderr is not None:
- sys.stderr = wrapped_stderr
- def wrap_stream(stream, convert, strip, autoreset, wrap):
- if wrap:
- wrapper = AnsiToWin32(stream,
- convert=convert, strip=strip, autoreset=autoreset)
- if wrapper.should_wrap():
- stream = wrapper.stream
- return stream
- # Use this for initial setup as well, to reduce code duplication
- _wipe_internal_state_for_tests()
|