]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-138568: Make `help` mode in PyREPL not exit on empty line input (#143512)
authorŁukasz Langa <lukasz@langa.pl>
Wed, 7 Jan 2026 15:30:58 +0000 (16:30 +0100)
committerGitHub <noreply@github.com>
Wed, 7 Jan 2026 15:30:58 +0000 (16:30 +0100)
Signed-off-by: yihong0618 <zouzou0208@gmail.com>
Co-authored-by: yihong0618 <zouzou0208@gmail.com>
Lib/pydoc.py
Lib/test/test_pydoc/test_pydoc.py
Misc/NEWS.d/next/Core_and_Builtins/2025-09-06-08-29-08.gh-issue-138568.iZlalC.rst [new file with mode: 0644]

index f3b44c9b3a620ac3d76ce3c1481a87b39be9f42f..69c83e085113c901b33f34d6a5e8ffaca28460b6 100644 (file)
@@ -2004,10 +2004,11 @@ has the same effect as typing a particular string at the help> prompt.
         while True:
             try:
                 request = self.getline('help> ')
-                if not request: break
             except (KeyboardInterrupt, EOFError):
                 break
             request = request.strip()
+            if not request:
+                continue  # back to the prompt
 
             # Make sure significant trailing quoting marks of literals don't
             # get deleted while cleaning input
index 3e12a2a96fa38155ca5386d5f7aa2eff8021c30e..0e113006cfa1564797c65372895fa6af66098159 100644 (file)
@@ -2147,10 +2147,47 @@ class PydocUrlHandlerTest(PydocBaseTest):
 
 
 class TestHelper(unittest.TestCase):
+    def mock_interactive_session(self, inputs):
+        """
+        Given a list of inputs, run an interactive help session.  Returns a string
+        of what would be shown on screen.
+        """
+        input_iter = iter(inputs)
+
+        def mock_getline(prompt):
+            output.write(prompt)
+            next_input = next(input_iter)
+            output.write(next_input + os.linesep)
+            return next_input
+
+        with captured_stdout() as output:
+            helper = pydoc.Helper(output=output)
+            with unittest.mock.patch.object(helper, "getline", mock_getline):
+                helper.interact()
+
+        # handle different line endings across platforms consistently
+        return output.getvalue().strip().splitlines(keepends=False)
+
     def test_keywords(self):
         self.assertEqual(sorted(pydoc.Helper.keywords),
                          sorted(keyword.kwlist))
 
+    def test_interact_empty_line_continues(self):
+        # gh-138568: test pressing Enter without input should continue in help session
+        self.assertEqual(
+            self.mock_interactive_session(["", "    ", "quit"]),
+            ["help> ", "help>     ", "help> quit"],
+        )
+
+    def test_interact_quit_commands_exit(self):
+        quit_commands = ["quit", "q", "exit"]
+        for quit_cmd in quit_commands:
+            with self.subTest(quit_command=quit_cmd):
+                self.assertEqual(
+                    self.mock_interactive_session([quit_cmd]),
+                    [f"help> {quit_cmd}"],
+                )
+
 
 class PydocWithMetaClasses(unittest.TestCase):
     def tearDown(self):
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-09-06-08-29-08.gh-issue-138568.iZlalC.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-09-06-08-29-08.gh-issue-138568.iZlalC.rst
new file mode 100644 (file)
index 0000000..8a91631
--- /dev/null
@@ -0,0 +1,2 @@
+Adjusted the built-in :func:`help` function so that empty inputs are ignored in
+interactive mode.