python - Non-graphical output from pycallgraph -
i've started writing small python utility cache functions. available caching tools (lru_cache
, beaker) not detect changes of sub-functions.
for this, need call graph. there exists excellent tool in pycallgraph gerald kaszuba. however, far i've got output function-name strings. need either function-objects or function-code-hashes.
what mean these 2 terms: let def foo(x): return x
, foo
function-object, , hash(foo.__code__.co_code)
function-code-hash.
what have
you can see have here. below minimal example. problem have in example, can't go function name (the string) function definition again. i'm trying eval(func)
.
so, guess there 2 ways of solving this:
- proper
pycallgraph.output
, or otherway want directly pycallgraph. - dynamically loading function
function.__name__
string.
import unittest pycallgraph import pycallgraph pycallgraph.output import graphvizoutput class callgraph: def __init__(self, output_file='callgraph.png'): self.graphviz = graphvizoutput() self.graphviz.output_file = output_file def execute(self, function, *args, **kwargs): pycallgraph(output=self.graphviz): ret = function(*args, **kwargs) self.graph = dict() node in self.graphviz.processor.nodes(): if node.name != '__main__': f = eval(node.name) self.graph[node.name] = hash(f.__code__.co_code) return ret def unchanged(self): '''checks each function in callgraph whether has changed. returns true if function have original code-hash. false otherwise. ''' func, codehash in self.graph.iteritems(): f = eval(func) if hash(f.__code__.co_code) != codehash: return false return true def func_inner(x): return x def func_outer(x): return 2*func_inner(x) class callgraphtest(unittest.testcase): def testchanges(self): cg = callgraph() y = cg.execute(func_outer, 3) self.assertequal(6, y) self.asserttrue(cg.unchanged()) # change 1 of functions def func_inner(x): return 3+x self.assertfalse(cg.unchanged()) # change back! def func_inner(x): return x self.asserttrue(cg.unchanged()) if __name__ == '__main__': unittest.main()
i've solved patching tracer.py
appropriate hashes.
# work out current function or method func_name = code.co_name + func_hash = hash(code.co_code)
i calculating value function name saved. later on, you'd need save value. doing dictionary func_name
key , hash value. in function nodes created assigning new field in stat_group
.
Comments
Post a Comment