Gevent: Cannot make weakref to gevent.event.Event object

Created on 16 May 2018  路  6Comments  路  Source: gevent/gevent

  • gevent version: 1.3
  • Python version: cPython 2.7.15 from Anaconda
  • Operating System: Linux

Description:

Newest 1.3 gevent version do not allow weak references on gevent.event.Event objects,
whereas it was working before (gevent 1.2.2).

What I've run:

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
Bug

Most helpful comment

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 

)

All 6 comments

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 

)

Was this page helpful?
0 / 5 - 0 ratings