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:
@@ -1,3 +1,4 @@
|
|||||||
|
import pytest
|
||||||
from uncompyle6.semantics.fragments import deparse_code as deparse
|
from uncompyle6.semantics.fragments import deparse_code as deparse
|
||||||
from uncompyle6 import PYTHON_VERSION, PYTHON3
|
from uncompyle6 import PYTHON_VERSION, PYTHON3
|
||||||
|
|
||||||
@@ -32,19 +33,20 @@ def get_parsed_for_fn(fn):
|
|||||||
code = fn.func_code
|
code = fn.func_code
|
||||||
return deparse(PYTHON_VERSION, code)
|
return deparse(PYTHON_VERSION, code)
|
||||||
|
|
||||||
def check_expect(expect, parsed):
|
def check_expect(expect, parsed, fn_name):
|
||||||
debug = False
|
debug = False
|
||||||
i = 2
|
i = 2
|
||||||
max_expect = len(expect)
|
max_expect = len(expect)
|
||||||
for name, offset in sorted(parsed.offsets.keys()):
|
for name, offset in sorted(parsed.offsets.keys()):
|
||||||
assert i+1 <= max_expect, "ran out if items in testing node"
|
assert i+1 <= max_expect, (
|
||||||
|
"%s: ran out if items in testing node" % fn_name)
|
||||||
nodeInfo = parsed.offsets[name, offset]
|
nodeInfo = parsed.offsets[name, offset]
|
||||||
node = nodeInfo.node
|
node = nodeInfo.node
|
||||||
extractInfo = parsed.extract_node_info(node)
|
extractInfo = parsed.extract_node_info(node)
|
||||||
|
|
||||||
assert expect[i] == extractInfo.selectedLine, \
|
assert expect[i] == extractInfo.selectedLine, \
|
||||||
('line %s expect:\n%s\ngot:\n%s' %
|
('%s: line %s expect:\n%s\ngot:\n%s' %
|
||||||
(i, expect[i], extractInfo.selectedLine))
|
(fn_name, i, expect[i], extractInfo.selectedLine))
|
||||||
assert expect[i+1] == extractInfo.markerLine, \
|
assert expect[i+1] == extractInfo.markerLine, \
|
||||||
('line %s expect:\n%s\ngot:\n%s' %
|
('line %s expect:\n%s\ngot:\n%s' %
|
||||||
(i+1, expect[i+1], extractInfo.markerLine))
|
(i+1, expect[i+1], extractInfo.markerLine))
|
||||||
@@ -72,6 +74,7 @@ def check_expect(expect, parsed):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skip(reason='needs reworking')
|
||||||
def test_stuff():
|
def test_stuff():
|
||||||
parsed = get_parsed_for_fn(map_stmts)
|
parsed = get_parsed_for_fn(map_stmts)
|
||||||
expect = """
|
expect = """
|
||||||
@@ -83,10 +86,10 @@ return (x, y)
|
|||||||
-------------
|
-------------
|
||||||
0
|
0
|
||||||
x = []
|
x = []
|
||||||
--
|
-
|
||||||
Contained in...
|
Contained in...
|
||||||
x = []
|
x = []
|
||||||
------
|
--
|
||||||
3
|
3
|
||||||
x = []
|
x = []
|
||||||
-
|
-
|
||||||
@@ -95,10 +98,10 @@ x = []
|
|||||||
------
|
------
|
||||||
6
|
6
|
||||||
y = {}
|
y = {}
|
||||||
--
|
-
|
||||||
Contained in...
|
Contained in...
|
||||||
y = {}
|
y = {}
|
||||||
------
|
--
|
||||||
9
|
9
|
||||||
y = {}
|
y = {}
|
||||||
-
|
-
|
||||||
@@ -130,7 +133,7 @@ Contained in...
|
|||||||
x = [] ...
|
x = [] ...
|
||||||
------ ...
|
------ ...
|
||||||
""".split("\n")
|
""".split("\n")
|
||||||
check_expect(expect, parsed)
|
check_expect(expect, parsed, 'map_stmts')
|
||||||
########################################################
|
########################################################
|
||||||
# return
|
# return
|
||||||
|
|
||||||
@@ -167,7 +170,7 @@ Contained in...
|
|||||||
return (x, y)
|
return (x, y)
|
||||||
-------------
|
-------------
|
||||||
""".split("\n")
|
""".split("\n")
|
||||||
check_expect(expect, parsed)
|
check_expect(expect, parsed, 'return_stmt')
|
||||||
########################################################
|
########################################################
|
||||||
# # try
|
# # try
|
||||||
|
|
||||||
@@ -315,4 +318,4 @@ for i in range(2): ...
|
|||||||
""".split("\n")
|
""".split("\n")
|
||||||
parsed = get_parsed_for_fn(for_range_stmt)
|
parsed = get_parsed_for_fn(for_range_stmt)
|
||||||
if not PYTHON3:
|
if not PYTHON3:
|
||||||
check_expect(expect, parsed)
|
check_expect(expect, parsed, 'range_stmt')
|
||||||
|
@@ -79,7 +79,7 @@ case $PYVERSION in
|
|||||||
[test_ioctl.py]=1 # Test takes too long to run
|
[test_ioctl.py]=1 # Test takes too long to run
|
||||||
[test_itertools.py]=1 # Syntax error - look at!
|
[test_itertools.py]=1 # Syntax error - look at!
|
||||||
[test_memoryio.py]=1 # FIX
|
[test_memoryio.py]=1 # FIX
|
||||||
[test_multiprocessing.py]=1 # FIX
|
[test_multiprocessing.py]=1 # On uncompyle2, taks 24 secs
|
||||||
[test_pep352.py]=1 # ?
|
[test_pep352.py]=1 # ?
|
||||||
[test_select.py]=1 # Runs okay but takes 11 seconds
|
[test_select.py]=1 # Runs okay but takes 11 seconds
|
||||||
[test_socket.py]=1 # Runs ok but takes 22 seconds
|
[test_socket.py]=1 # Runs ok but takes 22 seconds
|
||||||
@@ -105,7 +105,7 @@ cd $srcdir
|
|||||||
fulldir=$(pwd)
|
fulldir=$(pwd)
|
||||||
|
|
||||||
# DECOMPILER=uncompyle2
|
# DECOMPILER=uncompyle2
|
||||||
DECOMPILER="$fulldir/../../bin/uncompyle6"
|
DECOMPILER=${DECOMPILER:-"$fulldir/../../bin/uncompyle6"}
|
||||||
TESTDIR=/tmp/test${PYVERSION}
|
TESTDIR=/tmp/test${PYVERSION}
|
||||||
if [[ -e $TESTDIR ]] ; then
|
if [[ -e $TESTDIR ]] ; then
|
||||||
rm -fr $TESTDIR
|
rm -fr $TESTDIR
|
||||||
|
@@ -33,6 +33,7 @@ Options:
|
|||||||
-d print timestamps
|
-d print timestamps
|
||||||
-p <integer> use <integer> number of processes
|
-p <integer> use <integer> number of processes
|
||||||
-r recurse directories looking for .pyc and .pyo files
|
-r recurse directories looking for .pyc and .pyo files
|
||||||
|
--fragments use fragments deparser
|
||||||
--verify compare generated source with input byte-code
|
--verify compare generated source with input byte-code
|
||||||
--verify-run compile generated source, run it and check exit code
|
--verify-run compile generated source, run it and check exit code
|
||||||
--weak-verify compile generated source
|
--weak-verify compile generated source
|
||||||
@@ -84,9 +85,11 @@ def main_bin():
|
|||||||
try:
|
try:
|
||||||
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 verify-run version showgrammar'.split(' '))
|
'fragments verify verify-run version weak-verify '
|
||||||
except getopt.GetoptError, e:
|
'showgrammar'.split(' '))
|
||||||
|
except getopt.GetoptError(e):
|
||||||
sys.stderr.write('%s: %s\n' % (os.path.basename(sys.argv[0]), e))
|
sys.stderr.write('%s: %s\n' % (os.path.basename(sys.argv[0]), e))
|
||||||
|
print('%s: %s' % (os.path.basename(sys.argv[0]), e), file=sys.stderr)
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
|
|
||||||
options = {}
|
options = {}
|
||||||
@@ -101,6 +104,8 @@ def main_bin():
|
|||||||
options['do_verify'] = 'strong'
|
options['do_verify'] = 'strong'
|
||||||
elif opt == '--weak-verify':
|
elif opt == '--weak-verify':
|
||||||
options['do_verify'] = 'weak'
|
options['do_verify'] = 'weak'
|
||||||
|
elif opt == '--fragments':
|
||||||
|
options['do_fragments'] = True
|
||||||
elif opt == '--verify-run':
|
elif opt == '--verify-run':
|
||||||
options['do_verify'] = 'verify-run'
|
options['do_verify'] = 'verify-run'
|
||||||
elif opt == '--linemaps':
|
elif opt == '--linemaps':
|
||||||
|
@@ -6,9 +6,10 @@ from uncompyle6.disas import check_object_path
|
|||||||
from uncompyle6.semantics import pysource
|
from uncompyle6.semantics import pysource
|
||||||
from uncompyle6.parser import ParserError
|
from uncompyle6.parser import ParserError
|
||||||
from uncompyle6.version import VERSION
|
from uncompyle6.version import VERSION
|
||||||
from uncompyle6.linenumbers import line_number_mapping
|
# from uncompyle6.linenumbers import line_number_mapping
|
||||||
|
|
||||||
from uncompyle6.semantics.pysource import deparse_code
|
from uncompyle6.semantics.pysource import deparse_code
|
||||||
|
from uncompyle6.semantics.fragments import deparse_code as deparse_code_fragments
|
||||||
from uncompyle6.semantics.linemap import deparse_code_with_map
|
from uncompyle6.semantics.linemap import deparse_code_with_map
|
||||||
|
|
||||||
from xdis.load import load_module
|
from xdis.load import load_module
|
||||||
@@ -28,7 +29,7 @@ def decompile(
|
|||||||
bytecode_version, co, out=None, showasm=None, showast=False,
|
bytecode_version, co, out=None, showasm=None, showast=False,
|
||||||
timestamp=None, showgrammar=False, code_objects={},
|
timestamp=None, showgrammar=False, code_objects={},
|
||||||
source_size=None, is_pypy=False, magic_int=None,
|
source_size=None, is_pypy=False, magic_int=None,
|
||||||
mapstream=None):
|
mapstream=None, do_fragments=False):
|
||||||
"""
|
"""
|
||||||
ingests and deparses a given code block 'co'
|
ingests and deparses a given code block 'co'
|
||||||
|
|
||||||
@@ -89,9 +90,13 @@ def decompile(
|
|||||||
sorted(deparsed.source_linemap.keys())]
|
sorted(deparsed.source_linemap.keys())]
|
||||||
mapstream.write("\n\n# %s\n" % linemap)
|
mapstream.write("\n\n# %s\n" % linemap)
|
||||||
else:
|
else:
|
||||||
deparsed = deparse_code(bytecode_version, co, out, showasm, showast,
|
if do_fragments:
|
||||||
showgrammar, code_objects=code_objects,
|
deparse_fn = deparse_code_fragments
|
||||||
is_pypy=is_pypy)
|
else:
|
||||||
|
deparse_fn = deparse_code
|
||||||
|
deparsed = deparse_fn(bytecode_version, co, out, showasm, showast,
|
||||||
|
showgrammar, code_objects=code_objects,
|
||||||
|
is_pypy=is_pypy)
|
||||||
pass
|
pass
|
||||||
return deparsed
|
return deparsed
|
||||||
except pysource.SourceWalkerError, e:
|
except pysource.SourceWalkerError, e:
|
||||||
@@ -99,7 +104,7 @@ def decompile(
|
|||||||
raise pysource.SourceWalkerError(str(e))
|
raise pysource.SourceWalkerError(str(e))
|
||||||
|
|
||||||
def decompile_file(filename, outstream=None, showasm=None, showast=False,
|
def decompile_file(filename, outstream=None, showasm=None, showast=False,
|
||||||
showgrammar=False, mapstream=None):
|
showgrammar=False, mapstream=None, do_fragments=False):
|
||||||
"""
|
"""
|
||||||
decompile Python byte-code file (.pyc). Return objects to
|
decompile Python byte-code file (.pyc). Return objects to
|
||||||
all of the deparsed objects found in `filename`.
|
all of the deparsed objects found in `filename`.
|
||||||
@@ -123,7 +128,7 @@ def decompile_file(filename, outstream=None, showasm=None, showast=False,
|
|||||||
timestamp, showgrammar,
|
timestamp, showgrammar,
|
||||||
code_objects=code_objects, source_size=source_size,
|
code_objects=code_objects, source_size=source_size,
|
||||||
is_pypy=is_pypy, magic_int=magic_int,
|
is_pypy=is_pypy, magic_int=magic_int,
|
||||||
mapstream=mapstream)]
|
mapstream=mapstream, do_fragments=do_fragments)]
|
||||||
co = None
|
co = None
|
||||||
return deparsed
|
return deparsed
|
||||||
|
|
||||||
@@ -132,7 +137,7 @@ def decompile_file(filename, outstream=None, showasm=None, showast=False,
|
|||||||
def main(in_base, out_base, files, codes, outfile=None,
|
def main(in_base, out_base, files, codes, outfile=None,
|
||||||
showasm=None, showast=False, do_verify=False,
|
showasm=None, showast=False, do_verify=False,
|
||||||
showgrammar=False, raise_on_error=False,
|
showgrammar=False, raise_on_error=False,
|
||||||
do_linemaps=False):
|
do_linemaps=False, do_fragments=False):
|
||||||
"""
|
"""
|
||||||
in_base base directory for input files
|
in_base base directory for input files
|
||||||
out_base base directory for output files (ignored when
|
out_base base directory for output files (ignored when
|
||||||
@@ -196,7 +201,24 @@ def main(in_base, out_base, files, codes, outfile=None,
|
|||||||
|
|
||||||
# Try to uncompile the input file
|
# Try to uncompile the input file
|
||||||
try:
|
try:
|
||||||
decompile_file(infile, outstream, showasm, showast, showgrammar, linemap_stream)
|
deparsed = decompile_file(infile, outstream, showasm, showast, showgrammar,
|
||||||
|
linemap_stream, do_fragments)
|
||||||
|
if do_fragments:
|
||||||
|
for d in deparsed:
|
||||||
|
last_mod = None
|
||||||
|
offsets = d.offsets
|
||||||
|
for e in sorted(offsets.keys()):
|
||||||
|
if e[0] != last_mod:
|
||||||
|
line = '=' * len(e[0])
|
||||||
|
outstream.write("%s\n%s\n%s\n" % (line, e[0], line))
|
||||||
|
last_mod = e[0]
|
||||||
|
info = offsets[e]
|
||||||
|
extractInfo = d.extract_node_info(info)
|
||||||
|
outstream.write("%s" % info.node.format().strip() + "\n")
|
||||||
|
outstream.write(extractInfo.selectedLine + "\n")
|
||||||
|
outstream.write(extractInfo.markerLine + "\n\n")
|
||||||
|
pass
|
||||||
|
pass
|
||||||
tot_files += 1
|
tot_files += 1
|
||||||
except (ValueError, SyntaxError, ParserError, pysource.SourceWalkerError):
|
except (ValueError, SyntaxError, ParserError, pysource.SourceWalkerError):
|
||||||
sys.stdout.write("\n")
|
sys.stdout.write("\n")
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2016-2017 by Rocky Bernstein
|
# Copyright (c) 2016-2018 by Rocky Bernstein
|
||||||
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
|
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
|
||||||
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||||
# Copyright (c) 1999 John Aycock
|
# Copyright (c) 1999 John Aycock
|
||||||
@@ -14,7 +14,8 @@ import sys
|
|||||||
|
|
||||||
from uncompyle6 import PYTHON3, IS_PYPY
|
from uncompyle6 import PYTHON3, IS_PYPY
|
||||||
from uncompyle6.scanners.tok import Token
|
from uncompyle6.scanners.tok import Token
|
||||||
from xdis.bytecode import op_size
|
import xdis
|
||||||
|
from xdis.bytecode import op_size, extended_arg_val
|
||||||
from xdis.magics import py_str2float, canonic_python_version
|
from xdis.magics import py_str2float, canonic_python_version
|
||||||
from xdis.util import code2num
|
from xdis.util import code2num
|
||||||
|
|
||||||
@@ -103,14 +104,13 @@ class Scanner(object):
|
|||||||
target += pos + 3
|
target += pos + 3
|
||||||
return target
|
return target
|
||||||
|
|
||||||
# FIXME: the below can be removed after xdis version 3.6.1 has been released
|
|
||||||
def extended_arg_val(self, val):
|
|
||||||
return val << self.opc.EXTENDED_ARG_SHIFT
|
|
||||||
|
|
||||||
def get_argument(self, pos):
|
def get_argument(self, pos):
|
||||||
arg = self.code[pos+1] + self.code[pos+2] * 256
|
arg = self.code[pos+1] + self.code[pos+2] * 256
|
||||||
return arg
|
return arg
|
||||||
|
|
||||||
|
def next_offset(self, op, offset):
|
||||||
|
return xdis.next_offset(op, self.opc, offset)
|
||||||
|
|
||||||
def print_bytecode(self):
|
def print_bytecode(self):
|
||||||
for i in self.op_range(0, len(self.code)):
|
for i in self.op_range(0, len(self.code)):
|
||||||
op = self.code[i]
|
op = self.code[i]
|
||||||
@@ -188,7 +188,7 @@ class Scanner(object):
|
|||||||
|
|
||||||
if op == self.opc.EXTENDED_ARG:
|
if op == self.opc.EXTENDED_ARG:
|
||||||
arg = code2num(code, offset+1) | extended_arg
|
arg = code2num(code, offset+1) | extended_arg
|
||||||
extended_arg = self.extended_arg_val(arg)
|
extended_arg = extended_arg_val(self.opc, arg)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if op in instr:
|
if op in instr:
|
||||||
@@ -240,7 +240,7 @@ class Scanner(object):
|
|||||||
|
|
||||||
if op == self.opc.EXTENDED_ARG:
|
if op == self.opc.EXTENDED_ARG:
|
||||||
arg = code2num(code, offset+1) | extended_arg
|
arg = code2num(code, offset+1) | extended_arg
|
||||||
extended_arg = self.extended_arg_val(arg)
|
extended_arg = extended_arg_val(self.opc, arg)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if op in instr:
|
if op in instr:
|
||||||
|
@@ -56,6 +56,7 @@ from xdis.code import iscode
|
|||||||
from uncompyle6.semantics import pysource
|
from uncompyle6.semantics import pysource
|
||||||
from uncompyle6 import parser
|
from uncompyle6 import parser
|
||||||
from uncompyle6.scanner import Token, Code, get_scanner
|
from uncompyle6.scanner import Token, Code, get_scanner
|
||||||
|
import uncompyle6.parser as python_parser
|
||||||
from uncompyle6.semantics.check_ast import checker
|
from uncompyle6.semantics.check_ast import checker
|
||||||
|
|
||||||
from uncompyle6.show import (
|
from uncompyle6.show import (
|
||||||
@@ -70,7 +71,7 @@ from uncompyle6.semantics.pysource import (
|
|||||||
|
|
||||||
from uncompyle6.semantics.consts import (
|
from uncompyle6.semantics.consts import (
|
||||||
INDENT_PER_LEVEL, NONE, PRECEDENCE,
|
INDENT_PER_LEVEL, NONE, PRECEDENCE,
|
||||||
TABLE_DIRECT, escape, minint, MAP
|
TABLE_DIRECT, escape, MAP, PASS
|
||||||
)
|
)
|
||||||
|
|
||||||
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
||||||
@@ -986,17 +987,28 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
self.name = old_name
|
self.name = old_name
|
||||||
self.return_none = rn
|
self.return_none = rn
|
||||||
|
|
||||||
def build_ast(self, tokens, customize, is_lambda=False, noneInNames=False):
|
def build_ast(self, tokens, customize, is_lambda=False,
|
||||||
# assert type(tokens) == ListType
|
noneInNames=False, isTopLevel=False):
|
||||||
|
|
||||||
|
# FIXME: DRY with pysource.py
|
||||||
|
|
||||||
# assert isinstance(tokens[0], Token)
|
# assert isinstance(tokens[0], Token)
|
||||||
|
|
||||||
if is_lambda:
|
if is_lambda:
|
||||||
|
for t in tokens:
|
||||||
|
if t.kind == 'RETURN_END_IF':
|
||||||
|
t.kind = 'RETURN_END_IF_LAMBDA'
|
||||||
|
elif t.kind == 'RETURN_VALUE':
|
||||||
|
t.kind = 'RETURN_VALUE_LAMBDA'
|
||||||
tokens.append(Token('LAMBDA_MARKER'))
|
tokens.append(Token('LAMBDA_MARKER'))
|
||||||
try:
|
try:
|
||||||
ast = parser.parse(self.p, tokens, customize)
|
# FIXME: have p.insts update in a better way
|
||||||
except parser.ParserError(e):
|
# modularity is broken here
|
||||||
raise ParserError(e, tokens)
|
p_insts = self.p.insts
|
||||||
except AssertionError(e):
|
self.p.insts = self.scanner.insts
|
||||||
|
ast = python_parser.parse(self.p, tokens, customize)
|
||||||
|
self.p.insts = p_insts
|
||||||
|
except (parser.ParserError(e), 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
|
||||||
@@ -1011,19 +1023,30 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
#
|
#
|
||||||
# NOTE: this differs from behavior in pysource.py
|
# NOTE: this differs from behavior in pysource.py
|
||||||
|
|
||||||
if len(tokens) >= 2 and not noneInNames:
|
if self.hide_internal:
|
||||||
if tokens[-1].kind == 'RETURN_VALUE':
|
if len(tokens) >= 2 and not noneInNames:
|
||||||
if tokens[-2].kind != 'LOAD_CONST':
|
if tokens[-1].kind in ('RETURN_VALUE', 'RETURN_VALUE_LAMBDA'):
|
||||||
tokens.append(Token('RETURN_LAST'))
|
# Python 3.4's classes can add a "return None" which is
|
||||||
if len(tokens) == 0:
|
# invalid syntax.
|
||||||
return
|
if tokens[-2].kind == 'LOAD_CONST':
|
||||||
|
if isTopLevel or tokens[-2].pattr is None:
|
||||||
|
del tokens[-2:]
|
||||||
|
else:
|
||||||
|
tokens.append(Token('RETURN_LAST'))
|
||||||
|
else:
|
||||||
|
tokens.append(Token('RETURN_LAST'))
|
||||||
|
if len(tokens) == 0:
|
||||||
|
return PASS
|
||||||
|
|
||||||
# Build AST from disassembly.
|
# Build AST from disassembly.
|
||||||
try:
|
try:
|
||||||
|
# FIXME: have p.insts update in a better way
|
||||||
|
# modularity is broken here
|
||||||
|
p_insts = self.p.insts
|
||||||
|
self.p.insts = self.scanner.insts
|
||||||
ast = parser.parse(self.p, tokens, customize)
|
ast = parser.parse(self.p, tokens, customize)
|
||||||
except parser.ParserError(e):
|
self.p.insts = p_insts
|
||||||
raise ParserError(e, tokens)
|
except (parser.ParserError(e), AssertionError(e)):
|
||||||
except AssertionError(e):
|
|
||||||
raise ParserError(e, tokens)
|
raise ParserError(e, tokens)
|
||||||
|
|
||||||
maybe_show_ast(self.showast, ast)
|
maybe_show_ast(self.showast, ast)
|
||||||
@@ -1303,6 +1326,7 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
sep = INDENT_PER_LEVEL[:-1]
|
sep = INDENT_PER_LEVEL[:-1]
|
||||||
start = len(self.f.getvalue())
|
start = len(self.f.getvalue())
|
||||||
self.write('{')
|
self.write('{')
|
||||||
|
self.set_pos_info(node[0], start, start+1)
|
||||||
|
|
||||||
if self.version > 3.0:
|
if self.version > 3.0:
|
||||||
if node[0].kind.startswith('kvlist'):
|
if node[0].kind.startswith('kvlist'):
|
||||||
@@ -1371,9 +1395,6 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
sep = line_seperator
|
sep = line_seperator
|
||||||
self.write('}')
|
self.write('}')
|
||||||
finish = len(self.f.getvalue())
|
finish = len(self.f.getvalue())
|
||||||
for n in node:
|
|
||||||
n.parent = node
|
|
||||||
self.set_pos_info(n, start, finish)
|
|
||||||
self.set_pos_info(node, start, finish)
|
self.set_pos_info(node, start, finish)
|
||||||
self.indent_less(INDENT_PER_LEVEL)
|
self.indent_less(INDENT_PER_LEVEL)
|
||||||
self.prec = p
|
self.prec = p
|
||||||
@@ -1626,7 +1647,8 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def deparse_code(version, co, out=StringIO(), showasm=False, showast=False,
|
def deparse_code(version, co, out=StringIO(), showasm=False, showast=False,
|
||||||
showgrammar=False, is_pypy=False, walker=FragmentsWalker):
|
showgrammar=False, code_objects={}, compile_mode='exec',
|
||||||
|
is_pypy=False, walker=FragmentsWalker):
|
||||||
"""
|
"""
|
||||||
Convert the code object co into a python source fragment.
|
Convert the code object co into a python source fragment.
|
||||||
|
|
||||||
@@ -1654,7 +1676,8 @@ def deparse_code(version, co, out=StringIO(), showasm=False, showast=False,
|
|||||||
# store final output stream for case of error
|
# store final output stream for case of error
|
||||||
scanner = get_scanner(version, is_pypy=is_pypy)
|
scanner = get_scanner(version, is_pypy=is_pypy)
|
||||||
|
|
||||||
tokens, customize = scanner.ingest(co)
|
tokens, customize = scanner.ingest(co, code_objects=code_objects,
|
||||||
|
show_asm=showasm)
|
||||||
|
|
||||||
tokens, customize = scanner.ingest(co)
|
tokens, customize = scanner.ingest(co)
|
||||||
maybe_show_asm(showasm, tokens)
|
maybe_show_asm(showasm, tokens)
|
||||||
@@ -1667,7 +1690,8 @@ def deparse_code(version, co, out=StringIO(), showasm=False, showast=False,
|
|||||||
# Build AST from disassembly.
|
# Build AST from disassembly.
|
||||||
# deparsed = pysource.FragmentsWalker(out, scanner, showast=showast)
|
# deparsed = pysource.FragmentsWalker(out, scanner, showast=showast)
|
||||||
deparsed = walker(version, scanner, showast=showast,
|
deparsed = walker(version, scanner, showast=showast,
|
||||||
debug_parser=debug_parser)
|
debug_parser=debug_parser, compile_mode=compile_mode,
|
||||||
|
is_pypy=is_pypy)
|
||||||
|
|
||||||
deparsed.ast = deparsed.build_ast(tokens, customize)
|
deparsed.ast = deparsed.build_ast(tokens, customize)
|
||||||
|
|
||||||
@@ -1771,7 +1795,7 @@ if __name__ == '__main__':
|
|||||||
return
|
return
|
||||||
|
|
||||||
def deparse_test_around(offset, name, co, is_pypy=IS_PYPY):
|
def deparse_test_around(offset, name, co, is_pypy=IS_PYPY):
|
||||||
sys_version = sys.version_info.major + (sys.version_info.minor / 10.0)
|
sys_version = sys.version_info[0] + (sys.version_info[1] / 10.0)
|
||||||
walk = deparse_code_around_offset(name, offset, sys_version, co, showasm=False, showast=False,
|
walk = deparse_code_around_offset(name, offset, sys_version, co, showasm=False, showast=False,
|
||||||
showgrammar=False, is_pypy=IS_PYPY)
|
showgrammar=False, is_pypy=IS_PYPY)
|
||||||
print("deparsed source")
|
print("deparsed source")
|
||||||
@@ -1800,6 +1824,8 @@ if __name__ == '__main__':
|
|||||||
return
|
return
|
||||||
|
|
||||||
def get_code_for_fn(fn):
|
def get_code_for_fn(fn):
|
||||||
|
if hasattr(fn, 'func_code'):
|
||||||
|
return fn.func_code
|
||||||
return fn.__code__
|
return fn.__code__
|
||||||
|
|
||||||
def test():
|
def test():
|
||||||
@@ -1822,5 +1848,5 @@ if __name__ == '__main__':
|
|||||||
# deparse_test(get_code_for_fn(FragmentsWalker.fixup_offsets))
|
# deparse_test(get_code_for_fn(FragmentsWalker.fixup_offsets))
|
||||||
# deparse_test(get_code_for_fn(FragmentsWalker.n_list))
|
# deparse_test(get_code_for_fn(FragmentsWalker.n_list))
|
||||||
print('=' * 30)
|
print('=' * 30)
|
||||||
deparse_test_around(408, 'n_list', get_code_for_fn(FragmentsWalker.n_build_list))
|
deparse_test_around(408, 'n_list', get_code_for_fn(FragmentsWalker.n_list))
|
||||||
# deparse_test(inspect.currentframe().f_code)
|
# deparse_test(inspect.currentframe().f_code)
|
||||||
|
@@ -2540,6 +2540,8 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
def build_ast(self, tokens, customize, is_lambda=False,
|
def build_ast(self, tokens, customize, is_lambda=False,
|
||||||
noneInNames=False, isTopLevel=False):
|
noneInNames=False, isTopLevel=False):
|
||||||
|
|
||||||
|
# FIXME: DRY with fragments.py
|
||||||
|
|
||||||
# assert isinstance(tokens[0], Token)
|
# assert isinstance(tokens[0], Token)
|
||||||
|
|
||||||
if is_lambda:
|
if is_lambda:
|
||||||
|
Reference in New Issue
Block a user