Skip to content

Commit f407db9

Browse files
committed
Simplify the handling of line-endings.
This removes a bunch of special-case addition of newlines and attempts to preserve exactly the number provided by the user when inserting or setting. It also fixes a bug where inserting a line after a 'def' could produce additional newlines after the 'def' block. Note that this does change the expected results of the setter tests.
1 parent fb27ea7 commit f407db9

File tree

4 files changed

+112
-56
lines changed

4 files changed

+112
-56
lines changed

redbaron/base_nodes.py

Lines changed: 8 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,10 +1114,13 @@ def parse_code_block(self, string, parent, on_attribute):
11141114

11151115
# putting this in the string template will fail, need at least some indent
11161116
if indentation == 0:
1117-
clean_string = " " + "\n ".join(clean_string.split("\n"))
1118-
clean_string = clean_string.rstrip()
1117+
if clean_string == '':
1118+
clean_string = ' '
1119+
else:
1120+
clean_string = "\n".join([" " + x if x else '' for x in clean_string.split("\n")])
1121+
# clean_string = clean_string.rstrip()
11191122

1120-
fst = baron.parse("def a():\n%s\n" % clean_string)[0]["value"]
1123+
fst = baron.parse("def a():\n%s" % clean_string)[0]["value"]
11211124

11221125
result = NodeList.from_fst(fst, parent=parent, on_attribute=on_attribute)
11231126

@@ -1128,28 +1131,7 @@ def parse_code_block(self, string, parent, on_attribute):
11281131
elif indentation < target_indentation:
11291132
result.increase_indentation(target_indentation - indentation)
11301133

1131-
endl_base_node = Node.from_fst({'formatting': [], 'indent': '', 'type': 'endl', 'value': '\n'},
1132-
on_attribute=on_attribute, parent=parent)
1133-
1134-
if (self.on_attribute == "root" and self.next) or (not self.next and self.parent and self.parent.next):
1135-
# I need to finish with 3 endl nodes
1136-
if not all(map(lambda x: x.type == "endl", result[-1:])):
1137-
result.append(endl_base_node.copy())
1138-
elif not all(map(lambda x: x.type == "endl", result[-2:])):
1139-
result.append(endl_base_node.copy())
1140-
result.append(endl_base_node.copy())
1141-
elif not all(map(lambda x: x.type == "endl", result[-3:])):
1142-
result.append(endl_base_node.copy())
1143-
result.append(endl_base_node.copy())
1144-
result.append(endl_base_node.copy())
1145-
elif self.next:
1146-
# I need to finish with 2 endl nodes
1147-
if not all(map(lambda x: x.type == "endl", result[-2:])):
1148-
result.append(endl_base_node.copy())
1149-
elif not all(map(lambda x: x.type == "endl", result[-3:])):
1150-
result.append(endl_base_node.copy())
1151-
result.append(endl_base_node.copy())
1152-
1134+
if self.next:
11531135
result[-1].indent = self.indentation
11541136

11551137
return result
@@ -1721,8 +1703,7 @@ def modify_last_indentation(node, indentation):
17211703
log("[%s] %s", position, i)
17221704

17231705
if might_need_separator and i[0].type != "endl" and (
1724-
not previous or previous.type != "endl") and not isinstance(previous, (
1725-
CodeBlockNode, redbaron.nodes.IfelseblockNode)):
1706+
not previous or previous.type != "endl") and not isinstance(previous, CodeBlockNode):
17261707
log(">> Previous line has content and current needs to be indented, append separator to indent it")
17271708
expected_list.append(generate_separator())
17281709
log("-- current result: %s", ["".join(map(lambda x: x.dumps(), expected_list))])

redbaron/nodes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ def _string_to_node(self, string, parent, on_attribute):
708708
raise Exception("Unhandled case")
709709

710710

711-
class IfelseblockNode(Node):
711+
class IfelseblockNode(CodeBlockNode):
712712
def _string_to_node_list(self, string, parent, on_attribute):
713713
if on_attribute != "value":
714714
return super(IfelseblockNode, self)._string_to_node_list(string, parent=parent, on_attribute=on_attribute)

tests/test_insert.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,23 @@ def a(self, a):
318318
""")
319319

320320

321+
def test_insert_line_in_def_with_trailing_if():
322+
red = RedBaron("""\
323+
def a(self, a):
324+
if a == 42:
325+
return True
326+
""")
327+
328+
red.def_.insert(0, "a = 1")
329+
330+
assert_with_indent(red, """\
331+
def a(self, a):
332+
a = 1
333+
if a == 42:
334+
return True
335+
""")
336+
337+
321338
def test_insert_nested_line_in_def_with_if():
322339
red = RedBaron("""\
323340
def a(self, a):

tests/test_setter.py

Lines changed: 86 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -225,72 +225,130 @@ def d():
225225

226226
def test_set_attr_def_advanced_dont_break_next_block_indent():
227227
red = RedBaron(code_for_block_setattr)
228-
red.find("def", name="c").value = "return 42"
229-
assert len(red.find("def", name="c")("endl")) == 4
230-
assert red.find("def", name="c").value.node_list[-1].indent == ""
228+
c = red.find("def", name="c")
229+
c.value = "return 42"
230+
assert c.dumps() == """\
231+
def c():
232+
return 42
233+
"""
234+
assert len(c("endl")) == 2
235+
assert c.value.node_list[-1].indent == ""
231236

232237

233238
def test_set_attr_def_advanced_dont_break_next_block_indent_one_endl():
234239
red = RedBaron(code_for_block_setattr)
235-
red.find("def", name="c").value = "return 42\n"
236-
assert len(red.find("def", name="c")("endl")) == 4
237-
assert red.find("def", name="c").value.node_list[-1].indent == ""
240+
c = red.find("def", name="c")
241+
c.value = "return 42\n"
242+
assert c.dumps() == """\
243+
def c():
244+
return 42
245+
"""
246+
assert len(c("endl")) == 2
247+
assert c.value.node_list[-1].indent == ""
238248

239249

240250
def test_set_attr_def_advanced_dont_break_next_block_indent_two_endl():
241251
red = RedBaron(code_for_block_setattr)
252+
c = red.find("def", name="c")
253+
assert len(c("endl")) == 6
242254
red.find("def", name="c").value = "return 42\n\n"
243-
assert len(red.find("def", name="c")("endl")) == 4
255+
assert c.dumps() == """\
256+
def c():
257+
return 42
258+
259+
"""
260+
assert len(red.find("def", name="c")("endl")) == 3
244261
assert red.find("def", name="c").value.node_list[-1].indent == ""
245262

246263

247264
def test_set_attr_def_advanced_in_class_dont_break_next_block_indent():
248265
red = RedBaron(code_for_block_setattr)
249-
red.find("def", name="a").value = "return 42"
250-
assert len(red.find("def", name="a")("endl")) == 3
251-
assert red.find("def", name="a").value.node_list[-1].indent == " "
266+
a = red.find("def", name="a")
267+
assert a.dumps() == """\
268+
def a():
269+
pass
270+
271+
"""
272+
a.value = "return 42"
273+
assert a.dumps() == """\
274+
def a():
275+
return 42
276+
"""
277+
assert len(a("endl")) == 2
278+
assert a.value.node_list[-1].indent == " "
252279

253280

254281
def test_set_attr_def_advanced_in_class_dont_break_next_block_indent_one_endl():
255282
red = RedBaron(code_for_block_setattr)
256-
red.find("def", name="a").value = "return 42\n"
257-
assert len(red.find("def", name="a")("endl")) == 3
258-
assert red.find("def", name="a").value.node_list[-1].indent == " "
283+
a = red.find("def", name="a")
284+
a.value = "return 42\n"
285+
assert a.dumps() == """\
286+
def a():
287+
return 42
288+
"""
289+
assert len(a("endl")) == 2
290+
assert a.value.node_list[-1].indent == " "
259291

260292

261293
def test_set_attr_def_advanced_in_class_at_the_end_dont_break_next_block_indent():
262294
red = RedBaron(code_for_block_setattr)
263-
red.find("def", name="b").value = "return 42"
264-
assert len(red.find("def", name="b")("endl")) == 4
265-
assert red.find("def", name="b").value.node_list[-1].indent == ""
295+
b = red.find("def", name="b")
296+
b.value = "return 42"
297+
assert b.dumps() == """\
298+
def b():
299+
return 42
300+
"""
301+
assert len(b("endl")) == 2
302+
assert b.value.node_list[-1].indent == ""
266303

267304

268305
def test_set_attr_def_advanced_in_class_at_the_end_dont_break_next_block_indent_one_endl():
269306
red = RedBaron(code_for_block_setattr)
270-
red.find("def", name="b").value = "return 42\n"
271-
assert len(red.find("def", name="b")("endl")) == 4
272-
assert red.find("def", name="b").value.node_list[-1].indent == ""
307+
b = red.find("def", name="b")
308+
b.value = "return 42\n"
309+
assert b.dumps() == """\
310+
def b():
311+
return 42
312+
"""
313+
assert len(b("endl")) == 2
314+
assert b.value.node_list[-1].indent == ""
273315

274316

275317
def test_set_attr_def_advanced_in_class_at_the_end_dont_break_next_block_indent_two_endl():
276318
red = RedBaron(code_for_block_setattr)
277-
red.find("def", name="b").value = "return 42\n\n"
278-
assert len(red.find("def", name="b")("endl")) == 4
279-
assert red.find("def", name="b").value.node_list[-1].indent == ""
319+
b = red.find("def", name="b")
320+
b.value = "return 42\n\n"
321+
assert b.dumps() == """\
322+
def b():
323+
return 42
324+
325+
"""
326+
assert len(b("endl")) == 3
327+
assert b.value.node_list[-1].indent == ""
280328

281329

282330
def test_set_attr_def_advanced_inline_dont_break_next_block_indent():
283331
red = RedBaron(code_for_block_setattr)
284-
red.find("def", name="zomg").value = "return 42"
285-
assert len(red.find("def", name="zomg")("endl")) == 3
286-
assert red.find("def", name="zomg").value.node_list[-1].indent == " "
332+
zomg = red.find("def", name="zomg")
333+
zomg.value = "return 42"
334+
assert zomg.dumps() == """\
335+
def zomg():
336+
return 42
337+
"""
338+
assert len(zomg("endl")) == 2
339+
assert zomg.value.node_list[-1].indent == " "
287340

288341

289342
def test_set_attr_def_advanced_inline_dont_break_next_block_indent_one_endl():
290343
red = RedBaron(code_for_block_setattr)
291-
red.find("def", name="zomg").value = "return 42\n"
292-
assert len(red.find("def", name="zomg")("endl")) == 3
293-
assert red.find("def", name="zomg").value.node_list[-1].indent == " "
344+
zomg = red.find("def", name="zomg")
345+
zomg.value = "return 42\n"
346+
assert zomg.dumps() == """\
347+
def zomg():
348+
return 42
349+
"""
350+
assert len(zomg("endl")) == 2
351+
assert zomg.value.node_list[-1].indent == " "
294352

295353

296354
def test_set_decorator_def():

0 commit comments

Comments
 (0)