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:
Binary file not shown.
BIN
test/bytecode_3.8_run/05_control_flow_bugs.pyc-notyet
Normal file
BIN
test/bytecode_3.8_run/05_control_flow_bugs.pyc-notyet
Normal file
Binary file not shown.
4
test/simple_source/bug26/00_future_divide.py
Normal file
4
test/simple_source/bug26/00_future_divide.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# From 2.7.17 fractions
|
||||
"""Rational, infinite-precision, real numbers."""
|
||||
|
||||
from __future__ import division
|
@@ -57,3 +57,20 @@ assert test_frozen(1, 1) == 4.0
|
||||
assert test_frozen(0, 1) == 5.0
|
||||
assert test_frozen(0.5, 0) == 6.0
|
||||
assert test_frozen(0, 0.5) == 8.0
|
||||
|
||||
# From 3.6.10 test_binop.py
|
||||
# Bug was getting "other += 3" outside of "if"/"else.
|
||||
def __floordiv__(a, b):
|
||||
other = 0
|
||||
if a:
|
||||
other = 1
|
||||
else:
|
||||
if not b:
|
||||
return 2
|
||||
other += 3
|
||||
return other
|
||||
|
||||
assert __floordiv__(True, True) == 4
|
||||
assert __floordiv__(True, False) == 4
|
||||
assert __floordiv__(False, True) == 3
|
||||
assert __floordiv__(False, False) == 2
|
||||
|
@@ -125,7 +125,9 @@ def ifelsestmt(self, lhs, n, rule, ast, tokens, first, last):
|
||||
if jump_forward == "jf_cf_pop":
|
||||
jump_forward = jump_forward[0]
|
||||
|
||||
jump_to_jump = False
|
||||
if jump_forward == "JUMP_FORWARD":
|
||||
jump_to_jump = True
|
||||
endif_target = int(jump_forward.pattr)
|
||||
last_offset = tokens[last].off2int()
|
||||
if endif_target != last_offset:
|
||||
@@ -143,7 +145,7 @@ def ifelsestmt(self, lhs, n, rule, ast, tokens, first, last):
|
||||
# if jmp_target < else_suite.first_child().off2int():
|
||||
# return True
|
||||
|
||||
if tokens[first].off2int() > jmp_target:
|
||||
if tokens[first].off2int() > jmp_target and not jump_to_jump:
|
||||
return True
|
||||
|
||||
return (jmp_target > tokens[last].off2int()) and tokens[
|
||||
|
@@ -9,12 +9,6 @@ def ifstmts_jump(self, lhs, n, rule, ast, tokens, first, last):
|
||||
return False
|
||||
|
||||
come_froms = ast[-1]
|
||||
# Make sure all of the "come froms" offset at the
|
||||
# end of the "if" come from somewhere inside the "if".
|
||||
# Since the come_froms are ordered so that lowest
|
||||
# offset COME_FROM is last, it is sufficient to test
|
||||
# just the last one.
|
||||
|
||||
# This is complicated, but note that the JUMP_IF instruction comes immediately
|
||||
# *before* _ifstmts_jump so that's what we have to test
|
||||
# the COME_FROM against. This can be complicated by intervening
|
||||
@@ -28,31 +22,30 @@ def ifstmts_jump(self, lhs, n, rule, ast, tokens, first, last):
|
||||
"COME_FROM",
|
||||
):
|
||||
pop_jump_index -= 1
|
||||
come_froms = ast[-1]
|
||||
|
||||
# FIXME: something is fishy when and EXTENDED ARG is needed before the
|
||||
# pop_jump_index instruction to get the argment. In this case, the
|
||||
# _ifsmtst_jump can jump to a spot beyond the come_froms.
|
||||
# That is going on in the non-EXTENDED_ARG case is that the POP_JUMP_IF
|
||||
# jumps to a JUMP_(FORWARD) which is changed into an EXTENDED_ARG POP_JUMP_IF
|
||||
# to the jumped forwareded address
|
||||
# to the jumped forwarded address
|
||||
if tokens[pop_jump_index].attr > 256:
|
||||
return False
|
||||
|
||||
pop_jump_offset = tokens[pop_jump_index].off2int(prefer_last=False)
|
||||
if isinstance(come_froms, Token):
|
||||
if (
|
||||
tokens[pop_jump_index].attr < tokens[pop_jump_index].offset
|
||||
and ast[0] != "pass"
|
||||
tokens[pop_jump_index].attr < pop_jump_offset and ast[0] != "pass"
|
||||
):
|
||||
# This is a jump backwards to a loop. All bets are off here when there the
|
||||
# unless statement is "pass" which has no instructions associated with it.
|
||||
return False
|
||||
return (
|
||||
come_froms.attr is not None
|
||||
and tokens[pop_jump_index].offset > come_froms.attr
|
||||
and pop_jump_offset > come_froms.attr
|
||||
)
|
||||
|
||||
elif len(come_froms) == 0:
|
||||
return False
|
||||
else:
|
||||
return tokens[pop_jump_index].offset > come_froms[-1].attr
|
||||
return pop_jump_offset > come_froms[-1].attr
|
||||
|
@@ -142,13 +142,12 @@ ASSIGN_DOC_STRING = lambda doc_string, doc_load: \
|
||||
SyntaxTree("store", [ Token("STORE_NAME", pattr="__doc__")])
|
||||
])])
|
||||
|
||||
NAME_MODULE = SyntaxTree("sstmt",
|
||||
[ SyntaxTree("assign",
|
||||
[ SyntaxTree("expr",
|
||||
[Token("LOAD_NAME", pattr="__name__", offset=0, has_arg=True)]),
|
||||
SyntaxTree("store",
|
||||
[ Token("STORE_NAME", pattr="__module__", offset=3, has_arg=True)])
|
||||
])])
|
||||
NAME_MODULE = SyntaxTree('assign',
|
||||
[ SyntaxTree('expr',
|
||||
[Token('LOAD_NAME', pattr='__name__', offset=0, has_arg=True)]),
|
||||
SyntaxTree('store',
|
||||
[ Token('STORE_NAME', pattr='__module__', offset=3, has_arg=True)])
|
||||
])
|
||||
|
||||
# God intended \t, but Python has decided to use 4 spaces.
|
||||
# If you want real tabs, use Go.
|
||||
|
@@ -2236,8 +2236,10 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
assert ast == "stmts"
|
||||
for i in range(len(ast)):
|
||||
# search for an assign-statement
|
||||
assert ast[i] == "sstmt"
|
||||
if ast[i] == "sstmt":
|
||||
node = ast[i][0]
|
||||
else:
|
||||
node = ast[i]
|
||||
if node == "assign" and node[0] == ASSIGN_TUPLE_PARAM(name):
|
||||
# okay, this assigns '.n' to something
|
||||
del ast[i]
|
||||
@@ -2308,16 +2310,17 @@ class SourceWalker(GenericASTTraversal, object):
|
||||
),
|
||||
],
|
||||
)
|
||||
# FIXME: is this right now that we've redone the grammar?
|
||||
have_qualname = ast[0][0] == QUAL_NAME
|
||||
else:
|
||||
# Python 3.4+ has constants like 'cmp_to_key.<locals>.K'
|
||||
# which are not simple classes like the < 3 case.
|
||||
try:
|
||||
if (
|
||||
first_stmt[0] == "assign"
|
||||
and first_stmt[0][0][0] == "LOAD_STR"
|
||||
and first_stmt[0][1] == "store"
|
||||
and first_stmt[0][1][0] == Token("STORE_NAME", pattr="__qualname__")
|
||||
first_stmt == "assign"
|
||||
and first_stmt[0][0] == "LOAD_STR"
|
||||
and first_stmt[1] == "store"
|
||||
and first_stmt[1][0] == Token("STORE_NAME", pattr="__qualname__")
|
||||
):
|
||||
have_qualname = True
|
||||
except:
|
||||
|
@@ -113,7 +113,7 @@ class TreeTransform(GenericASTTraversal, object):
|
||||
|
||||
testexpr = node[0]
|
||||
|
||||
if testexpr.kind != "testexpr":
|
||||
if testexpr not in ("testexpr", "testexprl"):
|
||||
return node
|
||||
|
||||
if node.kind in ("ifstmt", "ifstmtl"):
|
||||
@@ -128,8 +128,11 @@ class TreeTransform(GenericASTTraversal, object):
|
||||
# iflaststmtl works this way
|
||||
stmts = node[1]
|
||||
|
||||
if stmts in ("c_stmts",) and len(stmts) == 1:
|
||||
if stmts in ("c_stmts", "stmts") and len(stmts) == 1:
|
||||
raise_stmt = stmts[0]
|
||||
if raise_stmt != "raise_stmt1":
|
||||
raise_stmt = raise_stmt[0]
|
||||
|
||||
testtrue_or_false = testexpr[0]
|
||||
if (
|
||||
raise_stmt.kind == "raise_stmt1"
|
||||
@@ -145,6 +148,7 @@ class TreeTransform(GenericASTTraversal, object):
|
||||
assert_expr = testtrue_or_false[0]
|
||||
jump_cond = testtrue_or_false[1]
|
||||
assert_expr.kind = "assert_expr"
|
||||
|
||||
expr = raise_stmt[0]
|
||||
RAISE_VARARGS_1 = raise_stmt[1]
|
||||
call = expr[0]
|
||||
@@ -171,7 +175,7 @@ class TreeTransform(GenericASTTraversal, object):
|
||||
kind = "assert2not"
|
||||
|
||||
LOAD_ASSERT = call[0].first_child()
|
||||
if LOAD_ASSERT != "LOAD_ASSERT":
|
||||
if LOAD_ASSERT not in ( "LOAD_ASSERT", "LOAD_GLOBAL"):
|
||||
return node
|
||||
if isinstance(call[1], SyntaxTree):
|
||||
expr = call[1][0]
|
||||
@@ -403,8 +407,13 @@ class TreeTransform(GenericASTTraversal, object):
|
||||
pass
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
for i in range(len(self.ast)):
|
||||
sstmt = ast[i]
|
||||
if len(sstmt) == 1 and sstmt == "sstmt":
|
||||
ast[i] = ast[i][0]
|
||||
|
||||
if is_docstring(self.ast[i]):
|
||||
docstring_ast = SyntaxTree(
|
||||
"docstring",
|
||||
|
Reference in New Issue
Block a user