From ca56539f96043273943e4404bc2b5d2ca16e8ec6 Mon Sep 17 00:00:00 2001 From: Attila Szollosi Date: Thu, 4 Oct 2018 09:39:37 +0200 Subject: [PATCH] Merge send_to_stdout and send_to_stderr; fix newline handling (#744) --- bpython/curtsiesfrontend/repl.py | 51 ++++++------------------------ bpython/test/test_curtsies_repl.py | 28 ++++++++++++++++ 2 files changed, 38 insertions(+), 41 deletions(-) diff --git a/bpython/curtsiesfrontend/repl.py b/bpython/curtsiesfrontend/repl.py index c4614a580..d36997a22 100644 --- a/bpython/curtsiesfrontend/repl.py +++ b/bpython/curtsiesfrontend/repl.py @@ -229,7 +229,7 @@ def readline(self): value = self.readline_results.pop(0) else: value = 'no saved input available' - self.repl.send_to_stdout(value) + self.repl.send_to_stdouterr(value) return value @@ -333,7 +333,7 @@ def __init__(self, if interp is None: interp = Interp(locals=locals_) - interp.write = self.send_to_stderr + interp.write = self.send_to_stdouterr if banner is None: if config.help_key: banner = (_('Welcome to bpython!') + ' ' + @@ -393,9 +393,9 @@ def __init__(self, # filenos match the backing device for libs that expect it, # but writing to them will do weird things to the display - self.stdout = FakeOutput(self.coderunner, self.send_to_stdout, + self.stdout = FakeOutput(self.coderunner, self.send_to_stdouterr, fileno=sys.__stdout__.fileno()) - self.stderr = FakeOutput(self.coderunner, self.send_to_stderr, + self.stderr = FakeOutput(self.coderunner, self.send_to_stdouterr, fileno=sys.__stderr__.fileno()) self.stdin = FakeStdin(self.coderunner, self, self.edit_keys) @@ -1140,27 +1140,16 @@ def clear_current_block(self, remove_from_history=True): def get_current_block(self): return '\n'.join(self.buffer + [self.current_line]) - def move_current_stdouterr_line_up(self): - """Append self.current_stdouterr_line to self.display_lines - then clean it.""" - self.display_lines.extend(paint.display_linize( - self.current_stdouterr_line, self.width)) - self.current_stdouterr_line = '' + def send_to_stdouterr(self, output): + """Send unicode strings or FmtStr to Repl stdout or stderr - def send_to_stdout(self, output): - """Send unicode string to Repl stdout""" + Must be able to handle FmtStrs because interpreter pass in + tracebacks already formatted.""" if not output: return lines = output.split('\n') - if all(not line for line in lines): - # If the string consist only of newline characters, - # str.split returns one more empty strings. - lines = lines[:-1] logger.debug('display_lines: %r', self.display_lines) - if lines[0]: - self.current_stdouterr_line += lines[0] - else: - self.move_current_stdouterr_line_up() + self.current_stdouterr_line += lines[0] if len(lines) > 1: self.display_lines.extend(paint.display_linize( self.current_stdouterr_line, self.width, blank_line=True)) @@ -1171,26 +1160,6 @@ def send_to_stdout(self, output): self.current_stdouterr_line = lines[-1] logger.debug('display_lines: %r', self.display_lines) - def send_to_stderr(self, error): - """Send unicode strings or FmtStr to Repl stderr - - Must be able to handle FmtStrs because interpreter pass in - tracebacks already formatted.""" - if not error: - return - lines = error.split('\n') - if all(not line for line in lines): - # If the string consist only of newline characters, - # str.split returns one more empty strings. - lines = lines[:-1] - if lines[-1]: - self.current_stdouterr_line += lines[-1] - else: - self.move_current_stdouterr_line_up() - self.display_lines.extend(sum((paint.display_linize(line, self.width, - blank_line=True) - for line in lines[:-1]), [])) - def send_to_stdin(self, line): if line.endswith('\n'): self.display_lines.extend( @@ -1653,7 +1622,7 @@ def reevaluate(self, insert_into_history=False): if not self.weak_rewind: self.interp = self.interp.__class__() - self.interp.write = self.send_to_stderr + self.interp.write = self.send_to_stdouterr self.coderunner.interp = self.interp self.initialize_interp() diff --git a/bpython/test/test_curtsies_repl.py b/bpython/test/test_curtsies_repl.py index e91fff022..330ed02d2 100644 --- a/bpython/test/test_curtsies_repl.py +++ b/bpython/test/test_curtsies_repl.py @@ -264,6 +264,34 @@ def test_interactive(self): self.assertEqual(out.getvalue(), '0.5\n0.5\n') +class TestStdOutErr(TestCase): + def setUp(self): + self.repl = create_repl() + + def test_newline(self): + self.repl.send_to_stdouterr('\n\n') + self.assertEqual(self.repl.display_lines[-2], '') + self.assertEqual(self.repl.display_lines[-1], '') + self.assertEqual(self.repl.current_stdouterr_line, '') + + def test_leading_newline(self): + self.repl.send_to_stdouterr('\nfoo\n') + self.assertEqual(self.repl.display_lines[-2], '') + self.assertEqual(self.repl.display_lines[-1], 'foo') + self.assertEqual(self.repl.current_stdouterr_line, '') + + def test_no_trailing_newline(self): + self.repl.send_to_stdouterr('foo') + self.assertEqual(self.repl.current_stdouterr_line, 'foo') + + def test_print_without_newline_then_print_with_leading_newline(self): + self.repl.send_to_stdouterr('foo') + self.repl.send_to_stdouterr('\nbar\n') + self.assertEqual(self.repl.display_lines[-2], 'foo') + self.assertEqual(self.repl.display_lines[-1], 'bar') + self.assertEqual(self.repl.current_stdouterr_line, '') + + class TestPredictedIndent(TestCase): def setUp(self): self.repl = create_repl()