Project: psygnal

Fast python callback/event system modeled after Qt Signals

Project Details

Latest version
0.9.5
Home Page
PyPI Page
https://pypi.org/project/psygnal/

Project Popularity

PageRank
0.004155073498009804
Number of downloads
73426

psygnal

License PyPI Conda Python Version CI codecov Documentation Status Benchmarks

Psygnal (pronounced "signal") is a pure python implementation of the observer pattern, with the API of Qt-style Signals with (optional) signature and type checking, and support for threading.

This library does not require or use Qt in any way, It simply implements a similar observer pattern API.

Documentation

https://psygnal.readthedocs.io/

Install

pip install psygnal
conda install -c conda-forge psygnal

Usage

The observer pattern is a software design pattern in which an object maintains a list of its dependents ("observers"), and notifies them of any state changes – usually by calling a callback function provided by the observer.

Here is a simple example of using psygnal:

from psygnal import Signal

class MyObject:
    # define one or more signals as class attributes
    value_changed = Signal(str)

# create an instance
my_obj = MyObject()

# You (or others) can connect callbacks to your signals
@my_obj.value_changed.connect
def on_change(new_value: str):
    print(f"The value changed to {new_value}!")

# The object may now emit signals when appropriate,
# (for example in a setter method)
my_obj.value_changed.emit('hi')  # prints "The value changed to hi!"

Much more detail available in the documentation!

Evented Dataclasses

A particularly nice usage of the signal pattern is to emit signals whenever a field of a dataclass changes. Psygnal provides an @evented decorator that will emit a signal whenever a field changes. It is compatible with dataclasses from the standard library, as well as attrs, and pydantic:

from psygnal import evented
from dataclasses import dataclass

@evented
@dataclass
class Person:
    name: str
    age: int = 0

person = Person('John', age=30)

# connect callbacks
@person.events.age.connect
def _on_age_change(new_age: str):
    print(f"Age changed to {new_age}")

person.age = 31  # prints: Age changed to 31

See the dataclass documentation for more details.

Benchmark history

https://pyapp-kit.github.io/psygnal/

and

https://codspeed.io/pyapp-kit/psygnal

Developers

Debugging

While psygnal is a pure python module, it is compiled with mypyc to increase performance. To disable all compiled files and run the pure python version, you may run:

python -c "import psygnal.utils; psygnal.utils.decompile()"

To return the compiled version, run:

python -c "import psygnal.utils; psygnal.utils.recompile()"

The psygnal._compiled variable will tell you if you're using the compiled version or not.