You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Merge branch 'master' into python-2.4
This commit is contained in:
@@ -63,10 +63,11 @@ fixed in the other decompilers.
|
|||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
|
|
||||||
This project requires Python 2.6 or later, PyPy 3-2.4, or PyPy-5.0.1.
|
The code here can be run on Python versions 2.6 or later, PyPy 3-2.4,
|
||||||
Python versions 2.4-2.7 are supported in the python-2.4 branch.
|
or PyPy-5.0.1. Python versions 2.4-2.7 are supported in the
|
||||||
The bytecode files it can read has been tested on Python bytecodes from
|
python-2.4 branch. The bytecode files it can read have been tested on
|
||||||
versions 1.5, 2.1-2.7, and 3.0-3.6 and the above-mentioned PyPy versions.
|
Python bytecodes from versions 1.5, 2.1-2.7, and 3.0-3.6 and the
|
||||||
|
above-mentioned PyPy versions.
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
|
@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
$ git commit -m"Get ready for release $VERSION" .
|
$ git commit -m"Get ready for release $VERSION" .
|
||||||
|
|
||||||
# Check against all versions
|
# Check against older versions
|
||||||
|
|
||||||
$ source admin-tools/check-older-versions.sh
|
$ source admin-tools/check-older-versions.sh
|
||||||
|
|
||||||
|
@@ -35,6 +35,7 @@ def test_grammar():
|
|||||||
expect_lhs.add("annotate_arg")
|
expect_lhs.add("annotate_arg")
|
||||||
expect_lhs.add("annotate_tuple")
|
expect_lhs.add("annotate_tuple")
|
||||||
unused_rhs.add("mkfunc_annotate")
|
unused_rhs.add("mkfunc_annotate")
|
||||||
|
unused_rhs.add('call')
|
||||||
if PYTHON_VERSION < 3.6:
|
if PYTHON_VERSION < 3.6:
|
||||||
# 3.6 has at least one non-custom call rule
|
# 3.6 has at least one non-custom call rule
|
||||||
# the others don't
|
# the others don't
|
||||||
@@ -47,8 +48,6 @@ def test_grammar():
|
|||||||
else:
|
else:
|
||||||
expect_right_recursive.add((('l_stmts',
|
expect_right_recursive.add((('l_stmts',
|
||||||
('lastl_stmt', 'COME_FROM', 'l_stmts'))))
|
('lastl_stmt', 'COME_FROM', 'l_stmts'))))
|
||||||
unused_rhs.add('build_map_unpack_with_call')
|
|
||||||
unused_rhs.add('unmapexpr')
|
|
||||||
# expect_lhs.add('kwargs1')
|
# expect_lhs.add('kwargs1')
|
||||||
pass
|
pass
|
||||||
pass
|
pass
|
||||||
|
@@ -29,7 +29,6 @@ class Python25Parser(Python26Parser):
|
|||||||
withstmt ::= expr setupwith SETUP_FINALLY suite_stmts_opt
|
withstmt ::= expr setupwith SETUP_FINALLY suite_stmts_opt
|
||||||
POP_BLOCK LOAD_CONST COME_FROM with_cleanup
|
POP_BLOCK LOAD_CONST COME_FROM with_cleanup
|
||||||
|
|
||||||
store ::= STORE_FAST
|
|
||||||
store ::= STORE_NAME
|
store ::= STORE_NAME
|
||||||
|
|
||||||
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
||||||
|
@@ -96,9 +96,6 @@ class Python3Parser(PythonParser):
|
|||||||
continues ::= lastl_stmt continue
|
continues ::= lastl_stmt continue
|
||||||
continues ::= continue
|
continues ::= continue
|
||||||
|
|
||||||
del_stmt ::= delete_subscr
|
|
||||||
delete_subscr ::= expr expr DELETE_SUBSCR
|
|
||||||
del_stmt ::= expr DELETE_ATTR
|
|
||||||
|
|
||||||
kwarg ::= LOAD_CONST expr
|
kwarg ::= LOAD_CONST expr
|
||||||
kwargs ::= kwarg*
|
kwargs ::= kwarg*
|
||||||
@@ -556,7 +553,8 @@ class Python3Parser(PythonParser):
|
|||||||
# include instructions that don't need customization,
|
# include instructions that don't need customization,
|
||||||
# but we'll do a finer check after the rough breakout.
|
# but we'll do a finer check after the rough breakout.
|
||||||
customize_instruction_basenames = frozenset(
|
customize_instruction_basenames = frozenset(
|
||||||
('BUILD', 'CALL', 'DELETE', 'JUMP', 'LOAD', 'LOOKUP', 'MAKE',
|
('BUILD', 'CALL', 'DELETE',
|
||||||
|
'JUMP', 'LOAD', 'LOOKUP', 'MAKE',
|
||||||
'RAISE', 'UNPACK'))
|
'RAISE', 'UNPACK'))
|
||||||
|
|
||||||
is_pypy = False
|
is_pypy = False
|
||||||
@@ -657,7 +655,8 @@ class Python3Parser(PythonParser):
|
|||||||
rule = ('build_map_unpack_with_call ::= ' + 'expr1024 ' * int(v//1024) +
|
rule = ('build_map_unpack_with_call ::= ' + 'expr1024 ' * int(v//1024) +
|
||||||
'expr32 ' * int((v//32) % 32) +
|
'expr32 ' * int((v//32) % 32) +
|
||||||
'expr ' * (v % 32) + opname)
|
'expr ' * (v % 32) + opname)
|
||||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
elif opname.startswith('BUILD_TUPLE_UNPACK_WITH_CALL'):
|
||||||
|
continue
|
||||||
elif opname_base in ('BUILD_LIST', 'BUILD_SET', 'BUILD_TUPLE'):
|
elif opname_base in ('BUILD_LIST', 'BUILD_SET', 'BUILD_TUPLE'):
|
||||||
v = token.attr
|
v = token.attr
|
||||||
|
|
||||||
@@ -694,14 +693,11 @@ class Python3Parser(PythonParser):
|
|||||||
'expr ::= build_slice3',
|
'expr ::= build_slice3',
|
||||||
'build_slice3 ::= expr expr expr BUILD_SLICE_3',
|
'build_slice3 ::= expr expr expr BUILD_SLICE_3',
|
||||||
], customize)
|
], customize)
|
||||||
elif opname.startswith('BUILD_TUPLE_UNPACK_WITH_CALL'):
|
elif (opname in frozenset(('CALL_FUNCTION',
|
||||||
v = token.attr
|
'CALL_FUNCTION_EX',
|
||||||
rule = ('build_tuple_unpack_with_call ::= ' + 'expr1024 ' * int(v//1024) +
|
'CALL_FUNCTION_EX_KW',
|
||||||
'expr32 ' * int((v//32) % 32) +
|
'CALL_FUNCTION_VAR',
|
||||||
'expr ' * (v % 32) + opname)
|
'CALL_FUNCTION_VAR_KW'))
|
||||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
|
||||||
elif (opname in ('CALL_FUNCTION', 'CALL_FUNCTION_VAR',
|
|
||||||
'CALL_FUNCTION_VAR_KW', 'CALL_FUNCTION_EX_KW')
|
|
||||||
or opname.startswith('CALL_FUNCTION_KW')):
|
or opname.startswith('CALL_FUNCTION_KW')):
|
||||||
self.custom_classfunc_rule(opname, token, customize,
|
self.custom_classfunc_rule(opname, token, customize,
|
||||||
seen_LOAD_BUILD_CLASS,
|
seen_LOAD_BUILD_CLASS,
|
||||||
@@ -718,11 +714,20 @@ class Python3Parser(PythonParser):
|
|||||||
('kwarg ' * args_kw) +
|
('kwarg ' * args_kw) +
|
||||||
'expr ' * nak + opname)
|
'expr ' * nak + opname)
|
||||||
self.add_unique_rule(rule, opname, token.attr, customize)
|
self.add_unique_rule(rule, opname, token.attr, customize)
|
||||||
|
elif opname == 'DELETE_ATTR':
|
||||||
|
self.addRule("""
|
||||||
|
del_stmt ::= expr DELETE_ATTR
|
||||||
|
""", nop_func)
|
||||||
elif opname == 'DELETE_DEREF':
|
elif opname == 'DELETE_DEREF':
|
||||||
self.addRule("""
|
self.addRule("""
|
||||||
stmt ::= del_deref_stmt
|
stmt ::= del_deref_stmt
|
||||||
del_deref_stmt ::= DELETE_DEREF
|
del_deref_stmt ::= DELETE_DEREF
|
||||||
""", nop_func)
|
""", nop_func)
|
||||||
|
elif opname == 'DELETE_SUBSCR':
|
||||||
|
self.addRule("""
|
||||||
|
del_stmt ::= delete_subscr
|
||||||
|
delete_subscr ::= expr expr DELETE_SUBSCR
|
||||||
|
""", nop_func)
|
||||||
elif opname == 'JUMP_IF_NOT_DEBUG':
|
elif opname == 'JUMP_IF_NOT_DEBUG':
|
||||||
v = token.attr
|
v = token.attr
|
||||||
self.addRule("""
|
self.addRule("""
|
||||||
|
@@ -27,7 +27,6 @@ class Python31Parser(Python32Parser):
|
|||||||
POP_BLOCK LOAD_CONST COME_FROM_FINALLY
|
POP_BLOCK LOAD_CONST COME_FROM_FINALLY
|
||||||
load del_stmt WITH_CLEANUP END_FINALLY
|
load del_stmt WITH_CLEANUP END_FINALLY
|
||||||
|
|
||||||
store ::= STORE_FAST
|
|
||||||
store ::= STORE_NAME
|
store ::= STORE_NAME
|
||||||
load ::= LOAD_FAST
|
load ::= LOAD_FAST
|
||||||
load ::= LOAD_NAME
|
load ::= LOAD_NAME
|
||||||
|
@@ -53,27 +53,7 @@ class Python35Parser(Python34Parser):
|
|||||||
POP_BLOCK LOAD_CONST COME_FROM_WITH
|
POP_BLOCK LOAD_CONST COME_FROM_WITH
|
||||||
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
|
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
|
||||||
|
|
||||||
|
|
||||||
# Python 3.5+ async additions
|
# Python 3.5+ async additions
|
||||||
|
|
||||||
stmt ::= async_with_stmt
|
|
||||||
async_with_stmt ::= expr
|
|
||||||
BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM
|
|
||||||
SETUP_ASYNC_WITH POP_TOP suite_stmts_opt
|
|
||||||
POP_BLOCK LOAD_CONST
|
|
||||||
WITH_CLEANUP_START
|
|
||||||
GET_AWAITABLE LOAD_CONST YIELD_FROM
|
|
||||||
WITH_CLEANUP_FINISH END_FINALLY
|
|
||||||
|
|
||||||
stmt ::= async_with_as_stmt
|
|
||||||
async_with_as_stmt ::= expr
|
|
||||||
BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM
|
|
||||||
SETUP_ASYNC_WITH store suite_stmts_opt
|
|
||||||
POP_BLOCK LOAD_CONST
|
|
||||||
WITH_CLEANUP_START
|
|
||||||
GET_AWAITABLE LOAD_CONST YIELD_FROM
|
|
||||||
WITH_CLEANUP_FINISH END_FINALLY
|
|
||||||
|
|
||||||
stmt ::= async_for_stmt
|
stmt ::= async_for_stmt
|
||||||
async_for_stmt ::= SETUP_LOOP expr
|
async_for_stmt ::= SETUP_LOOP expr
|
||||||
GET_AITER
|
GET_AITER
|
||||||
@@ -152,20 +132,57 @@ class Python35Parser(Python34Parser):
|
|||||||
nargs = token.attr % 256
|
nargs = token.attr % 256
|
||||||
map_unpack_n = "map_unpack_%s" % nargs
|
map_unpack_n = "map_unpack_%s" % nargs
|
||||||
rule = map_unpack_n + ' ::= ' + 'expr ' * (nargs)
|
rule = map_unpack_n + ' ::= ' + 'expr ' * (nargs)
|
||||||
print("XXXX", rule)
|
|
||||||
self.addRule(rule, nop_func)
|
self.addRule(rule, nop_func)
|
||||||
rule = "unmapexpr ::= %s %s" % (map_unpack_n, opname)
|
rule = "unmapexpr ::= %s %s" % (map_unpack_n, opname)
|
||||||
self.addRule(rule, nop_func)
|
self.addRule(rule, nop_func)
|
||||||
call_token = tokens[i+1]
|
call_token = tokens[i+1]
|
||||||
rule = 'call ::= expr unmapexpr ' + call_token.kind
|
rule = 'call ::= expr unmapexpr ' + call_token.kind
|
||||||
print("XXXX2", rule)
|
|
||||||
self.addRule(rule, nop_func)
|
self.addRule(rule, nop_func)
|
||||||
|
elif opname == 'BEFORE_ASYNC_WITH':
|
||||||
|
# Some Python 3.5+ async additions
|
||||||
|
rules_str = """
|
||||||
|
async_with_stmt ::= expr
|
||||||
|
stmt ::= async_with_stmt
|
||||||
|
|
||||||
|
async_with_stmt ::= expr
|
||||||
|
BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM
|
||||||
|
SETUP_ASYNC_WITH POP_TOP suite_stmts_opt
|
||||||
|
POP_BLOCK LOAD_CONST
|
||||||
|
WITH_CLEANUP_START
|
||||||
|
GET_AWAITABLE LOAD_CONST YIELD_FROM
|
||||||
|
WITH_CLEANUP_FINISH END_FINALLY
|
||||||
|
|
||||||
|
stmt ::= async_with_as_stmt
|
||||||
|
|
||||||
|
async_with_as_stmt ::= expr
|
||||||
|
BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM
|
||||||
|
SETUP_ASYNC_WITH store suite_stmts_opt
|
||||||
|
POP_BLOCK LOAD_CONST
|
||||||
|
WITH_CLEANUP_START
|
||||||
|
GET_AWAITABLE LOAD_CONST YIELD_FROM
|
||||||
|
WITH_CLEANUP_FINISH END_FINALLY
|
||||||
|
"""
|
||||||
|
self.addRule(rules_str, nop_func)
|
||||||
elif opname == 'BUILD_MAP_UNPACK':
|
elif opname == 'BUILD_MAP_UNPACK':
|
||||||
self.addRule("""
|
self.addRule("""
|
||||||
expr ::= unmap_dict
|
expr ::= unmap_dict
|
||||||
unmap_dict ::= dict_comp BUILD_MAP_UNPACK
|
unmap_dict ::= dict_comp BUILD_MAP_UNPACK
|
||||||
""", nop_func)
|
""", nop_func)
|
||||||
|
|
||||||
|
elif opname == 'SETUP_WITH':
|
||||||
|
# Python 3.5+ has WITH_CLEANUP_START/FINISH
|
||||||
|
rules_str = """
|
||||||
|
withstmt ::= expr
|
||||||
|
SETUP_WITH POP_TOP suite_stmts_opt
|
||||||
|
POP_BLOCK LOAD_CONST COME_FROM_WITH
|
||||||
|
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
|
||||||
|
|
||||||
|
withasstmt ::= expr
|
||||||
|
SETUP_WITH store suite_stmts_opt
|
||||||
|
POP_BLOCK LOAD_CONST COME_FROM_WITH
|
||||||
|
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
|
||||||
|
"""
|
||||||
|
self.addRule(rules_str, nop_func)
|
||||||
pass
|
pass
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
spark grammar differences over Python 3.5 for Python 3.6.
|
spark grammar differences over Python 3.5 for Python 3.6.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from uncompyle6.parser import PythonParserSingle
|
from uncompyle6.parser import PythonParserSingle, nop_func
|
||||||
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
||||||
from uncompyle6.parsers.parse35 import Python35Parser
|
from uncompyle6.parsers.parse35 import Python35Parser
|
||||||
|
|
||||||
@@ -26,16 +26,6 @@ class Python36Parser(Python35Parser):
|
|||||||
return_if_lambda ::= RETURN_END_IF_LAMBDA
|
return_if_lambda ::= RETURN_END_IF_LAMBDA
|
||||||
|
|
||||||
|
|
||||||
func_args36 ::= expr BUILD_TUPLE_0
|
|
||||||
call ::= func_args36 unmapexpr CALL_FUNCTION_EX
|
|
||||||
call ::= func_args36 build_map_unpack_with_call CALL_FUNCTION_EX_KW_1
|
|
||||||
|
|
||||||
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST
|
|
||||||
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
|
|
||||||
|
|
||||||
call ::= expr expr CALL_FUNCTION_EX
|
|
||||||
call ::= expr expr expr CALL_FUNCTION_EX_KW_1
|
|
||||||
|
|
||||||
for_block ::= l_stmts_opt come_from_loops JUMP_BACK
|
for_block ::= l_stmts_opt come_from_loops JUMP_BACK
|
||||||
come_from_loops ::= COME_FROM_LOOP*
|
come_from_loops ::= COME_FROM_LOOP*
|
||||||
|
|
||||||
@@ -45,23 +35,6 @@ class Python36Parser(Python35Parser):
|
|||||||
|
|
||||||
# Adds a COME_FROM_ASYNC_WITH over 3.5
|
# Adds a COME_FROM_ASYNC_WITH over 3.5
|
||||||
# FIXME: remove corresponding rule for 3.5?
|
# FIXME: remove corresponding rule for 3.5?
|
||||||
async_with_as_stmt ::= expr
|
|
||||||
BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM
|
|
||||||
SETUP_ASYNC_WITH store
|
|
||||||
suite_stmts_opt
|
|
||||||
POP_BLOCK LOAD_CONST
|
|
||||||
COME_FROM_ASYNC_WITH
|
|
||||||
WITH_CLEANUP_START
|
|
||||||
GET_AWAITABLE LOAD_CONST YIELD_FROM
|
|
||||||
WITH_CLEANUP_FINISH END_FINALLY
|
|
||||||
async_with_stmt ::= expr
|
|
||||||
BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM
|
|
||||||
SETUP_ASYNC_WITH POP_TOP suite_stmts_opt
|
|
||||||
POP_BLOCK LOAD_CONST
|
|
||||||
COME_FROM_ASYNC_WITH
|
|
||||||
WITH_CLEANUP_START
|
|
||||||
GET_AWAITABLE LOAD_CONST YIELD_FROM
|
|
||||||
WITH_CLEANUP_FINISH END_FINALLY
|
|
||||||
|
|
||||||
except_suite ::= c_stmts_opt COME_FROM POP_EXCEPT jump_except COME_FROM
|
except_suite ::= c_stmts_opt COME_FROM POP_EXCEPT jump_except COME_FROM
|
||||||
|
|
||||||
@@ -89,6 +62,30 @@ class Python36Parser(Python35Parser):
|
|||||||
fstring_single ::= expr FORMAT_VALUE
|
fstring_single ::= expr FORMAT_VALUE
|
||||||
"""
|
"""
|
||||||
self.add_unique_doc_rules(rules_str, customize)
|
self.add_unique_doc_rules(rules_str, customize)
|
||||||
|
elif opname == 'BEFORE_ASYNC_WITH':
|
||||||
|
rules_str = """
|
||||||
|
stmt ::= async_with_stmt
|
||||||
|
async_with_as_stmt ::= expr
|
||||||
|
BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM
|
||||||
|
SETUP_ASYNC_WITH store
|
||||||
|
suite_stmts_opt
|
||||||
|
POP_BLOCK LOAD_CONST
|
||||||
|
COME_FROM_ASYNC_WITH
|
||||||
|
WITH_CLEANUP_START
|
||||||
|
GET_AWAITABLE LOAD_CONST YIELD_FROM
|
||||||
|
WITH_CLEANUP_FINISH END_FINALLY
|
||||||
|
stmt ::= async_with_as_stmt
|
||||||
|
async_with_stmt ::= expr
|
||||||
|
BEFORE_ASYNC_WITH GET_AWAITABLE LOAD_CONST YIELD_FROM
|
||||||
|
SETUP_ASYNC_WITH POP_TOP suite_stmts_opt
|
||||||
|
POP_BLOCK LOAD_CONST
|
||||||
|
COME_FROM_ASYNC_WITH
|
||||||
|
WITH_CLEANUP_START
|
||||||
|
GET_AWAITABLE LOAD_CONST YIELD_FROM
|
||||||
|
WITH_CLEANUP_FINISH END_FINALLY
|
||||||
|
"""
|
||||||
|
self.addRule(rules_str, nop_func)
|
||||||
|
|
||||||
elif opname == 'BUILD_STRING':
|
elif opname == 'BUILD_STRING':
|
||||||
v = token.attr
|
v = token.attr
|
||||||
joined_str_n = "formatted_value_%s" % v
|
joined_str_n = "formatted_value_%s" % v
|
||||||
@@ -106,16 +103,53 @@ class Python36Parser(Python35Parser):
|
|||||||
%s ::= %sBUILD_STRING
|
%s ::= %sBUILD_STRING
|
||||||
""" % (joined_str_n, joined_str_n, "formatted_value " * v)
|
""" % (joined_str_n, joined_str_n, "formatted_value " * v)
|
||||||
self.add_unique_doc_rules(rules_str, customize)
|
self.add_unique_doc_rules(rules_str, customize)
|
||||||
|
elif opname.startswith('BUILD_MAP_UNPACK_WITH_CALL'):
|
||||||
|
v = token.attr
|
||||||
|
rule = ('build_map_unpack_with_call ::= ' + 'expr1024 ' * int(v//1024) +
|
||||||
|
'expr32 ' * int((v//32) % 32) +
|
||||||
|
'expr ' * (v % 32) + opname)
|
||||||
|
self.addRule(rule, nop_func)
|
||||||
|
elif opname.startswith('BUILD_TUPLE_UNPACK_WITH_CALL'):
|
||||||
|
v = token.attr
|
||||||
|
rule = ('build_tuple_unpack_with_call ::= ' + 'expr1024 ' * int(v//1024) +
|
||||||
|
'expr32 ' * int((v//32) % 32) +
|
||||||
|
'expr ' * (v % 32) + opname)
|
||||||
|
self.addRule(rule, nop_func)
|
||||||
|
elif opname == 'SETUP_WITH':
|
||||||
|
rules_str = """
|
||||||
|
withstmt ::= expr SETUP_WITH POP_TOP suite_stmts_opt POP_BLOCK LOAD_CONST
|
||||||
|
WITH_CLEANUP_START WITH_CLEANUP_FINISH END_FINALLY
|
||||||
|
"""
|
||||||
|
self.addRule(rules_str, nop_func)
|
||||||
|
|
||||||
def custom_classfunc_rule(self, opname, token, customize,
|
def custom_classfunc_rule(self, opname, token, customize,
|
||||||
possible_class_decorator,
|
possible_class_decorator,
|
||||||
seen_GET_AWAITABLE_YIELD_FROM, next_token):
|
seen_GET_AWAITABLE_YIELD_FROM, next_token):
|
||||||
if opname.startswith('CALL_FUNCTION_KW'):
|
if opname.startswith('CALL_FUNCTION_KW'):
|
||||||
|
self.addRule("expr ::= call_kw", nop_func)
|
||||||
values = 'expr ' * token.attr
|
values = 'expr ' * token.attr
|
||||||
rule = 'call ::= expr kwargs_only_36 {token.kind}'.format(**locals())
|
rule = 'call_kw ::= expr kwargs_36 {token.kind}'.format(**locals())
|
||||||
self.add_unique_rule(rule, token.kind, token.attr, customize)
|
self.addRule(rule, nop_func)
|
||||||
rule = 'kwargs_only_36 ::= {values} LOAD_CONST'.format(**locals())
|
rule = 'kwargs_36 ::= {values} LOAD_CONST'.format(**locals())
|
||||||
self.add_unique_rule(rule, token.kind, token.attr, customize)
|
self.add_unique_rule(rule, token.kind, token.attr, customize)
|
||||||
|
elif opname == 'CALL_FUNCTION_EX_KW':
|
||||||
|
self.addRule("""expr ::= call_ex_kw
|
||||||
|
expr ::= call_ex_kw2
|
||||||
|
call_ex_kw ::= expr expr build_map_unpack_with_call
|
||||||
|
CALL_FUNCTION_EX_KW
|
||||||
|
call_ex_kw2 ::= expr
|
||||||
|
build_tuple_unpack_with_call
|
||||||
|
build_map_unpack_with_call
|
||||||
|
CALL_FUNCTION_EX_KW
|
||||||
|
""",
|
||||||
|
nop_func)
|
||||||
|
elif opname == 'CALL_FUNCTION_EX':
|
||||||
|
self.addRule("""
|
||||||
|
expr ::= call_ex
|
||||||
|
unpack_list ::= list
|
||||||
|
call_ex ::= expr unpack_list CALL_FUNCTION_EX
|
||||||
|
""", nop_func)
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
super(Python36Parser, self).custom_classfunc_rule(opname, token,
|
super(Python36Parser, self).custom_classfunc_rule(opname, token,
|
||||||
customize,
|
customize,
|
||||||
@@ -123,7 +157,6 @@ class Python36Parser(Python35Parser):
|
|||||||
seen_GET_AWAITABLE_YIELD_FROM,
|
seen_GET_AWAITABLE_YIELD_FROM,
|
||||||
next_token)
|
next_token)
|
||||||
|
|
||||||
|
|
||||||
class Python36ParserSingle(Python36Parser, PythonParserSingle):
|
class Python36ParserSingle(Python36Parser, PythonParserSingle):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@@ -33,8 +33,6 @@ class Scanner36(Scanner3):
|
|||||||
pass
|
pass
|
||||||
elif t.op == self.opc.CALL_FUNCTION_KW:
|
elif t.op == self.opc.CALL_FUNCTION_KW:
|
||||||
t.kind = 'CALL_FUNCTION_KW_{t.attr}'.format(**locals())
|
t.kind = 'CALL_FUNCTION_KW_{t.attr}'.format(**locals())
|
||||||
elif t.op == self.opc.BUILD_TUPLE_UNPACK_WITH_CALL:
|
|
||||||
t.kind = 'BUILD_TUPLE_UNPACK_WITH_CALL_%d' % t.attr
|
|
||||||
elif t.op == self.opc.BUILD_MAP_UNPACK_WITH_CALL:
|
elif t.op == self.opc.BUILD_MAP_UNPACK_WITH_CALL:
|
||||||
t.kind = 'BUILD_MAP_UNPACK_WITH_CALL_%d' % t.attr
|
t.kind = 'BUILD_MAP_UNPACK_WITH_CALL_%d' % t.attr
|
||||||
pass
|
pass
|
||||||
|
@@ -127,6 +127,28 @@ def print_docstring(self, indent, docstring):
|
|||||||
self.println(indent, trimmed[-1], quote)
|
self.println(indent, trimmed[-1], quote)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def flatten_list(node):
|
||||||
|
"""
|
||||||
|
List of expressions may be nested in groups of 32 and 1024
|
||||||
|
items. flatten that out and return the list
|
||||||
|
"""
|
||||||
|
flat_elems = []
|
||||||
|
for elem in node:
|
||||||
|
if elem == 'expr1024':
|
||||||
|
for subelem in elem:
|
||||||
|
for subsubelem in subelem:
|
||||||
|
flat_elems.append(subsubelem)
|
||||||
|
elif elem == 'expr32':
|
||||||
|
for subelem in elem:
|
||||||
|
flat_elems.append(subelem)
|
||||||
|
else:
|
||||||
|
flat_elems.append(elem)
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
return flat_elems
|
||||||
|
|
||||||
|
|
||||||
# if __name__ == '__main__':
|
# if __name__ == '__main__':
|
||||||
# if PYTHON3:
|
# if PYTHON3:
|
||||||
# from io import StringIO
|
# from io import StringIO
|
||||||
|
@@ -127,7 +127,7 @@ from uncompyle6.semantics.make_function import (
|
|||||||
from uncompyle6.semantics.parser_error import ParserError
|
from uncompyle6.semantics.parser_error import ParserError
|
||||||
from uncompyle6.semantics.check_ast import checker
|
from uncompyle6.semantics.check_ast import checker
|
||||||
from uncompyle6.semantics.helper import (
|
from uncompyle6.semantics.helper import (
|
||||||
print_docstring, find_globals)
|
print_docstring, find_globals, flatten_list)
|
||||||
from uncompyle6.scanners.tok import Token
|
from uncompyle6.scanners.tok import Token
|
||||||
|
|
||||||
from uncompyle6.semantics.consts import (
|
from uncompyle6.semantics.consts import (
|
||||||
@@ -439,12 +439,8 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
# 'unmapexpr': ( '{**%c}', 0), # done by n_unmapexpr
|
# 'unmapexpr': ( '{**%c}', 0), # done by n_unmapexpr
|
||||||
|
|
||||||
})
|
})
|
||||||
if version >= 3.6:
|
|
||||||
TABLE_DIRECT.update({
|
|
||||||
'try_except36': ( '%|try:\n%+%c%-%c\n\n', 1, 2 ),
|
|
||||||
})
|
|
||||||
|
|
||||||
def n_async_call(node):
|
def async_call(node):
|
||||||
self.f.write('async ')
|
self.f.write('async ')
|
||||||
node.kind == 'call'
|
node.kind == 'call'
|
||||||
p = self.prec
|
p = self.prec
|
||||||
@@ -454,7 +450,7 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
self.prec = p
|
self.prec = p
|
||||||
node.kind == 'async_call'
|
node.kind == 'async_call'
|
||||||
self.prune()
|
self.prune()
|
||||||
self.n_async_call = n_async_call
|
self.n_async_call = async_call
|
||||||
self.n_build_list_unpack = self.n_list
|
self.n_build_list_unpack = self.n_list
|
||||||
|
|
||||||
if version == 3.5:
|
if version == 3.5:
|
||||||
@@ -500,7 +496,7 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
self.prune()
|
self.prune()
|
||||||
self.n_function_def = n_function_def
|
self.n_function_def = n_function_def
|
||||||
|
|
||||||
def n_unmapexpr(node):
|
def unmapexpr(node):
|
||||||
last_n = node[0][-1]
|
last_n = node[0][-1]
|
||||||
for n in node[0]:
|
for n in node[0]:
|
||||||
self.preorder(n)
|
self.preorder(n)
|
||||||
@@ -510,40 +506,191 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
pass
|
pass
|
||||||
self.prune()
|
self.prune()
|
||||||
pass
|
pass
|
||||||
self.n_unmapexpr = n_unmapexpr
|
self.n_unmapexpr = unmapexpr
|
||||||
|
|
||||||
if version >= 3.6:
|
if version >= 3.6:
|
||||||
########################
|
########################
|
||||||
# Python 3.6+ Additions
|
# Python 3.6+ Additions
|
||||||
#######################
|
#######################
|
||||||
|
|
||||||
TABLE_DIRECT.update({
|
TABLE_DIRECT.update({
|
||||||
'fstring_expr': ( "{%c%{conversion}}", 0),
|
'fstring_expr': ( "{%c%{conversion}}", 0),
|
||||||
'fstring_single': ( "f'{%c%{conversion}}'", 0),
|
'fstring_single': ( "f'{%c%{conversion}}'", 0),
|
||||||
'fstring_multi': ( "f'%c'", 0),
|
'fstring_multi': ( "f'%c'", 0),
|
||||||
'func_args36': ( "%c(**", 0),
|
'func_args36': ( "%c(**", 0),
|
||||||
#'kwargs_only_36': ( "%c(**", 0),
|
'try_except36': ( '%|try:\n%+%c%-%c\n\n', 1, 2 ),
|
||||||
|
'unpack_list': ( '*%c', (0, 'list') ),
|
||||||
|
'call_ex' : (
|
||||||
|
'%c(%c)',
|
||||||
|
(0, 'expr'), 1),
|
||||||
|
'call_ex_kw' : (
|
||||||
|
'%c(%c)',
|
||||||
|
(0, 'expr'), 2),
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
TABLE_R.update({
|
TABLE_R.update({
|
||||||
'CALL_FUNCTION_EX': ('%c(*%P)', 0, (1, 2, ', ', 100)),
|
'CALL_FUNCTION_EX': ('%c(*%P)', 0, (1, 2, ', ', 100)),
|
||||||
# Not quite right
|
# Not quite right
|
||||||
'CALL_FUNCTION_EX_KW': ('%c(**%C)', 0, (2,3, ',')),
|
'CALL_FUNCTION_EX_KW': ('%c(**%C)', 0, (2,3, ',')),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def build_unpack_tuple_with_call(node):
|
||||||
|
|
||||||
|
if node[0] == 'expr':
|
||||||
|
tup = node[0][0]
|
||||||
|
else:
|
||||||
|
tup = node[0]
|
||||||
|
pass
|
||||||
|
assert tup == 'tuple'
|
||||||
|
self.call36_tuple(tup)
|
||||||
|
|
||||||
|
buwc = node[-1]
|
||||||
|
assert buwc.kind.startswith('BUILD_TUPLE_UNPACK_WITH_CALL')
|
||||||
|
for n in node[1:-1]:
|
||||||
|
self.f.write(', *')
|
||||||
|
self.preorder(n)
|
||||||
|
pass
|
||||||
|
self.prune()
|
||||||
|
return
|
||||||
|
self.n_build_tuple_unpack_with_call = build_unpack_tuple_with_call
|
||||||
|
|
||||||
|
def build_unpack_map_with_call(node):
|
||||||
|
sep = '**'
|
||||||
|
for n in node[:-1]:
|
||||||
|
self.f.write(sep)
|
||||||
|
self.preorder(n)
|
||||||
|
sep = ', **'
|
||||||
|
pass
|
||||||
|
self.prune()
|
||||||
|
return
|
||||||
|
self.n_build_map_unpack_with_call = build_unpack_map_with_call
|
||||||
|
|
||||||
|
def call_ex_kw2(node):
|
||||||
|
# This is weird shit. Thanks Python!
|
||||||
|
self.preorder(node[0])
|
||||||
|
self.write('(')
|
||||||
|
|
||||||
|
assert node[1] == 'build_tuple_unpack_with_call'
|
||||||
|
btuwc = node[1]
|
||||||
|
tup = btuwc[0]
|
||||||
|
if tup == 'expr':
|
||||||
|
tup = tup[0]
|
||||||
|
assert tup == 'tuple'
|
||||||
|
self.call36_tuple(tup)
|
||||||
|
assert node[2] == 'build_map_unpack_with_call'
|
||||||
|
|
||||||
|
self.write(', ')
|
||||||
|
d = node[2][0]
|
||||||
|
if d == 'expr':
|
||||||
|
d = d[0]
|
||||||
|
assert d == 'dict'
|
||||||
|
self.call36_dict(d)
|
||||||
|
|
||||||
|
args = btuwc[1]
|
||||||
|
self.write(', *')
|
||||||
|
self.preorder(args)
|
||||||
|
|
||||||
|
self.write(', **')
|
||||||
|
star_star_args = node[2][1]
|
||||||
|
if star_star_args == 'expr':
|
||||||
|
star_star_args = star_star_args[0]
|
||||||
|
self.preorder(star_star_args)
|
||||||
|
self.write(')')
|
||||||
|
self.prune()
|
||||||
|
self.n_call_ex_kw2 = call_ex_kw2
|
||||||
|
|
||||||
|
def call36_tuple(node):
|
||||||
|
"""
|
||||||
|
A tuple used in a call, these are like normal tuples but they
|
||||||
|
don't have the enclosing parenthesis.
|
||||||
|
"""
|
||||||
|
assert node == 'tuple'
|
||||||
|
# Note: don't iterate over last element which is a
|
||||||
|
# BUILD_TUPLE...
|
||||||
|
flat_elems = flatten_list(node[:-1])
|
||||||
|
|
||||||
|
self.indent_more(INDENT_PER_LEVEL)
|
||||||
|
sep = ''
|
||||||
|
|
||||||
|
for elem in flat_elems:
|
||||||
|
if elem in ('ROT_THREE', 'EXTENDED_ARG'):
|
||||||
|
continue
|
||||||
|
assert elem == 'expr'
|
||||||
|
line_number = self.line_number
|
||||||
|
value = self.traverse(elem)
|
||||||
|
if line_number != self.line_number:
|
||||||
|
sep += '\n' + self.indent + INDENT_PER_LEVEL[:-1]
|
||||||
|
self.write(sep, value)
|
||||||
|
sep = ', '
|
||||||
|
|
||||||
|
self.indent_less(INDENT_PER_LEVEL)
|
||||||
|
return
|
||||||
|
self.call36_tuple = call36_tuple
|
||||||
|
|
||||||
|
def call36_dict(node):
|
||||||
|
"""
|
||||||
|
A dict used in a call_ex_kw2, which are a dictionary items expressed
|
||||||
|
in a call. This should format to:
|
||||||
|
a=1, b=2
|
||||||
|
In other words, no braces, no quotes around keys and ":" becomes
|
||||||
|
"=".
|
||||||
|
|
||||||
|
We will source-code use line breaks to guide us when to break.
|
||||||
|
"""
|
||||||
|
p = self.prec
|
||||||
|
self.prec = 100
|
||||||
|
|
||||||
|
self.indent_more(INDENT_PER_LEVEL)
|
||||||
|
sep = INDENT_PER_LEVEL[:-1]
|
||||||
|
line_number = self.line_number
|
||||||
|
|
||||||
|
assert node[0].kind.startswith('kvlist')
|
||||||
|
# Python 3.5+ style key/value list in dict
|
||||||
|
kv_node = node[0]
|
||||||
|
l = list(kv_node)
|
||||||
|
i = 0
|
||||||
|
# Respect line breaks from source
|
||||||
|
while i < len(l):
|
||||||
|
self.write(sep)
|
||||||
|
name = self.traverse(l[i], indent='')
|
||||||
|
# Strip off beginning and trailing quotes in name
|
||||||
|
name = name[1:-1]
|
||||||
|
if i > 0:
|
||||||
|
line_number = self.indent_if_source_nl(line_number,
|
||||||
|
self.indent + INDENT_PER_LEVEL[:-1])
|
||||||
|
line_number = self.line_number
|
||||||
|
self.write(name, '=')
|
||||||
|
value = self.traverse(l[i+1], indent=self.indent+(len(name)+2)*' ')
|
||||||
|
self.write(value)
|
||||||
|
sep = ","
|
||||||
|
if line_number != self.line_number:
|
||||||
|
sep += "\n" + self.indent + INDENT_PER_LEVEL[:-1]
|
||||||
|
line_number = self.line_number
|
||||||
|
i += 2
|
||||||
|
pass
|
||||||
|
self.prec = p
|
||||||
|
self.indent_less(INDENT_PER_LEVEL)
|
||||||
|
return
|
||||||
|
self.call36_dict = call36_dict
|
||||||
|
|
||||||
|
|
||||||
FSTRING_CONVERSION_MAP = {1: '!s', 2: '!r', 3: '!a'}
|
FSTRING_CONVERSION_MAP = {1: '!s', 2: '!r', 3: '!a'}
|
||||||
|
|
||||||
def f_conversion(node):
|
def f_conversion(node):
|
||||||
node.conversion = FSTRING_CONVERSION_MAP.get(node.data[1].attr, '')
|
node.conversion = FSTRING_CONVERSION_MAP.get(node.data[1].attr, '')
|
||||||
|
|
||||||
def n_fstring_expr(node):
|
def fstring_expr(node):
|
||||||
f_conversion(node)
|
f_conversion(node)
|
||||||
self.default(node)
|
self.default(node)
|
||||||
self.n_fstring_expr = n_fstring_expr
|
self.n_fstring_expr = fstring_expr
|
||||||
|
|
||||||
def n_fstring_single(node):
|
def fstring_single(node):
|
||||||
f_conversion(node)
|
f_conversion(node)
|
||||||
self.default(node)
|
self.default(node)
|
||||||
self.n_fstring_single = n_fstring_single
|
self.n_fstring_single = fstring_single
|
||||||
|
|
||||||
def n_kwargs_only_36(node):
|
def kwargs_only_36(node):
|
||||||
keys = node[-1].attr
|
keys = node[-1].attr
|
||||||
num_kwargs = len(keys)
|
num_kwargs = len(keys)
|
||||||
values = node[:num_kwargs]
|
values = node[:num_kwargs]
|
||||||
@@ -554,13 +701,13 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
self.write(',')
|
self.write(',')
|
||||||
self.prune()
|
self.prune()
|
||||||
return
|
return
|
||||||
self.n_kwargs_only_36 = n_kwargs_only_36
|
self.n_kwargs_only_36 = kwargs_only_36
|
||||||
|
|
||||||
def n_return_closure(node):
|
def return_closure(node):
|
||||||
# Nothing should be output here
|
# Nothing should be output here
|
||||||
self.prune()
|
self.prune()
|
||||||
return
|
return
|
||||||
self.n_return_closure = n_return_closure
|
self.n_return_closure = return_closure
|
||||||
pass # version > 3.6
|
pass # version > 3.6
|
||||||
pass # version > 3.4
|
pass # version > 3.4
|
||||||
pass # version > 3.0
|
pass # version > 3.0
|
||||||
@@ -1867,21 +2014,10 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
else:
|
else:
|
||||||
raise TypeError('Internal Error: n_build_list expects list, tuple, set, or unpack')
|
raise TypeError('Internal Error: n_build_list expects list, tuple, set, or unpack')
|
||||||
|
|
||||||
flat_elems = []
|
flat_elems = flatten_list(node)
|
||||||
for elem in node:
|
|
||||||
if elem == 'expr1024':
|
|
||||||
for subelem in elem:
|
|
||||||
for subsubelem in subelem:
|
|
||||||
flat_elems.append(subsubelem)
|
|
||||||
elif elem == 'expr32':
|
|
||||||
for subelem in elem:
|
|
||||||
flat_elems.append(subelem)
|
|
||||||
else:
|
|
||||||
flat_elems.append(elem)
|
|
||||||
|
|
||||||
self.indent_more(INDENT_PER_LEVEL)
|
self.indent_more(INDENT_PER_LEVEL)
|
||||||
sep = ''
|
sep = ''
|
||||||
|
|
||||||
for elem in flat_elems:
|
for elem in flat_elems:
|
||||||
if elem in ('ROT_THREE', 'EXTENDED_ARG'):
|
if elem in ('ROT_THREE', 'EXTENDED_ARG'):
|
||||||
continue
|
continue
|
||||||
@@ -1905,6 +2041,7 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
self.write(',')
|
self.write(',')
|
||||||
self.write(endchar)
|
self.write(endchar)
|
||||||
self.indent_less(INDENT_PER_LEVEL)
|
self.indent_less(INDENT_PER_LEVEL)
|
||||||
|
|
||||||
self.prec = p
|
self.prec = p
|
||||||
self.prune()
|
self.prune()
|
||||||
return
|
return
|
||||||
|
Reference in New Issue
Block a user