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
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):