Compare commits

...

9 Commits

Author SHA1 Message Date
rocky
ab6d322eca Get ready for release 2.9.7 2016-12-04 14:09:53 -05:00
rocky
1a8a0df107 Merge branch 'master' into python-2.4 2016-12-04 13:40:06 -05:00
rocky
0a37709b0a CircleCI build 2016-11-24 05:41:31 -05:00
rocky
98cd1417df Remove dup Python 3 grammar rule 2016-11-24 05:36:43 -05:00
rocky
460069ceaa Bug in 2.4 "if" dectection and...
Wrong language used in old-style exceptions: use "except Error,e" not
"except Error(e)""
2016-11-24 05:15:35 -05:00
rocky
316aa44f23 Python 2.6 grammary bug and..
__pkginfo.py__: Bump spark_parser version for parse_flags 'dups'
2016-11-24 04:09:32 -05:00
rocky
7133540c23 Make work on 2.4 2016-11-23 08:26:12 -05:00
rocky
590231741d Merge branch 'come-from-type' into python-2.4 2016-11-23 07:54:18 -05:00
rocky
a9349b8f3d Making it run on Python 2.4 and 2.5 2016-11-23 07:53:51 -05:00
41 changed files with 238 additions and 325 deletions

View File

@@ -3,11 +3,7 @@ language: python
sudo: false sudo: false
python: python:
- '3.5' - '2.7' # this is a cheat here because travis doesn't do 2.4-2.6
- '2.7.12'
- '2.6'
- '3.3'
- '3.4'
install: install:
- pip install -r requirements.txt - pip install -r requirements.txt

View File

@@ -1,6 +1,7 @@
2016-12-04 rocky <rb@dustyfeet.com> 2016-12-04 rocky <rb@dustyfeet.com>
* uncompyle6/version.py: Get ready for release 2.9.7 * : commit d22931cb49f0e28a0fbe48a7c1526b1f170a5b52 Author: rocky
<rb@dustyfeet.com> Date: Sun Dec 4 07:31:34 2016 -0500
2016-11-28 rocky <rb@dustyfeet.com> 2016-11-28 rocky <rb@dustyfeet.com>
@@ -51,11 +52,34 @@
* uncompyle6/semantics/pysource.py: Better line number tracking Indent Python 2 list comprehensions, albeit badly. DRY code a * uncompyle6/semantics/pysource.py: Better line number tracking Indent Python 2 list comprehensions, albeit badly. DRY code a
little via indent_if_source_nl little via indent_if_source_nl
2016-11-24 rocky <rb@dustyfeet.com>
* circle.yml: CircleCI build
2016-11-24 rocky <rb@dustyfeet.com>
* uncompyle6/parsers/parse3.py: Remove dup Python 3 grammar rule
2016-11-24 rocky <rb@dustyfeet.com> 2016-11-24 rocky <rb@dustyfeet.com>
* uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner2.py: * uncompyle6/parsers/parse3.py, uncompyle6/scanners/scanner2.py:
<2.7 "if" detection and dup Python 3 grammar rule <2.7 "if" detection and dup Python 3 grammar rule
2016-11-24 rocky <rb@dustyfeet.com>
* test/test_pyenvlib.py, uncompyle6/linenumbers.py,
uncompyle6/main.py, uncompyle6/scanners/scanner2.py,
uncompyle6/semantics/make_function.py,
uncompyle6/semantics/pysource.py, uncompyle6/verify.py: Bug in 2.4
"if" dectection and... Wrong language used in old-style exceptions: use "except Error,e"
not "except Error(e)""
2016-11-24 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> 2016-11-23 rocky <rb@dustyfeet.com>
* __pkginfo__.py, pytest/test_grammar.py, uncompyle6/parser.py, * __pkginfo__.py, pytest/test_grammar.py, uncompyle6/parser.py,
@@ -67,8 +91,17 @@
2016-11-23 rocky <rb@dustyfeet.com> 2016-11-23 rocky <rb@dustyfeet.com>
* : commit 6aa1531972de83ecab15b4c96b89c873ea5a7458 Author: rocky * : commit 7133540c235e16f02d2db62cb903b70aa311de20 Author: rocky
<rb@dustyfeet.com> Date: Wed Nov 23 00:48:38 2016 -0500 <rb@dustyfeet.com> Date: Wed Nov 23 08:26:12 2016 -0500
2016-11-23 rocky <rb@dustyfeet.com>
* : commit a9349b8f3d12b2aa0cd88286617c1af9cccad018 Author: rocky
<rb@dustyfeet.com> Date: Tue Nov 22 17:49:47 2016 -0500
2016-11-23 rocky <rb@dustyfeet.com>
* circle.yml: Circle CI uses 2.7.10 and 2.7.12 is not available
2016-11-22 rocky <rb@dustyfeet.com> 2016-11-22 rocky <rb@dustyfeet.com>

View File

@@ -37,7 +37,7 @@ check-3.0 check-3.1 check-3.2 check-3.5 check-3.6:
$(MAKE) -C test $@ $(MAKE) -C test $@
#:Tests for Python 2.6 (doesn't have pytest) #:Tests for Python 2.6 (doesn't have pytest)
check-2.6: check-2.4 check-2.5 check-2.6:
$(MAKE) -C test $@ $(MAKE) -C test $@
#:PyPy 2.6.1 or PyPy 5.0.1 #:PyPy 2.6.1 or PyPy 5.0.1

View File

@@ -10,4 +10,4 @@ dependencies:
- pip install -r requirements-dev.txt - pip install -r requirements-dev.txt
test: test:
override: override:
- python ./setup.py develop && make check-2.7 - python ./setup.py develop && make check-2.6

View File

@@ -1,150 +0,0 @@
# std
import os
# test
import pytest
import hypothesis
from hypothesis import strategies as st
# uncompyle6
from uncompyle6 import PYTHON_VERSION, deparse_code
@st.composite
def expressions(draw):
# todo : would be nice to generate expressions using hypothesis however
# this is pretty involved so for now just use a corpus of expressions
# from which to select.
return draw(st.sampled_from((
'abc',
'len(items)',
'x + 1',
'lineno',
'container',
'self.attribute',
'self.method()',
# These expressions are failing, I think these are control
# flow problems rather than problems with FORMAT_VALUE,
# however I need to confirm this...
#'sorted(items, key=lambda x: x.name)',
#'func(*args, **kwargs)',
#'text or default',
#'43 if life_the_universe and everything else None'
)))
@st.composite
def format_specifiers(draw):
"""
Generate a valid format specifier using the rules:
format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]
fill ::= <any character>
align ::= "<" | ">" | "=" | "^"
sign ::= "+" | "-" | " "
width ::= integer
precision ::= integer
type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
See https://docs.python.org/2/library/string.html
:param draw: Let hypothesis draw from other strategies.
:return: An example format_specifier.
"""
alphabet_strategy = st.characters(min_codepoint=ord('a'), max_codepoint=ord('z'))
fill = draw(st.one_of(alphabet_strategy, st.none()))
align = draw(st.sampled_from(list('<>=^')))
fill_align = (fill + align or '') if fill else ''
type_ = draw(st.sampled_from('bcdeEfFgGnosxX%'))
can_have_sign = type_ in 'deEfFgGnoxX%'
can_have_comma = type_ in 'deEfFgG%'
can_have_precision = type_ in 'fFgG'
can_have_pound = type_ in 'boxX%'
can_have_zero = type_ in 'oxX'
sign = draw(st.sampled_from(list('+- ') + [''])) if can_have_sign else ''
pound = draw(st.sampled_from(('#', '',))) if can_have_pound else ''
zero = draw(st.sampled_from(('0', '',))) if can_have_zero else ''
int_strategy = st.integers(min_value=1, max_value=1000)
width = draw(st.one_of(int_strategy, st.none()))
width = str(width) if width is not None else ''
comma = draw(st.sampled_from((',', '',))) if can_have_comma else ''
if can_have_precision:
precision = draw(st.one_of(int_strategy, st.none()))
precision = '.' + str(precision) if precision else ''
else:
precision = ''
return ''.join((fill_align, sign, pound, zero, width, comma, precision, type_,))
@st.composite
def fstrings(draw):
"""
Generate a valid f-string.
See https://www.python.org/dev/peps/pep-0498/#specification
:param draw: Let hypothsis draw from other strategies.
:return: A valid f-string.
"""
character_strategy = st.characters(
blacklist_characters='\r\n\'\\s{}',
min_codepoint=1,
max_codepoint=1000,
)
is_raw = draw(st.booleans())
integer_strategy = st.integers(min_value=0, max_value=3)
expression_count = draw(integer_strategy)
content = []
for _ in range(expression_count):
expression = draw(expressions())
conversion = draw(st.sampled_from(('', '!s', '!r', '!a',)))
has_specifier = draw(st.booleans())
specifier = ':' + draw(format_specifiers()) if has_specifier else ''
content.append('{{{}{}}}'.format(expression, conversion, specifier))
content.append(draw(st.text(character_strategy)))
content = ''.join(content)
return "f{}'{}'".format('r' if is_raw else '', content)
@pytest.mark.skipif(PYTHON_VERSION < 3.6, reason='need at least python 3.6')
@hypothesis.given(format_specifiers())
def test_format_specifiers(format_specifier):
"""Verify that format_specifiers generates valid specifiers"""
try:
exec('"{:' + format_specifier + '}".format(0)')
except ValueError as e:
if 'Unknown format code' not in str(e):
raise
def run_test(text):
hypothesis.assume(len(text))
hypothesis.assume("f'{" in text)
expr = text + '\n'
code = compile(expr, '<string>', 'single')
deparsed = deparse_code(PYTHON_VERSION, code, compile_mode='single')
recompiled = compile(deparsed.text, '<string>', 'single')
if recompiled != code:
assert 'dis(' + deparsed.text.strip('\n') + ')' == 'dis(' + expr.strip('\n') + ')'
@pytest.mark.skipif(PYTHON_VERSION < 3.6, reason='need at least python 3.6')
@hypothesis.given(fstrings())
def test_uncompyle_fstring(fstring):
"""Verify uncompyling fstring bytecode"""
run_test(fstring)
@pytest.mark.skipif(PYTHON_VERSION < 3.6, reason='need at least python 3.6')
@pytest.mark.parametrize('fstring', [
"f'{abc}{abc!s}'",
"f'{abc}0'",
])
def test_uncompyle_direct(fstring):
"""useful for debugging"""
run_test(fstring)

View File

@@ -20,7 +20,7 @@ check:
$(MAKE) check-$$PYTHON_VERSION $(MAKE) check-$$PYTHON_VERSION
#: Run working tests from Python 2.6 or 2.7 #: Run working tests from Python 2.6 or 2.7
check-2.6 check-2.7: check-bytecode-2 check-bytecode-3 check-bytecode-1 check-2.7-ok check-2.4 check-2.5 check-2.6 check-2.7: check-bytecode-2 check-bytecode-3 check-bytecode-1 check-2.7-ok
#: Run working tests from Python 3.1 #: Run working tests from Python 3.1
check-3.0: check-bytecode check-3.0: check-bytecode

View File

@@ -19,8 +19,6 @@ Step 2: Run the test:
test_pyenvlib --mylib --verify # decompile verify 'mylib' test_pyenvlib --mylib --verify # decompile verify 'mylib'
""" """
from __future__ import print_function
from uncompyle6 import main, PYTHON3 from uncompyle6 import main, PYTHON3
import os, time, shutil import os, time, shutil
from fnmatch import fnmatch from fnmatch import fnmatch

View File

@@ -27,8 +27,6 @@ Step 2: Run the test:
test_pythonlib.py --mylib --verify # decompile verify 'mylib' test_pythonlib.py --mylib --verify # decompile verify 'mylib'
""" """
from __future__ import print_function
import getopt, os, py_compile, sys, shutil, tempfile, time import getopt, os, py_compile, sys, shutil, tempfile, time
from uncompyle6 import PYTHON_VERSION from uncompyle6 import PYTHON_VERSION
@@ -127,8 +125,10 @@ def do_tests(src_dir, obj_patterns, target_dir, opts):
if opts['do_compile']: if opts['do_compile']:
compiled_version = opts['compiled_version'] compiled_version = opts['compiled_version']
if compiled_version and PYTHON_VERSION != compiled_version: if compiled_version and PYTHON_VERSION != compiled_version:
print("Not compiling: desired Python version is %s but we are running %s" % sys.stderr.write("Not compiling: "
(compiled_version, PYTHON_VERSION), file=sys.stderr) "desired Python version is %s "
"but we are running %s" %
(compiled_version, PYTHON_VERSION))
else: else:
for root, dirs, basenames in os.walk(src_dir): for root, dirs, basenames in os.walk(src_dir):
file_matches(files, root, basenames, PY) file_matches(files, root, basenames, PY)
@@ -146,8 +146,8 @@ def do_tests(src_dir, obj_patterns, target_dir, opts):
file_matches(files, dirname, basenames, obj_patterns) file_matches(files, dirname, basenames, obj_patterns)
if not files: if not files:
print("Didn't come up with any files to test! Try with --compile?", sys.stderr.write("Didn't come up with any files to test! "
file=sys.stderr) "Try with --compile?")
exit(1) exit(1)
os.chdir(cwd) os.chdir(cwd)
@@ -161,9 +161,9 @@ def do_tests(src_dir, obj_patterns, target_dir, opts):
except ValueError: except ValueError:
pass pass
print(time.ctime()) print time.ctime()
print('Source directory: ', src_dir) print 'Source directory: ', src_dir
print('Output directory: ', target_dir) print 'Output directory: ', target_dir
try: try:
_, _, failed_files, failed_verify = \ _, _, failed_files, failed_verify = \
main(src_dir, target_dir, files, [], main(src_dir, target_dir, files, [],
@@ -227,14 +227,13 @@ if __name__ == '__main__':
if os.path.isdir(src_dir): if os.path.isdir(src_dir):
checked_dirs.append([src_dir, pattern, target_dir]) checked_dirs.append([src_dir, pattern, target_dir])
else: else:
print("Can't find directory %s. Skipping" % src_dir, sys.stderr.write("Can't find directory %s. Skipping" % src_dir)
file=sys.stderr)
continue continue
last_compile_version = compiled_version last_compile_version = compiled_version
pass pass
if not checked_dirs: if not checked_dirs:
print("No directories found to check", file=sys.stderr) sys.stderr.write("No directories found to check\n")
sys.exit(1) sys.exit(1)
test_opts['compiled_version'] = last_compile_version test_opts['compiled_version'] = last_compile_version

View File

@@ -3,7 +3,6 @@
# #
# Copyright (c) 2015-2016 by Rocky Bernstein <rb@dustyfeet.com> # Copyright (c) 2015-2016 by Rocky Bernstein <rb@dustyfeet.com>
# #
from __future__ import print_function
import sys, os, getopt import sys, os, getopt
from uncompyle6.disas import disassemble_file from uncompyle6.disas import disassemble_file
@@ -26,7 +25,7 @@ Options:
-V | --version show version and stop -V | --version show version and stop
-h | --help show this message -h | --help show this message
""".format(program) """ % (program, program)
PATTERNS = ('*.pyc', '*.pyo') PATTERNS = ('*.pyc', '*.pyo')
@@ -37,15 +36,15 @@ Type -h for for full help.""" % program
native = True native = True
if len(sys.argv) == 1: if len(sys.argv) == 1:
print("No file(s) given", file=sys.stderr) sys.stderr.write("No file(s) given\n")
print(Usage_short, file=sys.stderr) sys.stderr.write(Usage_short)
sys.exit(1) sys.exit(1)
try: try:
opts, files = getopt.getopt(sys.argv[1:], 'hVU', opts, files = getopt.getopt(sys.argv[1:], 'hVU',
['help', 'version', 'uncompyle6']) ['help', 'version', 'uncompyle6'])
except getopt.GetoptError as e: except getopt.GetoptError(e):
print('%s: %s' % (os.path.basename(sys.argv[0]), e), file=sys.stderr) sys.stderr.write('%s: %s' % (os.path.basename(sys.argv[0]), e))
sys.exit(-1) sys.exit(-1)
for opt, val in opts: for opt, val in opts:
@@ -59,7 +58,7 @@ Type -h for for full help.""" % program
native = False native = False
else: else:
print(opt) print(opt)
print(Usage_short, file=sys.stderr) sys.stderr.write(Usage_short)
sys.exit(1) sys.exit(1)
@@ -67,8 +66,7 @@ Type -h for for full help.""" % program
if os.path.exists(files[0]): if os.path.exists(files[0]):
disassemble_file(file, sys.stdout, native) disassemble_file(file, sys.stdout, native)
else: else:
print("Can't read %s - skipping" % files[0], sys.stderr.write("Can't read %s - skipping\n" % files[0])
file=sys.stderr)
pass pass
pass pass
return return

View File

@@ -4,7 +4,6 @@
# Copyright (c) 2015-2016 by Rocky Bernstein # Copyright (c) 2015-2016 by Rocky Bernstein
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com> # Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
# #
from __future__ import print_function
import sys, os, getopt, time import sys, os, getopt, time
program, ext = os.path.splitext(os.path.basename(__file__)) program, ext = os.path.splitext(os.path.basename(__file__))
@@ -65,11 +64,11 @@ def usage():
def main_bin(): def main_bin():
if not (sys.version_info[0:2] in ((2, 6), (2, 7), if not (sys.version_info[0:2] in ((2, 4), (2, 5), (2, 6), (2, 7),
(3, 2), (3, 3), (3, 2), (3, 3),
(3, 4), (3, 5), (3, 6))): (3, 4), (3, 5), (3, 6))):
print('Error: %s requires Python 2.6, 2.7, 3.2, 3.3, 3.4, 3.5, or 3.6' % program, sys.stderr.write('Error: %s requires Python 2.4 2.5 2.6, 2.7, '
file=sys.stderr) '3.2, 3.3, 3.4, 3.5, or 3.6' % program)
sys.exit(-1) sys.exit(-1)
do_verify = recurse_dirs = False do_verify = recurse_dirs = False
@@ -84,8 +83,8 @@ def main_bin():
opts, files = getopt.getopt(sys.argv[1:], 'hagtdrVo:c:p:', opts, files = getopt.getopt(sys.argv[1:], 'hagtdrVo:c:p:',
'help asm grammar linemaps recurse timestamp tree ' 'help asm grammar linemaps recurse timestamp tree '
'verify version showgrammar'.split(' ')) 'verify version showgrammar'.split(' '))
except getopt.GetoptError as e: except getopt.GetoptError(e):
print('%s: %s' % (os.path.basename(sys.argv[0]), e), file=sys.stderr) sys.stderr.write('%s: %s\n' % (os.path.basename(sys.argv[0]), e))
sys.exit(-1) sys.exit(-1)
options = {} options = {}
@@ -119,7 +118,7 @@ def main_bin():
elif opt in ('--recurse', '-r'): elif opt in ('--recurse', '-r'):
recurse_dirs = True recurse_dirs = True
else: else:
print(opt, file=sys.stderr) sys.stderr.write(opt)
usage() usage()
# expand directory if specified # expand directory if specified
@@ -145,7 +144,7 @@ def main_bin():
del sb_len del sb_len
if not files: if not files:
print("No files given", file=sys.stderr) sys.stderr.write("No files given\n")
usage() usage()
if outfile == '-': if outfile == '-':

View File

@@ -16,8 +16,6 @@ Second, we need structured instruction information for the
want to run on Python 2.7. want to run on Python 2.7.
""" """
from __future__ import print_function
import sys import sys
from collections import deque from collections import deque
@@ -37,10 +35,9 @@ def disco(version, co, out=None, is_pypy=False):
# store final output stream for case of error # store final output stream for case of error
real_out = out or sys.stdout real_out = out or sys.stdout
print('# Python %s' % version, file=real_out) real_out.write('# Python %s\n' % version)
if co.co_filename: if co.co_filename:
print('# Embedded file name: %s' % co.co_filename, real_out.write('# Embedded file name: %s\n' % co.co_filename)
file=real_out)
scanner = get_scanner(version, is_pypy=is_pypy) scanner = get_scanner(version, is_pypy=is_pypy)
@@ -52,16 +49,15 @@ def disco_loop(disasm, queue, real_out):
while len(queue) > 0: while len(queue) > 0:
co = queue.popleft() co = queue.popleft()
if co.co_name != '<module>': if co.co_name != '<module>':
print('\n# %s line %d of %s' % real_out.write('\n# %s line %d of %s\n' %
(co.co_name, co.co_firstlineno, co.co_filename), (co.co_name, co.co_firstlineno, co.co_filename))
file=real_out)
tokens, customize = disasm(co) tokens, customize = disasm(co)
for t in tokens: for t in tokens:
if iscode(t.pattr): if iscode(t.pattr):
queue.append(t.pattr) queue.append(t.pattr)
elif iscode(t.attr): elif iscode(t.attr):
queue.append(t.attr) queue.append(t.attr)
print(t, file=real_out) real_out.write(t)
pass pass
pass pass

View File

@@ -10,7 +10,7 @@ def line_number_mapping(pyc_filename, src_filename):
source_size) = load_module(pyc_filename) source_size) = load_module(pyc_filename)
try: try:
code2 = load_file(src_filename) code2 = load_file(src_filename)
except SyntaxError as e: except SyntaxError, e:
return str(e) return str(e)
queue = deque([code1, code2]) queue = deque([code1, code2])

View File

@@ -1,4 +1,3 @@
from __future__ import print_function
import datetime, os, subprocess, sys, tempfile import datetime, os, subprocess, sys, tempfile
from uncompyle6 import verify, IS_PYPY from uncompyle6 import verify, IS_PYPY
@@ -22,31 +21,36 @@ def uncompyle(
# store final output stream for case of error # store final output stream for case of error
real_out = out or sys.stdout real_out = out or sys.stdout
co_pypy_str = 'PyPy ' if is_pypy else '' if is_pypy:
run_pypy_str = 'PyPy ' if IS_PYPY else '' co_pypy_str = 'PyPy '
print('# uncompyle6 version %s\n' else:
'# %sPython bytecode %s%s\n# Decompiled from: %sPython %s' % co_pypy_str = ''
(VERSION, co_pypy_str, bytecode_version,
" (%d)" % magic_int if magic_int else "",
run_pypy_str, '\n# '.join(sys.version.split('\n'))),
file=real_out)
if co.co_filename:
print('# Embedded file name: %s' % co.co_filename,
file=real_out)
if timestamp:
print('# Compiled at: %s' % datetime.datetime.fromtimestamp(timestamp),
file=real_out)
if source_size:
print('# Size of source mod 2**32: %d bytes' % source_size,
file=real_out)
try: if IS_PYPY:
pysource.deparse_code(bytecode_version, co, out, showasm, showast, run_pypy_str = 'PyPy '
showgrammar, code_objects=code_objects, else:
is_pypy=is_pypy) run_pypy_str = ''
except pysource.SourceWalkerError as e:
# deparsing failed if magic_int:
raise pysource.SourceWalkerError(str(e)) m = str(magic_int)
else:
m = ""
real_out.write('# uncompyle6 version %s\n'
'# %sPython bytecode %s%s\n# Decompiled from: %sPython %s\n' %
(VERSION, co_pypy_str, bytecode_version,
" (%s)" % m, run_pypy_str,
'\n# '.join(sys.version.split('\n'))))
if co.co_filename:
real_out.write('# Embedded file name: %s\n' % co.co_filename)
if timestamp:
real_out.write('# Compiled at: %s\n' %
datetime.datetime.fromtimestamp(timestamp))
if source_size:
real_out.write('# Size of source mod 2**32: %d bytes\n' % source_size)
pysource.deparse_code(bytecode_version, co, out, showasm, showast,
showgrammar, code_objects=code_objects,
is_pypy=is_pypy)
def uncompyle_file(filename, outstream=None, showasm=None, showast=False, def uncompyle_file(filename, outstream=None, showasm=None, showast=False,
@@ -143,9 +147,9 @@ def main(in_base, out_base, files, codes, outfile=None,
try: try:
uncompyle_file(infile, outstream, showasm, showast, showgrammar) uncompyle_file(infile, outstream, showasm, showast, showgrammar)
tot_files += 1 tot_files += 1
except (ValueError, SyntaxError, ParserError, pysource.SourceWalkerError) as e: except (ValueError, SyntaxError, ParserError, pysource.SourceWalkerError):
sys.stdout.write("\n") sys.stdout.write("\n")
sys.stderr.write("\n# file %s\n# %s\n" % (infile, e)) sys.stderr.write("# file %s\n" % (infile))
failed_files += 1 failed_files += 1
except KeyboardInterrupt: except KeyboardInterrupt:
if outfile: if outfile:
@@ -183,20 +187,24 @@ def main(in_base, out_base, files, codes, outfile=None,
okay_files += 1 okay_files += 1
else: else:
print('\n# %s\n\t%s', infile, msg) print('\n# %s\n\t%s', infile, msg)
except verify.VerifyCmpError as e: except verify.VerifyCmpError, e:
print(e) print(e)
verify_failed_files += 1 verify_failed_files += 1
os.rename(outfile, outfile + '_unverified') os.rename(outfile, outfile + '_unverified')
sys.stderr.write("### Error Verifying %s\n" % filename) sys.stderr.write("### Error Verifying %s\n" % filename)
sys.stderr.write(str(e) + "\n") sys.stderr.write(str(e) + "\n")
if not outfile: if not outfile:
sys.stder.write("### Error Verifiying %s" %
filename)
sys.stderr.write(e)
if raise_on_error: if raise_on_error:
raise raise
pass pass
pass pass
pass pass
elif do_verify: elif do_verify:
sys.stderr.write("\n### uncompile successful, but no file to compare against\n") sys.stderr.write("\n### uncompile successful, "
"but no file to compare against")
pass pass
else: else:
okay_files += 1 okay_files += 1

View File

@@ -6,8 +6,6 @@
Common uncompyle parser routines. Common uncompyle parser routines.
""" """
from __future__ import print_function
import sys import sys
from xdis.code import iscode from xdis.code import iscode
@@ -99,7 +97,10 @@ class PythonParser(GenericASTBuilder):
err_token = instructions[index] err_token = instructions[index]
print("Instruction context:") print("Instruction context:")
for i in range(start, finish): for i in range(start, finish):
indent = ' ' if i != index else '-> ' if i != index:
indent = ' '
else:
indent = '-> '
print("%s%s" % (indent, instructions[i])) print("%s%s" % (indent, instructions[i]))
raise ParserError(err_token, err_token.offset) raise ParserError(err_token, err_token.offset)

View File

@@ -12,8 +12,6 @@ If we succeed in creating a parse tree, then we have a Python program
that a later phase can turn into a sequence of ASCII text. that a later phase can turn into a sequence of ASCII text.
""" """
from __future__ import print_function
from uncompyle6.parser import PythonParser, PythonParserSingle, nop_func from uncompyle6.parser import PythonParser, PythonParserSingle, nop_func
from uncompyle6.parsers.astnode import AST from uncompyle6.parsers.astnode import AST
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG

View File

@@ -15,8 +15,6 @@ If we succeed in creating a parse tree, then we have a Python program
that a later phase can turn into a sequence of ASCII text. that a later phase can turn into a sequence of ASCII text.
""" """
from __future__ import print_function
from uncompyle6.parser import PythonParser, PythonParserSingle, nop_func from uncompyle6.parser import PythonParser, PythonParserSingle, nop_func
from uncompyle6.parsers.astnode import AST from uncompyle6.parsers.astnode import AST
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
@@ -449,7 +447,10 @@ class Python3Parser(PythonParser):
"""Python 3.3 added a an addtional LOAD_CONST before MAKE_FUNCTION and """Python 3.3 added a an addtional LOAD_CONST before MAKE_FUNCTION and
this has an effect on many rules. this has an effect on many rules.
""" """
new_rule = rule % (('LOAD_CONST ') * (1 if self.version >= 3.3 else 0)) if self.version >= 3.3:
new_rule = rule % (('LOAD_CONST ') * 1)
else:
new_rule = rule % (('LOAD_CONST ') * 0)
self.add_unique_rule(new_rule, opname, attr, customize) self.add_unique_rule(new_rule, opname, attr, customize)
def add_custom_rules(self, tokens, customize): def add_custom_rules(self, tokens, customize):

View File

@@ -2,7 +2,6 @@
""" """
spark grammar differences over Python 3.1 for Python 3.0. spark grammar differences over Python 3.1 for Python 3.0.
""" """
from __future__ import print_function
from uncompyle6.parser import PythonParserSingle from uncompyle6.parser import PythonParserSingle
from uncompyle6.parsers.parse3 import Python3Parser from uncompyle6.parsers.parse3 import Python3Parser

View File

@@ -2,7 +2,6 @@
""" """
spark grammar differences over Python 3.2 for Python 3.1. spark grammar differences over Python 3.2 for Python 3.1.
""" """
from __future__ import print_function
from uncompyle6.parser import PythonParserSingle from uncompyle6.parser import PythonParserSingle
from uncompyle6.parsers.parse32 import Python32Parser from uncompyle6.parsers.parse32 import Python32Parser

View File

@@ -2,8 +2,6 @@
""" """
spark grammar differences over Python 3 for Python 3.2. spark grammar differences over Python 3 for Python 3.2.
""" """
from __future__ import print_function
from uncompyle6.parser import PythonParserSingle from uncompyle6.parser import PythonParserSingle
from uncompyle6.parsers.parse3 import Python3Parser from uncompyle6.parsers.parse3 import Python3Parser

View File

@@ -2,7 +2,6 @@
""" """
spark grammar differences over Python 3.2 for Python 3.3. spark grammar differences over Python 3.2 for Python 3.3.
""" """
from __future__ import print_function
from uncompyle6.parser import PythonParserSingle from uncompyle6.parser import PythonParserSingle
from uncompyle6.parsers.parse32 import Python32Parser from uncompyle6.parsers.parse32 import Python32Parser

View File

@@ -2,7 +2,6 @@
""" """
spark grammar differences over Python 3.4 for Python 3.5. spark grammar differences over Python 3.4 for Python 3.5.
""" """
from __future__ import print_function
from uncompyle6.parser import PythonParserSingle from uncompyle6.parser import PythonParserSingle
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG

View File

@@ -2,7 +2,6 @@
""" """
spark grammar differences over Python 3.5 for Python 3.6. spark grammar differences over Python 3.5 for Python 3.6.
""" """
from __future__ import print_function
from uncompyle6.parser import PythonParserSingle from uncompyle6.parser import PythonParserSingle
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG

View File

@@ -10,8 +10,6 @@ scanner/ingestion module. From here we call various version-specific
scanners, e.g. for Python 2.7 or 3.4. scanners, e.g. for Python 2.7 or 3.4.
""" """
from __future__ import print_function
import sys import sys
from uncompyle6 import PYTHON3, IS_PYPY from uncompyle6 import PYTHON3, IS_PYPY

View File

@@ -20,9 +20,7 @@ For example:
Finally we save token information. Finally we save token information.
""" """
from __future__ import print_function from xdis.namedtuple25 import namedtuple
from collections import namedtuple
from array import array from array import array
from uncompyle6.scanner import op_has_argument from uncompyle6.scanner import op_has_argument
@@ -85,7 +83,9 @@ class Scanner2(scan.Scanner):
cause specific rules for the specific number of arguments they take. cause specific rules for the specific number of arguments they take.
""" """
show_asm = self.show_asm if not show_asm else show_asm if not show_asm:
show_asm = self.show_asm
# show_asm = 'after' # show_asm = 'after'
if show_asm in ('both', 'before'): if show_asm in ('both', 'before'):
from xdis.bytecode import Bytecode from xdis.bytecode import Bytecode
@@ -922,8 +922,10 @@ class Scanner2(scan.Scanner):
# FIXME: rocky: I think we need something like this... # FIXME: rocky: I think we need something like this...
if offset not in set(self.ignore_if) or self.version == 2.7: if offset not in set(self.ignore_if) or self.version == 2.7:
source = (self.setup_loops[label] if label in self.setup_loops:
if label in self.setup_loops else offset) source = self.setup_loops[label]
else:
source = offset
targets[label] = targets.get(label, []) + [source] targets[label] = targets.get(label, []) + [source]
pass pass

View File

@@ -86,7 +86,9 @@ class Scanner26(scan.Scanner2):
cause specific rules for the specific number of arguments they take. cause specific rules for the specific number of arguments they take.
""" """
show_asm = self.show_asm if not show_asm else show_asm if not show_asm:
show_asm = self.show_asm
# show_asm = 'after' # show_asm = 'after'
if show_asm in ('both', 'before'): if show_asm in ('both', 'before'):
from xdis.bytecode import Bytecode from xdis.bytecode import Bytecode

View File

@@ -7,8 +7,6 @@ grammar parsing.
""" """
from __future__ import print_function
from uncompyle6.scanners.scanner2 import Scanner2 from uncompyle6.scanners.scanner2 import Scanner2
from uncompyle6 import PYTHON3 from uncompyle6 import PYTHON3

View File

@@ -20,9 +20,7 @@ For example:
Finally we save token information. Finally we save token information.
""" """
from __future__ import print_function from xdis.namedtuple25 import namedtuple
from collections import namedtuple
from array import array from array import array
from uncompyle6.scanner import Scanner, op_has_argument from uncompyle6.scanner import Scanner, op_has_argument
@@ -147,7 +145,9 @@ class Scanner3(Scanner):
cause specific rules for the specific number of arguments they take. cause specific rules for the specific number of arguments they take.
""" """
show_asm = self.show_asm if not show_asm else show_asm if not show_asm:
show_asm = self.show_asm
# show_asm = 'after' # show_asm = 'after'
if show_asm in ('both', 'before'): if show_asm in ('both', 'before'):
bytecode = Bytecode(co, self.opc) bytecode = Bytecode(co, self.opc)

View File

@@ -6,8 +6,6 @@ This sets up opcodes Python's 3.0 and calls a generalized
scanner routine for Python 3. scanner routine for Python 3.
""" """
from __future__ import print_function
# bytecode verification, verify(), uses JUMP_OPs from here # bytecode verification, verify(), uses JUMP_OPs from here
from xdis.opcodes import opcode_30 as opc from xdis.opcodes import opcode_30 as opc
JUMP_OPs = map(lambda op: opc.opname[op], opc.hasjrel + opc.hasjabs) JUMP_OPs = map(lambda op: opc.opname[op], opc.hasjrel + opc.hasjabs)

View File

@@ -6,8 +6,6 @@ This sets up opcodes Python's 3.1 and calls a generalized
scanner routine for Python 3. scanner routine for Python 3.
""" """
from __future__ import print_function
# bytecode verification, verify(), uses JUMP_OPs from here # bytecode verification, verify(), uses JUMP_OPs from here
from xdis.opcodes import opcode_31 as opc from xdis.opcodes import opcode_31 as opc
JUMP_OPs = map(lambda op: opc.opname[op], opc.hasjrel + opc.hasjabs) JUMP_OPs = map(lambda op: opc.opname[op], opc.hasjrel + opc.hasjabs)

View File

@@ -6,8 +6,6 @@ This sets up opcodes Python's 3.2 and calls a generalized
scanner routine for Python 3. scanner routine for Python 3.
""" """
from __future__ import print_function
# bytecode verification, verify(), uses JUMP_OPs from here # bytecode verification, verify(), uses JUMP_OPs from here
from xdis.opcodes import opcode_32 as opc from xdis.opcodes import opcode_32 as opc
JUMP_OPs = map(lambda op: opc.opname[op], opc.hasjrel + opc.hasjabs) JUMP_OPs = map(lambda op: opc.opname[op], opc.hasjrel + opc.hasjabs)

View File

@@ -6,8 +6,6 @@ This sets up opcodes Python's 3.3 and calls a generalized
scanner routine for Python 3. scanner routine for Python 3.
""" """
from __future__ import print_function
# bytecode verification, verify(), uses JUMP_OPs from here # bytecode verification, verify(), uses JUMP_OPs from here
from xdis.opcodes import opcode_33 as opc from xdis.opcodes import opcode_33 as opc
JUMP_OPs = map(lambda op: opc.opname[op], opc.hasjrel + opc.hasjabs) JUMP_OPs = map(lambda op: opc.opname[op], opc.hasjrel + opc.hasjabs)

View File

@@ -6,8 +6,6 @@ This sets up opcodes Python's 3.4 and calls a generalized
scanner routine for Python 3. scanner routine for Python 3.
""" """
from __future__ import print_function
from xdis.opcodes import opcode_34 as opc from xdis.opcodes import opcode_34 as opc
# bytecode verification, verify(), uses JUMP_OPs from here # bytecode verification, verify(), uses JUMP_OPs from here

View File

@@ -6,8 +6,6 @@ This sets up opcodes Python's 3.5 and calls a generalized
scanner routine for Python 3. scanner routine for Python 3.
""" """
from __future__ import print_function
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

View File

@@ -6,8 +6,6 @@ This sets up opcodes Python's 3.5 and calls a generalized
scanner routine for Python 3. scanner routine for Python 3.
""" """
from __future__ import print_function
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

View File

@@ -56,12 +56,18 @@ class Token:
return self.format(line_prefix='') return self.format(line_prefix='')
def format(self, line_prefix=''): def format(self, line_prefix=''):
prefix = ('\n%s%4d ' % (line_prefix, self.linestart) if self.linestart:
if self.linestart else (' ' * (6 + len(line_prefix)))) prefix = '\n%s%4d ' % (line_prefix, self.linestart)
else:
prefix = ' ' * (6 + len(line_prefix))
offset_opname = '%6s %-17s' % (self.offset, self.type) offset_opname = '%6s %-17s' % (self.offset, self.type)
if not self.has_arg: if not self.has_arg:
return "%s%s" % (prefix, offset_opname) return "%s%s" % (prefix, offset_opname)
argstr = "%6d " % self.attr if isinstance(self.attr, int) else (' '*7)
if isinstance(self.attr, int):
argstr = "%6d " % self.attr
else:
argstr = ' '*7
if self.pattr: if self.pattr:
pattr = self.pattr pattr = self.pattr
if self.opc: if self.opc:

View File

@@ -51,8 +51,6 @@ The node position 0 will be associated with "import".
# FIXME: DRY code with pysource # FIXME: DRY code with pysource
from __future__ import print_function
import re, sys import re, sys
from uncompyle6 import PYTHON3, IS_PYPY from uncompyle6 import PYTHON3, IS_PYPY
@@ -75,16 +73,14 @@ from uncompyle6.semantics.pysource import AST, INDENT_PER_LEVEL, NONE, PRECEDENC
from uncompyle6.semantics.make_function import find_all_globals, find_none from uncompyle6.semantics.make_function import find_all_globals, find_none
if PYTHON3: if PYTHON3:
from itertools import zip_longest
from io import StringIO from io import StringIO
else: else:
from itertools import izip_longest as zip_longest
from StringIO import StringIO from StringIO import StringIO
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
from collections import namedtuple from xdis.namedtuple25 import namedtuple
NodeInfo = namedtuple("NodeInfo", "node start finish") NodeInfo = namedtuple("NodeInfo", "node start finish")
ExtractInfo = namedtuple("ExtractInfo", ExtractInfo = namedtuple("ExtractInfo",
"lineNo lineStartOffset markerLine selectedLine selectedText") "lineNo lineStartOffset markerLine selectedLine selectedText")
@@ -736,7 +732,10 @@ class FragmentsWalker(pysource.SourceWalker, object):
def n_genexpr(self, node): def n_genexpr(self, node):
start = len(self.f.getvalue()) start = len(self.f.getvalue())
self.write('(') self.write('(')
code_index = -6 if self.version > 3.2 else -5 if self.version > 3.2:
code_index = -6
else:
code_index = -5
self.comprehension_walk(node, iter_index=3, code_index=code_index) self.comprehension_walk(node, iter_index=3, code_index=code_index)
self.write(')') self.write(')')
self.set_pos_info(node, start, len(self.f.getvalue())) self.set_pos_info(node, start, len(self.f.getvalue()))
@@ -890,7 +889,10 @@ class FragmentsWalker(pysource.SourceWalker, object):
subclass = n.attr subclass = n.attr
break break
pass pass
subclass_info = node if node == 'classdefdeco2' else node[0] if node == 'classdefdeco2':
subclass_info = node
else:
subclass_info = node[0]
elif buildclass[1][0] == 'load_closure': elif buildclass[1][0] == 'load_closure':
# Python 3 with closures not functions # Python 3 with closures not functions
load_closure = buildclass[1] load_closure = buildclass[1]
@@ -914,7 +916,10 @@ class FragmentsWalker(pysource.SourceWalker, object):
subclass = buildclass[1][0].attr subclass = buildclass[1][0].attr
subclass_info = node[0] subclass_info = node[0]
else: else:
buildclass = node if (node == 'classdefdeco2') else node[0] if node == 'classdefdeco2':
buildclass = node
else:
buildclass = node[0]
build_list = buildclass[1][0] build_list = buildclass[1][0]
if hasattr(buildclass[-3][0], 'attr'): if hasattr(buildclass[-3][0], 'attr'):
subclass = buildclass[-3][0].attr subclass = buildclass[-3][0].attr
@@ -980,7 +985,9 @@ class FragmentsWalker(pysource.SourceWalker, object):
tokens.append(Token('LAMBDA_MARKER')) tokens.append(Token('LAMBDA_MARKER'))
try: try:
ast = parser.parse(self.p, tokens, customize) ast = parser.parse(self.p, tokens, customize)
except (parser.ParserError, AssertionError) as e: except parser.ParserError(e):
raise ParserError(e, tokens)
except AssertionError(e):
raise ParserError(e, tokens) raise ParserError(e, tokens)
maybe_show_ast(self.showast, ast) maybe_show_ast(self.showast, ast)
return ast return ast
@@ -1005,7 +1012,9 @@ class FragmentsWalker(pysource.SourceWalker, object):
# Build AST from disassembly. # Build AST from disassembly.
try: try:
ast = parser.parse(self.p, tokens, customize) ast = parser.parse(self.p, tokens, customize)
except (parser.ParserError, AssertionError) as e: except parser.ParserError(e):
raise ParserError(e, tokens)
except AssertionError(e):
raise ParserError(e, tokens) raise ParserError(e, tokens)
maybe_show_ast(self.showast, ast) maybe_show_ast(self.showast, ast)
@@ -1642,16 +1651,16 @@ class FragmentsWalker(pysource.SourceWalker, object):
code._customize, code._customize,
isLambda = isLambda, isLambda = isLambda,
noneInNames = ('None' in code.co_names)) noneInNames = ('None' in code.co_names))
except ParserError as p: except ParserError(p):
self.write(str(p)) self.write(str(p))
self.ERROR = p self.ERROR = p
return return
# build parameters # build parameters
tup = [paramnames, defparams]
params = [build_param(ast, name, default) for params = [build_param(ast, name, default) for
name, default in zip_longest(paramnames, defparams, fillvalue=None)] name, default in map(lambda *tup:tup, *tup)]
params.reverse() # back to correct order params.reverse() # back to correct order
if 4 & code.co_flags: # flag 2 -> variable number of args if 4 & code.co_flags: # flag 2 -> variable number of args

View File

@@ -6,14 +6,9 @@ All the crazy things we have to do to handle Python functions
from xdis.code import iscode from xdis.code import iscode
from uncompyle6.scanner import Code from uncompyle6.scanner import Code
from uncompyle6.parsers.astnode import AST from uncompyle6.parsers.astnode import AST
from uncompyle6 import PYTHON3
from uncompyle6.semantics.parser_error import ParserError from uncompyle6.semantics.parser_error import ParserError
from uncompyle6.semantics.helper import print_docstring from uncompyle6.semantics.helper import print_docstring
if PYTHON3:
from itertools import zip_longest
else:
from itertools import izip_longest as zip_longest
from uncompyle6.show import maybe_show_ast_param_default from uncompyle6.show import maybe_show_ast_param_default
@@ -122,7 +117,7 @@ def make_function3_annotate(self, node, isLambda, nested=1,
code._customize, code._customize,
isLambda = isLambda, isLambda = isLambda,
noneInNames = ('None' in code.co_names)) noneInNames = ('None' in code.co_names))
except ParserError as p: except ParserError, p:
self.write(str(p)) self.write(str(p))
self.ERROR = p self.ERROR = p
return return
@@ -156,7 +151,10 @@ def make_function3_annotate(self, node, isLambda, nested=1,
self.write(': %s' % value) self.write(': %s' % value)
suffix = ', ' suffix = ', '
suffix = ', ' if i > 0 else '' if i > 0:
suffix = ', '
else:
suffix = ''
for n in node: for n in node:
if n == 'pos_arg': if n == 'pos_arg':
self.write(suffix) self.write(suffix)
@@ -301,17 +299,21 @@ def make_function2(self, node, isLambda, nested=1, codeNode=None):
code._customize, code._customize,
isLambda = isLambda, isLambda = isLambda,
noneInNames = ('None' in code.co_names)) noneInNames = ('None' in code.co_names))
except ParserError as p: except ParserError, p:
self.write(str(p)) self.write(str(p))
self.ERROR = p self.ERROR = p
return return
kw_pairs = args_node.attr[1] if self.version >= 3.0 else 0 if self.version >= 3.0:
kw_pairs = args_node.attr[1]
else:
kw_pairs = 0
indent = self.indent indent = self.indent
# build parameters # build parameters
tup = [paramnames, defparams]
params = [build_param(ast, name, default) for params = [build_param(ast, name, default) for
name, default in zip_longest(paramnames, defparams, fillvalue=None)] name, default in map(lambda *tup:tup, *tup)]
params.reverse() # back to correct order params.reverse() # back to correct order
if 4 & code.co_flags: # flag 2 -> variable number of args if 4 & code.co_flags: # flag 2 -> variable number of args
@@ -437,18 +439,22 @@ def make_function3(self, node, isLambda, nested=1, codeNode=None):
code._customize, code._customize,
isLambda = isLambda, isLambda = isLambda,
noneInNames = ('None' in code.co_names)) noneInNames = ('None' in code.co_names))
except ParserError as p: except ParserError, p:
self.write(str(p)) self.write(str(p))
self.ERROR = p self.ERROR = p
return return
kw_pairs = args_node.attr[1] if self.version >= 3.0 else 0 if self.version >= 3.0:
kw_pairs = args_node.attr[1]
else:
kw_pairs = 0
indent = self.indent indent = self.indent
# build parameters # build parameters
if self.version != 3.2: if self.version != 3.2:
tup = [paramnames, defparams]
params = [build_param(ast, name, default) for params = [build_param(ast, name, default) for
name, default in zip_longest(paramnames, defparams, fillvalue=None)] name, default in map(lambda *tup:tup, *tup)]
params.reverse() # back to correct order params.reverse() # back to correct order
if 4 & code.co_flags: # flag 2 -> variable number of args if 4 & code.co_flags: # flag 2 -> variable number of args
@@ -483,7 +489,10 @@ def make_function3(self, node, isLambda, nested=1, codeNode=None):
i = len(paramnames) - len(defparams) i = len(paramnames) - len(defparams)
self.write(", ".join(paramnames[:i])) self.write(", ".join(paramnames[:i]))
suffix = ', ' if i > 0 else '' if i > 0:
suffix = ', '
else:
suffix = ''
for n in node: for n in node:
if n == 'pos_arg': if n == 'pos_arg':
self.write(suffix) self.write(suffix)

View File

@@ -67,8 +67,6 @@ methods implement most of the below.
The '%' may optionally be followed by a number (C) in square brackets, which The '%' may optionally be followed by a number (C) in square brackets, which
makes the engine walk down to N[C] before evaluating the escape code. makes the engine walk down to N[C] before evaluating the escape code.
""" """
from __future__ import print_function
import sys, re import sys, re
from uncompyle6 import PYTHON3 from uncompyle6 import PYTHON3
@@ -608,7 +606,10 @@ class SourceWalker(GenericASTTraversal, object):
code = node[-3] code = node[-3]
self.indentMore() self.indentMore()
annotate_last = -4 if self.version == 3.1 else -5 if self.version == 3.1:
annotate_last = -4
else:
annotate_last = -5
# FIXME: handle and pass full annotate args # FIXME: handle and pass full annotate args
make_function3_annotate(self, node, isLambda=False, make_function3_annotate(self, node, isLambda=False,
@@ -1121,7 +1122,10 @@ class SourceWalker(GenericASTTraversal, object):
return return
n = node[-1] n = node[-1]
elif node[-1] == 'del_stmt': elif node[-1] == 'del_stmt':
n = node[-3] if node[-2] == 'JUMP_BACK' else node[-2] if node[-2] == 'JUMP_BACK':
n = node[-3]
else:
n = node[-2]
assert n == 'list_iter' assert n == 'list_iter'
@@ -1140,7 +1144,10 @@ class SourceWalker(GenericASTTraversal, object):
list_iter = node[-1] list_iter = node[-1]
else: else:
expr = n[1] expr = n[1]
list_iter = node[-3] if node[-2] == 'JUMP_BACK' else node[-2] if node[-2] == 'JUMP_BACK':
list_iter = node[-3]
else:
list_iter = node[-2]
assert expr == 'expr' assert expr == 'expr'
assert list_iter == 'list_iter' assert list_iter == 'list_iter'
@@ -1192,7 +1199,10 @@ class SourceWalker(GenericASTTraversal, object):
self.write( '[ ') self.write( '[ ')
expr = n[0] expr = n[0]
list_iter = node[-2] if self.is_pypy and node[-1] == 'JUMP_BACK' else node[-1] if self.is_pypy and node[-1] == 'JUMP_BACK':
list_iter = node[-2]
else:
list_iter = node[-1]
assert expr == 'expr' assert expr == 'expr'
assert list_iter == 'list_iter' assert list_iter == 'list_iter'
@@ -1266,7 +1276,10 @@ class SourceWalker(GenericASTTraversal, object):
self.write(' for ') self.write(' for ')
self.preorder(ast[iter_index-1]) self.preorder(ast[iter_index-1])
self.write(' in ') self.write(' in ')
iter_expr = node[2] if node[2] == 'expr' else node[-3] if node[2] == 'expr':
iter_expr = node[2]
else:
iter_expr = node[-3]
assert iter_expr == 'expr' assert iter_expr == 'expr'
self.preorder(iter_expr) self.preorder(iter_expr)
self.preorder(ast[iter_index]) self.preorder(ast[iter_index])
@@ -1274,7 +1287,10 @@ class SourceWalker(GenericASTTraversal, object):
def n_genexpr(self, node): def n_genexpr(self, node):
self.write('(') self.write('(')
code_index = -6 if self.version > 3.2 else -5 if self.version > 3.2:
code_index = -6
else:
code_index = -5
self.comprehension_walk(node, iter_index=3, code_index=code_index) self.comprehension_walk(node, iter_index=3, code_index=code_index)
self.write(')') self.write(')')
self.prune() self.prune()
@@ -1508,7 +1524,10 @@ class SourceWalker(GenericASTTraversal, object):
break break
pass pass
pass pass
subclass_info = node if node == 'classdefdeco2' else node[0] if node == 'classdefdeco2':
subclass_info = node
else:
subclass_info = node[0]
elif buildclass[1][0] == 'load_closure': elif buildclass[1][0] == 'load_closure':
# Python 3 with closures not functions # Python 3 with closures not functions
load_closure = buildclass[1] load_closure = buildclass[1]
@@ -1532,7 +1551,10 @@ class SourceWalker(GenericASTTraversal, object):
subclass = buildclass[1][0].attr subclass = buildclass[1][0].attr
subclass_info = node[0] subclass_info = node[0]
else: else:
buildclass = node if (node == 'classdefdeco2') else node[0] if node == 'classdefdeco2':
buildclass = node
else:
buildclass = node[0]
build_list = buildclass[1][0] build_list = buildclass[1][0]
if hasattr(buildclass[-3][0], 'attr'): if hasattr(buildclass[-3][0], 'attr'):
subclass = buildclass[-3][0].attr subclass = buildclass[-3][0].attr
@@ -2170,7 +2192,9 @@ class SourceWalker(GenericASTTraversal, object):
tokens.append(Token('LAMBDA_MARKER')) tokens.append(Token('LAMBDA_MARKER'))
try: try:
ast = python_parser.parse(self.p, tokens, customize) ast = python_parser.parse(self.p, tokens, customize)
except (python_parser.ParserError, AssertionError) as e: except python_parser.ParserError, e:
raise ParserError(e, tokens)
except AssertionError, e:
raise ParserError(e, tokens) raise ParserError(e, tokens)
maybe_show_ast(self.showast, ast) maybe_show_ast(self.showast, ast)
return ast return ast
@@ -2197,7 +2221,9 @@ class SourceWalker(GenericASTTraversal, object):
# Build AST from disassembly. # Build AST from disassembly.
try: try:
ast = python_parser.parse(self.p, tokens, customize) ast = python_parser.parse(self.p, tokens, customize)
except (python_parser.ParserError, AssertionError) as e: except python_parser.ParserError, e:
raise ParserError(e, tokens)
except AssertionError, e:
raise ParserError(e, tokens) raise ParserError(e, tokens)
maybe_show_ast(self.showast, ast) maybe_show_ast(self.showast, ast)
@@ -2275,10 +2301,10 @@ def deparse_code(version, co, out=sys.stdout, showasm=None, showast=False,
if __name__ == '__main__': if __name__ == '__main__':
def deparse_test(co): def deparse_test(co):
"This is a docstring" "This is a docstring"
sys_version = sys.version_info.major + (sys.version_info.minor / 10.0) sys_version = float(sys.version[0:3])
deparsed = deparse_code(sys_version, co, showasm='after', showast=True) deparsed = deparse_code(sys_version, co, showasm='after', showast=True)
# deparsed = deparse_code(sys_version, co, showasm=None, showast=False, # deparsed = deparse_code(sys_version, co, showasm=None, showast=False,
# showgrammar=True) # showgrammar=True)
print(deparsed.text) print(deparsed.text)
return return
deparse_test(deparse_test.__code__) deparse_test(deparse_test.func_code)

View File

@@ -12,7 +12,10 @@ def maybe_show_asm(showasm, tokens):
:param tokens: The asm tokens to show. :param tokens: The asm tokens to show.
""" """
if showasm: if showasm:
stream = showasm if hasattr(showasm, 'write') else sys.stdout if hasattr(showasm, 'write'):
stream = showasm
else:
stream = sys.stdout
for t in tokens: for t in tokens:
stream.write(str(t)) stream.write(str(t))
stream.write('\n') stream.write('\n')
@@ -29,7 +32,10 @@ def maybe_show_ast(showast, ast):
:param ast: The ast to show. :param ast: The ast to show.
""" """
if showast: if showast:
stream = showast if hasattr(showast, 'write') else sys.stdout if hasattr(showast, 'write'):
stream = showast
else:
stream = sys.stdout
stream.write(str(ast)) stream.write(str(ast))
stream.write('\n') stream.write('\n')
@@ -48,7 +54,10 @@ def maybe_show_ast_param_default(showast, name, default):
:param default: The function parameter default. :param default: The function parameter default.
""" """
if showast: if showast:
stream = showast if hasattr(showast, 'write') else sys.stdout if hasattr(showast, 'write'):
stream = showast
else:
stream = sys.stdout
stream.write('\n') stream.write('\n')
stream.write('--' + name) stream.write('--' + name)
stream.write('\n') stream.write('\n')

View File

@@ -6,8 +6,6 @@
byte-code verification byte-code verification
""" """
from __future__ import print_function
import dis, operator import dis, operator
import uncompyle6 import uncompyle6
@@ -400,7 +398,7 @@ def compare_code_with_srcfile(pyc_filename, src_filename, weak_verify=False):
return msg return msg
try: try:
code_obj2 = load_file(src_filename) code_obj2 = load_file(src_filename)
except SyntaxError as e: except SyntaxError, e:
return str(e) return str(e)
cmp_code_objects(version, is_pypy, code_obj1, code_obj2, ignore_code=weak_verify) cmp_code_objects(version, is_pypy, code_obj1, code_obj2, ignore_code=weak_verify)
return None return None