Commits

Armin Rigo  committed 1b3b2e3

Generators work, at least in this simple test and by calling .next()
explicitly.

  • Participants
  • Parent commits a4906ce
  • Branches generator-in-rpython

Comments (0)

Files changed (4)

File pypy/annotation/description.py

         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

File pypy/rpython/test/test_generator.py

+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

File pypy/translator/generator.py

 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):
 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
                 newblock = newlink.target
                 #
                 class Resume(AbstractPosition):
+                    _immutable_ = True
                     block = newblock
                 Resume.__name__ = 'Resume%d' % len(mappings)
                 mappings.append(Resume)
                            Constant(AssertionError("bad generator class"))],
                           graph.exceptblock))
     graph.startblock = regular_entry_block
+    graph.signature = Signature(['entry'])
+    graph.defaults = ()
     checkgraph(graph)
     eliminate_empty_blocks(graph)

File pypy/translator/test/test_generator.py

 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
         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
         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):