Skip to main content

Signaller

Signals and slots implementation with asyncio support

Slots can be functions, methods or coroutines. Weak references are used by default. If slot is coroutine, it will be scheduled to run asynchronously with asyncio.async() (but you must run event loop by yourself).

You can also run blocking functions asynchronously by specifying force_async=True when connecting signal to slot (it will only apply to that slot) or when creating signal (it will apply to all connected slots). ThreadPoolExecutor with 5 worker threads is used by default, but it can be changed when creating signal with executor argument.

Requirements

  • Python >= 3.4

Usage

Example:

import logging
from signaller import Signal, autoconnect

# Enable verbose logging
logging.basicConfig(level=logging.DEBUG)

# Creating signals (you can set signal name, but it is not required,
# signals can be anonymous):
sig_test = Signal('sig_test')

# Connecting signals to slots (uses weak references by default,
# but you can force strong references by specifying weak=False):
def slot(arg):
    print('slot:', arg)

sig_test.connect(slot)
sig_test.connect(lambda arg: print('slot_lambda:', arg), weak=False)

# You can also use decorators for connecting signals to slots:
@sig_test.connect
def slot2(arg):
    print('slot2:', arg)

# And keyword arguments can be specified when using decorators too:
@sig_test.connect(force_async=True)
def slot3(arg):
    print('slot3:', arg)

# You can also use decorators on methods, then signals will be connected to instance
# methods automatically whenever new instance is created. But you must decorate class
# with @autoconnect decorator for autoconnection to work. Class methods and
# static methods are not supported.
@autoconnect
class Cls:
    @sig_test.connect
    def slot4(self, arg):
        print('slot4:', arg)

obj = Cls()

# Slots are automatically disconnected from signals
# when using weak references:
del slot

# Or you can disconnect slots manually:
sig_test.disconnect(slot2)

# Emitting signals (you can send both positional and keyword
# arguments to connected slots):
sig_test.emit('Hello world!')

Output:

INFO:signaller:Connecting signal <Signal 'sig_test' at 0x7f3c468bfc50> to slot <function slot at 0x7f3c46cc6f28>
INFO:signaller:Connecting signal <Signal 'sig_test' at 0x7f3c468bfc50> to slot <function <lambda> at 0x7f3c468c97b8>
INFO:signaller:Connecting signal <Signal 'sig_test' at 0x7f3c468bfc50> to slot <function slot2 at 0x7f3c43c9e400>
INFO:signaller:Connecting signal <Signal 'sig_test' at 0x7f3c468bfc50> to slot <function slot3 at 0x7f3c43c9e598>
DEBUG:signaller:Marking instance method <function Cls.slot4 at 0x7f3c43c9e6a8> for autoconnect to signal <Signal 'sig_test' at 0x7f3c468bfc50>
INFO:signaller:Connecting signal <Signal 'sig_test' at 0x7f3c468bfc50> to slot <bound method Cls.slot4 of <__main__.Cls object at 0x7f3c43f11d30>>
DEBUG:signaller:Object <function slot at 0x7f3c46cc6f28> has been deleted
INFO:signaller:Disconnecting slot <Reference (weak) to <function slot at 0x7f3c46cc6f28> (dead)> from signal <Signal 'sig_test' at 0x7f3c468bfc50>
INFO:signaller:Disconnecting slot <function slot2 at 0x7f3c43c9e400> from signal <Signal 'sig_test' at 0x7f3c468bfc50>
INFO:signaller:Emitting signal <Signal 'sig_test' at 0x7f3c468bfc50>
DEBUG:signaller:Calling slot <Reference (weak) to <function slot3 at 0x7f3c43c9e598>> asynchronously (in executor <concurrent.futures.thread.ThreadPoolExecutor object at 0x7f3c468bff28>)
slot3: Hello world!
DEBUG:signaller:Calling slot <Reference (strong) to <function <lambda> at 0x7f3c468c97b8>>
slot_lambda: Hello world!
DEBUG:signaller:Calling slot <Reference (weak) to <bound method Cls.slot4 of <__main__.Cls object at 0x7f3c43f11d30>>>
slot4: Hello world!

Metadata

Release files for Signaller 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for Signaller 1.1.0
File Size Uploaded Provenance
Signaller-1.1.0.tar.gz 4.6 kB Without provenance Details

Release files / Signaller-1.1.0.tar.gz

Download URL Signaller-1.1.0.tar.gz
Size 4.6 kB
Tags Source
SHA-256 checksum
How to use checksums
df43d1bb47bbd389a001be6a1aae708ae6a9e8f9fa7514efab35123b642df8b8
BLAKE2b-256 checksum
How to use checksums
9b87c350cc8d91cf33a26f0912a4a06b375017a51ddadf3723d1c1bb682e087b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Security for Signaller 1.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.1.0 This release

1 release file No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page