From cfec28d13ce191506fcdc49321cb30b6cecd342d Mon Sep 17 00:00:00 2001 From: Vladimir Iakovlev Date: Wed, 10 May 2017 16:09:08 +0200 Subject: [PATCH 1/3] #18: Fix formatted string with only one value, like `f{foo}` --- lib/astunparse/unparser.py | 13 +++++-------- tests/common.py | 3 +++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/astunparse/unparser.py b/lib/astunparse/unparser.py index 71a9456..c52ee87 100644 --- a/lib/astunparse/unparser.py +++ b/lib/astunparse/unparser.py @@ -446,7 +446,7 @@ def _Str(self, tree): def _FormattedValue(self, t): # FormattedValue(expr value, int? conversion, expr? format_spec) - self.write("{") + self.write("f'''{") self.dispatch(t.value) if t.conversion is not None and t.conversion != -1: self.write("!") @@ -458,17 +458,14 @@ def _FormattedValue(self, t): self.write(t.format_spec.s) else: self.dispatch(t.format_spec) - self.write("}") + self.write("}'''") def _JoinedStr(self, t): # JoinedStr(expr* values) - self.write("f'''") + self.write("(") for value in t.values: - if isinstance(value, ast.Str): - self.write(value.s) - else: - self.dispatch(value) - self.write("'''") + self.dispatch(value) + self.write(")") def _Name(self, t): self.write(t.id) diff --git a/tests/common.py b/tests/common.py index f930308..6b0ebe7 100644 --- a/tests/common.py +++ b/tests/common.py @@ -288,6 +288,9 @@ def test_raise_from(self): def test_bytes(self): self.check_roundtrip("b'123'") + def test_formatted_value(self): + self.check_roundtrip('f"{key}"') + @unittest.skipIf(sys.version_info < (3, 6), "Not supported < 3.6") def test_joined_str(self): self.check_roundtrip('f"{key}={value!s}"') From 8de282f7c0be8107aff37d77ce45541e3a23f4ce Mon Sep 17 00:00:00 2001 From: Vladimir Iakovlev Date: Wed, 10 May 2017 17:04:29 +0200 Subject: [PATCH 2/3] #18: Handle `FormattedValue` inside `JoinedStr` and outside differently --- lib/astunparse/unparser.py | 24 +++++++++++++++++------- tests/common.py | 6 +++++- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/lib/astunparse/unparser.py b/lib/astunparse/unparser.py index c52ee87..3db9b0b 100644 --- a/lib/astunparse/unparser.py +++ b/lib/astunparse/unparser.py @@ -444,9 +444,8 @@ def _Str(self, tree): format_conversions = {97: 'a', 114: 'r', 115: 's'} - def _FormattedValue(self, t): - # FormattedValue(expr value, int? conversion, expr? format_spec) - self.write("f'''{") + def _generic_FormattedValue(self, t): + self.write("{") self.dispatch(t.value) if t.conversion is not None and t.conversion != -1: self.write("!") @@ -458,14 +457,25 @@ def _FormattedValue(self, t): self.write(t.format_spec.s) else: self.dispatch(t.format_spec) - self.write("}'''") + self.write("}") + + def _FormattedValue(self, t): + # FormattedValue(expr value, int? conversion, expr? format_spec) + self.write("f'''") + self._generic_FormattedValue(t) + self.write("'''") def _JoinedStr(self, t): # JoinedStr(expr* values) - self.write("(") + self.write("f'''") for value in t.values: - self.dispatch(value) - self.write(")") + if isinstance(value, ast.Str): + self.write(value.s) + elif isinstance(value, ast.FormattedValue): + self._generic_FormattedValue(value) + else: + self.dispatch(value) + self.write("'''") def _Name(self, t): self.write(t.id) diff --git a/tests/common.py b/tests/common.py index 6b0ebe7..baeba34 100644 --- a/tests/common.py +++ b/tests/common.py @@ -288,8 +288,12 @@ def test_raise_from(self): def test_bytes(self): self.check_roundtrip("b'123'") + @unittest.skipIf(sys.version_info < (3, 6), "Not supported < 3.6") def test_formatted_value(self): - self.check_roundtrip('f"{key}"') + self.check_roundtrip('f"{value}"') + self.check_roundtrip('f"{value!s}"') + self.check_roundtrip('f"{value:4}"') + self.check_roundtrip('f"{value!s:4}"') @unittest.skipIf(sys.version_info < (3, 6), "Not supported < 3.6") def test_joined_str(self): From 11392ea1fd0f9d73e32ab2ab1200af8c0a3120c5 Mon Sep 17 00:00:00 2001 From: Vladimir Iakovlev Date: Wed, 10 May 2017 17:39:05 +0200 Subject: [PATCH 3/3] #18: Fix `FormattedValue` on Python 3.6.1 --- lib/astunparse/unparser.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/astunparse/unparser.py b/lib/astunparse/unparser.py index 3db9b0b..87cc866 100644 --- a/lib/astunparse/unparser.py +++ b/lib/astunparse/unparser.py @@ -454,7 +454,15 @@ def _generic_FormattedValue(self, t): if t.format_spec is not None: self.write(":") if isinstance(t.format_spec, ast.Str): + # It's ast.Str in 3.6.0 self.write(t.format_spec.s) + elif isinstance(t.format_spec, ast.JoinedStr): + # It's ast.JoinedStr in 3.6.1+ + for value in t.format_spec.values: + if isinstance(value, ast.Str): + self.write(value.s) + else: + self.dispatch(value) else: self.dispatch(t.format_spec) self.write("}")