Skip to content

Commit 45e0b82

Browse files
gh-152942: Split the source into lines at newlines only
str.splitlines() also breaks at form feed and similar characters that the parser and the Text widget keep within the line, which misaligned the column mapping for the following lines. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent eacd68e commit 45e0b82

2 files changed

Lines changed: 11 additions & 1 deletion

File tree

Lib/idlelib/astbrowser.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,8 @@ def populate(self, event=None):
149149
first, scope = "1.0", "text"
150150
self.base = tuple(int(i) for i in first.split("."))
151151
source = text.get(first, last)
152-
self.source_lines = source.splitlines()
152+
# Split at "\n" only; str.splitlines() would also break at "\f" etc.
153+
self.source_lines = source.split("\n")
153154
error = count = None
154155
try:
155156
tree = ast.parse(source)

Lib/idlelib/idle_test/test_astbrowser.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ def test_node_range(self):
9898
item = self.find("Name(id='x'")
9999
self.assertEqual(self.window.ranges[item], ("4.11", "4.12"))
100100

101+
def test_form_feed_does_not_shift_lines(self):
102+
# gh-152942: a form feed breaks str.splitlines() but not the parser,
103+
# so it must not shift source_lines and misplace later nodes.
104+
self.text.delete("1.0", "end")
105+
self.text.insert("1.0", "x = 1\f\ny = 22\n") # form feed ends line 1.
106+
self.window.populate()
107+
item = self.find("Constant(value=22)")
108+
self.assertEqual(self.window.ranges[item], ("2.4", "2.6"))
109+
101110
def test_selection_scope(self):
102111
self.text.tag_add("sel", "4.11", "4.16") # 'x + 1' on line 4.
103112
self.window.populate()

0 commit comments

Comments
 (0)