Author: Armin Rigo <[email protected]>
Branch: generator-in-rpython
Changeset: r50715:1b3b2e3f0e18
Date: 2011-12-19 18:22 +0100
http://bitbucket.org/pypy/pypy/changeset/1b3b2e3f0e18/
Log: Generators work, at least in this simple test and by calling .next()
explicitly.
diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py
--- a/pypy/annotation/description.py
+++ b/pypy/annotation/description.py
@@ -180,7 +180,12 @@
if name is None:
name = pyobj.func_name
if signature is None:
- signature = cpython_code_signature(pyobj.func_code)
+ if hasattr(pyobj, '_generator_next_method_of_'):
+ from pypy.interpreter.argument import Signature
+ signature = Signature(['entry']) # haaaaaack
+ defaults = ()
+ else:
+ signature = cpython_code_signature(pyobj.func_code)
if defaults is None:
defaults = pyobj.func_defaults
self.name = name
diff --git a/pypy/rpython/test/test_generator.py
b/pypy/rpython/test/test_generator.py
new file mode 100644
--- /dev/null
+++ b/pypy/rpython/test/test_generator.py
@@ -0,0 +1,25 @@
+from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
+
+
+class BaseTestGenerator(BaseRtypingTest):
+
+ def test_simple_explicit(self):
+ def g(a, b, c):
+ yield a
+ yield b
+ yield c
+ def f():
+ gen = g(3, 5, 8)
+ x = gen.next() * 100
+ x += gen.next() * 10
+ x += gen.next()
+ return x
+ res = self.interpret(f, [])
+ assert res == 358
+
+
+class TestLLtype(BaseTestGenerator, LLRtypeMixin):
+ pass
+
+class TestOOtype(BaseTestGenerator, OORtypeMixin):
+ pass
diff --git a/pypy/translator/generator.py b/pypy/translator/generator.py
--- a/pypy/translator/generator.py
+++ b/pypy/translator/generator.py
@@ -4,6 +4,7 @@
from pypy.translator.unsimplify import split_block
from pypy.translator.simplify import eliminate_empty_blocks
from pypy.tool.sourcetools import func_with_new_name
+from pypy.interpreter.argument import Signature
class AbstractPosition(object):
@@ -30,6 +31,7 @@
def make_generatoriterator_class(graph):
class GeneratorIterator(object):
class Entry(AbstractPosition):
+ _immutable_ = True
varnames = get_variable_names(graph.startblock.inputargs)
def __init__(self, entry):
self.current = entry
@@ -113,6 +115,7 @@
newblock = newlink.target
#
class Resume(AbstractPosition):
+ _immutable_ = True
block = newblock
Resume.__name__ = 'Resume%d' % len(mappings)
mappings.append(Resume)
@@ -157,5 +160,7 @@
Constant(AssertionError("bad generator class"))],
graph.exceptblock))
graph.startblock = regular_entry_block
+ graph.signature = Signature(['entry'])
+ graph.defaults = ()
checkgraph(graph)
eliminate_empty_blocks(graph)
diff --git a/pypy/translator/test/test_generator.py
b/pypy/translator/test/test_generator.py
--- a/pypy/translator/test/test_generator.py
+++ b/pypy/translator/test/test_generator.py
@@ -1,6 +1,7 @@
from pypy.conftest import option
from pypy.objspace.flow.objspace import FlowObjSpace
from pypy.objspace.flow.model import Variable
+from pypy.interpreter.argument import Signature
from pypy.translator.translator import TranslationContext
from pypy.translator.generator import make_generatoriterator_class
from pypy.translator.generator import replace_graph_with_bootstrap
@@ -96,7 +97,7 @@
assert block.exits[0].target is graph.returnblock
def test_tweak_generator_body_graph(self):
- def f(n, x, y, z):
+ def f(n, x, y, z=3):
z *= 10
yield n + 1
z -= 10
@@ -109,6 +110,9 @@
if option.view:
graph.show()
# XXX how to test directly that the graph is correct? :-(
+ assert len(graph.startblock.inputargs) == 1
+ assert graph.signature == Signature(['entry'])
+ assert graph.defaults == ()
def test_tweak_generator_graph(self):
def f(n, x, y, z):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit