Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion Lib/pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -762,9 +762,32 @@ def input_auto_indent():
# If the last line is empty, we don't need to indent
return

# A stack to keep track of string delimiters (quotes). Push a
# quote when entering a string, and pop it when the string
# ends. When the stack is empty, we're not inside a string. If
# encounter a '#' while not inside a string, it's a comment
# start; otherwise, it's just a '#' character within a string.
in_string: list[str] = []
last_char = None
last_line = last_line.rstrip('\r\n')
indent = len(last_line) - len(last_line.lstrip())
if last_line.endswith(":"):

for i, char in enumerate(last_line):
if char == "#":
if in_string:
last_char = char # hashtag in string, not comment
else:
break # ignore from comment start to line end
elif char not in " \t" and not in_string:
last_char = char

if char in "\"'" and (i == 0 or last_line[i - 1] != "\\"):
if in_string and in_string[-1] == char:
in_string.pop()
else:
in_string.append(char)

if last_char == ":":
indent += 4
readline.insert_text(' ' * indent)

Expand Down
16 changes: 16 additions & 0 deletions Lib/test/test_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -4870,6 +4870,22 @@ def test_multiline_auto_indent(self):

self.assertIn(b'42', output)

# can ignore comment to locate trailing colon
input = b"def f(s): # comment\n"
# can distinguish hashtag from comment
input += b"if s == '#':\n"
input += b"return 's == ' + '#'\n"
# can ignore all comments, not just from the rightmost '#' to end
input += b"\x08\x08\x08\x08else: ##\n"
input += b"return 's != ' + '#'\n"
input += b"\n"
input += b"f('#')\n"
input += b"c\n"

output = run_pty(script, input)

self.assertIn(b's == #', output)

def test_multiline_completion(self):
script = textwrap.dedent("""
import pdb; pdb.Pdb().set_trace()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix :mod:`pdb` multiline auto-indent not work with comments.
Loading