You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 09:22:40 +08:00
Merge branch 'master' into python-2.4
This commit is contained in:
@@ -12,7 +12,7 @@ Introduction
|
|||||||
|
|
||||||
*uncompyle6* translates Python bytecode back into equivalent Python
|
*uncompyle6* translates Python bytecode back into equivalent Python
|
||||||
source code. It accepts bytecodes from Python version 1.3 to version
|
source code. It accepts bytecodes from Python version 1.3 to version
|
||||||
3.7, spanning over 22 years of Python releases. We include Dropbox's
|
3.8, spanning over 24 years of Python releases. We include Dropbox's
|
||||||
Python 2.5 bytecode and some PyPy bytecode.
|
Python 2.5 bytecode and some PyPy bytecode.
|
||||||
|
|
||||||
Why this?
|
Why this?
|
||||||
@@ -76,7 +76,7 @@ Requirements
|
|||||||
The code here can be run on Python versions 2.6 or later, PyPy 3-2.4,
|
The code here can be run on Python versions 2.6 or later, PyPy 3-2.4,
|
||||||
or PyPy-5.0.1. Python versions 2.4-2.7 are supported in the
|
or PyPy-5.0.1. Python versions 2.4-2.7 are supported in the
|
||||||
python-2.4 branch. The bytecode files it can read have been tested on
|
python-2.4 branch. The bytecode files it can read have been tested on
|
||||||
Python bytecodes from versions 1.4, 2.1-2.7, and 3.0-3.6 and the
|
Python bytecodes from versions 1.4, 2.1-2.7, and 3.0-3.8 and the
|
||||||
above-mentioned PyPy versions.
|
above-mentioned PyPy versions.
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
|
@@ -43,6 +43,7 @@ classifiers = ['Development Status :: 5 - Production/Stable',
|
|||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
'Programming Language :: Python :: 3.7',
|
'Programming Language :: Python :: 3.7',
|
||||||
|
'Programming Language :: Python :: 3.8',
|
||||||
'Topic :: Software Development :: Debuggers',
|
'Topic :: Software Development :: Debuggers',
|
||||||
'Topic :: Software Development :: Libraries :: Python Modules',
|
'Topic :: Software Development :: Libraries :: Python Modules',
|
||||||
]
|
]
|
||||||
|
Binary file not shown.
BIN
test/bytecode_3.4_run/06_while_return.pyc
Normal file
BIN
test/bytecode_3.4_run/06_while_return.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.5_run/06_while_return.pyc
Normal file
BIN
test/bytecode_3.5_run/06_while_return.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.7/04_call_function.pyc
Normal file
BIN
test/bytecode_3.7/04_call_function.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.8/04_call_function.pyc
Normal file
BIN
test/bytecode_3.8/04_call_function.pyc
Normal file
Binary file not shown.
@@ -1,28 +1,32 @@
|
|||||||
# From Python 3.4 asynchat.py
|
# From Python 3.4 asynchat.py
|
||||||
# Tests presence or absense of
|
# Tests presence or absense of
|
||||||
# SETUP_LOOP testexpr return_stmts POP_BLOCK COME_FROM_LOOP
|
# SETUP_LOOP testexpr return_stmts POP_BLOCK COME_FROM_LOOP
|
||||||
|
# Note: that there is no JUMP_BACK because of the return_stmts.
|
||||||
|
|
||||||
def initiate_send(self, num_sent, first):
|
def initiate_send(a, b, c, num_sent):
|
||||||
while self.producer_fifo and self.connected:
|
while a and b:
|
||||||
try:
|
try:
|
||||||
5
|
1 / (b - 1)
|
||||||
except OSError:
|
except ZeroDivisionError:
|
||||||
return
|
return 1
|
||||||
|
|
||||||
if num_sent:
|
if num_sent:
|
||||||
if first:
|
c = 2
|
||||||
self.producer_fifo = '6'
|
return c
|
||||||
else:
|
|
||||||
del self.producer_fifo[0]
|
|
||||||
return
|
|
||||||
|
|
||||||
|
|
||||||
# FIXME: this causes a parse error:
|
def initiate_send2(a, b):
|
||||||
# def initiate_send(self):
|
while a and b:
|
||||||
# while self.producer_fifo and self.connected:
|
try:
|
||||||
# try:
|
1 / (b - 1)
|
||||||
# 6
|
except ZeroDivisionError:
|
||||||
# except OSError:
|
return 1
|
||||||
# return
|
|
||||||
|
|
||||||
# return
|
return 2
|
||||||
|
|
||||||
|
assert initiate_send(1, 1, 2, False) == 1
|
||||||
|
assert initiate_send(1, 2, 3, False) == 3
|
||||||
|
assert initiate_send(1, 2, 3, True) == 2
|
||||||
|
|
||||||
|
assert initiate_send2(1, 1) == 1
|
||||||
|
assert initiate_send2(1, 2) == 2
|
||||||
|
@@ -100,7 +100,8 @@ class Python3Parser(PythonParser):
|
|||||||
|
|
||||||
return_if_stmts ::= return_if_stmt come_from_opt
|
return_if_stmts ::= return_if_stmt come_from_opt
|
||||||
return_if_stmts ::= _stmts return_if_stmt
|
return_if_stmts ::= _stmts return_if_stmt
|
||||||
return_if_stmt ::= ret_expr RETURN_END_IF
|
return_if_stmt ::= ret_expr RETURN_END_IF
|
||||||
|
returns ::= _stmts return_if_stmt
|
||||||
|
|
||||||
stmt ::= break
|
stmt ::= break
|
||||||
break ::= BREAK_LOOP
|
break ::= BREAK_LOOP
|
||||||
|
@@ -34,6 +34,8 @@ class Python34Parser(Python33Parser):
|
|||||||
# passtmt is needed for semantic actions to add "pass"
|
# passtmt is needed for semantic actions to add "pass"
|
||||||
suite_stmts_opt ::= pass
|
suite_stmts_opt ::= pass
|
||||||
|
|
||||||
|
whilestmt ::= SETUP_LOOP testexpr returns come_froms POP_BLOCK COME_FROM_LOOP
|
||||||
|
|
||||||
# Seems to be needed starting 3.4.4 or so
|
# Seems to be needed starting 3.4.4 or so
|
||||||
while1stmt ::= SETUP_LOOP l_stmts
|
while1stmt ::= SETUP_LOOP l_stmts
|
||||||
COME_FROM JUMP_BACK POP_BLOCK COME_FROM_LOOP
|
COME_FROM JUMP_BACK POP_BLOCK COME_FROM_LOOP
|
||||||
|
@@ -27,7 +27,6 @@ class Python35Parser(Python34Parser):
|
|||||||
while1stmt ::= SETUP_LOOP l_stmts POP_BLOCK COME_FROM_LOOP
|
while1stmt ::= SETUP_LOOP l_stmts POP_BLOCK COME_FROM_LOOP
|
||||||
while1elsestmt ::= SETUP_LOOP l_stmts JUMP_BACK
|
while1elsestmt ::= SETUP_LOOP l_stmts JUMP_BACK
|
||||||
POP_BLOCK else_suite COME_FROM_LOOP
|
POP_BLOCK else_suite COME_FROM_LOOP
|
||||||
whilestmt ::= SETUP_LOOP testexpr returns POP_BLOCK COME_FROM_LOOP
|
|
||||||
|
|
||||||
# The following rule is for Python 3.5+ where we can have stuff like
|
# The following rule is for Python 3.5+ where we can have stuff like
|
||||||
# while ..
|
# while ..
|
||||||
@@ -105,7 +104,6 @@ class Python35Parser(Python34Parser):
|
|||||||
return_if_stmt ::= ret_expr RETURN_END_IF POP_BLOCK
|
return_if_stmt ::= ret_expr RETURN_END_IF POP_BLOCK
|
||||||
return_if_lambda ::= RETURN_END_IF_LAMBDA COME_FROM
|
return_if_lambda ::= RETURN_END_IF_LAMBDA COME_FROM
|
||||||
|
|
||||||
|
|
||||||
jb_else ::= JUMP_BACK ELSE
|
jb_else ::= JUMP_BACK ELSE
|
||||||
ifelsestmtc ::= testexpr c_stmts_opt JUMP_FORWARD else_suitec
|
ifelsestmtc ::= testexpr c_stmts_opt JUMP_FORWARD else_suitec
|
||||||
ifelsestmtl ::= testexpr c_stmts_opt jb_else else_suitel
|
ifelsestmtl ::= testexpr c_stmts_opt jb_else else_suitel
|
||||||
|
@@ -22,13 +22,16 @@ This sets up opcodes Python's 3.7 and calls a generalized
|
|||||||
scanner routine for Python 3.
|
scanner routine for Python 3.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from uncompyle6.scanners.scanner36 import Scanner36
|
||||||
from uncompyle6.scanners.scanner3 import Scanner3
|
from uncompyle6.scanners.scanner3 import Scanner3
|
||||||
|
|
||||||
# bytecode verification, verify(), uses JUMP_OPs from here
|
# bytecode verification, verify(), uses JUMP_OPs from here
|
||||||
from xdis.opcodes import opcode_37 as opc
|
from xdis.opcodes import opcode_37 as opc
|
||||||
JUMP_OPs = opc.JUMP_OPS
|
JUMP_OPs = opc.JUMP_OPS
|
||||||
|
|
||||||
class Scanner37(Scanner3):
|
class Scanner37(Scanner36):
|
||||||
|
|
||||||
def __init__(self, show_asm=None):
|
def __init__(self, show_asm=None):
|
||||||
Scanner3.__init__(self, 3.7, show_asm)
|
Scanner3.__init__(self, 3.7, show_asm)
|
||||||
|
@@ -24,13 +24,14 @@ scanner routine for Python 3.
|
|||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
from uncompyle6.scanners.scanner37 import Scanner37
|
||||||
from uncompyle6.scanners.scanner3 import Scanner3
|
from uncompyle6.scanners.scanner3 import Scanner3
|
||||||
|
|
||||||
# bytecode verification, verify(), uses JUMP_OPs from here
|
# bytecode verification, verify(), uses JUMP_OPs from here
|
||||||
from xdis.opcodes import opcode_38 as opc
|
from xdis.opcodes import opcode_38 as opc
|
||||||
JUMP_OPs = opc.JUMP_OPS
|
JUMP_OPs = opc.JUMP_OPS
|
||||||
|
|
||||||
class Scanner38(Scanner3):
|
class Scanner38(Scanner37):
|
||||||
|
|
||||||
def __init__(self, show_asm=None):
|
def __init__(self, show_asm=None):
|
||||||
Scanner3.__init__(self, 3.8, show_asm)
|
Scanner3.__init__(self, 3.8, show_asm)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2018 by Rocky Bernstein
|
# Copyright (c) 2018-2019 by Rocky Bernstein
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -48,13 +48,77 @@ def customize_for_version(self, is_pypy, version):
|
|||||||
'assign3': ( '%|%c, %c, %c = %c, %c, %c\n',
|
'assign3': ( '%|%c, %c, %c = %c, %c, %c\n',
|
||||||
5, 6, 7, 0, 1, 2 ),
|
5, 6, 7, 0, 1, 2 ),
|
||||||
})
|
})
|
||||||
if version < 3.0:
|
if version >= 3.0:
|
||||||
if version == 2.4:
|
TABLE_DIRECT.update({
|
||||||
def n_iftrue_stmt24(node):
|
# Gotta love Python for its futzing around with syntax like this
|
||||||
self.template_engine(('%c', 0), node)
|
'raise_stmt2': ( '%|raise %c from %c\n', 0, 1),
|
||||||
self.default(node)
|
})
|
||||||
self.prune()
|
|
||||||
self.n_iftrue_stmt24 = n_iftrue_stmt24
|
if version >= 3.2:
|
||||||
|
TABLE_DIRECT.update({
|
||||||
|
'del_deref_stmt': ( '%|del %c\n', 0),
|
||||||
|
'DELETE_DEREF': ( '%{pattr}', 0 ),
|
||||||
|
})
|
||||||
|
from uncompyle6.semantics.customize3 import customize_for_version3
|
||||||
|
customize_for_version3(self, version)
|
||||||
|
else: # < 3.0
|
||||||
|
if 2.4 <= version <= 2.6:
|
||||||
|
TABLE_DIRECT.update({
|
||||||
|
'comp_for': ( ' for %c in %c', 3, 1 ),
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
TABLE_DIRECT.update({
|
||||||
|
'comp_for': ( ' for %c in %c%c', 2, 0, 3 ),
|
||||||
|
})
|
||||||
|
|
||||||
|
if version >= 2.5:
|
||||||
|
from uncompyle6.semantics.customize25 import customize_for_version25
|
||||||
|
customize_for_version25(self, version)
|
||||||
|
|
||||||
|
if version >= 2.6:
|
||||||
|
from uncompyle6.semantics.customize26_27 import customize_for_version26_27
|
||||||
|
customize_for_version26_27(self, version)
|
||||||
|
pass
|
||||||
|
else: # < 2.5
|
||||||
|
global NAME_MODULE
|
||||||
|
NAME_MODULE = SyntaxTree('stmt',
|
||||||
|
[ SyntaxTree('assign',
|
||||||
|
[ SyntaxTree('expr',
|
||||||
|
[Token('LOAD_GLOBAL', pattr='__name__',
|
||||||
|
offset=0, has_arg=True)]),
|
||||||
|
SyntaxTree('store',
|
||||||
|
[ Token('STORE_NAME', pattr='__module__',
|
||||||
|
offset=3, has_arg=True)])
|
||||||
|
])])
|
||||||
|
TABLE_DIRECT.update({
|
||||||
|
'importmultiple': ( '%|import %c%c\n', 2, 3),
|
||||||
|
'import_cont' : ( ', %c', 2),
|
||||||
|
'tryfinallystmt': ( '%|try:\n%+%c%-%|finally:\n%+%c%-',
|
||||||
|
(1, 'suite_stmts_opt') ,
|
||||||
|
(5, 'suite_stmts_opt') )
|
||||||
|
})
|
||||||
|
if version == 2.4:
|
||||||
|
def n_iftrue_stmt24(node):
|
||||||
|
self.template_engine(('%c', 0), node)
|
||||||
|
self.default(node)
|
||||||
|
self.prune()
|
||||||
|
self.n_iftrue_stmt24 = n_iftrue_stmt24
|
||||||
|
else: # version <= 2.3:
|
||||||
|
TABLE_DIRECT.update({
|
||||||
|
'if1_stmt': ( '%|if 1\n%+%c%-', 5 )
|
||||||
|
})
|
||||||
|
if version <= 2.1:
|
||||||
|
TABLE_DIRECT.update({
|
||||||
|
'importmultiple': ( '%c', 2 ),
|
||||||
|
# FIXME: not quite right. We have indiividual imports
|
||||||
|
# when there is in fact one: "import a, b, ..."
|
||||||
|
'imports_cont': ( '%C%,', (1, 100, '\n') ),
|
||||||
|
})
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
pass # < 2.5
|
||||||
|
|
||||||
|
# < 3.0 continues
|
||||||
|
|
||||||
TABLE_R.update({
|
TABLE_R.update({
|
||||||
'STORE_SLICE+0': ( '%c[:]', 0 ),
|
'STORE_SLICE+0': ( '%c[:]', 0 ),
|
||||||
@@ -87,109 +151,6 @@ def customize_for_version(self, is_pypy, version):
|
|||||||
self.prune() # stop recursing
|
self.prune() # stop recursing
|
||||||
self.n_exec_smt = n_exec_stmt
|
self.n_exec_smt = n_exec_stmt
|
||||||
|
|
||||||
else:
|
pass # < 3.0
|
||||||
TABLE_DIRECT.update({
|
|
||||||
# Gotta love Python for its futzing around with syntax like this
|
|
||||||
'raise_stmt2': ( '%|raise %c from %c\n', 0, 1),
|
|
||||||
})
|
|
||||||
|
|
||||||
if version >= 3.2:
|
|
||||||
TABLE_DIRECT.update({
|
|
||||||
'del_deref_stmt': ( '%|del %c\n', 0),
|
|
||||||
'DELETE_DEREF': ( '%{pattr}', 0 ),
|
|
||||||
})
|
|
||||||
|
|
||||||
if version <= 2.4:
|
|
||||||
TABLE_DIRECT.update({
|
|
||||||
'importmultiple': ( '%|import %c%c\n', 2, 3),
|
|
||||||
'import_cont' : ( ', %c', 2),
|
|
||||||
'tryfinallystmt': ( '%|try:\n%+%c%-%|finally:\n%+%c%-',
|
|
||||||
(1, 'suite_stmts_opt') ,
|
|
||||||
(5, 'suite_stmts_opt') )
|
|
||||||
})
|
|
||||||
if version == 2.3:
|
|
||||||
TABLE_DIRECT.update({
|
|
||||||
'if1_stmt': ( '%|if 1\n%+%c%-', 5 )
|
|
||||||
})
|
|
||||||
|
|
||||||
global NAME_MODULE
|
|
||||||
NAME_MODULE = SyntaxTree('stmt',
|
|
||||||
[ SyntaxTree('assign',
|
|
||||||
[ SyntaxTree('expr',
|
|
||||||
[Token('LOAD_GLOBAL', pattr='__name__',
|
|
||||||
offset=0, has_arg=True)]),
|
|
||||||
SyntaxTree('store',
|
|
||||||
[ Token('STORE_NAME', pattr='__module__',
|
|
||||||
offset=3, has_arg=True)])
|
|
||||||
])])
|
|
||||||
pass
|
|
||||||
if version <= 2.3:
|
|
||||||
if version <= 2.1:
|
|
||||||
TABLE_DIRECT.update({
|
|
||||||
'importmultiple': ( '%c', 2 ),
|
|
||||||
# FIXME: not quite right. We have indiividual imports
|
|
||||||
# when there is in fact one: "import a, b, ..."
|
|
||||||
'imports_cont': ( '%C%,', (1, 100, '\n') ),
|
|
||||||
})
|
|
||||||
pass
|
|
||||||
pass
|
|
||||||
pass
|
|
||||||
elif version >= 2.5:
|
|
||||||
########################
|
|
||||||
# Import style for 2.5+
|
|
||||||
########################
|
|
||||||
TABLE_DIRECT.update({
|
|
||||||
'importmultiple': ( '%|import %c%c\n', 2, 3 ),
|
|
||||||
'import_cont' : ( ', %c', 2 ),
|
|
||||||
# With/as is allowed as "from future" thing in 2.5
|
|
||||||
# Note: It is safe to put the variables after "as" in parenthesis,
|
|
||||||
# and sometimes it is needed.
|
|
||||||
'withstmt': ( '%|with %c:\n%+%c%-', 0, 3),
|
|
||||||
'withasstmt': ( '%|with %c as (%c):\n%+%c%-', 0, 2, 3),
|
|
||||||
})
|
|
||||||
|
|
||||||
# In 2.5+ "except" handlers and the "finally" can appear in one
|
|
||||||
# "try" statement. So the below has the effect of combining the
|
|
||||||
# "tryfinally" with statement with the "try_except" statement
|
|
||||||
def tryfinallystmt(node):
|
|
||||||
if len(node[1][0]) == 1 and node[1][0][0] == 'stmt':
|
|
||||||
if node[1][0][0][0] == 'try_except':
|
|
||||||
node[1][0][0][0].kind = 'tf_try_except'
|
|
||||||
if node[1][0][0][0] == 'tryelsestmt':
|
|
||||||
node[1][0][0][0].kind = 'tf_tryelsestmt'
|
|
||||||
self.default(node)
|
|
||||||
self.n_tryfinallystmt = tryfinallystmt
|
|
||||||
|
|
||||||
########################################
|
|
||||||
# Python 2.6+
|
|
||||||
# except <condition> as <var>
|
|
||||||
# vs. older:
|
|
||||||
# except <condition> , <var>
|
|
||||||
#
|
|
||||||
# For 2.6 we use the older syntax which
|
|
||||||
# matches how we parse this in bytecode
|
|
||||||
########################################
|
|
||||||
if version > 2.6:
|
|
||||||
TABLE_DIRECT.update({
|
|
||||||
'except_cond2': ( '%|except %c as %c:\n', 1, 5 ),
|
|
||||||
})
|
|
||||||
else:
|
|
||||||
TABLE_DIRECT.update({
|
|
||||||
'except_cond3': ( '%|except %c, %c:\n', 1, 6 ),
|
|
||||||
'testtrue_then': ( 'not %p', (0, 22) ),
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
if 2.4 <= version <= 2.6:
|
|
||||||
TABLE_DIRECT.update({
|
|
||||||
'comp_for': ( ' for %c in %c', 3, 1 ),
|
|
||||||
})
|
|
||||||
else:
|
|
||||||
TABLE_DIRECT.update({
|
|
||||||
'comp_for': ( ' for %c in %c%c', 2, 0, 3 ),
|
|
||||||
})
|
|
||||||
|
|
||||||
if version >= 3.0:
|
|
||||||
from uncompyle6.semantics.customize3 import customize_for_version3
|
|
||||||
customize_for_version3(self, version)
|
|
||||||
return
|
return
|
||||||
|
48
uncompyle6/semantics/customize25.py
Normal file
48
uncompyle6/semantics/customize25.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# Copyright (c) 2019 by Rocky Bernstein
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
"""Isolate Python 2.5+ version-specific semantic actions here.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from uncompyle6.semantics.consts import TABLE_DIRECT
|
||||||
|
|
||||||
|
#######################
|
||||||
|
# Python 2.5+ Changes #
|
||||||
|
#######################
|
||||||
|
def customize_for_version25(self, version):
|
||||||
|
|
||||||
|
########################
|
||||||
|
# Import style for 2.5+
|
||||||
|
########################
|
||||||
|
TABLE_DIRECT.update({
|
||||||
|
'importmultiple': ( '%|import %c%c\n', 2, 3 ),
|
||||||
|
'import_cont' : ( ', %c', 2 ),
|
||||||
|
# With/as is allowed as "from future" thing in 2.5
|
||||||
|
# Note: It is safe to put the variables after "as" in parenthesis,
|
||||||
|
# and sometimes it is needed.
|
||||||
|
'withstmt': ( '%|with %c:\n%+%c%-', 0, 3),
|
||||||
|
'withasstmt': ( '%|with %c as (%c):\n%+%c%-', 0, 2, 3),
|
||||||
|
})
|
||||||
|
|
||||||
|
# In 2.5+ "except" handlers and the "finally" can appear in one
|
||||||
|
# "try" statement. So the below has the effect of combining the
|
||||||
|
# "tryfinally" with statement with the "try_except" statement
|
||||||
|
def tryfinallystmt(node):
|
||||||
|
if len(node[1][0]) == 1 and node[1][0][0] == 'stmt':
|
||||||
|
if node[1][0][0][0] == 'try_except':
|
||||||
|
node[1][0][0][0].kind = 'tf_try_except'
|
||||||
|
if node[1][0][0][0] == 'tryelsestmt':
|
||||||
|
node[1][0][0][0].kind = 'tf_tryelsestmt'
|
||||||
|
self.default(node)
|
||||||
|
self.n_tryfinallystmt = tryfinallystmt
|
40
uncompyle6/semantics/customize26_27.py
Normal file
40
uncompyle6/semantics/customize26_27.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Copyright (c) 2019 by Rocky Bernstein
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
"""Isolate Python 2.6 and 2.7 version-specific semantic actions here.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from uncompyle6.semantics.consts import TABLE_DIRECT
|
||||||
|
|
||||||
|
def customize_for_version26_27(self, version):
|
||||||
|
|
||||||
|
########################################
|
||||||
|
# Python 2.6+
|
||||||
|
# except <condition> as <var>
|
||||||
|
# vs. older:
|
||||||
|
# except <condition> , <var>
|
||||||
|
#
|
||||||
|
# For 2.6 we use the older syntax which
|
||||||
|
# matches how we parse this in bytecode
|
||||||
|
########################################
|
||||||
|
if version > 2.6:
|
||||||
|
TABLE_DIRECT.update({
|
||||||
|
'except_cond2': ( '%|except %c as %c:\n', 1, 5 ),
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
TABLE_DIRECT.update({
|
||||||
|
'except_cond3': ( '%|except %c, %c:\n', 1, 6 ),
|
||||||
|
'testtrue_then': ( 'not %p', (0, 22) ),
|
||||||
|
|
||||||
|
})
|
@@ -27,8 +27,13 @@ from uncompyle6.semantics.customize38 import customize_for_version38
|
|||||||
|
|
||||||
def customize_for_version3(self, version):
|
def customize_for_version3(self, version):
|
||||||
TABLE_DIRECT.update({
|
TABLE_DIRECT.update({
|
||||||
|
'except_cond2': ( '%|except %c as %c:\n', 1, 5 ),
|
||||||
'function_def_annotate': ( '\n\n%|def %c%c\n', -1, 0),
|
'function_def_annotate': ( '\n\n%|def %c%c\n', -1, 0),
|
||||||
|
'importmultiple': ( '%|import %c%c\n', 2, 3 ),
|
||||||
|
'import_cont' : ( ', %c', 2 ),
|
||||||
'store_locals': ( '%|# inspect.currentframe().f_locals = __locals__\n', ),
|
'store_locals': ( '%|# inspect.currentframe().f_locals = __locals__\n', ),
|
||||||
|
'withstmt': ( '%|with %c:\n%+%c%-', 0, 3),
|
||||||
|
'withasstmt': ( '%|with %c as (%c):\n%+%c%-', 0, 2, 3),
|
||||||
})
|
})
|
||||||
|
|
||||||
assert version >= 3.0
|
assert version >= 3.0
|
||||||
@@ -269,8 +274,8 @@ def customize_for_version3(self, version):
|
|||||||
(5, 'else_suitel') ),
|
(5, 'else_suitel') ),
|
||||||
})
|
})
|
||||||
if version >= 3.4:
|
if version >= 3.4:
|
||||||
########################
|
#######################
|
||||||
# Python 3.4+ Additions
|
# Python 3.4+ Changes #
|
||||||
#######################
|
#######################
|
||||||
TABLE_DIRECT.update({
|
TABLE_DIRECT.update({
|
||||||
'LOAD_CLASSDEREF': ( '%{pattr}', ),
|
'LOAD_CLASSDEREF': ( '%{pattr}', ),
|
||||||
|
@@ -21,8 +21,8 @@ from uncompyle6.semantics.consts import (
|
|||||||
INDENT_PER_LEVEL, TABLE_DIRECT)
|
INDENT_PER_LEVEL, TABLE_DIRECT)
|
||||||
from uncompyle6.semantics.helper import flatten_list
|
from uncompyle6.semantics.helper import flatten_list
|
||||||
|
|
||||||
########################
|
#######################
|
||||||
# Python 3.5+ Additions
|
# Python 3.5+ Changes #
|
||||||
#######################
|
#######################
|
||||||
def customize_for_version35(self, version):
|
def customize_for_version35(self, version):
|
||||||
TABLE_DIRECT.update({
|
TABLE_DIRECT.update({
|
||||||
|
@@ -46,8 +46,12 @@ def customize_for_version38(self, version):
|
|||||||
(0, 'expr'), (6, 'store'),
|
(0, 'expr'), (6, 'store'),
|
||||||
(7, 'suite_stmts') ),
|
(7, 'suite_stmts') ),
|
||||||
|
|
||||||
|
'except_handler38': (
|
||||||
|
'%c', (2, 'except_stmts') ),
|
||||||
|
|
||||||
'except_handler38a': (
|
'except_handler38a': (
|
||||||
'%c', (-2, 'stmts') ),
|
'%c', (-2, 'stmts') ),
|
||||||
|
|
||||||
'except_ret38a': (
|
'except_ret38a': (
|
||||||
'return %c', (4, 'expr') ),
|
'return %c', (4, 'expr') ),
|
||||||
'except_ret38': ( '%|return %c\n', (1, 'expr') ),
|
'except_ret38': ( '%|return %c\n', (1, 'expr') ),
|
||||||
|
@@ -1825,7 +1825,6 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
# print(startnode)
|
# print(startnode)
|
||||||
# print(entry[0])
|
# print(entry[0])
|
||||||
# print('======')
|
# print('======')
|
||||||
|
|
||||||
fmt = entry[0]
|
fmt = entry[0]
|
||||||
arg = 1
|
arg = 1
|
||||||
i = 0
|
i = 0
|
||||||
|
Reference in New Issue
Block a user