From 8a0241f7dbf50f25a3b16c61c4958064b35beec9 Mon Sep 17 00:00:00 2001 From: Koudai Aono Date: Mon, 20 May 2024 12:02:06 -0400 Subject: [PATCH 1/8] gh-119205: Fix autocompletion bug in new repl --- Lib/_pyrepl/readline.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/_pyrepl/readline.py b/Lib/_pyrepl/readline.py index 0adecf235a4eb4..1379f8aad8caff 100644 --- a/Lib/_pyrepl/readline.py +++ b/Lib/_pyrepl/readline.py @@ -297,12 +297,15 @@ def multiline_input(self, more_lines: MoreLinesCallable, ps1: str, ps2: str) -> """ reader = self.get_reader() saved = reader.more_lines + original_stderr = sys.stderr + sys.stderr = None try: reader.more_lines = more_lines reader.ps1 = reader.ps2 = ps1 reader.ps3 = reader.ps4 = ps2 return reader.readline(), reader.was_paste_mode_activated finally: + sys.stderr = original_stderr reader.more_lines = saved reader.paste_mode = False reader.was_paste_mode_activated = False From 852cd531117064cbf963aa061d4a10f98e3e5fc9 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 16:16:20 +0000 Subject: [PATCH 2/8] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2024-05-20-16-16-19.gh-issue-119205.TW2D_b.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2024-05-20-16-16-19.gh-issue-119205.TW2D_b.rst diff --git a/Misc/NEWS.d/next/Library/2024-05-20-16-16-19.gh-issue-119205.TW2D_b.rst b/Misc/NEWS.d/next/Library/2024-05-20-16-16-19.gh-issue-119205.TW2D_b.rst new file mode 100644 index 00000000000000..1cacea31ba7cfb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-05-20-16-16-19.gh-issue-119205.TW2D_b.rst @@ -0,0 +1 @@ +Fix autocompletion bug in new repl From f9ee8097e930258bad90c6a21704bc2927af19d0 Mon Sep 17 00:00:00 2001 From: Koudai Aono Date: Mon, 20 May 2024 14:46:29 -0400 Subject: [PATCH 3/8] gh-119205: Add unittest --- Lib/test/test_pyrepl.py | 51 ++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/Lib/test/test_pyrepl.py b/Lib/test/test_pyrepl.py index c8990b699b214c..027ecc44ce6011 100644 --- a/Lib/test/test_pyrepl.py +++ b/Lib/test/test_pyrepl.py @@ -1,4 +1,6 @@ import itertools + +import io import os import rlcompleter import sys @@ -20,7 +22,7 @@ readline = import_module("readline") from _pyrepl.console import Console, Event -from _pyrepl.readline import ReadlineAlikeReader, ReadlineConfig +from _pyrepl.readline import ReadlineAlikeReader, ReadlineConfig, _ReadlineWrapper from _pyrepl.simple_interact import _strip_final_indent from _pyrepl.unix_eventqueue import EventQueue from _pyrepl.simple_interact import InteractiveColoredConsole @@ -276,7 +278,7 @@ def test_cursor_position_double_width_characters_move_up(self): # fmt: off code = ( - f"{for_loop}\n" + f"{for_loop}\n" " ' 可口可乐; 可口可樂'" ) # fmt: on @@ -299,7 +301,7 @@ def test_cursor_position_double_width_characters_move_up_down(self): # fmt: off code = ( - f"{for_loop}\n" + f"{for_loop}\n" " ' 可口可乐; 可口可樂'" ) # fmt: on @@ -346,8 +348,8 @@ def test_cursor_position_move_up_to_eol(self): code = ( f"{first_line}\n" f"{second_line}\n" - " h\n" - " hel" + " h\n" + " hel" ) # fmt: on @@ -379,7 +381,7 @@ def test_cursor_position_move_down_to_eol(self): "for _ in _:\n" " hello\n" " h\n" - f"{last_line}" + f"{last_line}" ) # fmt: on @@ -607,6 +609,27 @@ def test_global_namespace_completion(self): output = multiline_input(reader, namespace) self.assertEqual(output, "python") + @patch("_pyrepl.readline._ReadlineWrapper.get_reader") + def test_completion_with_warnings(self, mock_get_reader): + class Dummy: + @property + def test_func(self): + import sys + sys.stderr.write("warnings\n") + return None + + dummy = Dummy() + events = code_to_events("dummy.test_func.\t\n\n") + namespace = {"dummy": dummy} + reader = self.prepare_reader(events, namespace) + from _pyrepl.readline import multiline_input as readline_multiline_input + with patch("_pyrepl.readline._ReadlineWrapper.get_reader", lambda _: reader), \ + patch("sys.stderr", new_callable=io.StringIO) as f: + output = readline_multiline_input(more_lines, ">>>", "...") + + self.assertEqual(output[0], "dummy.test_func.") + self.assertEqual(f.getvalue(), "") + @patch("_pyrepl.curses.tigetstr", lambda x: b"") class TestUnivEventQueue(TestCase): @@ -883,24 +906,24 @@ def assert_screen_equals(self, reader, expected): def test_calc_screen_wrap_simple(self): events = code_to_events(10 * "a") reader, _ = handle_events_narrow_console(events) - self.assert_screen_equals(reader, f"{9*"a"}\\\na") + self.assert_screen_equals(reader, f"{9 * "a"}\\\na") def test_calc_screen_wrap_wide_characters(self): events = code_to_events(8 * "a" + "樂") reader, _ = handle_events_narrow_console(events) - self.assert_screen_equals(reader, f"{8*"a"}\\\n樂") + self.assert_screen_equals(reader, f"{8 * "a"}\\\n樂") def test_calc_screen_wrap_three_lines(self): events = code_to_events(20 * "a") reader, _ = handle_events_narrow_console(events) - self.assert_screen_equals(reader, f"{9*"a"}\\\n{9*"a"}\\\naa") + self.assert_screen_equals(reader, f"{9 * "a"}\\\n{9 * "a"}\\\naa") def test_calc_screen_wrap_three_lines_mixed_character(self): # fmt: off code = ( "def f():\n" - f" {8*"a"}\n" - f" {5*"樂"}" + f" {8 * "a"}\n" + f" {5 * "樂"}" ) # fmt: on @@ -910,9 +933,9 @@ def test_calc_screen_wrap_three_lines_mixed_character(self): # fmt: off self.assert_screen_equals(reader, ( "def f():\n" - f" {7*"a"}\\\n" + f" {7 * "a"}\\\n" "a\n" - f" {3*"樂"}\\\n" + f" {3 * "樂"}\\\n" "樂樂" )) # fmt: on @@ -945,7 +968,7 @@ def test_calc_screen_backspace_in_second_line_after_wrap(self): ], ) reader, _ = handle_events_narrow_console(events) - self.assert_screen_equals(reader, f"{9*"a"}\\\na") + self.assert_screen_equals(reader, f"{9 * "a"}\\\na") def test_setpos_for_xy_simple(self): events = code_to_events("11+11") From 241e6345684caa05a3136d6160f29e67d0466b32 Mon Sep 17 00:00:00 2001 From: Koudai Aono Date: Mon, 20 May 2024 16:50:23 -0400 Subject: [PATCH 4/8] gh-119205: revert unnecessary changes --- Lib/test/test_pyrepl.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/Lib/test/test_pyrepl.py b/Lib/test/test_pyrepl.py index faf1de290498ad..963aed8defff89 100644 --- a/Lib/test/test_pyrepl.py +++ b/Lib/test/test_pyrepl.py @@ -22,7 +22,7 @@ readline = import_module("readline") from _pyrepl.console import Console, Event -from _pyrepl.readline import ReadlineAlikeReader, ReadlineConfig, _ReadlineWrapper +from _pyrepl.readline import ReadlineAlikeReader, ReadlineConfig from _pyrepl.simple_interact import _strip_final_indent from _pyrepl.unix_eventqueue import EventQueue from _pyrepl.input import KeymapTranslator @@ -279,7 +279,7 @@ def test_cursor_position_double_width_characters_move_up(self): # fmt: off code = ( - f"{for_loop}\n" + f"{for_loop}\n" " ' 可口可乐; 可口可樂'" ) # fmt: on @@ -302,7 +302,7 @@ def test_cursor_position_double_width_characters_move_up_down(self): # fmt: off code = ( - f"{for_loop}\n" + f"{for_loop}\n" " ' 可口可乐; 可口可樂'" ) # fmt: on @@ -349,8 +349,8 @@ def test_cursor_position_move_up_to_eol(self): code = ( f"{first_line}\n" f"{second_line}\n" - " h\n" - " hel" + " h\n" + " hel" ) # fmt: on @@ -382,7 +382,7 @@ def test_cursor_position_move_down_to_eol(self): "for _ in _:\n" " hello\n" " h\n" - f"{last_line}" + f"{last_line}" ) # fmt: on @@ -655,6 +655,7 @@ def test_func(self): self.assertEqual(output[0], "dummy.test_func.") self.assertEqual(f.getvalue(), "") + @patch("_pyrepl.curses.tigetstr", lambda x: b"") class TestUnivEventQueue(TestCase): def setUp(self): @@ -930,24 +931,24 @@ def assert_screen_equals(self, reader, expected): def test_calc_screen_wrap_simple(self): events = code_to_events(10 * "a") reader, _ = handle_events_narrow_console(events) - self.assert_screen_equals(reader, f"{9 * "a"}\\\na") + self.assert_screen_equals(reader, f"{9*"a"}\\\na") def test_calc_screen_wrap_wide_characters(self): events = code_to_events(8 * "a" + "樂") reader, _ = handle_events_narrow_console(events) - self.assert_screen_equals(reader, f"{8 * "a"}\\\n樂") + self.assert_screen_equals(reader, f"{8*"a"}\\\n樂") def test_calc_screen_wrap_three_lines(self): events = code_to_events(20 * "a") reader, _ = handle_events_narrow_console(events) - self.assert_screen_equals(reader, f"{9 * "a"}\\\n{9 * "a"}\\\naa") + self.assert_screen_equals(reader, f"{9*"a"}\\\n{9*"a"}\\\naa") def test_calc_screen_wrap_three_lines_mixed_character(self): # fmt: off code = ( "def f():\n" - f" {8 * "a"}\n" - f" {5 * "樂"}" + f" {8*"a"}\n" + f" {5*"樂"}" ) # fmt: on @@ -957,9 +958,9 @@ def test_calc_screen_wrap_three_lines_mixed_character(self): # fmt: off self.assert_screen_equals(reader, ( "def f():\n" - f" {7 * "a"}\\\n" + f" {7*"a"}\\\n" "a\n" - f" {3 * "樂"}\\\n" + f" {3*"樂"}\\\n" "樂樂" )) # fmt: on @@ -992,7 +993,7 @@ def test_calc_screen_backspace_in_second_line_after_wrap(self): ], ) reader, _ = handle_events_narrow_console(events) - self.assert_screen_equals(reader, f"{9 * "a"}\\\na") + self.assert_screen_equals(reader, f"{9*"a"}\\\na") def test_setpos_for_xy_simple(self): events = code_to_events("11+11") From e5f1575e096046ab734ccb9f6d13478fed61f61e Mon Sep 17 00:00:00 2001 From: Koudai Aono Date: Mon, 20 May 2024 16:51:57 -0400 Subject: [PATCH 5/8] gh-119205: revert unnecessary changes --- Lib/test/test_pyrepl.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/Lib/test/test_pyrepl.py b/Lib/test/test_pyrepl.py index 963aed8defff89..2681b3308c1386 100644 --- a/Lib/test/test_pyrepl.py +++ b/Lib/test/test_pyrepl.py @@ -1,9 +1,7 @@ import itertools - import io import os import rlcompleter -import sys import tempfile import unittest from code import InteractiveConsole From b2f1b028f3c151a50adea83c4d19ed4ef1905c59 Mon Sep 17 00:00:00 2001 From: Koudai Aono Date: Mon, 20 May 2024 16:58:56 -0400 Subject: [PATCH 6/8] gh-119205: Improve unittest --- Lib/test/test_pyrepl.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_pyrepl.py b/Lib/test/test_pyrepl.py index 2681b3308c1386..848d468ff06162 100644 --- a/Lib/test/test_pyrepl.py +++ b/Lib/test/test_pyrepl.py @@ -20,7 +20,7 @@ readline = import_module("readline") from _pyrepl.console import Console, Event -from _pyrepl.readline import ReadlineAlikeReader, ReadlineConfig +from _pyrepl.readline import ReadlineAlikeReader, ReadlineConfig, multiline_input as readline_multiline_input from _pyrepl.simple_interact import _strip_final_indent from _pyrepl.unix_eventqueue import EventQueue from _pyrepl.input import KeymapTranslator @@ -633,7 +633,8 @@ def test_updown_arrow_with_completion_menu(self): self.assertEqual(output, "os.") @patch("_pyrepl.readline._ReadlineWrapper.get_reader") - def test_completion_with_warnings(self, mock_get_reader): + @patch("sys.stderr", new_callable=io.StringIO) + def test_completion_with_warnings(self, mock_stderr, mock_get_reader): class Dummy: @property def test_func(self): @@ -645,13 +646,10 @@ def test_func(self): events = code_to_events("dummy.test_func.\t\n\n") namespace = {"dummy": dummy} reader = self.prepare_reader(events, namespace) - from _pyrepl.readline import multiline_input as readline_multiline_input - with patch("_pyrepl.readline._ReadlineWrapper.get_reader", lambda _: reader), \ - patch("sys.stderr", new_callable=io.StringIO) as f: - output = readline_multiline_input(more_lines, ">>>", "...") - + mock_get_reader.return_value = reader + output = readline_multiline_input(more_lines, ">>>", "...") self.assertEqual(output[0], "dummy.test_func.") - self.assertEqual(f.getvalue(), "") + self.assertEqual(mock_stderr.getvalue(), "") @patch("_pyrepl.curses.tigetstr", lambda x: b"") From 6509c29e76d181d8d24a6784a4104a9a1d518cd4 Mon Sep 17 00:00:00 2001 From: Koudai Aono Date: Mon, 20 May 2024 17:29:45 -0400 Subject: [PATCH 7/8] gh-119205: Improve suppression warning --- Lib/_pyrepl/readline.py | 7 +++---- Lib/test/test_pyrepl.py | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Lib/_pyrepl/readline.py b/Lib/_pyrepl/readline.py index 1379f8aad8caff..ff755e5da4c520 100644 --- a/Lib/_pyrepl/readline.py +++ b/Lib/_pyrepl/readline.py @@ -28,6 +28,7 @@ from __future__ import annotations +import warnings from dataclasses import dataclass, field import os @@ -297,15 +298,13 @@ def multiline_input(self, more_lines: MoreLinesCallable, ps1: str, ps2: str) -> """ reader = self.get_reader() saved = reader.more_lines - original_stderr = sys.stderr - sys.stderr = None try: reader.more_lines = more_lines reader.ps1 = reader.ps2 = ps1 reader.ps3 = reader.ps4 = ps2 - return reader.readline(), reader.was_paste_mode_activated + with warnings.catch_warnings(action="ignore"): + return reader.readline(), reader.was_paste_mode_activated finally: - sys.stderr = original_stderr reader.more_lines = saved reader.paste_mode = False reader.was_paste_mode_activated = False diff --git a/Lib/test/test_pyrepl.py b/Lib/test/test_pyrepl.py index 848d468ff06162..c0ce1f33a631ca 100644 --- a/Lib/test/test_pyrepl.py +++ b/Lib/test/test_pyrepl.py @@ -638,8 +638,8 @@ def test_completion_with_warnings(self, mock_stderr, mock_get_reader): class Dummy: @property def test_func(self): - import sys - sys.stderr.write("warnings\n") + import warnings + warnings.warn("warnings\n") return None dummy = Dummy() @@ -648,7 +648,7 @@ def test_func(self): reader = self.prepare_reader(events, namespace) mock_get_reader.return_value = reader output = readline_multiline_input(more_lines, ">>>", "...") - self.assertEqual(output[0], "dummy.test_func.") + self.assertEqual(output[0], "dummy.test_func.__") self.assertEqual(mock_stderr.getvalue(), "") From fe484c77147a50d7614f275c7ff22524794601d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Tue, 21 May 2024 20:51:46 +0200 Subject: [PATCH 8/8] Remove news --- .../next/Library/2024-05-20-16-16-19.gh-issue-119205.TW2D_b.rst | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Misc/NEWS.d/next/Library/2024-05-20-16-16-19.gh-issue-119205.TW2D_b.rst diff --git a/Misc/NEWS.d/next/Library/2024-05-20-16-16-19.gh-issue-119205.TW2D_b.rst b/Misc/NEWS.d/next/Library/2024-05-20-16-16-19.gh-issue-119205.TW2D_b.rst deleted file mode 100644 index 1cacea31ba7cfb..00000000000000 --- a/Misc/NEWS.d/next/Library/2024-05-20-16-16-19.gh-issue-119205.TW2D_b.rst +++ /dev/null @@ -1 +0,0 @@ -Fix autocompletion bug in new repl