diff --git a/pytest/test_fstring.py b/pytest/test_fstring.py index 1f019eb6..2789d82a 100644 --- a/pytest/test_fstring.py +++ b/pytest/test_fstring.py @@ -142,9 +142,9 @@ def test_uncompyle_fstring(fstring): @pytest.mark.skipif(PYTHON_VERSION < 3.6, reason='need at least python 3.6') @pytest.mark.parametrize('fstring', [ - #"f'{abc}{abc!s}'", + "f'{abc}{abc!s}'", "f'{abc}0'", ]) def test_uncompyle_direct(fstring): """useful for debugging""" - run_test(fstring) \ No newline at end of file + run_test(fstring) diff --git a/test/bytecode_3.6/01_fstring.pyc b/test/bytecode_3.6/01_fstring.pyc index 6507cc0e..7d959b54 100644 Binary files a/test/bytecode_3.6/01_fstring.pyc and b/test/bytecode_3.6/01_fstring.pyc differ diff --git a/test/simple_source/bug36/01_fstring.py b/test/simple_source/bug36/01_fstring.py index d7ee22e7..d9db44dc 100644 --- a/test/simple_source/bug36/01_fstring.py +++ b/test/simple_source/bug36/01_fstring.py @@ -1,3 +1,5 @@ var1 = 'x' var2 = 'y' print(f'interpolate {var1} strings {var2!r} {var2!s} py36') +print(f'{abc}0') +print(f'{abc}{abc!s}') diff --git a/uncompyle6/semantics/pysource.py b/uncompyle6/semantics/pysource.py index b95e8912..511dae89 100644 --- a/uncompyle6/semantics/pysource.py +++ b/uncompyle6/semantics/pysource.py @@ -514,12 +514,11 @@ class SourceWalker(GenericASTTraversal, object): self.name = None self.version = version self.is_pypy = is_pypy - self.customize_for_version(is_pypy, version) + return - @staticmethod - def customize_for_version(is_pypy, version): + def customize_for_version(self, is_pypy, version): if is_pypy: ######################## # PyPy changes @@ -632,10 +631,26 @@ class SourceWalker(GenericASTTraversal, object): # Python 3.6+ Additions ####################### TABLE_DIRECT.update({ - 'fstring_expr': ( "{%c%{conversion}}", 0), + 'fstring_expr': ( "{%c%{conversion}}", 0), 'fstring_single': ( "f'{%c%{conversion}}'", 0), 'fstring_multi': ( "f'%c'", 0), }) + + FSTRING_CONVERSION_MAP = {1: '!s', 2: '!r', 3: '!a'} + def f_conversion(node): + node.conversion = FSTRING_CONVERSION_MAP.get(node.data[1].attr, '') + + def n_fstring_expr(node): + f_conversion(node) + self.default(node) + self.n_fstring_expr = n_fstring_expr + + def n_fstring_single(node): + f_conversion(node) + self.default(node) + + self.n_fstring_single = n_fstring_single + return f = property(lambda s: s.params['f'], @@ -1888,15 +1903,6 @@ class SourceWalker(GenericASTTraversal, object): node[-2][0].type = 'unpack_w_parens' self.default(node) - FSTRING_CONVERSION_MAP = {1: '!s', 2: '!r', 3: '!a'} - - def n_fstring_expr(self, node): - node.conversion = self.FSTRING_CONVERSION_MAP.get(node.data[1].attr, '') - self.default(node) - - def n_fstring_single(self, node): - return self.n_fstring_expr(node) - def engine(self, entry, startnode): """The format template interpetation engine. See the comment at the beginning of this module for the how we interpret format specifications such as