8000 Refactor `_should_auto_indent()` · python/cpython@6e80edb · GitHub
[go: up one dir, main page]

Skip to content

Commit 6e80edb

Browse files
committed
Refactor _should_auto_indent()
1 parent 98e2c3a commit 6e80edb

File tree

1 file changed

+31
-13
lines changed

1 file changed

+31
-13
lines changed

Lib/_pyrepl/readline.py

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -254,19 +254,37 @@ def _should_auto_indent(buffer: list[str], pos: int) -> bool:
254254
# check if last character before "pos" is a colon, ignoring
255255
# whitespaces and comments.
256256
last_char = None
257-
while pos > 0:
258-
pos -= 1
259-
if last_char is None:
260-
if buffer[pos] not in " \t\n#": # ignore whitespaces and comments
261-
last_char = buffer[pos]
262-
else:
263-
# even if we found a non-whitespace character before
264-
# original pos, we keep going back until newline is reached
265-
# to make sure we ignore comments
266-
if buffer[pos] == "\n":
267-
break
268-
if buffer[pos] == "#":
269-
last_char = None
257+
# A stack to keep track of string delimiters (quotes). Push a quote when
258+
# entering a string, and pop it when the string ends. When the stack is
259+
# empty, we're not inside a string. If encounter a '#' while not inside a
260+
# string, it's a comment start; otherwise, it's just a '#' character within
261+
# a string.
262+
in_string: list[str] = []
263+
in_comment = False
264+
i = -1
265+
while i < pos - 1:
266+
i += 1
267+
char = buffer[i]
268+
269+
# update last_char
270+
if char == "#":
271+
if in_string:
272+
last_char = char # '#' inside a string is just a character
273+
else:
274+
in_comment = True
275+
elif char == "\n":
276+
# newline ends a comment
277+
in_comment = False
278+
elif char not in " \t" and not in_comment and not in_string:
279+
# update last_char with non-whitespace chars outside comments and strings
280+
last_char = char
281+
282+
# update stack
283+
if char in "\"'" and (i == 0 or buffer[i - 1] != "\\"):
284+
if in_string and in_string[-1] == char:
285+
in_string.pop()
286+
else:
287+
in_string.append(char)
270288
return last_char == ":"
271289

272290

0 commit comments

Comments
 (0)
0