Newest 1.3 gevent version do not allow weak references on gevent.event.Event objects,
whereas it was working before (gevent 1.2.2).
Python 2.7.15 |Anaconda, Inc.| (default, May 1 2018, 23:32:55)
[GCC 7.2.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from gevent.event import Event
>>> import weakref
>>> e=Event()
>>> wref=weakref.ref(e)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot create weak reference to 'gevent._event.Event' object
Thanks for the report! That's definitely a regression. There are no test cases for this, either in the standard library or gevent's own suite.
I'm curious, could you share your use case?
@jamadden Use case is the following: we use louie (aka pydispatcher) to execute callbacks selectively with a signals/dispatcher mechanism. Internally, louie uses weakrefs to not hold strong references to callback functions. One of our registered callback is .set() on an gevent.event.Event object, hence the creation of a weakref on it by louie...
Is this fix also working for the following error I got in Ajenti?
TypeError: cannot create weak reference to 'gevent._queue.Queue' object
This is the script that Ajenti uses (in /usr/local/lib/python2.7/dist-packages/aj/util/broadcast_queue.py):
import weakref
from gevent.queue import Queue
class BroadcastQueue(object):
def __init__(self):
self._queues = []
def register(self):
q = Queue()
self._queues.append(weakref.ref(q))
return q
def broadcast(self, val):
for q in list(self._queues):
if q():
q().put(val)
else:
self._queues.remove(q)
No, please open a separate issue.
A quick workaround would be a trivial subclass of Queue.
Thanks for your quick reply.
I have created a new issue https://github.com/gevent/gevent/issues/1217
What do you mean with trivial subclass? What do I have to change in that broadcast_queue.py file?
I tried to remove the weakref.ref(q), but that caused this error:
TypeError: 'gevent._queue.Queue' object is not callable
(Caused by if q():)
What do you mean with trivial subclass? What do I have to change in that broadcast_queue.py file?
Classes implemented in Python are automatically weakly referencable. So adding one line to the top of the file will workaround this issue:
from gevent.queue import Queue
class Queue(Queue): pass # New line
(Of course, if you expect to support 1.3.0 and 1.3.1 before this fix is released, I would suggest writing it like this:
from gevent.queue import Queue
try:
weakref.ref(Queue())
except TypeError:
class Queue(Queue): pass
)
Most helpful comment
Classes implemented in Python are automatically weakly referencable. So adding one line to the top of the file will workaround this issue:
(Of course, if you expect to support 1.3.0 and 1.3.1 before this fix is released, I would suggest writing it like this:
)