You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Sync with decompyle3
This commit is contained in:
@@ -210,7 +210,8 @@ class SourceWalkerError(Exception):
|
||||
|
||||
class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
"""
|
||||
Class to traverses a Parse Tree of the bytecode instruction built from parsing to produce some sort of source text.
|
||||
Class to traverses a Parse Tree of the bytecode instruction built from parsing to
|
||||
produce some sort of source text.
|
||||
The Parse tree may be turned an Abstract Syntax tree as an intermediate step.
|
||||
"""
|
||||
|
||||
@@ -318,7 +319,7 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
customize_for_version(self, is_pypy, version)
|
||||
return
|
||||
|
||||
def maybe_show_tree(self, ast, phase):
|
||||
def maybe_show_tree(self, tree, phase):
|
||||
if self.showast.get("before", False):
|
||||
self.println(
|
||||
"""
|
||||
@@ -334,7 +335,7 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
||||
+ " "
|
||||
)
|
||||
if self.showast.get(phase, False):
|
||||
maybe_show_tree(self, ast)
|
||||
maybe_show_tree(self, tree)
|
||||
|
||||
def str_with_template(self, ast):
|
||||
stream = sys.stdout
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Copyright (c) 2019-2023 by Rocky Bernstein
|
||||
# Copyright (c) 2019-2024 by Rocky Bernstein
|
||||
|
||||
# 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
|
||||
@@ -14,6 +14,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from copy import copy
|
||||
from typing import Optional
|
||||
|
||||
from spark_parser import GenericASTTraversal, GenericASTTraversalPruningException
|
||||
|
||||
@@ -56,29 +57,34 @@ def is_docstring(node, version, co_consts):
|
||||
return node == ASSIGN_DOC_STRING(co_consts[0], doc_load)
|
||||
|
||||
|
||||
def is_not_docstring(call_stmt_node):
|
||||
def is_not_docstring(call_stmt_node) -> bool:
|
||||
try:
|
||||
return (
|
||||
call_stmt_node == "call_stmt"
|
||||
and call_stmt_node[0][0] == "LOAD_STR"
|
||||
and call_stmt_node[1] == "POP_TOP"
|
||||
)
|
||||
except:
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
class TreeTransform(GenericASTTraversal, object):
|
||||
def __init__(self, version, show_ast=None, is_pypy=False):
|
||||
def __init__(
|
||||
self,
|
||||
version: tuple,
|
||||
is_pypy=False,
|
||||
show_ast: Optional[dict] = None,
|
||||
):
|
||||
self.version = version
|
||||
self.showast = show_ast
|
||||
self.is_pypy = is_pypy
|
||||
return
|
||||
|
||||
def maybe_show_tree(self, ast):
|
||||
def maybe_show_tree(self, tree):
|
||||
if isinstance(self.showast, dict) and (
|
||||
self.showast.get("before") or self.showast.get("after")
|
||||
):
|
||||
maybe_show_tree(self, ast)
|
||||
maybe_show_tree(self, tree)
|
||||
|
||||
def preorder(self, node=None):
|
||||
"""Walk the tree in roughly 'preorder' (a bit of a lie explained below).
|
||||
@@ -122,6 +128,7 @@ class TreeTransform(GenericASTTraversal, object):
|
||||
|
||||
mkfunc_pattr = node[-1].pattr
|
||||
if isinstance(mkfunc_pattr, tuple):
|
||||
assert isinstance(mkfunc_pattr, tuple)
|
||||
assert len(mkfunc_pattr) == 4 and isinstance(mkfunc_pattr, int)
|
||||
|
||||
if len(code.co_consts) > 0 and isinstance(code.co_consts[0], str):
|
||||
@@ -216,6 +223,7 @@ class TreeTransform(GenericASTTraversal, object):
|
||||
return node
|
||||
if isinstance(call[1], SyntaxTree):
|
||||
expr = call[1][0]
|
||||
assert_expr.transformed_by = "n_ifstmt"
|
||||
node = SyntaxTree(
|
||||
kind,
|
||||
[
|
||||
@@ -225,8 +233,8 @@ class TreeTransform(GenericASTTraversal, object):
|
||||
expr,
|
||||
RAISE_VARARGS_1,
|
||||
],
|
||||
transformed_by="n_ifstmt",
|
||||
)
|
||||
node.transformed_by = "n_ifstmt"
|
||||
pass
|
||||
pass
|
||||
else:
|
||||
@@ -254,9 +262,10 @@ class TreeTransform(GenericASTTraversal, object):
|
||||
|
||||
LOAD_ASSERT = expr[0]
|
||||
node = SyntaxTree(
|
||||
kind, [assert_expr, jump_cond, LOAD_ASSERT, RAISE_VARARGS_1]
|
||||
kind,
|
||||
[assert_expr, jump_cond, LOAD_ASSERT, RAISE_VARARGS_1],
|
||||
transformed_by="n_ifstmt",
|
||||
)
|
||||
node.transformed_by = ("n_ifstmt",)
|
||||
pass
|
||||
pass
|
||||
return node
|
||||
@@ -416,6 +425,12 @@ class TreeTransform(GenericASTTraversal, object):
|
||||
list_for_node.transformed_by = ("n_list_for",)
|
||||
return list_for_node
|
||||
|
||||
def n_negated_testtrue(self, node):
|
||||
assert node[0] == "testtrue"
|
||||
test_node = node[0][0]
|
||||
test_node.transformed_by = "n_negated_testtrue"
|
||||
return test_node
|
||||
|
||||
def n_stmts(self, node):
|
||||
if node.first_child() == "SETUP_ANNOTATIONS":
|
||||
prev = node[0][0]
|
||||
@@ -448,26 +463,28 @@ class TreeTransform(GenericASTTraversal, object):
|
||||
node = self.preorder(node)
|
||||
return node
|
||||
|
||||
def transform(self, ast, code):
|
||||
self.maybe_show_tree(ast)
|
||||
self.ast = copy(ast)
|
||||
def transform(self, parse_tree: GenericASTTraversal, code) -> GenericASTTraversal:
|
||||
self.maybe_show_tree(parse_tree)
|
||||
self.ast = copy(parse_tree)
|
||||
del parse_tree
|
||||
self.ast = self.traverse(self.ast, is_lambda=False)
|
||||
n = len(self.ast)
|
||||
|
||||
try:
|
||||
# Disambiguate a string (expression) which appears as a "call_stmt" at
|
||||
# the beginning of a function versus a docstring. Seems pretty academic,
|
||||
# but this is Python.
|
||||
call_stmt = ast[0][0]
|
||||
call_stmt = self.ast[0][0]
|
||||
if is_not_docstring(call_stmt):
|
||||
call_stmt.kind = "string_at_beginning"
|
||||
call_stmt.transformed_by = "transform"
|
||||
pass
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
for i in range(len(self.ast)):
|
||||
sstmt = ast[i]
|
||||
for i in range(n):
|
||||
sstmt = self.ast[i]
|
||||
if len(sstmt) == 1 and sstmt == "sstmt":
|
||||
self.ast[i] = self.ast[i][0]
|
||||
|
||||
@@ -493,7 +510,7 @@ class TreeTransform(GenericASTTraversal, object):
|
||||
if self.ast[-1] == RETURN_NONE:
|
||||
self.ast.pop() # remove last node
|
||||
# todo: if empty, add 'pass'
|
||||
except:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return self.ast
|
||||
|
Reference in New Issue
Block a user