You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 09:22:40 +08:00
Merge branch 'master' into python-3.3-to-3.5
This commit is contained in:
Binary file not shown.
7
test/simple_source/bug27+/01_argument_quoting.py
Normal file
7
test/simple_source/bug27+/01_argument_quoting.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# Bug was erroneously putting quotes around Exception on decompilatoin
|
||||||
|
# RUNNABLE!
|
||||||
|
|
||||||
|
"""This program is self-checking!"""
|
||||||
|
z = ["y", Exception]
|
||||||
|
assert z[0] == "y"
|
||||||
|
assert isinstance(z[1], Exception)
|
@@ -725,3 +725,10 @@ values = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert sorted(values.values())[1:] == list(range(2, 34))
|
assert sorted(values.values())[1:] == list(range(2, 34))
|
||||||
|
|
||||||
|
|
||||||
|
# Check that we can distinguish names from strings in literal collections, e.g. lists.
|
||||||
|
# The list has to have more than 4 items to get accumulated in a collection
|
||||||
|
a = ["y", 'Exception', "x", Exception, "z"]
|
||||||
|
assert a[1] == "Exception"
|
||||||
|
assert a[3] == Exception
|
||||||
|
@@ -81,7 +81,7 @@ SKIP_TESTS=(
|
|||||||
[test_winreg.py]=1 # it fails on its own
|
[test_winreg.py]=1 # it fails on its own
|
||||||
[test_winsound.py]=1 # it fails on its own
|
[test_winsound.py]=1 # it fails on its own
|
||||||
|
|
||||||
[test_zipimport_support.py]=1
|
[test_zipimport_support.py]=1 # expected test to raise ImportError
|
||||||
[test_zipfile64.py]=1 # Skip Long test
|
[test_zipfile64.py]=1 # Skip Long test
|
||||||
# .pyenv/versions/2.6.9/lib/python2.6/lib2to3/refactor.pyc
|
# .pyenv/versions/2.6.9/lib/python2.6/lib2to3/refactor.pyc
|
||||||
# .pyenv/versions/2.6.9/lib/python2.6/pyclbr.pyc
|
# .pyenv/versions/2.6.9/lib/python2.6/pyclbr.pyc
|
||||||
|
@@ -22,25 +22,20 @@ SKIP_TESTS=(
|
|||||||
[test_doctest2.py]=1 # Fails on its own
|
[test_doctest2.py]=1 # Fails on its own
|
||||||
|
|
||||||
[test_format.py]=1 # Control flow "and" vs nested "if"
|
[test_format.py]=1 # Control flow "and" vs nested "if"
|
||||||
[test_float.py]=1
|
|
||||||
[test_grp.py]=1 # test takes to long, works interactively though
|
|
||||||
[test_io.py]=1 # Test takes too long to run
|
[test_io.py]=1 # Test takes too long to run
|
||||||
[test_ioctl.py]=1 # Test takes too long to run
|
|
||||||
[test_lib2to3.py]=1 # test takes too long to run: 28 seconds
|
|
||||||
[test_memoryio.py]=1 # FIX
|
[test_memoryio.py]=1 # FIX
|
||||||
[test_multiprocessing.py]=1 # On uncompyle2, takes 24 secs
|
[test_multiprocessing.py]=1 # On uncompyle2, takes 24 secs
|
||||||
[test_poll.py]=1 # test takes too long to run: 11 seconds
|
|
||||||
[test_regrtest.py]=1 #
|
[test_regrtest.py]=1 #
|
||||||
[test_runpy.py]=1 # Long and fails on its own
|
[test_runpy.py]=1 # Long and fails on its own
|
||||||
[test_socket.py]=1 # Runs ok but takes 22 seconds
|
[test_socket.py]=1 # Runs ok but takes 22 seconds
|
||||||
[test_ssl.py]=1 #
|
[test_ssl.py]=1 # Fails on its own
|
||||||
[test_subprocess.py]=1 # Runs ok but takes 22 seconds
|
[test_subprocess.py]=1 # Runs ok but takes 22 seconds
|
||||||
[test_sys_settrace.py]=1 # Line numbers are expected to be different
|
[test_sys_settrace.py]=1 # Line numbers are expected to be different
|
||||||
|
|
||||||
[test_traceback.py]=1 # Line numbers change - duh.
|
[test_traceback.py]=1 # Line numbers change - duh.
|
||||||
[test_xpickle.py]=1 # Runs ok but takes 72 seconds
|
[test_xpickle.py]=1 # Runs ok but takes 72 seconds
|
||||||
[test_zipfile64.py]=1 # Runs ok but takes 204 seconds
|
[test_zipfile64.py]=1 # Runs ok but takes 204 seconds
|
||||||
[test_zipimport.py]=1 #
|
[test_zipimport.py]=1 # expected test to raise ImportError
|
||||||
)
|
)
|
||||||
# 334 unit-test files in about 15 minutes
|
# 334 unit-test files in about 15 minutes
|
||||||
|
|
||||||
|
@@ -174,11 +174,11 @@ class Scanner(object):
|
|||||||
has_extended_arg=False,
|
has_extended_arg=False,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if tokens[j] == "LOAD_CONST":
|
|
||||||
opname = "ADD_VALUE"
|
|
||||||
else:
|
|
||||||
opname = "ADD_VALUE_VAR"
|
|
||||||
for j in range(collection_start, i):
|
for j in range(collection_start, i):
|
||||||
|
if tokens[j] == "LOAD_CONST":
|
||||||
|
opname = "ADD_VALUE"
|
||||||
|
else:
|
||||||
|
opname = "ADD_VALUE_VAR"
|
||||||
new_tokens.append(
|
new_tokens.append(
|
||||||
Token(
|
Token(
|
||||||
opname=opname,
|
opname=opname,
|
||||||
|
@@ -321,7 +321,9 @@ class Scanner2(Scanner):
|
|||||||
"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]
|
||||||
next_tokens = self.bound_collection_from_tokens(
|
next_tokens = self.bound_collection_from_tokens(
|
||||||
|
@@ -19,6 +19,7 @@ import re
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
intern = sys.intern
|
intern = sys.intern
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
|
||||||
def off2int(offset, prefer_last=True):
|
def off2int(offset, prefer_last=True):
|
||||||
@@ -60,7 +61,7 @@ class Token:
|
|||||||
opname,
|
opname,
|
||||||
attr=None,
|
attr=None,
|
||||||
pattr=None,
|
pattr=None,
|
||||||
offset=-1,
|
offset:Union[int, str]=-1,
|
||||||
linestart=None,
|
linestart=None,
|
||||||
op=None,
|
op=None,
|
||||||
has_arg=None,
|
has_arg=None,
|
||||||
|
@@ -783,7 +783,7 @@ class NonterminalActions:
|
|||||||
def n_import_from(self, node):
|
def n_import_from(self, node):
|
||||||
relative_path_index = 0
|
relative_path_index = 0
|
||||||
if self.version >= (2, 5):
|
if self.version >= (2, 5):
|
||||||
if node[relative_path_index].attr > 0:
|
if node[relative_path_index].pattr > 0:
|
||||||
node[2].pattr = ("." * node[relative_path_index].attr) + node[2].pattr
|
node[2].pattr = ("." * node[relative_path_index].attr) + node[2].pattr
|
||||||
if self.version > (2, 7):
|
if self.version > (2, 7):
|
||||||
if isinstance(node[1].pattr, tuple):
|
if isinstance(node[1].pattr, tuple):
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2015-2022 by Rocky Bernstein
|
# Copyright (c) 2015-2023 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
|
||||||
@@ -131,8 +131,6 @@ Python.
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
IS_PYPY = "__pypy__" in sys.builtin_module_names
|
|
||||||
|
|
||||||
from spark_parser import GenericASTTraversal
|
from spark_parser import GenericASTTraversal
|
||||||
from xdis import COMPILER_FLAG_BIT, iscode
|
from xdis import COMPILER_FLAG_BIT, iscode
|
||||||
from xdis.version_info import PYTHON_VERSION_TRIPLE
|
from xdis.version_info import PYTHON_VERSION_TRIPLE
|
||||||
@@ -143,7 +141,7 @@ from uncompyle6.parsers.treenode import SyntaxTree
|
|||||||
from uncompyle6.scanner import Code, get_scanner
|
from uncompyle6.scanner import Code, get_scanner
|
||||||
from uncompyle6.scanners.tok import Token
|
from uncompyle6.scanners.tok import Token
|
||||||
from uncompyle6.semantics.check_ast import checker
|
from uncompyle6.semantics.check_ast import checker
|
||||||
from uncompyle6.semantics.consts import (ASSIGN_DOC_STRING, ASSIGN_TUPLE_PARAM,
|
from uncompyle6.semantics.consts import (ASSIGN_TUPLE_PARAM,
|
||||||
INDENT_PER_LEVEL, LINE_LENGTH, MAP,
|
INDENT_PER_LEVEL, LINE_LENGTH, MAP,
|
||||||
MAP_DIRECT, NAME_MODULE, NONE, PASS,
|
MAP_DIRECT, NAME_MODULE, NONE, PASS,
|
||||||
PRECEDENCE, RETURN_LOCALS,
|
PRECEDENCE, RETURN_LOCALS,
|
||||||
@@ -178,6 +176,8 @@ PARSER_DEFAULT_DEBUG = {
|
|||||||
"dups": False,
|
"dups": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IS_PYPY = "__pypy__" in sys.builtin_module_names
|
||||||
|
|
||||||
TREE_DEFAULT_DEBUG = {"before": False, "after": False}
|
TREE_DEFAULT_DEBUG = {"before": False, "after": False}
|
||||||
|
|
||||||
DEFAULT_DEBUG_OPTS = {
|
DEFAULT_DEBUG_OPTS = {
|
||||||
@@ -978,7 +978,6 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
|||||||
return result
|
return result
|
||||||
# return self.traverse(node[1])
|
# return self.traverse(node[1])
|
||||||
return "(" + name
|
return "(" + name
|
||||||
raise Exception("Can't find tuple parameter " + name)
|
|
||||||
|
|
||||||
def build_class(self, code):
|
def build_class(self, code):
|
||||||
"""Dump class definition, doc string and class body."""
|
"""Dump class definition, doc string and class body."""
|
||||||
@@ -1193,10 +1192,11 @@ class SourceWalker(GenericASTTraversal, NonterminalActions, ComprehensionMixin):
|
|||||||
del ast # Save memory
|
del ast # Save memory
|
||||||
return transform_tree
|
return transform_tree
|
||||||
|
|
||||||
# The bytecode for the end of the main routine has a
|
# The bytecode for the end of the main routine has a "return
|
||||||
# "return None". However, you can't issue a "return" statement in
|
# None". However, you can't issue a "return" statement in
|
||||||
# main. So as the old cigarette slogan goes: I'd rather switch (the token stream)
|
# main. So as the old cigarette slogan goes: I'd rather switch
|
||||||
# than fight (with the grammar to not emit "return None").
|
# (the token stream) than fight (with the grammar to not emit
|
||||||
|
# "return None").
|
||||||
if self.hide_internal:
|
if self.hide_internal:
|
||||||
if len(tokens) >= 2 and not noneInNames:
|
if len(tokens) >= 2 and not noneInNames:
|
||||||
if tokens[-1].kind in ("RETURN_VALUE", "RETURN_VALUE_LAMBDA"):
|
if tokens[-1].kind in ("RETURN_VALUE", "RETURN_VALUE_LAMBDA"):
|
||||||
@@ -1257,6 +1257,7 @@ def code_deparse(
|
|||||||
|
|
||||||
assert iscode(co)
|
assert iscode(co)
|
||||||
|
|
||||||
|
|
||||||
if version is None:
|
if version is None:
|
||||||
version = PYTHON_VERSION_TRIPLE
|
version = PYTHON_VERSION_TRIPLE
|
||||||
|
|
||||||
@@ -1328,16 +1329,11 @@ def code_deparse(
|
|||||||
|
|
||||||
assert not nonlocals
|
assert not nonlocals
|
||||||
|
|
||||||
if version >= (3, 0):
|
|
||||||
load_op = "LOAD_STR"
|
|
||||||
else:
|
|
||||||
load_op = "LOAD_CONST"
|
|
||||||
|
|
||||||
# convert leading '__doc__ = "..." into doc string
|
# convert leading '__doc__ = "..." into doc string
|
||||||
try:
|
try:
|
||||||
stmts = deparsed.ast
|
stmts = deparsed.ast
|
||||||
first_stmt = stmts[0][0]
|
first_stmt = stmts[0]
|
||||||
if version >= 3.6:
|
if version >= (3, 6):
|
||||||
if first_stmt[0] == "SETUP_ANNOTATIONS":
|
if first_stmt[0] == "SETUP_ANNOTATIONS":
|
||||||
del stmts[0]
|
del stmts[0]
|
||||||
assert stmts[0] == "sstmt"
|
assert stmts[0] == "sstmt"
|
||||||
@@ -1345,13 +1341,13 @@ def code_deparse(
|
|||||||
first_stmt = stmts[0][0]
|
first_stmt = stmts[0][0]
|
||||||
pass
|
pass
|
||||||
pass
|
pass
|
||||||
if first_stmt == ASSIGN_DOC_STRING(co.co_consts[0], load_op):
|
if first_stmt == "docstring":
|
||||||
print_docstring(deparsed, "", co.co_consts[0])
|
print_docstring(deparsed, "", co.co_consts[0])
|
||||||
del stmts[0]
|
del stmts[0]
|
||||||
if stmts[-1] == RETURN_NONE:
|
if stmts[-1] == RETURN_NONE:
|
||||||
stmts.pop() # remove last node
|
stmts.pop() # remove last node
|
||||||
# todo: if empty, add 'pass'
|
# todo: if empty, add 'pass'
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
deparsed.FUTURE_UNICODE_LITERALS = (
|
deparsed.FUTURE_UNICODE_LITERALS = (
|
||||||
|
Reference in New Issue
Block a user