diff --git a/test/bytecode_3.6/04_try_finally.pyc b/test/bytecode_3.6/04_try_finally.pyc index 8f7ab09f..9e859661 100644 Binary files a/test/bytecode_3.6/04_try_finally.pyc and b/test/bytecode_3.6/04_try_finally.pyc differ diff --git a/test/simple_source/bug36/04_try_finally.py b/test/simple_source/bug36/04_try_finally.py index 1b2d2e49..ce3226e6 100644 --- a/test/simple_source/bug36/04_try_finally.py +++ b/test/simple_source/bug36/04_try_finally.py @@ -31,3 +31,18 @@ def handle_read(self): return why return data + +# From 3.6 contextlib +# Bug is indentation of "return exc" +# Also there are extra statements to remove exec, +# which we hide (unless doing fragments). +# Note: The indentation bug may be a result of using improper +# grammar. +def __exit__(self, type, value, traceback): + try: + value() + except StopIteration as exc: + return exc + except RuntimeError as exc: + return exc + return diff --git a/uncompyle6/semantics/consts.py b/uncompyle6/semantics/consts.py index 87b2d068..34ae5152 100644 --- a/uncompyle6/semantics/consts.py +++ b/uncompyle6/semantics/consts.py @@ -288,7 +288,10 @@ TABLE_DIRECT = { 'except': ( '%|except:\n%+%c%-', 3 ), 'except_cond1': ( '%|except %c:\n', 1 ), 'except_suite': ( '%+%c%-%C', 0, (1, maxint, '') ), + + # In Python 3.6, this is more complicated in the presence of "returns" 'except_suite_finalize': ( '%+%c%-%C', 1, (3, maxint, '') ), + 'pass': ( '%|pass\n', ), 'STORE_FAST': ( '%{pattr}', ), 'kv': ( '%c: %c', 3, 1 ), diff --git a/uncompyle6/semantics/customize.py b/uncompyle6/semantics/customize.py index df70c43d..c8fb2aad 100644 --- a/uncompyle6/semantics/customize.py +++ b/uncompyle6/semantics/customize.py @@ -609,6 +609,22 @@ def customize_for_version(self, is_pypy, version): FSTRING_CONVERSION_MAP = {1: '!s', 2: '!r', 3: '!a'} + def n_except_suite_finalize(node): + if node[1] == 'returns' and self.hide_internal: + # Process node[1] only. + # The code after "returns", e.g. node[3], is dead code. + # Adding it is wrong as it dedents and another + # exception handler "except_stmt" afterwards. + # Note it is also possible that the grammar is wrong here. + # and this should not be "except_stmt". + self.indent_more() + self.preorder(node[1]) + self.indent_less() + else: + self.default(node) + self.prune() + self.n_except_suite_finalize = n_except_suite_finalize + def n_formatted_value(node): if node[0] == 'LOAD_CONST': self.write(node[0].attr)