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

Reply via email to