You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Better doc string detection
A bug in 2.7 test_descr.py revealed a problem with the way we were detecting docstrings. __doc__ = DocDescr() was getting confused with a docstring. This program also reveals other bugs in 3.2+ but we'll deal with that in another commit.
This commit is contained in:
@@ -21,7 +21,7 @@ for path in py_source:
|
|||||||
cfile = "bytecode_%s%s/%s" % (version, suffix, short) + "c"
|
cfile = "bytecode_%s%s/%s" % (version, suffix, short) + "c"
|
||||||
print("byte-compiling %s to %s" % (path, cfile))
|
print("byte-compiling %s to %s" % (path, cfile))
|
||||||
optimize = 2
|
optimize = 2
|
||||||
if vers >= (3, 0):
|
if vers > (3, 1):
|
||||||
py_compile.compile(path, cfile, optimize=optimize)
|
py_compile.compile(path, cfile, optimize=optimize)
|
||||||
else:
|
else:
|
||||||
py_compile.compile(path, cfile)
|
py_compile.compile(path, cfile)
|
||||||
|
BIN
test/bytecode_2.7_run/03_doc_assign.pyc
Normal file
BIN
test/bytecode_2.7_run/03_doc_assign.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.1_run/03_doc_assign.pyc
Normal file
BIN
test/bytecode_3.1_run/03_doc_assign.pyc
Normal file
Binary file not shown.
BIN
test/bytecode_3.3_run/03_doc_assign.pyc-notyet
Normal file
BIN
test/bytecode_3.3_run/03_doc_assign.pyc-notyet
Normal file
Binary file not shown.
BIN
test/bytecode_3.6_run/03_doc_assign.pyc-notyet
Normal file
BIN
test/bytecode_3.6_run/03_doc_assign.pyc-notyet
Normal file
Binary file not shown.
27
test/simple_source/bug27+/03_doc_assign.py
Normal file
27
test/simple_source/bug27+/03_doc_assign.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# From 2.7 test_descr.py
|
||||||
|
# Testing __doc__ descriptor...
|
||||||
|
# The bug in decompilation was erroneously matching
|
||||||
|
# __doc__ = as a docstring
|
||||||
|
|
||||||
|
"""This program is self-checking!"""
|
||||||
|
|
||||||
|
def test_doc_descriptor():
|
||||||
|
# Testing __doc__ descriptor...
|
||||||
|
# Python SF bug 542984
|
||||||
|
class DocDescr(object):
|
||||||
|
def __get__(self, object, otype):
|
||||||
|
if object:
|
||||||
|
object = object.__class__.__name__ + ' instance'
|
||||||
|
if otype:
|
||||||
|
otype = otype.__name__
|
||||||
|
return 'object=%s; type=%s' % (object, otype)
|
||||||
|
class OldClass:
|
||||||
|
__doc__ = DocDescr()
|
||||||
|
class NewClass(object):
|
||||||
|
__doc__ = DocDescr()
|
||||||
|
assert OldClass.__doc__ == 'object=None; type=OldClass'
|
||||||
|
assert OldClass().__doc__ == 'object=OldClass instance; type=OldClass'
|
||||||
|
assert NewClass.__doc__ == 'object=None; type=NewClass'
|
||||||
|
assert NewClass().__doc__ == 'object=NewClass instance; type=NewClass'
|
||||||
|
|
||||||
|
test_doc_descriptor()
|
@@ -164,7 +164,6 @@ from uncompyle6.semantics.consts import (
|
|||||||
NONE,
|
NONE,
|
||||||
RETURN_NONE,
|
RETURN_NONE,
|
||||||
PASS,
|
PASS,
|
||||||
ASSIGN_DOC_STRING,
|
|
||||||
NAME_MODULE,
|
NAME_MODULE,
|
||||||
TAB,
|
TAB,
|
||||||
INDENT_PER_LEVEL,
|
INDENT_PER_LEVEL,
|
||||||
@@ -2324,6 +2323,7 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
if ast[0] == "docstring":
|
if ast[0] == "docstring":
|
||||||
self.println(self.traverse(ast[0]))
|
self.println(self.traverse(ast[0]))
|
||||||
del ast[0]
|
del ast[0]
|
||||||
|
first_stmt = ast[0]
|
||||||
|
|
||||||
if 3.0 <= self.version <= 3.3:
|
if 3.0 <= self.version <= 3.3:
|
||||||
try:
|
try:
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from xdis import iscode
|
|
||||||
from uncompyle6.show import maybe_show_tree
|
from uncompyle6.show import maybe_show_tree
|
||||||
from copy import copy
|
from copy import copy
|
||||||
from spark_parser import GenericASTTraversal, GenericASTTraversalPruningException
|
from spark_parser import GenericASTTraversal, GenericASTTraversalPruningException
|
||||||
@@ -21,16 +20,35 @@ from spark_parser import GenericASTTraversal, GenericASTTraversalPruningExceptio
|
|||||||
from uncompyle6.semantics.helper import find_code_node
|
from uncompyle6.semantics.helper import find_code_node
|
||||||
from uncompyle6.parsers.treenode import SyntaxTree
|
from uncompyle6.parsers.treenode import SyntaxTree
|
||||||
from uncompyle6.scanners.tok import NoneToken, Token
|
from uncompyle6.scanners.tok import NoneToken, Token
|
||||||
from uncompyle6.semantics.consts import RETURN_NONE
|
from uncompyle6.semantics.consts import RETURN_NONE, ASSIGN_DOC_STRING
|
||||||
|
|
||||||
|
|
||||||
def is_docstring(node):
|
def is_docstring(node):
|
||||||
if node == "sstmt":
|
if node == "sstmt":
|
||||||
node = node[0]
|
node = node[0]
|
||||||
try:
|
# TODO: the test below on 2.7 succeeds for
|
||||||
return node.kind == "assign" and node[1][0].pattr == "__doc__"
|
# class OldClass:
|
||||||
except:
|
# __doc__ = DocDescr()
|
||||||
return False
|
# which produces:
|
||||||
|
#
|
||||||
|
# assign (2)
|
||||||
|
# 0. expr
|
||||||
|
# call (2)
|
||||||
|
# 0. expr
|
||||||
|
# L. 16 6 LOAD_DEREF 0 'DocDescr'
|
||||||
|
# 1. 9 CALL_FUNCTION_0 0 None
|
||||||
|
# 1. store
|
||||||
|
#
|
||||||
|
# See Python 2.7 test_descr.py
|
||||||
|
|
||||||
|
# If ASSIGN_DOC_STRING doesn't work we need something like the below
|
||||||
|
# but more elaborate to address the above.
|
||||||
|
|
||||||
|
# try:
|
||||||
|
# return node.kind == "assign" and node[1][0].pattr == "__doc__"
|
||||||
|
# except:
|
||||||
|
# return False
|
||||||
|
return node == ASSIGN_DOC_STRING
|
||||||
|
|
||||||
|
|
||||||
def is_not_docstring(call_stmt_node):
|
def is_not_docstring(call_stmt_node):
|
||||||
|
Reference in New Issue
Block a user