You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Python 2.5 compatability
This commit is contained in:
@@ -307,17 +307,6 @@ def main(
|
|||||||
outstream = sys.stdout
|
outstream = sys.stdout
|
||||||
if do_linemaps:
|
if do_linemaps:
|
||||||
linemap_stream = sys.stdout
|
linemap_stream = sys.stdout
|
||||||
if do_verify:
|
|
||||||
prefix = os.path.basename(filename) + "-"
|
|
||||||
if prefix.endswith(".py"):
|
|
||||||
prefix = prefix[: -len(".py")]
|
|
||||||
|
|
||||||
# Unbuffer output if possible
|
|
||||||
if sys.stdout.isatty():
|
|
||||||
buffering = -1
|
|
||||||
else:
|
|
||||||
buffering = 0
|
|
||||||
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', buffering)
|
|
||||||
else:
|
else:
|
||||||
if filename.endswith(".pyc"):
|
if filename.endswith(".pyc"):
|
||||||
current_outfile = os.path.join(out_base, filename[0:-1])
|
current_outfile = os.path.join(out_base, filename[0:-1])
|
||||||
@@ -399,39 +388,7 @@ def main(
|
|||||||
else: # uncompile successful
|
else: # uncompile successful
|
||||||
if current_outfile:
|
if current_outfile:
|
||||||
outstream.close()
|
outstream.close()
|
||||||
if do_verify:
|
okay_files += 1
|
||||||
try:
|
|
||||||
msg = verify.compare_code_with_srcfile(
|
|
||||||
infile, current_outfile, do_verify
|
|
||||||
)
|
|
||||||
if not current_outfile:
|
|
||||||
if not msg:
|
|
||||||
print("\n# okay decompiling %s" % infile)
|
|
||||||
okay_files += 1
|
|
||||||
else:
|
|
||||||
verify_failed_files += 1
|
|
||||||
print("\n# %s\n\t%s", infile, msg)
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
okay_files += 1
|
|
||||||
pass
|
|
||||||
except verify.VerifyCmpError, e:
|
|
||||||
print(e)
|
|
||||||
verify_failed_files += 1
|
|
||||||
os.rename(current_outfile, current_outfile + "_unverified")
|
|
||||||
sys.stderr.write("### Error Verifying %s\n" % filename)
|
|
||||||
sys.stderr.write(str(e) + "\n")
|
|
||||||
if not outfile:
|
|
||||||
sys.stderr.write("### Error Verifiying %s" %
|
|
||||||
filename)
|
|
||||||
sys.stderr.write(e)
|
|
||||||
if raise_on_error:
|
|
||||||
raise
|
|
||||||
pass
|
|
||||||
pass
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
okay_files += 1
|
|
||||||
pass
|
pass
|
||||||
elif do_verify:
|
elif do_verify:
|
||||||
sys.stderr.write("\n### uncompile successful, "
|
sys.stderr.write("\n### uncompile successful, "
|
||||||
|
@@ -32,9 +32,7 @@ from xdis import (
|
|||||||
instruction_size,
|
instruction_size,
|
||||||
next_offset,
|
next_offset,
|
||||||
)
|
)
|
||||||
from xdis.version_info import PYTHON_VERSION_TRIPLE
|
from xdis.version_info import IS_PYPY, PYTHON_VERSION_TRIPLE, version_tuple_to_str
|
||||||
|
|
||||||
from xdis.version_info import IS_PYPY, version_tuple_to_str
|
|
||||||
|
|
||||||
from uncompyle6.scanners.tok import Token
|
from uncompyle6.scanners.tok import Token
|
||||||
|
|
||||||
@@ -106,7 +104,7 @@ class Code(object):
|
|||||||
|
|
||||||
|
|
||||||
class Scanner:
|
class Scanner:
|
||||||
def __init__(self, version: tuple, show_asm=None, is_pypy=False):
|
def __init__(self, version, show_asm=None, is_pypy=False):
|
||||||
self.version = version
|
self.version = version
|
||||||
self.show_asm = show_asm
|
self.show_asm = show_asm
|
||||||
self.is_pypy = is_pypy
|
self.is_pypy = is_pypy
|
||||||
@@ -321,7 +319,7 @@ class Scanner:
|
|||||||
return arg
|
return arg
|
||||||
|
|
||||||
def next_offset(self, op, offset):
|
def next_offset(self, op, offset):
|
||||||
return xdis.next_offset(op, self.opc, offset)
|
return 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)):
|
||||||
@@ -646,7 +644,7 @@ def get_scanner(version, is_pypy=False, show_asm=None):
|
|||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"Import Python version, %s, for decompilation failed"
|
"Import Python version, %s, for decompilation failed"
|
||||||
% version_tuple_to_str(version)
|
% version_tuple_to_str(version)
|
||||||
)
|
)
|
||||||
|
|
||||||
if is_pypy:
|
if is_pypy:
|
||||||
scanner_class_name = "ScannerPyPy%s" % v_str
|
scanner_class_name = "ScannerPyPy%s" % v_str
|
||||||
@@ -671,5 +669,6 @@ if __name__ == "__main__":
|
|||||||
# scanner = get_scanner('2.7.13', True)
|
# scanner = get_scanner('2.7.13', True)
|
||||||
# scanner = get_scanner(sys.version[:5], False)
|
# scanner = get_scanner(sys.version[:5], False)
|
||||||
from xdis.version_info import PYTHON_VERSION_TRIPLE
|
from xdis.version_info import PYTHON_VERSION_TRIPLE
|
||||||
|
|
||||||
scanner = get_scanner(PYTHON_VERSION_TRIPLE, IS_PYPY, True)
|
scanner = get_scanner(PYTHON_VERSION_TRIPLE, IS_PYPY, True)
|
||||||
tokens, customize = scanner.ingest(co, {}, show_asm="after")
|
tokens, customize = scanner.ingest(co, {}, show_asm="after")
|
||||||
|
@@ -6,21 +6,18 @@ This massages tokenized 1.5 bytecode to make it more amenable for
|
|||||||
grammar parsing.
|
grammar parsing.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# bytecode verification, verify(), uses JUMP_OPs from here
|
||||||
|
from xdis.opcodes import opcode_15
|
||||||
|
|
||||||
import uncompyle6.scanners.scanner21 as scan
|
import uncompyle6.scanners.scanner21 as scan
|
||||||
|
|
||||||
# from uncompyle6.scanners.scanner26 import ingest as ingest26
|
# from uncompyle6.scanners.scanner26 import ingest as ingest26
|
||||||
|
|
||||||
# bytecode verification, verify(), uses JUMP_OPs from here
|
|
||||||
from xdis.opcodes import opcode_15
|
|
||||||
|
|
||||||
JUMP_OPS = opcode_15.JUMP_OPS
|
JUMP_OPS = opcode_15.JUMP_OPS
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
# We base this off of 2.1 instead of the other way around
|
|
||||||
=======
|
|
||||||
|
|
||||||
# We base this off of 2.2 instead of the other way around
|
# We base this off of 2.1 instead of the other way around
|
||||||
>>>>>>> python-3.0-to-3.2
|
|
||||||
# because we cleaned things up this way.
|
# because we cleaned things up this way.
|
||||||
# The history is that 2.7 support is the cleanest,
|
# The history is that 2.7 support is the cleanest,
|
||||||
# then from that we got 2.6 and so on.
|
# then from that we got 2.6 and so on.
|
||||||
|
@@ -22,25 +22,28 @@ other versions of Python. Also, we save token information for later
|
|||||||
use in deparsing.
|
use in deparsing.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import uncompyle6.scanners.scanner2 as scan
|
# bytecode verification, verify(), uses jump_ops from here
|
||||||
|
|
||||||
# bytecode verification, verify(), uses JUMP_OPs from here
|
|
||||||
from xdis import iscode
|
from xdis import iscode
|
||||||
from xdis.opcodes import opcode_26
|
|
||||||
from xdis.bytecode import _get_const_info
|
from xdis.bytecode import _get_const_info
|
||||||
|
from xdis.opcodes import opcode_26
|
||||||
|
|
||||||
from uncompyle6.scanner import Token
|
from uncompyle6.scanner import Token
|
||||||
|
from uncompyle6.scanners.scanner2 import Scanner2
|
||||||
|
|
||||||
JUMP_OPS = opcode_26.JUMP_OPS
|
JUMP_OPS = opcode_26.JUMP_OPS
|
||||||
|
|
||||||
class Scanner26(scan.Scanner2):
|
|
||||||
|
class Scanner26(Scanner2):
|
||||||
def __init__(self, show_asm=False):
|
def __init__(self, show_asm=False):
|
||||||
super(Scanner26, self).__init__((2, 6), show_asm)
|
Scanner2.__init__(self, (2, 6), show_asm)
|
||||||
|
|
||||||
# "setup" opcodes
|
# "setup" opcodes
|
||||||
self.setup_ops = frozenset([
|
self.setup_ops = frozenset(
|
||||||
self.opc.SETUP_EXCEPT, self.opc.SETUP_FINALLY,
|
[
|
||||||
])
|
self.opc.SETUP_EXCEPT,
|
||||||
|
self.opc.SETUP_FINALLY,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -93,17 +96,18 @@ class Scanner26(scan.Scanner2):
|
|||||||
# 'LOAD_ASSERT' is used in assert statements.
|
# 'LOAD_ASSERT' is used in assert statements.
|
||||||
self.load_asserts = set()
|
self.load_asserts = set()
|
||||||
for i in self.op_range(0, codelen):
|
for i in self.op_range(0, codelen):
|
||||||
|
|
||||||
# We need to detect the difference between:
|
# We need to detect the difference between:
|
||||||
# raise AssertionError
|
# raise AssertionError
|
||||||
# and
|
# and
|
||||||
# assert ...
|
# assert ...
|
||||||
if (self.code[i] == self.opc.JUMP_IF_TRUE and
|
if (
|
||||||
i + 4 < codelen and
|
self.code[i] == self.opc.JUMP_IF_TRUE
|
||||||
self.code[i+3] == self.opc.POP_TOP and
|
and i + 4 < codelen
|
||||||
self.code[i+4] == self.opc.LOAD_GLOBAL):
|
and self.code[i + 3] == self.opc.POP_TOP
|
||||||
if names[self.get_argument(i+4)] == 'AssertionError':
|
and self.code[i + 4] == self.opc.LOAD_GLOBAL
|
||||||
self.load_asserts.add(i+4)
|
):
|
||||||
|
if names[self.get_argument(i + 4)] == "AssertionError":
|
||||||
|
self.load_asserts.add(i + 4)
|
||||||
|
|
||||||
jump_targets = self.find_jump_targets(show_asm)
|
jump_targets = self.find_jump_targets(show_asm)
|
||||||
# contains (code, [addrRefToCode])
|
# contains (code, [addrRefToCode])
|
||||||
@@ -128,7 +132,8 @@ class Scanner26(scan.Scanner2):
|
|||||||
i += 1
|
i += 1
|
||||||
op = self.code[offset]
|
op = self.code[offset]
|
||||||
op_name = self.opname[op]
|
op_name = self.opname[op]
|
||||||
oparg = None; pattr = None
|
oparg = None
|
||||||
|
pattr = None
|
||||||
|
|
||||||
if offset in jump_targets:
|
if offset in jump_targets:
|
||||||
jump_idx = 0
|
jump_idx = 0
|
||||||
@@ -139,28 +144,37 @@ class Scanner26(scan.Scanner2):
|
|||||||
# properly. For example, a "loop" with an "if" nested in it should have the
|
# properly. For example, a "loop" with an "if" nested in it should have the
|
||||||
# "loop" tag last so the grammar rule matches that properly.
|
# "loop" tag last so the grammar rule matches that properly.
|
||||||
last_jump_offset = -1
|
last_jump_offset = -1
|
||||||
for jump_offset in sorted(jump_targets[offset], reverse=True):
|
for jump_offset in sorted(jump_targets[offset], reverse=True):
|
||||||
if jump_offset != last_jump_offset:
|
if jump_offset != last_jump_offset:
|
||||||
tokens.append(Token(
|
tokens.append(
|
||||||
'COME_FROM', jump_offset, repr(jump_offset),
|
Token(
|
||||||
offset="%s_%d" % (offset, jump_idx),
|
"COME_FROM",
|
||||||
has_arg = True))
|
jump_offset,
|
||||||
|
repr(jump_offset),
|
||||||
|
offset="%s_%d" % (offset, jump_idx),
|
||||||
|
has_arg=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
jump_idx += 1
|
jump_idx += 1
|
||||||
last_jump_offset = jump_offset
|
last_jump_offset = jump_offset
|
||||||
elif offset in self.thens:
|
elif offset in self.thens:
|
||||||
tokens.append(Token(
|
tokens.append(
|
||||||
'THEN', None, self.thens[offset],
|
Token(
|
||||||
offset="%s_0" % offset,
|
"THEN",
|
||||||
has_arg = True))
|
None,
|
||||||
|
self.thens[offset],
|
||||||
|
offset="%s_0" % offset,
|
||||||
|
has_arg=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
has_arg = (op >= self.opc.HAVE_ARGUMENT)
|
has_arg = op >= self.opc.HAVE_ARGUMENT
|
||||||
if has_arg:
|
if has_arg:
|
||||||
oparg = self.get_argument(offset) + extended_arg
|
oparg = self.get_argument(offset) + extended_arg
|
||||||
extended_arg = 0
|
extended_arg = 0
|
||||||
if op == self.opc.EXTENDED_ARG:
|
if op == self.opc.EXTENDED_ARG:
|
||||||
extended_arg += self.extended_arg_val(oparg)
|
extended_arg += self.extended_arg_val(oparg)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
# Note: name used to match on rather than op since
|
# Note: name used to match on rather than op since
|
||||||
# BUILD_SET isn't in earlier Pythons.
|
# BUILD_SET isn't in earlier Pythons.
|
||||||
@@ -169,7 +183,14 @@ class Scanner26(scan.Scanner2):
|
|||||||
"BUILD_SET",
|
"BUILD_SET",
|
||||||
):
|
):
|
||||||
t = Token(
|
t = Token(
|
||||||
op_name, oparg, pattr, offset, self.linestarts.get(offset, None), op, has_arg, self.opc
|
op_name,
|
||||||
|
oparg,
|
||||||
|
pattr,
|
||||||
|
offset,
|
||||||
|
self.linestarts.get(offset, None),
|
||||||
|
op,
|
||||||
|
has_arg,
|
||||||
|
self.opc,
|
||||||
)
|
)
|
||||||
|
|
||||||
collection_type = op_name.split("_")[1]
|
collection_type = op_name.split("_")[1]
|
||||||
@@ -218,8 +239,8 @@ class Scanner26(scan.Scanner2):
|
|||||||
# FIXME: this is a hack to catch stuff like:
|
# FIXME: this is a hack to catch stuff like:
|
||||||
# if x: continue
|
# if x: continue
|
||||||
# the "continue" is not on a new line.
|
# the "continue" is not on a new line.
|
||||||
if len(tokens) and tokens[-1].kind == 'JUMP_BACK':
|
if len(tokens) and tokens[-1].kind == "JUMP_BACK":
|
||||||
tokens[-1].kind = intern('CONTINUE')
|
tokens[-1].kind = intern("CONTINUE")
|
||||||
|
|
||||||
elif op in self.opc.JABS_OPS:
|
elif op in self.opc.JABS_OPS:
|
||||||
pattr = repr(oparg)
|
pattr = repr(oparg)
|
||||||
@@ -237,17 +258,23 @@ class Scanner26(scan.Scanner2):
|
|||||||
# CE - Hack for >= 2.5
|
# CE - Hack for >= 2.5
|
||||||
# Now all values loaded via LOAD_CLOSURE are packed into
|
# Now all values loaded via LOAD_CLOSURE are packed into
|
||||||
# a tuple before calling MAKE_CLOSURE.
|
# a tuple before calling MAKE_CLOSURE.
|
||||||
if (self.version >= (2, 5) and op == self.opc.BUILD_TUPLE and
|
if (
|
||||||
self.code[self.prev[offset]] == self.opc.LOAD_CLOSURE):
|
self.version >= (2, 5)
|
||||||
|
and op == self.opc.BUILD_TUPLE
|
||||||
|
and self.code[self.prev[offset]] == self.opc.LOAD_CLOSURE
|
||||||
|
):
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
op_name = '%s_%d' % (op_name, oparg)
|
op_name = "%s_%d" % (op_name, oparg)
|
||||||
customize[op_name] = oparg
|
customize[op_name] = oparg
|
||||||
elif self.version > (2, 0) and op == self.opc.CONTINUE_LOOP:
|
elif self.version > (2, 0) and op == self.opc.CONTINUE_LOOP:
|
||||||
customize[op_name] = 0
|
customize[op_name] = 0
|
||||||
elif op_name in """
|
elif (
|
||||||
|
op_name
|
||||||
|
in """
|
||||||
CONTINUE_LOOP EXEC_STMT LOAD_LISTCOMP LOAD_SETCOMP
|
CONTINUE_LOOP EXEC_STMT LOAD_LISTCOMP LOAD_SETCOMP
|
||||||
""".split():
|
""".split()
|
||||||
|
):
|
||||||
customize[op_name] = 0
|
customize[op_name] = 0
|
||||||
elif op == self.opc.JUMP_ABSOLUTE:
|
elif op == self.opc.JUMP_ABSOLUTE:
|
||||||
# Further classify JUMP_ABSOLUTE into backward jumps
|
# Further classify JUMP_ABSOLUTE into backward jumps
|
||||||
@@ -263,23 +290,24 @@ class Scanner26(scan.Scanner2):
|
|||||||
# rule for that.
|
# rule for that.
|
||||||
target = self.get_target(offset)
|
target = self.get_target(offset)
|
||||||
if target <= offset:
|
if target <= offset:
|
||||||
op_name = 'JUMP_BACK'
|
op_name = "JUMP_BACK"
|
||||||
if (offset in self.stmts
|
if offset in self.stmts and self.code[offset + 3] not in (
|
||||||
and self.code[offset+3] not in (self.opc.END_FINALLY,
|
self.opc.END_FINALLY,
|
||||||
self.opc.POP_BLOCK)):
|
self.opc.POP_BLOCK,
|
||||||
if ((offset in self.linestarts and
|
):
|
||||||
tokens[-1].kind == 'JUMP_BACK')
|
if (
|
||||||
or offset not in self.not_continue):
|
offset in self.linestarts and tokens[-1].kind == "JUMP_BACK"
|
||||||
op_name = 'CONTINUE'
|
) or offset not in self.not_continue:
|
||||||
|
op_name = "CONTINUE"
|
||||||
else:
|
else:
|
||||||
# FIXME: this is a hack to catch stuff like:
|
# FIXME: this is a hack to catch stuff like:
|
||||||
# if x: continue
|
# if x: continue
|
||||||
# the "continue" is not on a new line.
|
# the "continue" is not on a new line.
|
||||||
if tokens[-1].kind == 'JUMP_BACK':
|
if tokens[-1].kind == "JUMP_BACK":
|
||||||
# We need 'intern' since we have
|
# We need 'intern' since we have
|
||||||
# already have processed the previous
|
# already have processed the previous
|
||||||
# token.
|
# token.
|
||||||
tokens[-1].kind = intern('CONTINUE')
|
tokens[-1].kind = intern("CONTINUE")
|
||||||
|
|
||||||
elif op == self.opc.LOAD_GLOBAL:
|
elif op == self.opc.LOAD_GLOBAL:
|
||||||
if offset in self.load_asserts:
|
if offset in self.load_asserts:
|
||||||
@@ -331,4 +359,6 @@ if __name__ == "__main__":
|
|||||||
print(t.format())
|
print(t.format())
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
print("Need to be Python 2.6 to demo; I am version %s." % version_tuple_to_str())
|
print(
|
||||||
|
"Need to be Python 2.6 to demo; I am version %s." % version_tuple_to_str()
|
||||||
|
)
|
||||||
|
@@ -7,20 +7,20 @@ grammar parsing.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
from uncompyle6.scanners.scanner2 import Scanner2
|
|
||||||
|
|
||||||
from xdis.version_info import version_tuple_to_str
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# bytecode verification, verify(), uses JUMP_OPs from here
|
# bytecode verification, verify(), uses JUMP_OPs from here
|
||||||
from xdis.opcodes import opcode_27
|
from xdis.opcodes import opcode_27
|
||||||
|
from xdis.version_info import version_tuple_to_str
|
||||||
|
|
||||||
|
from uncompyle6.scanners.scanner2 import Scanner2
|
||||||
|
|
||||||
JUMP_OPS = opcode_27.JUMP_OPs
|
JUMP_OPS = opcode_27.JUMP_OPs
|
||||||
|
|
||||||
|
|
||||||
class Scanner27(Scanner2):
|
class Scanner27(Scanner2):
|
||||||
def __init__(self, show_asm=False, is_pypy=False):
|
def __init__(self, show_asm=False, is_pypy=False):
|
||||||
super(Scanner27, self).__init__((2, 7), show_asm, is_pypy)
|
Scanner2.__init__(self, (2, 7), show_asm, is_pypy)
|
||||||
|
|
||||||
# opcodes that start statements
|
# opcodes that start statements
|
||||||
self.statement_opcodes = frozenset(
|
self.statement_opcodes = frozenset(
|
||||||
@@ -117,4 +117,6 @@ if __name__ == "__main__":
|
|||||||
print(t.format())
|
print(t.format())
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
print("Need to be Python 2.7 to demo; I am version %s." % version_tuple_to_str())
|
print(
|
||||||
|
"Need to be Python 2.7 to demo; I am version %s." % version_tuple_to_str()
|
||||||
|
)
|
||||||
|
@@ -33,11 +33,6 @@ For example:
|
|||||||
Finally we save token information.
|
Finally we save token information.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from xdis import iscode, instruction_size
|
|
||||||
from xdis.bytecode import _get_const_info
|
|
||||||
|
|
||||||
from uncompyle6.scanners.tok import Token
|
|
||||||
from uncompyle6.scanner import parse_fn_counts_30_35
|
|
||||||
import xdis
|
import xdis
|
||||||
|
|
||||||
# Get all the opcodes into globals
|
# Get all the opcodes into globals
|
||||||
@@ -54,7 +49,7 @@ globals().update(op3.opmap)
|
|||||||
|
|
||||||
class Scanner3(Scanner):
|
class Scanner3(Scanner):
|
||||||
def __init__(self, version, show_asm=None, is_pypy=False):
|
def __init__(self, version, show_asm=None, is_pypy=False):
|
||||||
super(Scanner3, self).__init__(version, show_asm, is_pypy)
|
Scanner.__init__(self, version, show_asm, is_pypy)
|
||||||
|
|
||||||
# Create opcode classification sets
|
# Create opcode classification sets
|
||||||
# Note: super initialization above initializes self.opc
|
# Note: super initialization above initializes self.opc
|
||||||
@@ -286,8 +281,7 @@ class Scanner3(Scanner):
|
|||||||
)
|
)
|
||||||
return new_tokens
|
return new_tokens
|
||||||
|
|
||||||
def bound_map_from_inst(
|
def bound_map_from_inst(self, insts, next_tokens, inst, t, i):
|
||||||
self, insts, next_tokens, inst, t, i):
|
|
||||||
"""
|
"""
|
||||||
Try to a sequence of instruction that ends with a BUILD_MAP into
|
Try to a sequence of instruction that ends with a BUILD_MAP into
|
||||||
a sequence that can be parsed much faster, but inserting the
|
a sequence that can be parsed much faster, but inserting the
|
||||||
@@ -1532,16 +1526,3 @@ class Scanner3(Scanner):
|
|||||||
instr_offsets = filtered
|
instr_offsets = filtered
|
||||||
filtered = []
|
filtered = []
|
||||||
return instr_offsets
|
return instr_offsets
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import inspect
|
|
||||||
|
|
||||||
from xdis.version_info import PYTHON_VERSION_TRIPLE
|
|
||||||
|
|
||||||
co = inspect.currentframe().f_code
|
|
||||||
|
|
||||||
tokens, customize = Scanner3(PYTHON_VERSION_TRIPLE).ingest(co)
|
|
||||||
for t in tokens:
|
|
||||||
print(t)
|
|
||||||
>>>>>>> python-3.0-to-3.2
|
|
||||||
|
@@ -48,7 +48,7 @@ CONST_COLLECTIONS = ("CONST_LIST", "CONST_SET", "CONST_DICT")
|
|||||||
|
|
||||||
class Scanner37Base(Scanner):
|
class Scanner37Base(Scanner):
|
||||||
def __init__(self, version, show_asm=None, debug="", is_pypy=False):
|
def __init__(self, version, show_asm=None, debug="", is_pypy=False):
|
||||||
super(Scanner37Base, self).__init__(version, show_asm, is_pypy)
|
Scanner.__init__(self, version, show_asm, is_pypy)
|
||||||
self.offset2tok_index = None
|
self.offset2tok_index = None
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
self.is_pypy = is_pypy
|
self.is_pypy = is_pypy
|
||||||
|
@@ -22,13 +22,13 @@ This sets up opcodes Python's 3.8 and calls a generalized
|
|||||||
scanner routine for Python 3.7 and up.
|
scanner routine for Python 3.7 and up.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from uncompyle6.scanners.tok import off2int
|
|
||||||
from uncompyle6.scanners.scanner37 import Scanner37
|
|
||||||
from uncompyle6.scanners.scanner37base import Scanner37Base
|
|
||||||
|
|
||||||
# bytecode verification, verify(), uses JUMP_OPs from here
|
# bytecode verification, verify(), uses JUMP_OPs from here
|
||||||
from xdis.opcodes import opcode_38 as opc
|
from xdis.opcodes import opcode_38 as opc
|
||||||
|
|
||||||
|
from uncompyle6.scanners.scanner37 import Scanner37
|
||||||
|
from uncompyle6.scanners.scanner37base import Scanner37Base
|
||||||
|
from uncompyle6.scanners.tok import off2int
|
||||||
|
|
||||||
# bytecode verification, verify(), uses JUMP_OPS from here
|
# bytecode verification, verify(), uses JUMP_OPS from here
|
||||||
JUMP_OPs = opc.JUMP_OPS
|
JUMP_OPs = opc.JUMP_OPS
|
||||||
|
|
||||||
@@ -60,8 +60,8 @@ class Scanner38(Scanner37):
|
|||||||
grammar rules. Specifically, variable arg tokens like MAKE_FUNCTION or BUILD_LIST
|
grammar rules. Specifically, variable arg tokens like MAKE_FUNCTION or BUILD_LIST
|
||||||
cause specific rules for the specific number of arguments they take.
|
cause specific rules for the specific number of arguments they take.
|
||||||
"""
|
"""
|
||||||
tokens, customize = super(Scanner38, self).ingest(
|
tokens, customize = Scanner37.ingest(
|
||||||
bytecode, classname, code_objects, show_asm
|
self, bytecode, classname, code_objects, show_asm
|
||||||
)
|
)
|
||||||
|
|
||||||
# Hacky way to detect loop ranges.
|
# Hacky way to detect loop ranges.
|
||||||
@@ -93,7 +93,7 @@ class Scanner38(Scanner37):
|
|||||||
if len(loop_ends):
|
if len(loop_ends):
|
||||||
next_end = loop_ends[-1]
|
next_end = loop_ends[-1]
|
||||||
else:
|
else:
|
||||||
next_end = tokens[len(tokens)-1].off2int() + 10
|
next_end = tokens[len(tokens) - 1].off2int() + 10
|
||||||
|
|
||||||
# things that smash new_tokens like BUILD_LIST have to come first.
|
# things that smash new_tokens like BUILD_LIST have to come first.
|
||||||
|
|
||||||
@@ -161,4 +161,6 @@ if __name__ == "__main__":
|
|||||||
print(t.format())
|
print(t.format())
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
print("Need to be Python 3.8 to demo; I am version %s." % version_tuple_to_str())
|
print(
|
||||||
|
"Need to be Python 3.8 to demo; I am version %s." % version_tuple_to_str()
|
||||||
|
)
|
||||||
|
@@ -65,7 +65,6 @@ The node position 0 will be associated with "import".
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
from bisect import bisect_right
|
from bisect import bisect_right
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
||||||
from spark_parser.ast import GenericASTTraversalPruningException
|
from spark_parser.ast import GenericASTTraversalPruningException
|
||||||
@@ -77,7 +76,7 @@ from uncompyle6.parsers.treenode import SyntaxTree
|
|||||||
from uncompyle6.scanner import Code, Token, get_scanner
|
from uncompyle6.scanner import Code, Token, get_scanner
|
||||||
from uncompyle6.semantics import pysource
|
from uncompyle6.semantics import pysource
|
||||||
from uncompyle6.semantics.check_ast import checker
|
from uncompyle6.semantics.check_ast import checker
|
||||||
from uncompyle6.semantics.pysource import ParserError
|
from uncompyle6.semantics.parser_error import ParserError
|
||||||
from uncompyle6.show import maybe_show_asm, maybe_show_tree
|
from uncompyle6.show import maybe_show_asm, maybe_show_tree
|
||||||
|
|
||||||
if PYTHON_VERSION_TRIPLE < (2, 5):
|
if PYTHON_VERSION_TRIPLE < (2, 5):
|
||||||
@@ -94,19 +93,18 @@ from uncompyle6.semantics.consts import (
|
|||||||
TABLE_DIRECT,
|
TABLE_DIRECT,
|
||||||
escape,
|
escape,
|
||||||
)
|
)
|
||||||
|
from uncompyle6.semantics.pysource import (
|
||||||
|
DEFAULT_DEBUG_OPTS,
|
||||||
|
TREE_DEFAULT_DEBUG,
|
||||||
|
StringIO,
|
||||||
|
)
|
||||||
|
from uncompyle6.show import maybe_show_asm, maybe_show_tree
|
||||||
|
|
||||||
if PYTHON_VERSION_TRIPLE < (2, 6):
|
if PYTHON_VERSION_TRIPLE < (2, 6):
|
||||||
from xdis.namedtuple24 import namedtuple
|
from xdis.namedtuple24 import namedtuple
|
||||||
else:
|
else:
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
from uncompyle6.semantics.pysource import (
|
|
||||||
DEFAULT_DEBUG_OPTS,
|
|
||||||
TREE_DEFAULT_DEBUG,
|
|
||||||
ParserError,
|
|
||||||
StringIO,
|
|
||||||
)
|
|
||||||
from uncompyle6.show import maybe_show_asm, maybe_show_tree
|
|
||||||
|
|
||||||
NodeInfo = namedtuple("NodeInfo", "node start finish")
|
NodeInfo = namedtuple("NodeInfo", "node start finish")
|
||||||
ExtractInfo = namedtuple(
|
ExtractInfo = namedtuple(
|
||||||
"ExtractInfo",
|
"ExtractInfo",
|
||||||
@@ -166,7 +164,7 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
version: tuple,
|
version,
|
||||||
scanner,
|
scanner,
|
||||||
showast=TREE_DEFAULT_DEBUG,
|
showast=TREE_DEFAULT_DEBUG,
|
||||||
debug_parser=PARSER_DEFAULT_DEBUG,
|
debug_parser=PARSER_DEFAULT_DEBUG,
|
||||||
@@ -1201,7 +1199,7 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
ast = python_parser.parse(self.p, tokens, customize, code)
|
ast = python_parser.parse(self.p, tokens, customize, code)
|
||||||
self.customize(customize)
|
self.customize(customize)
|
||||||
self.p.insts = p_insts
|
self.p.insts = p_insts
|
||||||
except (parser.ParserError(e), AssertionError(e)):
|
except (ParserError(e), AssertionError(e)):
|
||||||
raise ParserError(e, tokens)
|
raise ParserError(e, tokens)
|
||||||
transform_tree = self.treeTransform.transform(ast, code)
|
transform_tree = self.treeTransform.transform(ast, code)
|
||||||
maybe_show_tree(self, ast)
|
maybe_show_tree(self, ast)
|
||||||
@@ -1241,7 +1239,7 @@ class FragmentsWalker(pysource.SourceWalker, object):
|
|||||||
self.p.opc = self.scanner.opc
|
self.p.opc = self.scanner.opc
|
||||||
ast = python_parser.parse(self.p, tokens, customize, code)
|
ast = python_parser.parse(self.p, tokens, customize, code)
|
||||||
self.p.insts = p_insts
|
self.p.insts = p_insts
|
||||||
except (parser.ParserError(e), AssertionError(e)):
|
except (ParserError(e), AssertionError(e)):
|
||||||
raise ParserError(e, tokens, {})
|
raise ParserError(e, tokens, {})
|
||||||
|
|
||||||
checker(ast, False, self.ast_errors)
|
checker(ast, False, self.ast_errors)
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2022-2023 by Rocky Bernstein
|
# Copyright (c) 2022-2024 by Rocky Bernstein
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,16 +18,10 @@ Custom Nonterminal action functions. See NonterminalActions docstring.
|
|||||||
|
|
||||||
from uncompyle6.parsers.treenode import SyntaxTree
|
from uncompyle6.parsers.treenode import SyntaxTree
|
||||||
from uncompyle6.scanners.tok import Token
|
from uncompyle6.scanners.tok import Token
|
||||||
|
|
||||||
from uncompyle6.semantics.helper import (
|
|
||||||
find_code_node,
|
|
||||||
flatten_list,
|
|
||||||
)
|
|
||||||
from uncompyle6.util import better_repr
|
|
||||||
|
|
||||||
from uncompyle6.semantics.consts import INDENT_PER_LEVEL, NONE, PRECEDENCE, minint
|
from uncompyle6.semantics.consts import INDENT_PER_LEVEL, NONE, PRECEDENCE, minint
|
||||||
from uncompyle6.semantics.helper import find_code_node, flatten_list
|
from uncompyle6.semantics.helper import find_code_node, flatten_list
|
||||||
from uncompyle6.util import better_repr, get_code_name
|
from uncompyle6.util import better_repr
|
||||||
|
|
||||||
|
|
||||||
class NonterminalActions:
|
class NonterminalActions:
|
||||||
"""
|
"""
|
||||||
@@ -719,8 +713,9 @@ class NonterminalActions:
|
|||||||
iter_index = 4
|
iter_index = 4
|
||||||
else:
|
else:
|
||||||
iter_index = 3
|
iter_index = 3
|
||||||
self.comprehension_walk(node, iter_index=iter_index,
|
self.comprehension_walk(
|
||||||
code_index=code_index)
|
node, iter_index=iter_index, code_index=code_index
|
||||||
|
)
|
||||||
pass
|
pass
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
@@ -168,6 +168,7 @@ from uncompyle6.semantics.parser_error import ParserError
|
|||||||
from uncompyle6.semantics.transform import TreeTransform, is_docstring
|
from uncompyle6.semantics.transform import TreeTransform, is_docstring
|
||||||
from uncompyle6.show import maybe_show_tree
|
from uncompyle6.show import maybe_show_tree
|
||||||
from uncompyle6.util import better_repr
|
from uncompyle6.util import better_repr
|
||||||
|
|
||||||
if PYTHON_VERSION_TRIPLE < (2, 5):
|
if PYTHON_VERSION_TRIPLE < (2, 5):
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
else:
|
else:
|
||||||
@@ -1260,7 +1261,7 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
|||||||
self.p.opc = self.scanner.opc
|
self.p.opc = self.scanner.opc
|
||||||
ast = parse(self.p, tokens, customize, code)
|
ast = parse(self.p, tokens, customize, code)
|
||||||
self.p.insts = p_insts
|
self.p.insts = p_insts
|
||||||
except python_parser.ParserError, e:
|
except ParserError, e:
|
||||||
raise ParserError(e, tokens, self.p.debug["reduce"])
|
raise ParserError(e, tokens, self.p.debug["reduce"])
|
||||||
|
|
||||||
checker(ast, False, self.ast_errors)
|
checker(ast, False, self.ast_errors)
|
||||||
|
@@ -4,22 +4,23 @@
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
from math import copysign
|
from math import copysign
|
||||||
|
|
||||||
def is_negative_zero(n):
|
def is_negative_zero(n):
|
||||||
"""Returns true if n is -0.0"""
|
"""Returns true if n is -0.0"""
|
||||||
return n == 0.0 and copysign(1, n) == -1
|
return n == 0.0 and copysign(1, n) == -1
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
||||||
def is_negative_zero(n):
|
def is_negative_zero(n):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_code_name(code) -> str:
|
|
||||||
|
def get_code_name(code):
|
||||||
code_name = code.co_name
|
code_name = code.co_name
|
||||||
if isinstance(code_name, UnicodeForPython3):
|
if isinstance(code_name, UnicodeForPython3):
|
||||||
return code_name.value.decode("utf-8")
|
return code_name.value.decode("utf-8")
|
||||||
return code_name
|
return code_name
|
||||||
|
|
||||||
def is_negative_zero(n):
|
|
||||||
"""Returns true if n is -0.0"""
|
|
||||||
return n == 0.0 and copysign(1, n) == -1
|
|
||||||
|
|
||||||
def better_repr(v, version):
|
def better_repr(v, version):
|
||||||
"""Work around Python's unorthogonal and unhelpful repr() for primitive float
|
"""Work around Python's unorthogonal and unhelpful repr() for primitive float
|
||||||
|
Reference in New Issue
Block a user