def xxx_test_later_along_link(): S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True}) s1 = lltype.malloc(S1) s1.x = 123 s2 = lltype.malloc(S1) s2.x = 60 def fn(x, y): if x: x = s1.x else: x = s2.x y *= 2 return (x + 1) - y graph, t = get_graph(fn, [int, int]) assert summary(graph) == { 'int_is_true': 1, 'getfield': 2, 'int_mul': 1, 'int_add': 1, 'int_sub': 1 } constant_fold_graph(graph) assert summary(graph) == {'int_is_true': 1, 'int_mul': 1, 'int_sub': 1} check_graph(graph, [-1], 124, t) check_graph(graph, [0], 61, t)
def test_isinstance(): class A: pass class B(A): pass def g(n): if n > 10: return A() else: b = B() b.value = 321 return b def fn(n): x = g(n) assert isinstance(x, B) return x.value t, graph = check(fn, [5], 321) assert summary(graph)['debug_assert'] == 1 from pypy.translator.backendopt.removenoops import remove_debug_assert remove_debug_assert(graph) assert "debug_assert" not in summary(graph) from pypy.translator.simplify import transform_dead_op_vars transform_dead_op_vars(graph, t) assert summary(graph)["direct_call"] == 1
def test_access_directly_specialized(self): def g(b): return b.v0 def f(n): b = B(n) x = g(b) y = g(hint(b, access_directly=True)) return x + y t, typer, graph = self.gengraph(f, [int]) desc = typer.annotator.bookkeeper.getdesc(g) g_graphs = desc._cache.items() assert len(g_graphs) == 2 g_graphs.sort() assert g_graphs[0][0] is None assert get_force_virtualizable_flags(g_graphs[0][1]) == [{}] expected = [{'access_directly': True}] assert get_force_virtualizable_flags(g_graphs[1][1]) == expected self.replace_force_virtualizable(typer, [g_graphs[0][1], g_graphs[1][1]]) assert summary(g_graphs[0][1]) == {'direct_call': 1, self.GETFIELD: 1} assert summary(g_graphs[1][1]) == {self.GETFIELD: 1} res = self.interpret(f, [23]) assert res == 46
def test_keepalive_const_arrayitems(): A1 = lltype.GcArray(lltype.Signed) a1 = lltype.malloc(A1, 10) a1[6] = 1234 def fn(): p1 = lltype.direct_arrayitems(a1) p2 = lltype.direct_ptradd(p1, 6) return p2[0] graph, t = get_graph(fn, []) assert summary(graph) == { 'direct_arrayitems': 1, 'direct_ptradd': 1, 'getarrayitem': 1 } constant_fold_graph(graph) # kill all references to 'a1' a1 = fn = None del graph.func import gc gc.collect() assert summary(graph) == {'getarrayitem': 1} check_graph(graph, [], 1234, t)
def test_access_directly_escape(self): class Global: pass glob = Global() def g(b): glob.b = b def h(b): return b.v0 def f(n): b = B(n) g(b) g(hint(b, access_directly=True)) return h(glob.b) t, typer, graph = self.gengraph(f, [int]) desc = typer.annotator.bookkeeper.getdesc(g) g_graphs = desc._cache.items() assert len(g_graphs) == 2 g_graphs.sort() assert g_graphs[0][0] is None assert summary(g_graphs[0][1]) == {self.SETFIELD: 1} assert summary(g_graphs[1][1]) == {self.SETFIELD: 1} h_graph = t._graphof(h) assert summary(h_graph) == {'jit_force_virtualizable': 1, self.GETFIELD: 1} assert get_force_virtualizable_flags(h_graph) == [{}] res = self.interpret(f, [23]) assert res == 23
def xxx_test_later_along_link(): S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True}) s1 = lltype.malloc(S1) s1.x = 123 s2 = lltype.malloc(S1) s2.x = 60 def fn(x, y): if x: x = s1.x else: x = s2.x y *= 2 return (x+1) - y graph, t = get_graph(fn, [int, int]) assert summary(graph) == {'int_is_true': 1, 'getfield': 2, 'int_mul': 1, 'int_add': 1, 'int_sub': 1} constant_fold_graph(graph) assert summary(graph) == {'int_is_true': 1, 'int_mul': 1, 'int_sub': 1} check_graph(graph, [-1], 124, t) check_graph(graph, [0], 61, t)
def test_access_directly_specialized(self): def g(b): return b.v0 def f(n): b = B(n) x = g(b) y = g(hint(b, access_directly=True)) return x + y t, typer, graph = self.gengraph(f, [int]) desc = typer.annotator.bookkeeper.getdesc(g) g_graphs = desc._cache.items() assert len(g_graphs) == 2 g_graphs.sort() assert g_graphs[0][0] is None assert get_promote_virtualizable_flags(g_graphs[0][1]) == [{}] expected = [{'access_directly': True}] assert get_promote_virtualizable_flags(g_graphs[1][1]) == expected self.replace_promote_virtualizable(typer, [g_graphs[0][1], g_graphs[1][1]]) assert summary(g_graphs[0][1]) == {'direct_call': 1, self.GETFIELD: 1} assert summary(g_graphs[1][1]) == {self.GETFIELD: 1} res = self.interpret(f, [23]) assert res == 46
def test_dont_constfold_debug_print(): def fn(): llop.debug_print(lltype.Void, "hello world") graph, t = get_graph(fn, []) assert summary(graph) == {'debug_print': 1} constant_fold_graph(graph) assert summary(graph) == {'debug_print': 1}
def test_simple_melting_away(): def fn(n): assert n >= 1 return n-1 graph, t = get_graph(fn, [int]) assert summary(graph) == {'int_ge': 1, 'int_sub': 1} remove_asserts(t, [graph]) assert summary(graph) == {'int_ge': 1, 'debug_assert': 1, 'int_sub': 1} check_graph(graph, [1], 0, t)
def test_simple_melting_away(): def fn(n): assert n >= 1 return n - 1 graph, t = get_graph(fn, [int]) assert summary(graph) == {'int_ge': 1, 'int_sub': 1} remove_asserts(t, [graph]) assert summary(graph) == {'int_ge': 1, 'debug_assert': 1, 'int_sub': 1} check_graph(graph, [1], 0, t)
def test_simple(): S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True}) s1 = lltype.malloc(S1) s1.x = 123 def g(y): return y + 1 def fn(): return g(s1.x) graph, t = get_graph(fn, []) assert summary(graph) == {'getfield': 1, 'direct_call': 1} constant_fold_graph(graph) assert summary(graph) == {'direct_call': 1} check_graph(graph, [], 124, t)
def test_simple_melting_away(): def fn(n): assert n >= 1 return n-1 graph, t = get_graph(fn, [int]) assert summary(graph) == {'int_ge': 1, 'int_sub': 1} remove_asserts(t, [graph]) assert summary(graph) == {'int_ge': 1, 'debug_assert': 1, 'int_sub': 1} check_graph(graph, [1], 0, t) from pypy.translator.backendopt.removenoops import remove_debug_assert remove_debug_assert(graph) assert summary(graph) == {'int_ge': 1, 'int_sub': 1} from pypy.translator.simplify import transform_dead_op_vars transform_dead_op_vars(graph) assert summary(graph) == {'int_sub': 1}
def test_framework_safe_pushpop(self): class A(object): pass class B(object): pass def g(x): # cause a collect llop.gc__collect(lltype.Void) g._dont_inline_ = True global_a = A() global_a.b = B() global_a.b.a = A() global_a.b.a.b = B() global_a.b.a.b.c = 1 def make(): global_a.b.a.b.c = 40 a = global_a.b.a b = a.b b.c = 41 g(1) b0 = a.b b0.c = b.c = 42 make._dont_inline_ = True def f(): make() llop.gc__collect(lltype.Void) return global_a.b.a.b.c fn = self.getcompiled(f) res = fn() assert res == 42 insns = summary(self.t.graphs[0]) assert 'gc_reload_possibly_moved' not in insns
def test_simple_melting_away(): def fn(n): assert n >= 1 return n - 1 graph, t = get_graph(fn, [int]) assert summary(graph) == {'int_ge': 1, 'int_sub': 1} remove_asserts(t, [graph]) assert summary(graph) == {'int_ge': 1, 'debug_assert': 1, 'int_sub': 1} check_graph(graph, [1], 0, t) from pypy.translator.backendopt.removenoops import remove_debug_assert remove_debug_assert(graph) assert summary(graph) == {'int_ge': 1, 'int_sub': 1} from pypy.translator.simplify import transform_dead_op_vars transform_dead_op_vars(graph) assert summary(graph) == {'int_sub': 1}
def test_access_directly(self): def g(b): b.v0 += 1 return b.v0 def f(n): b = B(n) b = hint(b, access_directly=True) return g(b) t, typer, graph = self.gengraph(f, [int]) g_graph = t._graphof(g) expected = [{'access_directly': True}] * 3 assert get_promote_virtualizable_flags(g_graph) == expected self.replace_promote_virtualizable(typer, [g_graph]) assert summary(g_graph) == { self.GETFIELD: 2, self.SETFIELD: 1, 'int_add': 1 } res = self.interpret(f, [23]) assert res == 24
def test_access_directly_escape(): class Global: pass glob = Global() def g(b): glob.b = b def h(b): return b.v0 def f(n): b = B(n) g(b) g(hint(b, access_directly=True)) return h(glob.b) interp, graph = get_interpreter(f, [23]) desc = interp.typer.annotator.bookkeeper.getdesc(g) g_graphs = desc._cache.values() assert len(g_graphs) == 2 summaries = map(summary, g_graphs) summaries.sort() assert summaries == [{'setfield': 1}, {'setfield': 1}] h_graph = interp.typer.annotator.translator._graphof(h) assert summary(h_graph) == {'direct_call': 1} res = interp.eval_graph(graph, [23]) assert res == 23
def test_implicit_cast(self): z = llexternal('z', [USHORT, ULONG, USHORT, DOUBLE], USHORT) def f(x, y, xx, yy): return z(x, y, xx, yy) a = RPythonAnnotator() r = a.build_types(f, [int, int, int, int]) rtyper = RPythonTyper(a) rtyper.specialize() a.translator.rtyper = rtyper backend_optimizations(a.translator) if option.view: a.translator.view() graph = graphof(a.translator, f) s = summary(graph) # there should be not too many operations here by now expected = { 'cast_int_to_uint': 1, 'direct_call': 1, 'cast_primitive': 2, 'cast_int_to_float': 1 } for k, v in expected.items(): assert s[k] == v
def test_access_directly_method(self): class A: _virtualizable2_ = ['v0'] def __init__(self, v): self.v0 = v def meth1(self, x): return self.g(x + 1) def g(self, y): return self.v0 * y def f(n): a = A(n) a = hint(a, access_directly=True) return a.meth1(100) t, typer, graph = self.gengraph(f, [int]) g_graph = t._graphof(A.g.im_func) self.replace_promote_virtualizable(typer, [g_graph]) assert summary(g_graph) == {self.GETFIELD: 1, 'int_mul': 1} res = self.interpret(f, [23]) assert res == 2323
def check_insns(self, expected=None, **counts): residual_graph = self.get_residual_graph() self.insns = summary(residual_graph) if expected is not None: assert self.insns == expected for opname, count in counts.items(): assert self.insns.get(opname, 0) == count
def test_multiple_incoming_links(): S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True}) s1 = lltype.malloc(S1) s1.x = 123 s2 = lltype.malloc(S1) s2.x = 60 s3 = lltype.malloc(S1) s3.x = 15 def fn(x): y = x * 10 if x == 1: x = s1.x elif x == 2: x = s2.x elif x == 3: x = s3.x y = s1.x return (x+1) + y graph, t = get_graph(fn, [int]) constant_fold_graph(graph) assert summary(graph) == {'int_mul': 1, 'int_eq': 3, 'int_add': 2} for link in graph.iterlinks(): if Constant(139) in link.args: break else: raise AssertionError("139 not found in the graph as a constant") for i in range(4): check_graph(graph, [i], fn(i), t)
def test_multiple_incoming_links(): S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True}) s1 = lltype.malloc(S1) s1.x = 123 s2 = lltype.malloc(S1) s2.x = 60 s3 = lltype.malloc(S1) s3.x = 15 def fn(x): y = x * 10 if x == 1: x = s1.x elif x == 2: x = s2.x elif x == 3: x = s3.x y = s1.x return (x + 1) + y graph, t = get_graph(fn, [int]) constant_fold_graph(graph) assert summary(graph) == {'int_mul': 1, 'int_eq': 3, 'int_add': 2} for link in graph.iterlinks(): if Constant(139) in link.args: break else: raise AssertionError("139 not found in the graph as a constant") for i in range(4): check_graph(graph, [i], fn(i), t)
def test_coalesce_exitswitchs(): def g(n): return n > 5 and n < 20 def fn(n): if g(n): return 100 else: return 0 graph, t = get_graph(fn, [int]) from pypy.translator.backendopt import removenoops, inline inline.auto_inline_graphs(t, t.graphs, threshold=999) removenoops.remove_same_as(graph) constant_fold_graph(graph) if conftest.option.view: t.view() # check that the graph starts with a condition (which should be 'n > 5') # and that if this condition is false, it goes directly to 'return 0'. assert summary(graph) == {'int_gt': 1, 'int_lt': 1} assert len(graph.startblock.exits) == 2 assert graph.startblock.exits[0].exitcase == False assert graph.startblock.exits[0].target is graph.returnblock check_graph(graph, [2], 0, t) check_graph(graph, [10], 100, t) check_graph(graph, [42], 0, t)
def test_access_directly_method(self): class A: _virtualizable2_ = ['v0'] def __init__(self, v): self.v0 = v def meth1(self, x): return self.g(x+1) def g(self, y): return self.v0 * y def f(n): a = A(n) a = hint(a, access_directly=True) return a.meth1(100) t, typer, graph = self.gengraph(f, [int]) g_graph = t._graphof(A.g.im_func) self.replace_force_virtualizable(typer, [g_graph]) assert summary(g_graph) == {self.GETFIELD: 1, 'int_mul': 1} res = self.interpret(f, [23]) assert res == 2323
def test_substitute_graph(self): class MetaG: pass # the details are only used by the timeshifter def g(m): return m * 17 def f(n, m): x = g(n) y = g(m) hint(y, concrete=True) return g(m) class MyPolicy(HintAnnotatorPolicy): entrypoint_returns_red = False def look_inside_graph(self, graph): if graph.func is g: return MetaG # replaces g with a meta-call to metafunc() else: return True hs, hannotator = self.hannotate(f, [int, int], policy=MyPolicy(), annotator=True) assert hs.is_green() for graph in hannotator.translator.graphs: assert 'int_mul' not in flowmodel.summary(graph)
def test_substitute_graph(): class MetaG: pass # the details are only used by the timeshifter def g(m): return m * 17 def f(n, m): x = g(n) y = g(m) hint(y, concrete=True) return g(m) class MyPolicy(HintAnnotatorPolicy): entrypoint_returns_red = False def look_inside_graph(self, graph): if graph.func is g: return MetaG # replaces g with a meta-call to metafunc() else: return True hs, hannotator = hannotate(f, [int, int], policy=MyPolicy(), annotator=True) assert hs.is_green() for graph in hannotator.translator.graphs: assert 'int_mul' not in flowmodel.summary(graph)
def test_keepalive_const_fieldptr(): S1 = lltype.GcStruct('S1', ('x', lltype.Signed)) s1 = lltype.malloc(S1) s1.x = 1234 def fn(): p1 = lltype.direct_fieldptr(s1, 'x') return p1[0] graph, t = get_graph(fn, []) assert summary(graph) == {'direct_fieldptr': 1, 'getarrayitem': 1} constant_fold_graph(graph) # kill all references to 's1' s1 = fn = None del graph.func import gc; gc.collect() assert summary(graph) == {'getarrayitem': 1} check_graph(graph, [], 1234, t)
def test_keepalive_const_substruct(): py.test.skip("do we want partial folding of getinteriorfield?") S2 = lltype.Struct('S2', ('x', lltype.Signed)) S1 = lltype.GcStruct('S1', ('sub', S2)) s1 = lltype.malloc(S1) s1.sub.x = 1234 def fn(): return s1.sub.x graph, t = get_graph(fn, []) assert summary(graph) == {'getinteriorfield': 1} constant_fold_graph(graph) # kill all references to 's1' s1 = fn = None del graph.func import gc; gc.collect() assert summary(graph) == {'getfield': 1} check_graph(graph, [], 1234, t)
def test_fold_exitswitch(): S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True}) s1 = lltype.malloc(S1) s1.x = 123 s2 = lltype.malloc(S1) s2.x = 60 def fn(n): if s1.x: return n * 5 else: return n - 7 graph, t = get_graph(fn, [int]) assert summary(graph) == {'getfield': 1, 'int_is_true': 1, 'int_mul': 1, 'int_sub': 1} constant_fold_graph(graph) assert summary(graph) == {'int_mul': 1} check_graph(graph, [12], 60, t)
def test_nonmovable(self): for (nonmovable, opname) in [(True, 'malloc_nonmovable'), (False, 'malloc')]: class A(object): _alloc_nonmovable_ = nonmovable def f(): return A() t, typer, graph = self.gengraph(f, []) assert summary(graph) == {opname: 1, 'cast_pointer': 1, 'setfield': 1}
def test_keepalive_const_arrayitems(): A1 = lltype.GcArray(lltype.Signed) a1 = lltype.malloc(A1, 10) a1[6] = 1234 def fn(): p1 = lltype.direct_arrayitems(a1) p2 = lltype.direct_ptradd(p1, 6) return p2[0] graph, t = get_graph(fn, []) assert summary(graph) == {'direct_arrayitems': 1, 'direct_ptradd': 1, 'getarrayitem': 1} constant_fold_graph(graph) # kill all references to 'a1' a1 = fn = None del graph.func import gc; gc.collect() assert summary(graph) == {'getarrayitem': 1} check_graph(graph, [], 1234, t)
def test_fold_concat(self): def g(tail): return "head"+tail def f(): return g("tail") from pypy import conftest t, typer, fgraph = self.gengraph(f, [], backendopt=True) if conftest.option.view: t.view() assert summary(fgraph) == {}
def test_fn1(self): def fn1(x, y): if x > 0: t = x+y, x-y else: t = x-y, x+y s, d = t return s*d graph = self.check(fn1, [int, int], [15, 10], 125) insns = summary(graph) assert insns['int_mul'] == 1
def test_keepalive_const_fieldptr(): S1 = lltype.GcStruct('S1', ('x', lltype.Signed)) s1 = lltype.malloc(S1) s1.x = 1234 def fn(): p1 = lltype.direct_fieldptr(s1, 'x') return p1[0] graph, t = get_graph(fn, []) assert summary(graph) == {'direct_fieldptr': 1, 'getarrayitem': 1} constant_fold_graph(graph) # kill all references to 's1' s1 = fn = None del graph.func import gc gc.collect() assert summary(graph) == {'getarrayitem': 1} check_graph(graph, [], 1234, t)
def test_fold_concat(self): const = self.const def g(tail): return const("head")+tail def f(): return g(const("tail")) from pypy import conftest t, typer, fgraph = self.gengraph(f, [], backendopt=True) if conftest.option.view: t.view() assert summary(fgraph) == {}
def test_keepalive_const_substruct(): py.test.skip("do we want partial folding of getinteriorfield?") S2 = lltype.Struct('S2', ('x', lltype.Signed)) S1 = lltype.GcStruct('S1', ('sub', S2)) s1 = lltype.malloc(S1) s1.sub.x = 1234 def fn(): return s1.sub.x graph, t = get_graph(fn, []) assert summary(graph) == {'getinteriorfield': 1} constant_fold_graph(graph) # kill all references to 's1' s1 = fn = None del graph.func import gc gc.collect() assert summary(graph) == {'getfield': 1} check_graph(graph, [], 1234, t)
def test_always_inline(self): def f(x, y, z, k): p = (((x, y), z), k) return p[0][0][0] + p[-1] f._always_inline_ = True def g(x, y, z, k): a = f(x, y, z, k) return a eval_func, t = self.check_auto_inlining(g, [int, int, int, int], multiplier=0.1) graph = graphof(t, g) s = summary(graph) assert len(s) > 3
def test_immutable(self): class I(object): _immutable_ = True def __init__(self, v): self.v = v i = I(3) def f(): return i.v t, typer, graph = self.gengraph(f, [], backendopt=True) assert summary(graph) == {}
def test_fold_exitswitch(): S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True}) s1 = lltype.malloc(S1) s1.x = 123 s2 = lltype.malloc(S1) s2.x = 60 def fn(n): if s1.x: return n * 5 else: return n - 7 graph, t = get_graph(fn, [int]) assert summary(graph) == { 'getfield': 1, 'int_is_true': 1, 'int_mul': 1, 'int_sub': 1 } constant_fold_graph(graph) assert summary(graph) == {'int_mul': 1} check_graph(graph, [12], 60, t)
def test_llexternal(self): from pypy.rpython.lltypesystem.rffi import llexternal from pypy.rpython.lltypesystem import lltype z = llexternal('z', [lltype.Signed], lltype.Signed) def f(x): y = -1 if x > 0: y = z(x) return y + x t,g = self.transform_func(f, [int], True) # llexternals normally should not raise, the graph should have no exception # checking assert summary(g) == {'int_gt': 1, 'int_add': 1, 'direct_call': 1}
def test_access_directly_escape(self): class Global: pass glob = Global() def g(b): glob.b = b def h(b): return b.v0 def f(n): b = B(n) g(b) g(hint(b, access_directly=True)) return h(glob.b) t, typer, graph = self.gengraph(f, [int]) desc = typer.annotator.bookkeeper.getdesc(g) g_graphs = desc._cache.items() assert len(g_graphs) == 2 g_graphs.sort() assert g_graphs[0][0] is None assert summary(g_graphs[0][1]) == {self.SETFIELD: 1} assert summary(g_graphs[1][1]) == {self.SETFIELD: 1} h_graph = t._graphof(h) assert summary(h_graph) == { 'promote_virtualizable': 1, self.GETFIELD: 1 } assert get_promote_virtualizable_flags(h_graph) == [{}] res = self.interpret(f, [23]) assert res == 23
def test_first_subfield_access_is_cast_pointer(): B = GcStruct("B", ('x', Signed)) C = GcStruct("C", ('super', B), ('y', Signed)) def f(): c = malloc(C) c.super.x = 1 c.y = 2 return c.super.x + c.y s, t = ll_rtype(f, []) from pypy.translator.translator import graphof from pypy.objspace.flow.model import summary graph = graphof(t, f) graphsum = summary(graph) assert 'getsubstruct' not in graphsum assert 'cast_pointer' in graphsum
def test_access_directly(): def g(b): return b.v0 def f(n): b = B(n) b = hint(b, access_directly=True) return g(b) interp, graph = get_interpreter(f, [23]) g_graph = interp.typer.annotator.translator._graphof(g) assert summary(g_graph) == {'getfield': 1} res = interp.eval_graph(graph, [23]) assert res == 23
def test_nonmovable(self): for (nonmovable, opname) in [(True, 'malloc_nonmovable'), (False, 'malloc')]: class A(object): _alloc_nonmovable_ = nonmovable def f(): return A() t, typer, graph = self.gengraph(f, []) assert summary(graph) == { opname: 1, 'cast_pointer': 1, 'setfield': 1 }
def test_knownswitch_after_exitswitch(): def fn(n): cond = n > 10 if cond: return cond + 5 else: return cond + 17 graph, t = get_graph(fn, [int]) from pypy.translator.backendopt import removenoops removenoops.remove_same_as(graph) constant_fold_graph(graph) if conftest.option.view: t.view() assert summary(graph) == {'int_gt': 1} check_graph(graph, [2], 17, t) check_graph(graph, [42], 6, t)
def test_detect_list_comprehension(): def f1(l): return [x*17 for x in l] t = TranslationContext(list_comprehension_operations=True) graph = t.buildflowgraph(f1) if conftest.option.view: graph.show() assert summary(graph) == { 'newlist': 1, 'iter': 1, 'next': 1, 'mul': 1, 'getattr': 1, 'simple_call': 1, 'hint': 2, }
def test_detect_list_comprehension(): def f1(l): return [x * 17 for x in l] t = TranslationContext(list_comprehension_operations=True) graph = t.buildflowgraph(f1) if conftest.option.view: graph.show() assert summary(graph) == { 'newlist': 1, 'iter': 1, 'next': 1, 'mul': 1, 'getattr': 1, 'simple_call': 1, 'hint': 2, }
def test_access_directly_method(): class A(B): def meth1(self, x): return self.g(x+1) def g(self, y): return self.v0 * y def f(n): a = A(n) a = hint(a, access_directly=True) return a.meth1(100) interp, graph = get_interpreter(f, [23]) g_graph = interp.typer.annotator.translator._graphof(A.g.im_func) assert summary(g_graph) == {'getfield': 1, 'int_mul': 1} res = interp.eval_graph(graph, [23]) assert res == 2323