Work on fragments API...

* Add code_deparse_around_offset
* find_globals -> find_globals_and_nonlocals
This commit is contained in:
rocky
2018-03-20 13:43:16 -04:00
parent 9f2c7352e7
commit 85a49aec2f

View File

@@ -65,9 +65,10 @@ The node position 0 will be associated with "import".
from __future__ import print_function
import re, sys
import re
from xdis.code import iscode
from xdis.magics import sysinfo2float
from uncompyle6.semantics import pysource
from uncompyle6 import parser
from uncompyle6.scanner import Token, Code, get_scanner
@@ -1763,7 +1764,7 @@ def code_deparse(co, out=StringIO(), version=None, is_pypy=None,
assert iscode(co)
if version is None:
version = float(sys.version[0:3])
version = sysinfo2float()
if is_pypy is None:
is_pypy = IS_PYPY
@@ -1797,7 +1798,11 @@ def code_deparse(co, out=StringIO(), version=None, is_pypy=None,
# convert leading '__doc__ = "..." into doc string
assert deparsed.ast == 'stmts'
deparsed.mod_globs = pysource.find_globals(deparsed.ast, set())
(deparsed.mod_globs,
nonlocals) = (pysource
.find_globals_and_nonlocals(deparsed.ast,
set(), set(),
co, version))
# Just when you think we've forgotten about what we
# were supposed to to: Generate source from AST!
@@ -1836,15 +1841,22 @@ def find_gt(a, x):
return a[i]
raise ValueError
def deparse_code_around_offset(name, offset, version, co, out=StringIO(),
showasm=False, showast=False,
showgrammar=False, is_pypy=False):
def code_deparse_around_offset(name, offset, co, out=StringIO(),
version=None, is_pypy=None,
debug_opts=DEFAULT_DEBUG_OPTS):
"""
Like deparse_code(), but given a function/module name and
offset, finds the node closest to offset. If offset is not an instruction boundary,
we raise an IndexError.
"""
deparsed = deparse_code(version, co, out, showasm, showast, showgrammar, is_pypy)
assert iscode(co)
if version is None:
version = sysinfo2float()
if is_pypy is None:
is_pypy = IS_PYPY
deparsed = code_deparse(co, out, version, is_pypy, debug_opts)
if (name, offset) in deparsed.offsets.keys():
# This is the easy case
return deparsed
@@ -1857,6 +1869,17 @@ def deparse_code_around_offset(name, offset, version, co, out=StringIO(),
deparsed.offsets[name, offset] = deparsed.offsets[name, found_offset]
return deparsed
# Deprecated. Here still for compatability
def deparse_code_around_offset(name, offset, version, co, out=StringIO(),
showasm=False, showast=False,
showgrammar=False, is_pypy=False):
debug_opts = {
'asm': showasm,
'ast': showast,
'grammar': showgrammar
}
return code_deparse(name, offset, co, out, version, is_pypy,
debug_opts)
def op_at_code_loc(code, loc, opc):
"""Return the instruction name at code[loc] using
@@ -1893,96 +1916,91 @@ def deparsed_find(tup, deparsed, code):
return nodeInfo
# if __name__ == '__main__':
if __name__ == '__main__':
# def deparse_test(co, is_pypy=IS_PYPY):
# deparsed = code_deparse(co, is_pypy=IS_PYPY)
# print("deparsed source")
# print(deparsed.text, "\n")
# print('------------------------')
# for name, offset in sorted(deparsed.offsets.keys(),
# key=lambda x: str(x[0])):
# print("name %s, offset %s" % (name, offset))
# nodeInfo = deparsed.offsets[name, offset]
# nodeInfo2 = deparsed_find((name, offset), deparsed, co)
# assert nodeInfo == nodeInfo2
# node = nodeInfo.node
# extractInfo = deparsed.extract_node_info(node)
# print("code: %s" % node.kind)
# # print extractInfo
# print(extractInfo.selectedText)
# print(extractInfo.selectedLine)
# print(extractInfo.markerLine)
# extractInfo, p = deparsed.extract_parent_info(node)
def deparse_test(co, is_pypy=IS_PYPY):
deparsed = code_deparse(co, is_pypy=IS_PYPY)
print("deparsed source")
print(deparsed.text, "\n")
print('------------------------')
for name, offset in sorted(deparsed.offsets.keys(),
key=lambda x: str(x[0])):
print("name %s, offset %s" % (name, offset))
nodeInfo = deparsed.offsets[name, offset]
nodeInfo2 = deparsed_find((name, offset), deparsed, co)
assert nodeInfo == nodeInfo2
node = nodeInfo.node
extractInfo = deparsed.extract_node_info(node)
print("code: %s" % node.kind)
# print extractInfo
print(extractInfo.selectedText)
print(extractInfo.selectedLine)
print(extractInfo.markerLine)
extractInfo, p = deparsed.extract_parent_info(node)
# if extractInfo:
# print("Contained in...")
# print(extractInfo.selectedLine)
# print(extractInfo.markerLine)
# print("code: %s" % p.kind)
# print('=' * 40)
# pass
# pass
# return
if extractInfo:
print("Contained in...")
print(extractInfo.selectedLine)
print(extractInfo.markerLine)
print("code: %s" % p.kind)
print('=' * 40)
pass
pass
return
# def deparse_test_around(offset, name, co, is_pypy=IS_PYPY):
# sys_version = sys.version_info.major + (sys.version_info.minor / 10.0)
# deparsed = deparse_code_around_offset(name, offset, sys_version, co,
# showasm=False,
# showast=False,
# showgrammar=False,
# is_pypy=IS_PYPY)
# print("deparsed source")
# print(deparsed.text, "\n")
# print('------------------------')
# for name, offset in sorted(deparsed.offsets.keys(),
# key=lambda x: str(x[0])):
# print("name %s, offset %s" % (name, offset))
# nodeInfo = deparsed.offsets[name, offset]
# node = nodeInfo.node
# extractInfo = deparsed.extract_node_info(node)
# print("code: %s" % node.kind)
# # print extractInfo
# print(extractInfo.selectedText)
# print(extractInfo.selectedLine)
# print(extractInfo.markerLine)
# extractInfo, p = deparsed.extract_parent_info(node)
# if extractInfo:
# print("Contained in...")
# print(extractInfo.selectedLine)
# print(extractInfo.markerLine)
# print("code: %s" % p.kind)
# print('=' * 40)
# pass
# pass
# return
def deparse_test_around(offset, name, co, is_pypy=IS_PYPY):
deparsed = code_deparse_around_offset(name, offset, co)
print("deparsed source")
print(deparsed.text, "\n")
print('------------------------')
for name, offset in sorted(deparsed.offsets.keys(),
key=lambda x: str(x[0])):
print("name %s, offset %s" % (name, offset))
nodeInfo = deparsed.offsets[name, offset]
node = nodeInfo.node
extractInfo = deparsed.extract_node_info(node)
print("code: %s" % node.kind)
# print extractInfo
print(extractInfo.selectedText)
print(extractInfo.selectedLine)
print(extractInfo.markerLine)
extractInfo, p = deparsed.extract_parent_info(node)
if extractInfo:
print("Contained in...")
print(extractInfo.selectedLine)
print(extractInfo.markerLine)
print("code: %s" % p.kind)
print('=' * 40)
pass
pass
return
# def get_code_for_fn(fn):
# return fn.__code__
def get_code_for_fn(fn):
return fn.__code__
# def test():
# import os, sys
def test():
import os, sys
# def div_test(a, b, c):
# return a / b / c
def div_test(a, b, c):
return a / b / c
# def gcd(a, b):
# if a > b:
# (a, b) = (b, a)
# pass
def gcd(a, b):
if a > b:
(a, b) = (b, a)
pass
# if a <= 0:
# return None
# if a == 1 or a == b:
# return a
# return gcd(b-a, a)
if a <= 0:
return None
if a == 1 or a == b:
return a
return gcd(b-a, a)
# # check_args(['3', '5'])
# # deparse_test(get_code_for_fn(gcd))
# deparse_test(get_code_for_fn(div_test))
# # deparse_test(get_code_for_fn(test))
# # deparse_test(get_code_for_fn(FragmentsWalker.fixup_offsets))
# # deparse_test(get_code_for_fn(FragmentsWalker.n_list))
# print('=' * 30)
# # deparse_test_around(408, 'n_list', get_code_for_fn(FragmentsWalker.n_build_list))
# # deparse_test(inspect.currentframe().f_code)
# check_args(['3', '5'])
# deparse_test(get_code_for_fn(gcd))
deparse_test(get_code_for_fn(div_test))
# deparse_test(get_code_for_fn(test))
# deparse_test(get_code_for_fn(FragmentsWalker.fixup_offsets))
# deparse_test(get_code_for_fn(FragmentsWalker.n_list))
print('=' * 30)
# deparse_test_around(408, 'n_list', get_code_for_fn(FragmentsWalker.n_build_list))
# deparse_test(inspect.currentframe().f_code)