From 43e6a4b915bae27ce577df50c5d08d2c9693255a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Thu, 23 May 2024 13:28:31 -0400 Subject: [PATCH] gh-119469: Fix _pyrepl reference leaks (#119470) --- Lib/test/test_pyrepl/test_interact.py | 6 +++- Lib/test/test_pyrepl/test_unix_console.py | 36 ++++++++++++++++------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Lib/test/test_pyrepl/test_interact.py b/Lib/test/test_pyrepl/test_interact.py index b3dc07c063f90eb..10e34045bcf92df 100644 --- a/Lib/test/test_pyrepl/test_interact.py +++ b/Lib/test/test_pyrepl/test_interact.py @@ -27,9 +27,11 @@ def bar(self): a """) console = InteractiveColoredConsole(namespace, filename="") + f = io.StringIO() with ( patch.object(InteractiveColoredConsole, "showsyntaxerror") as showsyntaxerror, patch.object(InteractiveColoredConsole, "runsource", wraps=console.runsource) as runsource, + contextlib.redirect_stdout(f), ): more = console.push(code, filename="", _symbol="single") # type: ignore[call-arg] self.assertFalse(more) @@ -71,7 +73,9 @@ def test_runsource_compiles_and_runs_code(self): def test_runsource_returns_false_for_successful_compilation(self): console = InteractiveColoredConsole() source = "print('Hello, world!')" - result = console.runsource(source) + f = io.StringIO() + with contextlib.redirect_stdout(f): + result = console.runsource(source) self.assertFalse(result) @force_not_colorized diff --git a/Lib/test/test_pyrepl/test_unix_console.py b/Lib/test/test_pyrepl/test_unix_console.py index cec3ae033325ac3..e1faa00caafc270 100644 --- a/Lib/test/test_pyrepl/test_unix_console.py +++ b/Lib/test/test_pyrepl/test_unix_console.py @@ -112,17 +112,18 @@ class TestConsole(TestCase): def test_simple_addition(self, _os_write): code = "12+34" events = code_to_events(code) - _, _ = handle_events_unix_console(events) + _, con = handle_events_unix_console(events) _os_write.assert_any_call(ANY, b"1") _os_write.assert_any_call(ANY, b"2") _os_write.assert_any_call(ANY, b"+") _os_write.assert_any_call(ANY, b"3") _os_write.assert_any_call(ANY, b"4") + con.restore() def test_wrap(self, _os_write): code = "12+34" events = code_to_events(code) - _, _ = handle_events_narrow_unix_console(events) + _, con = handle_events_narrow_unix_console(events) _os_write.assert_any_call(ANY, b"1") _os_write.assert_any_call(ANY, b"2") _os_write.assert_any_call(ANY, b"+") @@ -130,6 +131,8 @@ def test_wrap(self, _os_write): _os_write.assert_any_call(ANY, b"\\") _os_write.assert_any_call(ANY, b"\n") _os_write.assert_any_call(ANY, b"4") + con.restore() + def test_cursor_left(self, _os_write): code = "1" @@ -137,8 +140,9 @@ def test_cursor_left(self, _os_write): code_to_events(code), [Event(evt="key", data="left", raw=bytearray(b"\x1bOD"))], ) - _, _ = handle_events_unix_console(events) + _, con = handle_events_unix_console(events) _os_write.assert_any_call(ANY, TERM_CAPABILITIES["cub"] + b":1") + con.restore() def test_cursor_left_right(self, _os_write): code = "1" @@ -149,9 +153,10 @@ def test_cursor_left_right(self, _os_write): Event(evt="key", data="right", raw=bytearray(b"\x1bOC")), ], ) - _, _ = handle_events_unix_console(events) + _, con = handle_events_unix_console(events) _os_write.assert_any_call(ANY, TERM_CAPABILITIES["cub"] + b":1") _os_write.assert_any_call(ANY, TERM_CAPABILITIES["cuf"] + b":1") + con.restore() def test_cursor_up(self, _os_write): code = "1\n2+3" @@ -159,8 +164,9 @@ def test_cursor_up(self, _os_write): code_to_events(code), [Event(evt="key", data="up", raw=bytearray(b"\x1bOA"))], ) - _, _ = handle_events_unix_console(events) + _, con = handle_events_unix_console(events) _os_write.assert_any_call(ANY, TERM_CAPABILITIES["cuu"] + b":1") + con.restore() def test_cursor_up_down(self, _os_write): code = "1\n2+3" @@ -171,9 +177,10 @@ def test_cursor_up_down(self, _os_write): Event(evt="key", data="down", raw=bytearray(b"\x1bOB")), ], ) - _, _ = handle_events_unix_console(events) + _, con = handle_events_unix_console(events) _os_write.assert_any_call(ANY, TERM_CAPABILITIES["cuu"] + b":1") _os_write.assert_any_call(ANY, TERM_CAPABILITIES["cud"] + b":1") + con.restore() def test_cursor_back_write(self, _os_write): events = itertools.chain( @@ -181,10 +188,11 @@ def test_cursor_back_write(self, _os_write): [Event(evt="key", data="left", raw=bytearray(b"\x1bOD"))], code_to_events("2"), ) - _, _ = handle_events_unix_console(events) + _, con = handle_events_unix_console(events) _os_write.assert_any_call(ANY, b"1") _os_write.assert_any_call(ANY, TERM_CAPABILITIES["cub"] + b":1") _os_write.assert_any_call(ANY, b"2") + con.restore() def test_multiline_function_move_up_short_terminal(self, _os_write): # fmt: off @@ -201,8 +209,9 @@ def test_multiline_function_move_up_short_terminal(self, _os_write): Event(evt="scroll", data=None), ], ) - _, _ = handle_events_short_unix_console(events) + _, con = handle_events_short_unix_console(events) _os_write.assert_any_call(ANY, TERM_CAPABILITIES["ri"] + b":") + con.restore() def test_multiline_function_move_up_down_short_terminal(self, _os_write): # fmt: off @@ -221,9 +230,10 @@ def test_multiline_function_move_up_down_short_terminal(self, _os_write): Event(evt="scroll", data=None), ], ) - _, _ = handle_events_short_unix_console(events) + _, con = handle_events_short_unix_console(events) _os_write.assert_any_call(ANY, TERM_CAPABILITIES["ri"] + b":") _os_write.assert_any_call(ANY, TERM_CAPABILITIES["ind"] + b":") + con.restore() def test_resize_bigger_on_multiline_function(self, _os_write): # fmt: off @@ -246,7 +256,7 @@ def same_console(events): console.get_event = MagicMock(side_effect=events) return console - _, _ = handle_all_events( + _, con = handle_all_events( [Event(evt="resize", data=None)], prepare_reader=same_reader, prepare_console=same_console, @@ -258,6 +268,8 @@ def same_console(events): call(ANY, b"def f():"), ] ) + console.restore() + con.restore() def test_resize_smaller_on_multiline_function(self, _os_write): # fmt: off @@ -280,7 +292,7 @@ def same_console(events): console.get_event = MagicMock(side_effect=events) return console - _, _ = handle_all_events( + _, con = handle_all_events( [Event(evt="resize", data=None)], prepare_reader=same_reader, prepare_console=same_console, @@ -292,3 +304,5 @@ def same_console(events): call(ANY, b" foo"), ] ) + console.restore() + con.restore()