Author: Armin Rigo <[email protected]>
Branch: py3.5
Changeset: r86340:d5c8c1282a7d
Date: 2016-08-20 12:05 +0200
http://bitbucket.org/pypy/pypy/changeset/d5c8c1282a7d/

Log:    Fix for test_close_on_collect

diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -1,7 +1,7 @@
 """ PyFrame class implementation with the interpreter main loop.
 """
 
-from rpython.rlib import jit
+from rpython.rlib import jit, rweakref
 from rpython.rlib.debug import make_sure_not_resized, check_nonneg
 from rpython.rlib.jit import hint
 from rpython.rlib.objectmodel import instantiate, specialize, we_are_translated
@@ -62,7 +62,8 @@
     __metaclass__ = extendabletype
 
     frame_finished_execution = False
-    frame_generator          = None    # for generators/coroutines
+    f_generator_wref         = rweakref.dead_ref  # for generators/coroutines
+    f_generator_nowref       = None               # (only one of the two attrs)
     last_instr               = -1
     last_exception           = None
     f_backref                = jit.vref_None
@@ -239,17 +240,23 @@
             self.locals_cells_stack_w[index] = outer_func.closure[i]
             index += 1
 
+    def _is_generator_or_coroutine(self):
+        return (self.getcode().co_flags & (pycode.CO_COROUTINE |
+                                           pycode.CO_GENERATOR)) != 0
+
     def run(self):
         """Start this frame's execution."""
-        if self.getcode().co_flags & (pycode.CO_COROUTINE |
-                                      pycode.CO_GENERATOR):
+        if self._is_generator_or_coroutine():
             if self.getcode().co_flags & pycode.CO_COROUTINE:
                 from pypy.interpreter.generator import Coroutine
                 gen = Coroutine(self)
             else:
                 from pypy.interpreter.generator import GeneratorIterator
                 gen = GeneratorIterator(self)
-            self.frame_generator = gen
+            if self.space.config.translation.rweakref:
+                self.f_generator_wref = rweakref.ref(gen)
+            else:
+                self.f_generator_nowref = gen
             return self.space.wrap(gen)
         else:
             return self.execute_frame()
@@ -897,12 +904,20 @@
         # is not quite like CPython when it clears f_exc_* (however
         # there might not be an observable difference).
         if not self.frame_finished_execution:
-            if self.frame_generator is None or self.frame_generator.running:
+            if not self._is_generator_or_coroutine():
                 raise oefmt(space.w_RuntimeError,
                             "cannot clear an executing frame")
-            # xxx CPython raises the RuntimeWarning "coroutine was never
-            # awaited" in this case too.  Does it make any sense?
-            self.frame_generator.descr_close()
+            if space.config.translation.rweakref:
+                gen = self.f_generator_wref()
+            else:
+                gen = self.f_generator_nowref
+            if gen is not None:
+                if gen.running:
+                    raise oefmt(space.w_RuntimeError,
+                                "cannot clear an executing frame")
+                # xxx CPython raises the RuntimeWarning "coroutine was never
+                # awaited" in this case too.  Does it make any sense?
+                gen.descr_close()
 
         self.last_exception = None
         debug = self.getdebug()
diff --git a/pypy/interpreter/test/test_generator.py 
b/pypy/interpreter/test/test_generator.py
--- a/pypy/interpreter/test/test_generator.py
+++ b/pypy/interpreter/test/test_generator.py
@@ -220,22 +220,17 @@
         raises(RuntimeError, g.close)
 
     def test_close_on_collect(self):
-        ## we need to exec it, else it won't run on python2.4
-        d = {}
-        exec("""
         def f():
             try:
                 yield
             finally:
                 f.x = 42
-        """.strip(), d, d)
-
-        g = d['f']()
+        g = f()
         next(g)
         del g
         import gc
         gc.collect()
-        assert d['f'].x == 42
+        assert f.x == 42
 
     def test_generator_raises_typeerror(self):
         def f():
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to