'A context manager that sets up the isolation for invoking of a
command line tool.  This sets up stdin with the given input data
and `os.environ` with the overrides from the given dictionary.
This also rebinds some internals in Click to be mocked (like the
prompt functionality).
This is automatically done in the :meth:`invoke` method.
.. versionadded:: 4.0
The ``color`` parameter was added.
:param input: the input stream to put into sys.stdin.
:param env: the environment overrides as dictionary.
:param color: whether the output should contain color codes. The
application can still override this explicitly.'

@contextlib.contextmanager
def isolation(self, input=None, env=None, color=False):

    input = make_input_stream(input, self.charset)
    old_stdin = sys.stdin
    old_stdout = sys.stdout
    old_stderr = sys.stderr
    old_forced_width = clickpkg.formatting.FORCED_WIDTH
    clickpkg.formatting.FORCED_WIDTH = 80
    env = self.make_env(env)
    if PY2:
        sys.stdout = sys.stderr = bytes_output = StringIO()
        if self.echo_stdin:
            input = EchoingStdin(input, bytes_output)
    else:
        bytes_output = io.BytesIO()
        if self.echo_stdin:
            input = EchoingStdin(input, bytes_output)
        input = io.TextIOWrapper(input, encoding=self.charset)
        sys.stdout = sys.stderr = io.TextIOWrapper(bytes_output, encoding=self.charset)
    sys.stdin = input
    def visible_input(prompt=None):
        sys.stdout.write((prompt or ''))
        val = input.readline().rstrip('\r\n')
        sys.stdout.write((val + '\n'))
        sys.stdout.flush()
        return val
    def hidden_input(prompt=None):
        sys.stdout.write(((prompt or '') + '\n'))
        sys.stdout.flush()
        return input.readline().rstrip('\r\n')
    def _getchar(echo):
        char = sys.stdin.read(1)
        if echo:
            sys.stdout.write(char)
            sys.stdout.flush()
        return char
    default_color = color
    def should_strip_ansi(stream=None, color=None):
        if (color is None):
            return (not default_color)
        return (not color)
    old_visible_prompt_func = clickpkg.termui.visible_prompt_func
    old_hidden_prompt_func = clickpkg.termui.hidden_prompt_func
    old__getchar_func = clickpkg.termui._getchar
    old_should_strip_ansi = clickpkg.utils.should_strip_ansi
    clickpkg.termui.visible_prompt_func = visible_input
    clickpkg.termui.hidden_prompt_func = hidden_input
    clickpkg.termui._getchar = _getchar
    clickpkg.utils.should_strip_ansi = should_strip_ansi
    old_env = {}
    try:
        for (key, value) in iteritems(env):
            old_env[key] = os.environ.get(key)
            if (value is None):
                try:
                    del os.environ[key]
                except Exception:
                    pass
            else:
                os.environ[key] = value
        (yield bytes_output)
    finally:
        for (key, value) in iteritems(old_env):
            if (value is None):
                try:
                    del os.environ[key]
                except Exception:
                    pass
            else:
                os.environ[key] = value
        sys.stdout = old_stdout
        sys.stderr = old_stderr
        sys.stdin = old_stdin
        clickpkg.termui.visible_prompt_func = old_visible_prompt_func
        clickpkg.termui.hidden_prompt_func = old_hidden_prompt_func
        clickpkg.termui._getchar = old__getchar_func
        clickpkg.utils.should_strip_ansi = old_should_strip_ansi
        clickpkg.formatting.FORCED_WIDTH = old_forced_width
