From 7fc7e083c3af97be199fa27365c002e679eb2144 Mon Sep 17 00:00:00 2001 From: rocky Date: Wed, 21 Mar 2018 19:54:28 -0400 Subject: [PATCH] A couple of 3.6 bugs... remove parens around decorators by adjusting precidence Partial handling of quotes within 3.6 format strings --- test/bytecode_3.6/01_fstring.pyc | Bin 255 -> 0 bytes test/bytecode_3.6/02_kwargs.pyc | Bin 320 -> 504 bytes test/bytecode_3.6_run/01_fstring.pyc | Bin 0 -> 505 bytes test/simple_source/bug36/01_fstring.py | 19 ++++++++++++++++--- test/simple_source/bug36/02_kwargs.py | 10 +++++++++- uncompyle6/semantics/consts.py | 9 +++++++-- uncompyle6/semantics/customize.py | 14 ++++++++++++-- 7 files changed, 44 insertions(+), 8 deletions(-) delete mode 100644 test/bytecode_3.6/01_fstring.pyc create mode 100644 test/bytecode_3.6_run/01_fstring.pyc diff --git a/test/bytecode_3.6/01_fstring.pyc b/test/bytecode_3.6/01_fstring.pyc deleted file mode 100644 index 7d959b54b1d665538bb532c1af2e77a323259527..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 255 zcmXrw<>mU)$sJL}z`*brh~a<($Z`PUVmBa>!Vtxf!WhMv%9O&C$}pQDg*laRHd6`< zkYr3@oy*?L$jFe&l*$a0VVlc@-~mM#A^a5fU zx(ZDEQY_BQEyziYFU~J5N>0^JDor;w(>E}TPlK4MS5SG2!zMRBr8FnijuGS`kk42c KSr}y)`4|B~E$%6uW9ji` z*qlEaegdYSz;=}jKW@r9yLixkkzGhRAv+Ay_(1%%01b7}T=*nKizw#s!~ZGBRk(44TZzAUP0V zniylmQo>lmG;xxZB6AdPL1IyHYJ75jZf%{7( P$ymfQ`4poX3rIfz>bo8` diff --git a/test/bytecode_3.6_run/01_fstring.pyc b/test/bytecode_3.6_run/01_fstring.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f6a2a1dc002ce60bf287525cdc36e6b2b150080 GIT binary patch literal 505 zcmYjOJx{|h5cN4p)0Vb;6~q{(QVG#7i3t!4tPHRjp{mr^Do~QjPOBy(`~mh-iItWA zz@PBSA7JjpH6W<%dp^H=_hiehVlnT2y^9ZE?2|1Gm-15z{YoI2U=jpKF1WOiO_{V2 zrd&FNATu*py7ye~N7f_AEOM&nW}KLll*um`3P`!jlv|O7K5!;%;h;_WB05t(vqVOg zFhl26xpwEG^8}Qy&m57(jNBl{=S4SWn25TP1|gHD8A zlJj(={GhMBIe3ZV4dd2f;w?)ie~L<6@#0h=Y;vj_sMCe8N6SFNKywbqNxnAQaUssxyo22|-{-ySs)r)FQ*yE0Bq}Vi8=eBD~XIi6*{4h9IDpUsU z4U83i1T*$s=m&~Z`o`26Z7Ixmwf`_2U|WYH)y3NFsNXuQ)f?^J&l3-ZvB@4igmN^% Z6N|d^Hh~R`xea;PfU;A766`<$z5#{@iE01< literal 0 HcmV?d00001 diff --git a/test/simple_source/bug36/01_fstring.py b/test/simple_source/bug36/01_fstring.py index d9db44dc..26bc3904 100644 --- a/test/simple_source/bug36/01_fstring.py +++ b/test/simple_source/bug36/01_fstring.py @@ -1,5 +1,18 @@ +# Self-checking 3.6+ string interpolation tests + var1 = 'x' var2 = 'y' -print(f'interpolate {var1} strings {var2!r} {var2!s} py36') -print(f'{abc}0') -print(f'{abc}{abc!s}') +abc = 'def' +assert (f'interpolate {var1} strings {var2!r} {var2!s} py36' == + "interpolate x strings 'y' y py36") +assert 'def0' == f'{abc}0' +assert 'defdef' == f'{abc}{abc!s}' + +# From 3.6 functools.py +# Bug was handling format operator strings. + +k, v = "1", ["2"] +x = f"{k}={v!r}" +y = f"functools.{x}({', '.join(v)})" +assert x == "1=['2']" +assert y == "functools.1=['2'](2)" diff --git a/test/simple_source/bug36/02_kwargs.py b/test/simple_source/bug36/02_kwargs.py index 5c56adae..5b5af9e9 100644 --- a/test/simple_source/bug36/02_kwargs.py +++ b/test/simple_source/bug36/02_kwargs.py @@ -1,5 +1,13 @@ # From 3.6 _markupbase _parse_doctype_subset() -def bug(self, j): +def bug(self, j, a, b): self.parse_comment(j, report=0) self.parse_comment(j, report=1, foo=2) self.parse_comment(a, b, report=3) + +# From 3.6 fnmatch.py +# Bug was precidence parenthesis around decorator + +import functools +@functools.lru_cache(maxsize=256, typed=True) +def _compile_pattern(pat): + pass diff --git a/uncompyle6/semantics/consts.py b/uncompyle6/semantics/consts.py index 682899f5..8071c4fa 100644 --- a/uncompyle6/semantics/consts.py +++ b/uncompyle6/semantics/consts.py @@ -317,6 +317,10 @@ MAP = { # See https://docs.python.org/2/reference/expressions.html # or https://docs.python.org/3/reference/expressions.html # for a list. + +# Things at the top of this list below with low-value precidence will +# tend to have parenthesis around them. Things at the bottom +# of the list will tend not to have parenthesis around them. PRECEDENCE = { 'list': 0, 'dict': 0, @@ -377,8 +381,9 @@ PRECEDENCE = { 'ret_cond_not': 28, '_mklambda': 30, - 'yield': 101, - 'yield_from': 101 + 'call_kw': 100, # 100 seems to to be module/function precidence + 'yield': 101, + 'yield_from': 101 } ASSIGN_TUPLE_PARAM = lambda param_name: \ diff --git a/uncompyle6/semantics/customize.py b/uncompyle6/semantics/customize.py index 57098598..3e88842e 100644 --- a/uncompyle6/semantics/customize.py +++ b/uncompyle6/semantics/customize.py @@ -357,8 +357,10 @@ def customize_for_version(self, is_pypy, version): 'tryfinally36': ( '%|try:\n%+%c%-%|finally:\n%+%c%-\n\n', (1, 'returns'), 3 ), 'fstring_expr': ( "{%c%{conversion}}", 0), - 'fstring_single': ( "f'{%c%{conversion}}'", 0), - 'fstring_multi': ( "f'%c'", 0), + # FIXME: the below assumes the format strings + # don't have ''' in them. Fix this properly + 'fstring_single': ( "f'''{%c%{conversion}}'''", 0), + 'fstring_multi': ( "f'''%c'''", 0), 'func_args36': ( "%c(**", 0), 'try_except36': ( '%|try:\n%+%c%-%c\n\n', 1, 2 ), 'unpack_list': ( '*%c', (0, 'list') ), @@ -603,6 +605,14 @@ def customize_for_version(self, is_pypy, version): FSTRING_CONVERSION_MAP = {1: '!s', 2: '!r', 3: '!a'} + def n_formatted_value(node): + if node[0] == 'LOAD_CONST': + self.write(node[0].attr) + self.prune() + else: + self.default(node) + self.n_formatted_value = n_formatted_value + def f_conversion(node): node.conversion = FSTRING_CONVERSION_MAP.get(node.data[1].attr, '')