[pypy-issue] Issue #3162: GreenletExit not thrown when a greenlet is garbage-collected (pypy/pypy)
Antonio Cuni
issues-reply at bitbucket.org
Wed Jan 29 12:27:27 EST 2020
New issue 3162: GreenletExit not thrown when a greenlet is garbage-collected
https://bitbucket.org/pypy/pypy/issues/3162/greenletexit-not-thrown-when-a-greenlet-is
Antonio Cuni:
```python
import greenlet
import gc
class A(object):
def __del__(self):
print 'A.__del__'
def g1():
try:
print 'g1: begin'
a = A()
print 'g1: switching'
MAIN.switch()
except greenlet.GreenletExit:
print 'g1: GreenletExit'
finally:
print 'g1: finally'
def main():
global MAIN
MAIN = greenlet.getcurrent()
greenlet.greenlet(g1).switch()
gc.collect()
main()
```
These are the results on CPython and PyPy; `A.__del__` is used just to show that the greenlet is actually garbage collected.
```
$ python green.py
g1: begin
g1: switching
g1: GreenletExit
g1: finally
A.__del__
$ pypy green.py
g1: begin
g1: switching
A.__del__
```
The following patch seems to be enough to fix the problem; however, since it’s a good practice to be very careful when dealing with greenlets and continuelets, I’d like some feeback before committing it:
```diff
diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py
--- a/lib_pypy/greenlet.py
+++ b/lib_pypy/greenlet.py
@@ -47,6 +47,9 @@
if parent is not None:
self.parent = parent
+ def __del__(self):
+ self.throw()
+
def switch(self, *args, **kwds):
"Switch execution to this greenlet, optionally passing the values "
"given as argument(s). Returns the value passed when switching back."
```
More information about the pypy-issue
mailing list