Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserve active input when writing to console #1181

Merged
merged 1 commit into from
Aug 6, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 43 additions & 1 deletion brownie/_cli/console.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/python3

import builtins
import code
import importlib
import inspect
Expand Down Expand Up @@ -79,6 +80,42 @@ def __call__(self, code=None):
raise SystemExit(code)


class ConsolePrinter:
"""
Custom printer during console input.

Ensures that stdout of the active prompt buffer is preserved when the console
is written to during user imnut.
"""

_builtins_print = builtins.print

def __init__(self, console):
self.console = console

def start(self):
builtins.print = self

def __call__(self, *values, sep=" ", end="\n", file=sys.stdout, flush=False):
if file != sys.stdout:
self._builtins_print(*values, sep=sep, end=end, file=file, flush=flush)
return

ps = sys.ps2 if self.console.buffer else sys.ps1
line = f"{ps}{self.console.prompt_session.app.current_buffer.text}"

# overwrite the prompt output with whitespace, in case the printed data is shorter
self.console.write(f"\r{' ' * len(line)}\r")

if not end.endswith("\n"):
end = "{end}\n"
text = f"{sep.join(str(i) for i in values)}{end}{line}"
self.console.write(text)

def finish(self):
builtins.print = self._builtins_print


class Console(code.InteractiveConsole):

# This value is used as the `input` arg when initializing `prompt_toolkit.PromptSession`.
Expand Down Expand Up @@ -172,6 +209,7 @@ def __init__(self, project=None, extra_locals=None, exit_on_continue=False):

colorama.init()

self.console_printer = ConsolePrinter(self)
super().__init__(locals_dict)

def _dir(self, obj=None):
Expand Down Expand Up @@ -208,7 +246,11 @@ def interact(self, *args, **kwargs):
CONFIG.argv["cli"] = cli_mode

def raw_input(self, prompt=""):
return self.prompt_session.prompt(prompt)
self.console_printer.start()
try:
return self.prompt_session.prompt(prompt)
finally:
self.console_printer.finish()

def showsyntaxerror(self, filename):
tb = color.format_tb(sys.exc_info()[1])
Expand Down