Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connect signal to async callback #345

Open
davidbrochart opened this issue Dec 19, 2024 · 1 comment · May be fixed by #346
Open

Connect signal to async callback #345

davidbrochart opened this issue Dec 19, 2024 · 1 comment · May be fixed by #346

Comments

@davidbrochart
Copy link

  • psygnal version: 0.11.1
  • Python version: 3.13.1
  • Operating System: Debian 12

Description

I'd like to connect a signal to an async callback, but it doesn't seem to be supported.

What I Did

This gives a "coroutine 'on_value_changed' was never awaited" warning:

from psygnal import Signal

# define an object with class attribute Signals
class MyObj:

    # this signal will emit a single string
    value_changed = Signal(str)

    def __init__(self, value=0):
        self._value = value

    def set_value(self, value):
        if value != self._value:
            self._value = str(value)
            # emit the signal
            self.value_changed.emit(self._value)

async def on_value_changed(new_value: str):
    print(f"The new value is {new_value!r}")

# instantiate the object with Signals
obj = MyObj()

# connect one or more callbacks with `connect`
obj.value_changed.connect(on_value_changed)

# callbacks are called when value changes
obj.set_value('hello!')  # prints: 'The new value is 'hello!'
@tlambert03
Copy link
Member

hey @davidbrochart, nice to see you here again.

you're right, we haven't explicitly supported coroutine functions yet. #346 should handle this case, but I'll note a slight modification to what you'll need to do in your example: Because psygnal itself has no concept of an event loop (it's a "bring-your-own-event-loop" library), you would need to slightly modify your example to call obj.set_value() within the context of an asyncio event loop. So, basically just change that last line with:

async def main():
    # callbacks are called when value changes
    obj.set_value("hello!")

import asyncio
asyncio.run(main())

... and then with #346, it should work. Still need to clean up some typing. But if you have a moment to look and if you have any comments or suggestions, i'd be happy to hear them

@tlambert03 tlambert03 linked a pull request Dec 20, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants