diff --git a/admin-tools/pyenv-newest-versions b/admin-tools/pyenv-newest-versions index b6dd3491..f2c5ebcc 100644 --- a/admin-tools/pyenv-newest-versions +++ b/admin-tools/pyenv-newest-versions @@ -5,4 +5,4 @@ if [[ $0 == ${BASH_SOURCE[0]} ]] ; then echo "This script should be *sourced* rather than run directly through bash" exit 1 fi -export PYVERSIONS='3.6.15 pypy3.6-7.3.1 3.7.13 pypy3.8-7.3.9 pyston-2.3.3 3.8.13' +export PYVERSIONS='3.6.15 pypy3.6-7.3.1 3.7.14 pypy3.8-7.3.9 pyston-2.3.3 3.8.14' diff --git a/test/bytecode_3.6_run/10_fstring.pyc b/test/bytecode_3.6_run/10_fstring.pyc index b54bc491..c3ae2325 100644 Binary files a/test/bytecode_3.6_run/10_fstring.pyc and b/test/bytecode_3.6_run/10_fstring.pyc differ diff --git a/test/simple_source/bug36/10_fstring.py b/test/simple_source/bug36/10_fstring.py index 876f15e9..52f79481 100644 --- a/test/simple_source/bug36/10_fstring.py +++ b/test/simple_source/bug36/10_fstring.py @@ -59,9 +59,9 @@ log_rounds = 5 assert "05$" == f"{log_rounds:02d}$" -def testit(a, b, l): - # print(l) - return l +def testit(a, b, ll): + # print(ll) + return ll # The call below shows the need for BUILD_STRING to count expr arguments. @@ -102,11 +102,11 @@ assert f"x={x*y:{width}}" == "x=foofoo " # equivalent thing. For compatiblity with older Python we'll use "%" # instead of a format string def f(): - f"""Not a docstring""" + f"""Not a docstring""" # noqa def g(): - """Not a docstring""" f"" + """Not a docstring""" f"" # noqa assert f.__doc__ is None @@ -129,3 +129,17 @@ assert f'{f"{0}"*3}' == "000" # The former, {{ confuses the format strings so dictionary/set comprehensions # don't work. assert f"expr={ {x: y for x, y in [(1, 2), ]}}" == "expr={1: 2}" + + +class Line: + def __init__(self, x, y): + self.x = x + self.y = y + + # From 3.7 test_typing.py + def __str__(self): + return f"{self.x} -> {self.y}" + + +line = Line(1, 2) +assert str(line) == "1 -> 2" diff --git a/uncompyle6/semantics/customize37.py b/uncompyle6/semantics/customize37.py index fe4c0c4b..b2680432 100644 --- a/uncompyle6/semantics/customize37.py +++ b/uncompyle6/semantics/customize37.py @@ -94,8 +94,7 @@ def customize_for_version37(self, version): # need parenthesis. # Note there are async dictionary expressions are like await expr's # the below is just the default fersion - "await_expr": ("await %p", (0, PRECEDENCE["await_expr"]-1)), - + "await_expr": ("await %p", (0, PRECEDENCE["await_expr"] - 1)), "await_stmt": ("%|%c\n", 0), "c_async_with_stmt": ("%|async with %c:\n%+%c%-", (0, "expr"), 3), "call_ex": ("%c(%p)", (0, "expr"), (1, 100)), @@ -156,7 +155,10 @@ def customize_for_version37(self, version): (2, "import_from_attr37"), (3, "store"), ), - "import_one": ("%c", (0, "importlists"),), + "import_one": ( + "%c", + (0, "importlists"), + ), "importattr37": ("%c", (0, "IMPORT_NAME_ATTR")), "import_from_attr37": ( "%c import %c", @@ -165,12 +167,9 @@ def customize_for_version37(self, version): ), "list_afor": ( " async for %[1]{%c} in %c%[1]{%c}", - (1, "store"), (0, "get_aiter"), (3, "list_iter"), - ), - - "list_afor": ( - " async for %[1]{%c} in %c%[1]{%c}", - (1, "store"), (0, "get_aiter"), (3, "list_iter"), + (1, "store"), + (0, "get_aiter"), + (3, "list_iter"), ), "list_if37": (" if %p%c", (0, 27), 1), @@ -408,12 +407,17 @@ def customize_for_version37(self, version): self.n_call = n_call def n_compare_chained(node): - if node[0] == "compare_chained37": + if node[0] in ( + "c_compare_chained37", + "c_compare_chained37_false", + "compare_chained37", + "compare_chained37_false", + ): self.default(node[0]) else: self.default(node) - self.n_compare_chained = n_compare_chained + self.n_compare_chained = self.n_c_compare_chained = n_compare_chained def n_importlist37(node): if len(node) == 1: @@ -439,3 +443,26 @@ def customize_for_version37(self, version): self.prune() self.n_list_comp_async = n_list_comp_async + + # FIXME: The following adjusts I guess a bug in the parser. + # It might be as simple as renaming grammar symbol "testtrue" to "testtrue_or_false" + # and then keeping this as is with the name change. + # Fixing in the parsing by inspection is harder than doing it here. + def n_testtrue(node): + compare_chained37 = node[0] + if ( + compare_chained37 == "compare_chained37" + and compare_chained37[1] == "compare_chained1b_37" + ): + compare_chained1b_37 = compare_chained37[1] + if ( + len(compare_chained1b_37) > 2 + and compare_chained1b_37[-2] == "JUMP_FORWARD" + ): + node.kind = "testfalse" + pass + pass + self.default(node) + return + + self.n_testtrue = n_testtrue