Kaydet (Commit) c72349f3 authored tarafından Felix Yan's avatar Felix Yan Kaydeden (comit) Berker Peksag

Fix string parsing with newline (#123)

When looping over a joined str, if a node is ast.Str and the value is
just a newline "\n", the write() function adds an additional indentation
after it, which fails to represent the original string. By calling
self.result.append() here directly the issue is resolved.

The added test could show the issue. With code_gen unmodifed, it fails
with the following error:

```
AssertionError: "if 1:\n    x = f'{host}\\n\\t{port}\\n    '" != "if
1:\n    x = f'{host}\\n\\t{port}\\n'"
  if 1:
      -     x = f'{host}\n\t{port}\n    '?
      ----
      +     x = f'{host}\n\t{port}\n'
```

Which is exactly the problem.

This fixes parsing issues with many of Python 3.7's stdlib. Namely the
following ones:

/usr/lib/python3.7/warnings.py
/usr/lib/python3.7/netrc.py
/usr/lib/python3.7/test/test_embed.py
/usr/lib/python3.7/test/support/testresult.py
/usr/lib/python3.7/idlelib/grep.py

Fixes #119
üst a3c9e284
...@@ -14,3 +14,4 @@ And with some modifications based on Armin's code: ...@@ -14,3 +14,4 @@ And with some modifications based on Armin's code:
* Lenny Truong <leonardtruong@protonmail.com> * Lenny Truong <leonardtruong@protonmail.com>
* Radomír Bosák <radomir.bosak@gmail.com> * Radomír Bosák <radomir.bosak@gmail.com>
* Kodi Arfer <git@arfer.net> * Kodi Arfer <git@arfer.net>
* Felix Yan <felixonmars@archlinux.org>
...@@ -168,8 +168,6 @@ class SourceGenerator(ExplicitNodeVisitor): ...@@ -168,8 +168,6 @@ class SourceGenerator(ExplicitNodeVisitor):
visit(item) visit(item)
elif callable(item): elif callable(item):
item() item()
elif item == '\n':
newline()
else: else:
if self.new_lines: if self.new_lines:
append('\n' * self.new_lines) append('\n' * self.new_lines)
...@@ -220,7 +218,7 @@ class SourceGenerator(ExplicitNodeVisitor): ...@@ -220,7 +218,7 @@ class SourceGenerator(ExplicitNodeVisitor):
def else_body(self, elsewhat): def else_body(self, elsewhat):
if elsewhat: if elsewhat:
self.write('\n', 'else:') self.write(self.newline, 'else:')
self.body(elsewhat) self.body(elsewhat)
def body_or_else(self, node): def body_or_else(self, node):
...@@ -359,7 +357,7 @@ class SourceGenerator(ExplicitNodeVisitor): ...@@ -359,7 +357,7 @@ class SourceGenerator(ExplicitNodeVisitor):
if len(else_) == 1 and isinstance(else_[0], ast.If): if len(else_) == 1 and isinstance(else_[0], ast.If):
node = else_[0] node = else_[0]
set_precedence(node, node.test) set_precedence(node, node.test)
self.write('\n', 'elif ', node.test, ':') self.write(self.newline, 'elif ', node.test, ':')
self.body(node.body) self.body(node.body)
else: else:
self.else_body(else_) self.else_body(else_)
......
...@@ -71,7 +71,7 @@ def wrap_line(line, maxline=79, result=[], count=count): ...@@ -71,7 +71,7 @@ def wrap_line(line, maxline=79, result=[], count=count):
indentation = line[0] indentation = line[0]
lenfirst = len(indentation) lenfirst = len(indentation)
indent = lenfirst - len(indentation.strip()) indent = lenfirst - len(indentation.lstrip())
assert indent in (0, lenfirst) assert indent in (0, lenfirst)
indentation = line.pop(0) if indent else '' indentation = line.pop(0) if indent else ''
......
...@@ -13,9 +13,14 @@ New features ...@@ -13,9 +13,14 @@ New features
Bug fixes Bug fixes
~~~~~~~~~ ~~~~~~~~~
* Fix string parsing when there is a newline inside an f-string. (Reported by
Adam Cécile in `Issue 119`_ and fixed by Felix Yan in `PR 123`_.)
* Fixed code generation with escaped braces in f-strings. * Fixed code generation with escaped braces in f-strings.
(Reported by Felix Yan in `Issue 124`_ and fixed by Kodi Arfer in `PR 125`_.) (Reported by Felix Yan in `Issue 124`_ and fixed by Kodi Arfer in `PR 125`_.)
.. _`Issue 119`: https://github.com/berkerpeksag/astor/issues/119
.. _`PR 123`: https://github.com/berkerpeksag/astor/pull/123
.. _`Issue 124`: https://github.com/berkerpeksag/astor/issues/124 .. _`Issue 124`: https://github.com/berkerpeksag/astor/issues/124
.. _`PR 125`: https://github.com/berkerpeksag/astor/pull/125 .. _`PR 125`: https://github.com/berkerpeksag/astor/pull/125
......
...@@ -516,6 +516,11 @@ class CodegenTestCase(unittest.TestCase, Comparisons): ...@@ -516,6 +516,11 @@ class CodegenTestCase(unittest.TestCase, Comparisons):
x = f"""{host}\n\t{port}\n""" x = f"""{host}\n\t{port}\n"""
''' '''
self.assertSrcRoundtripsGtVer(source, (3, 6)) self.assertSrcRoundtripsGtVer(source, (3, 6))
source = '''
if 1:
x = f'{host}\\n\\t{port}\\n'
'''
self.assertSrcRoundtripsGtVer(source, (3, 6))
def test_fstring_escaped_braces(self): def test_fstring_escaped_braces(self):
source = ''' source = '''
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment