1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
from rpython.conftest import option
from rpython.flowspace.objspace import build_flow
from rpython.flowspace.model import Variable
from rpython.flowspace.generator import (
make_generator_entry_graph, get_variable_names)
from rpython.translator.simplify import join_blocks
# ____________________________________________________________
def f_gen(n):
i = 0
while i < n:
yield i
i += 1
class GeneratorIterator(object):
def __init__(self, entry):
self.current = entry
def next(self):
e = self.current
self.current = None
if isinstance(e, Yield1):
n = e.n_0
i = e.i_0
i += 1
else:
n = e.n_0
i = 0
if i < n:
e = Yield1()
e.n_0 = n
e.i_0 = i
self.current = e
return i
raise StopIteration
def __iter__(self):
return self
class AbstractPosition(object):
_immutable_ = True
class Entry1(AbstractPosition):
_immutable_ = True
class Yield1(AbstractPosition):
_immutable_ = True
def f_explicit(n):
e = Entry1()
e.n_0 = n
return GeneratorIterator(e)
def test_explicit():
assert list(f_gen(10)) == list(f_explicit(10))
def test_get_variable_names():
lst = get_variable_names([Variable('a'), Variable('b_'), Variable('a')])
assert lst == ['g_a', 'g_b', 'g_a_']
# ____________________________________________________________
class TestGenerator:
def test_replace_graph_with_bootstrap(self):
def func(n, x, y, z):
yield n
yield n
#
graph = make_generator_entry_graph(func)
if option.view:
graph.show()
block = graph.startblock
ops = block.operations
assert ops[0].opname == 'simple_call' # e = Entry1()
assert ops[1].opname == 'setattr' # e.g_n = n
assert ops[1].args[1].value == 'g_n'
assert ops[2].opname == 'setattr' # e.g_x = x
assert ops[2].args[1].value == 'g_x'
assert ops[3].opname == 'setattr' # e.g_y = y
assert ops[3].args[1].value == 'g_y'
assert ops[4].opname == 'setattr' # e.g_z = z
assert ops[4].args[1].value == 'g_z'
assert ops[5].opname == 'simple_call' # g = GeneratorIterator(e)
assert ops[5].args[1] == ops[0].result
assert len(ops) == 6
assert len(block.exits) == 1
assert block.exits[0].target is graph.returnblock
def test_tweak_generator_graph(self):
def f(n, x, y, z):
z *= 10
yield n + 1
z -= 10
#
graph = make_generator_entry_graph(f)
func1 = graph._tweaked_func
if option.view:
graph.show()
GeneratorIterator = graph._tweaked_func._generator_next_method_of_
assert hasattr(GeneratorIterator, 'next')
#
graph_next = build_flow(GeneratorIterator.next.im_func)
join_blocks(graph_next)
if option.view:
graph_next.show()
#
graph1 = build_flow(func1)
if option.view:
graph1.show()
def test_automatic(self):
def f(n, x, y, z):
z *= 10
yield n + 1
z -= 10
#
graph = build_flow(f)
if option.view:
graph.show()
block = graph.startblock
assert len(block.exits) == 1
assert block.exits[0].target is graph.returnblock
|