Author: Armin Rigo <ar...@tunes.org>
Branch: py3.5
Changeset: r88496:e7e2aa356442
Date: 2016-11-20 17:26 +0100
http://bitbucket.org/pypy/pypy/changeset/e7e2aa356442/

Log:    Test and fix for frame.clear()

diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -782,8 +782,10 @@
 
     def descr_clear(self, space):
         """F.clear(): clear most references held by the frame"""
-        # Clears a random subset of the attributes (e.g. the fast
-        # locals, but not f_locals).
+        # Clears a random subset of the attributes: the local variables
+        # and the w_locals.  Note that CPython doesn't clear f_locals
+        # (which can create leaks) but it's hard to notice because
+        # the next Python-level read of 'frame.f_locals' will clear it.
         if not self.frame_finished_execution:
             if not self._is_generator_or_coroutine():
                 raise oefmt(space.w_RuntimeError,
@@ -800,6 +802,8 @@
         debug = self.getdebug()
         if debug is not None:
             debug.w_f_trace = None
+            if debug.w_locals is not None:
+                debug.w_locals = space.newdict()
 
         # clear the locals, including the cell/free vars, and the stack
         for i in range(len(self.locals_cells_stack_w)):
diff --git a/pypy/interpreter/test/test_pyframe.py 
b/pypy/interpreter/test/test_pyframe.py
--- a/pypy/interpreter/test/test_pyframe.py
+++ b/pypy/interpreter/test/test_pyframe.py
@@ -618,6 +618,15 @@
         #
         raises(StopIteration, next, gen)
 
+    def test_frame_clear_really(self):
+        import sys
+        def f(x):
+            return sys._getframe()
+        frame = f(42)
+        assert frame.f_locals['x'] == 42
+        frame.clear()
+        assert frame.f_locals == {}
+
     def test_throw_trace_bug(self):
         import sys
         def f():
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to