Skip to content
Open
3 changes: 2 additions & 1 deletion Lib/pydoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2059,9 +2059,10 @@ def interact(self):
while True:
try:
request = self.getline('help> ')
if not request: break
except (KeyboardInterrupt, EOFError):
break
if not request or request.isspace():
continue # back to the prompt
request = request.strip()

Comment on lines +2064 to 2067
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think the following is cleaner than having the extra .isspace call. I don't think we're actually saving a string allocation that way, either, since in the case where we would be continuing, .strip() would take us down to the empty string, which is interned.

But this is a judgement call, and it's ultimately up to @AA-Turner.

Suggested change
if not request or request.isspace():
continue # back to the prompt
request = request.strip()
request = request.strip()
if not request:
continue # back to the prompt

# Make sure significant trailing quoting marks of literals don't
Expand Down
37 changes: 37 additions & 0 deletions Lib/test/test_pydoc/test_pydoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2161,10 +2161,47 @@ def test_url_requests(self):


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):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Adjusted the built-in :func:`help` function so that empty inputs are ignored in
interactive mode.
Loading