Merge branch 'master' of github.com:rocky/python-uncompyle6

This commit is contained in:
rocky
2016-12-09 21:13:31 -05:00
18 changed files with 134 additions and 32 deletions

101
ChangeLog
View File

@@ -1,6 +1,105 @@
2016-12-04 rocky <rb@dustyfeet.com>
* uncompyle6/version.py: Get ready for release 2.9.7
2016-11-28 rocky <rb@dustyfeet.com>
* uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse36.py:
Shorten Python3 grammars with + and *
2016-11-28 rocky <rb@dustyfeet.com>
* __pkginfo__.py, uncompyle6/parser.py,
uncompyle6/parsers/parse2.py: Try new spark 2.5.1 grammar syntax
shortcuts This package I now declare stable
2016-11-28 R. Bernstein <rocky@users.noreply.github.com>
* README.rst: Update README.rst
2016-11-27 rocky <rb@dustyfeet.com>
* README.rst: Limitations of decompiling control structures.
2016-11-27 R. Bernstein <rocky@users.noreply.github.com>
* : Merge pull request #69 from rocky/ast-reduce-checks AST reduce checks
2016-11-26 rocky <rb@dustyfeet.com>
* test/simple_source/bug26/03_elif_vs_continue.py,
uncompyle6/main.py, uncompyle6/parser.py,
uncompyle6/parsers/parse2.py, uncompyle6/scanners/scanner2.py,
uncompyle6/scanners/scanner26.py: Misc changes scanner26.py: make scanner2.py and scanner26.py more alike
scanner2.py: check that return stmt is last in list. (May change)
main.py: show filename on verify error test/*: add more
2016-11-25 rocky <rb@dustyfeet.com>
* __pkginfo__.py, test/Makefile, uncompyle6/parser.py,
uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse3.py: Start
grammar reduction checks
2016-11-24 rocky <rb@dustyfeet.com>
* uncompyle6/parsers/parse27.py, uncompyle6/scanners/scanner2.py,
uncompyle6/semantics/helper.py, uncompyle6/semantics/pysource.py:
2.7 grammar bug workaround. Fix docstring bug
2016-11-24 rocky <rb@dustyfeet.com>
* uncompyle6/semantics/pysource.py: Better line number tracking Indent Python 2 list comprehensions, albeit badly. DRY code a
little via indent_if_source_nl
2016-11-24 rocky <rb@dustyfeet.com>
* uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner2.py:
<2.7 "if" detection and dup Python 3 grammar rule
2016-11-23 rocky <rb@dustyfeet.com>
* __pkginfo__.py, pytest/test_grammar.py, uncompyle6/parser.py,
uncompyle6/parsers/parse26.py: Python 2.6 grammary bug and.. __pkginfo.py__: Bump spark_parser version for parse_flags 'dups'
2016-11-23 rocky <rb@dustyfeet.com>
* __pkginfo__.py: Note that we now work on 2.4 and 2.5
2016-11-23 rocky <rb@dustyfeet.com>
* : commit 6aa1531972de83ecab15b4c96b89c873ea5a7458 Author: rocky
<rb@dustyfeet.com> Date: Wed Nov 23 00:48:38 2016 -0500
2016-11-22 rocky <rb@dustyfeet.com>
* uncompyle6/parsers/parse3.py, uncompyle6/parsers/parse32.py,
uncompyle6/parsers/parse33.py, uncompyle6/parsers/parse34.py,
uncompyle6/parsers/parse35.py: DRY Python3 grammar
2016-11-22 rocky <rb@dustyfeet.com>
* uncompyle6/parsers/parse2.py, uncompyle6/parsers/parse27.py,
uncompyle6/scanners/scanner2.py: More detailed COME_FROMs For now we only add COME_FROM_FINALLY and COME_FROM_WITH and even
here only on 2.7
2016-11-22 rocky <rb@dustyfeet.com>
* circle.yml, pytest/test_grammar.py, tox.ini,
uncompyle6/parser.py, uncompyle6/parsers/parse2.py,
uncompyle6/parsers/parse27.py: Remove redundant 2.7 (and 2.x)
grammar rules
2016-11-22 rocky <rb@dustyfeet.com>
* pytest/test_docstring.py, uncompyle6/linenumbers.py,
uncompyle6/semantics/fragments.py, uncompyle6/semantics/helper.py,
uncompyle6/semantics/make_function.py,
uncompyle6/semantics/pysource.py: Split out print_docstring move from pysource.py to new helper.py
2016-11-20 rocky <rb@dustyfeet.com>
* uncompyle6/version.py: Get ready for release 2.9.6
* ChangeLog, NEWS, uncompyle6/version.py: Get ready for release
2.9.6
2016-11-20 R. Bernstein <rocky@users.noreply.github.com>

8
NEWS
View File

@@ -1,3 +1,11 @@
uncompyle6 2.9.6 2016-12-04
- Shorten Python3 grammars with + and *
this requires spark parser 1.5.1
- Add some AST reduction checks to improve
decompile accuracy. This too requires
spark parser 1.5.1
uncompyle6 2.9.6 2016-11-20
- Correct MANIFEST.in

View File

@@ -49,7 +49,6 @@ def uncompyle(
raise pysource.SourceWalkerError(str(e))
def uncompyle_file(filename, outstream=None, showasm=None, showast=False,
showgrammar=False):
"""
@@ -61,7 +60,6 @@ def uncompyle_file(filename, outstream=None, showasm=None, showast=False,
(version, timestamp, magic_int, co, is_pypy,
source_size) = load_module(filename, code_objects)
if type(co) == list:
for con in co:
uncompyle(version, con, outstream, showasm, showast,

View File

@@ -136,9 +136,9 @@ class PythonParser(GenericASTBuilder):
# print >> sys.stderr, 'resolve', str(list)
return GenericASTBuilder.resolve(self, list)
##############################################
## Common Python 2 and Python 3 grammar rules
##############################################
###############################################
# Common Python 2 and Python 3 grammar rules #
###############################################
def p_start(self, args):
'''
# The start or goal symbol

View File

@@ -13,7 +13,6 @@ class Python26Parser(Python2Parser):
super(Python26Parser, self).__init__(debug_parser)
self.customized = {}
def p_try_except26(self, args):
"""
except_stmt ::= except_cond3 except_suite
@@ -246,8 +245,8 @@ if __name__ == '__main__':
""".split()))
remain_tokens = set(tokens) - opcode_set
import re
remain_tokens = set([re.sub('_\d+$','', t) for t in remain_tokens])
remain_tokens = set([re.sub('_CONT$','', t) for t in remain_tokens])
remain_tokens = set([re.sub('_\d+$', '', t) for t in remain_tokens])
remain_tokens = set([re.sub('_CONT$', '', t) for t in remain_tokens])
remain_tokens = set(remain_tokens) - opcode_set
print(remain_tokens)
# print(sorted(p.rule2name.items()))

View File

@@ -249,7 +249,6 @@ class Python3Parser(PythonParser):
c_stmts_opt34 ::= JUMP_BACK JUMP_ABSOLUTE c_stmts_opt
"""
def p_def_annotations3(self, args):
"""
# Annotated functions
@@ -443,10 +442,10 @@ class Python3Parser(PythonParser):
args_kw = (token.attr >> 8) & 0xff
nak = ( len(opname)-len('CALL_FUNCTION') ) // 3
token.type = self.call_fn_name(token)
rule = ('call_function ::= expr '
+ ('pos_arg ' * args_pos)
+ ('kwarg ' * args_kw)
+ 'expr ' * nak + token.type)
rule = ('call_function ::= expr ' +
('pos_arg ' * args_pos) +
('kwarg ' * args_kw) +
'expr ' * nak + token.type)
self.add_unique_rule(rule, token.type, args_pos, customize)
rule = ('classdefdeco2 ::= LOAD_BUILD_CLASS mkfunc %s%s_%d'
% (('expr ' * (args_pos-1)), opname, args_pos))
@@ -638,10 +637,10 @@ class Python3Parser(PythonParser):
# number of apply equiv arguments:
nak = ( len(opname_base)-len('CALL_METHOD') ) // 3
rule = ('call_function ::= expr '
+ ('pos_arg ' * args_pos)
+ ('kwarg ' * args_kw)
+ 'expr ' * nak + opname)
rule = ('call_function ::= expr ' +
('pos_arg ' * args_pos) +
('kwarg ' * args_kw) +
'expr ' * nak + opname)
self.add_unique_rule(rule, opname, token.attr, customize)
elif opname.startswith('MAKE_CLOSURE'):
# DRY with MAKE_FUNCTION

View File

@@ -40,8 +40,8 @@ if __name__ == '__main__':
""".split()))
remain_tokens = set(tokens) - opcode_set
import re
remain_tokens = set([re.sub('_\d+$','', t) for t in remain_tokens])
remain_tokens = set([re.sub('_CONT$','', t) for t in remain_tokens])
remain_tokens = set([re.sub('_\d+$', '', t) for t in remain_tokens])
remain_tokens = set([re.sub('_CONT$', '', t) for t in remain_tokens])
remain_tokens = set(remain_tokens) - opcode_set
print(remain_tokens)
# print(sorted(p.rule2name.items()))

View File

@@ -66,8 +66,8 @@ if __name__ == '__main__':
""".split()))
remain_tokens = set(tokens) - opcode_set
import re
remain_tokens = set([re.sub('_\d+$','', t) for t in remain_tokens])
remain_tokens = set([re.sub('_CONT$','', t) for t in remain_tokens])
remain_tokens = set([re.sub('_\d+$', '', t) for t in remain_tokens])
remain_tokens = set([re.sub('_CONT$', '', t) for t in remain_tokens])
remain_tokens = set(remain_tokens) - opcode_set
print(remain_tokens)
# print(sorted(p.rule2name.items()))

View File

@@ -27,7 +27,8 @@ if PYTHON3:
intern = sys.intern
L65536 = 65536
def long(l): l
def long(l):
return l
else:
L65536 = long(65536) # NOQA

View File

@@ -902,7 +902,6 @@ class Scanner2(scan.Scanner):
pass
pass
# FIXME: All the < 2.7 conditions are is horrible. We need a better way.
if label is not None and label != -1:
# In Python < 2.7, the POP_TOP in:

View File

@@ -25,5 +25,5 @@ class Scanner23(scan.Scanner24):
# These are the only differences in initialization between
# 2.3-2.6
self.version = 2.3
self.genexpr_name = '<generator expression>';
self.genexpr_name = '<generator expression>'
return

View File

@@ -25,5 +25,5 @@ class Scanner24(scan.Scanner25):
self.opc = opcode_24
self.opname = opcode_24.opname
self.version = 2.4
self.genexpr_name = '<generator expression>';
self.genexpr_name = '<generator expression>'
return

View File

@@ -128,7 +128,6 @@ class Scanner3(Scanner):
varargs_ops.add(self.opc.CALL_METHOD)
self.varargs_ops = frozenset(varargs_ops)
def opName(self, offset):
return self.opc.opname[self.code[offset]]

View File

@@ -29,7 +29,7 @@ class Token:
self.pattr = pattr
self.offset = offset
self.linestart = linestart
if has_arg == False:
if has_arg is False:
self.attr = None
self.pattr = None
self.opc = opc

View File

@@ -38,7 +38,7 @@ def find_globals(node, globs):
def find_none(node):
for n in node:
if isinstance(n, AST):
if not n in ('return_stmt', 'return_if_stmt'):
if n not in ('return_stmt', 'return_if_stmt'):
if find_none(n):
return True
elif n.type == 'LOAD_CONST' and n.pattr is None:

View File

@@ -641,6 +641,7 @@ class SourceWalker(GenericASTTraversal, object):
})
FSTRING_CONVERSION_MAP = {1: '!s', 2: '!r', 3: '!a'}
def f_conversion(node):
node.conversion = FSTRING_CONVERSION_MAP.get(node.data[1].attr, '')
@@ -897,7 +898,6 @@ class SourceWalker(GenericASTTraversal, object):
pass
self.write(')')
def n_LOAD_CONST(self, node):
data = node.pattr; datatype = type(data)
if isinstance(datatype, int) and data == minint:

View File

@@ -317,7 +317,7 @@ def cmp_code_objects(version, is_pypy, code_obj1, code_obj2,
i2 += 2
continue
elif tokens1[i1].type == 'LOAD_NAME' and tokens2[i2].type == 'LOAD_CONST' \
and tokens1[i1].pattr == 'None' and tokens2[i2].pattr == None:
and tokens1[i1].pattr == 'None' and tokens2[i2].pattr is None:
pass
else:
raise CmpErrorCode(name, tokens1[i1].offset, tokens1[i1],

View File

@@ -1,3 +1,3 @@
# This file is suitable for sourcing inside bash as
# well as importing into Python
VERSION='2.9.6'
VERSION='2.9.7'