Skip to content

Instantly share code, notes, and snippets.

@podhmo
Last active July 13, 2019 03:10
Show Gist options
  • Save podhmo/5bbd7d6187afdcd68102e7ea81096640 to your computer and use it in GitHub Desktop.
Save podhmo/5bbd7d6187afdcd68102e7ea81096640 to your computer and use it in GitHub Desktop.
lineno:1 node:classdef value:A
lineno:2 node:funcdef value:f
lineno:4 node:simple_stmt value:
----------------------------------------
01:class A:
02: def f(self, x):
04: return "[]"
from pycomment.parse import parse_file, node_name, PyTreeVisitor, token
from lib2to3.pytree import Node
class Visitor(PyTreeVisitor):
def __init__(self, lineno):
self.lineno = lineno
self.r = []
# todo: performance
def visit(self, node):
if node.get_lineno() == self.lineno and node.type != token.INDENT:
self.r.append(node)
return
super().visit(node)
def select_node(t: Node, *, lineno: int) -> Node:
visitor = Visitor(lineno)
t = parse_file(filename)
visitor.visit(t)
return next(iter(visitor.r)) # xxx:
def find_parents(node: Node) -> Node:
r = [node]
seen = set()
target = node
while target:
if id(target) in seen:
break
if node_name(target) in ("funcdef", "classdef"):
r.append(target)
elif target.parent is None:
break
seen.add(id(target))
target = target.parent
return reversed(r)
def run(filename: str, *, lineno: int) -> None:
t = parse_file(filename)
node = select_node(t, lineno=lineno)
parents = list(find_parents(node))
for node in parents:
print(
f"lineno:{node.get_lineno()} node:{node_name(node)} value:{getattr(node.children[1], 'value', '')}"
)
print("----------------------------------------")
import linecache
for node in parents:
lineno = node.get_lineno()
print(f"{lineno:02d}:{linecache.getline(filename, lineno)}", end="")
filename = "target00.py"
run(filename, lineno=4)
class A:
def f(self, x):
if x is None:
return "[]"
else:
return f"[{x}]"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment