A fast Python in-process signal/event dispatching system.

Related tags

Miscellaneousblinker
Overview

Build Status

Blinker

Blinker provides a fast dispatching system that allows any number of interested parties to subscribe to events, or "signals".

Signal receivers can subscribe to specific senders or receive signals sent by any sender.

It supports dispatching to an arbitrary mix of connected coroutines and receiver functions.

>>> from blinker import signal
>>> started = signal('round-started')
>>> def each(round):
...     print "Round %s!" % round
...
>>> started.connect(each)

>>> def round_two(round):
...     print "This is round two."
...
>>> started.connect(round_two, sender=2)

>>> for round in range(1, 4):
...     started.send(round)
...
Round 1!
Round 2!
This is round two.
Round 3!

See the Blinker documentation for more information.

Requirements

Blinker requires Python 2.7, Python 3.4 or higher, or Jython 2.7 or higher.

Changelog Summary

1.3 (July 3, 2013)

  • The global signal stash behind blinker.signal() is now backed by a regular name-to-Signal dictionary. Previously, weak references were held in the mapping and ephemeral usage in code like signal('foo').connect(...) could have surprising program behavior depending on import order of modules.
  • blinker.Namespace is now built on a regular dict. Use blinker.WeakNamespace for the older, weak-referencing behavior.
  • Signal.connect('text-sender') uses an alternate hashing strategy to avoid sharp edges in text identity.

1.2 (October 26, 2011)

  • Added Signal.receiver_connected and Signal.receiver_disconnected per-Signal signals.
  • Deprecated the global 'receiver_connected' signal.
  • Verified Python 3.2 support (no changes needed!)

1.1 (July 21, 2010)

  • Added @signal.connect_via(sender) decorator
  • Added signal.connected_to shorthand name for the temporarily_connected_to context manager.

1.0 (March 28, 2010)

  • Python 3.x compatibility

0.9 (February 26, 2010)

  • Sphinx docs, project website
  • Added with a_signal.temporarily_connected_to(receiver): ... support
Comments
  • Consider asyncio features ala asyncblink

    Consider asyncio features ala asyncblink

    "AsyncBlink is a small extention to Blinker and enables you to use coroutines as receivers for your signals."

    Seems to be essentially a modification of send() like so:

            # the only difference is here. If it's a coroutine,
            # run it with asyncio.async()
            receivers = self.receivers_for(sender) or []
            return_list = []
    
            for receiver in receivers:
                ret = receiver(sender, **kwargs)
                if asyncio.coroutines.iscoroutine(ret):
                    ret = asyncio.async(ret)
                return_list.append((receiver, ret))
    
            return return_list
    

    Useful to have this in Blinker natively? Perhaps something ala:

    def send_async(self, *sender, **kw):
        wrapped = lambda v: asyncio.coroutine(lambda: v)
        values = [(r, wrapped(v)) if asyncio.iscoroutine(v) else (r, v)
                       for r, v in self.send(*sender, **kw)]
        return asyncio.gather(*values)
    

    cc: @jucacrispim

    enhancement 
    opened by jek 22
  • move to github.com/discorporate/blinker

    move to github.com/discorporate/blinker

    @jek iirc you can click somewhere in the settings to move a repo to a new github org.

    guess that is the easiest option to get it there.

    i'ld offer to do some basic maintenance if i get the permissions (like for flatland, including a new pypi release with the new URL).

    opened by ThomasWaldmann 11
  • Speed up send() by 30% when there are no receivers.

    Speed up send() by 30% when there are no receivers.

    Use Cython if exists to speed up the checking if there are receivers. if Cython cant be found it uses a none optimized version.

    A couple of considerations:

    1. Cython module can be marked as required, speeding up all environments. But this is up to you.
    2. The TypeError error raised when more than one sender is given as a param is done AFTER checking the availability of the receivers. it might broken a bit the contract.
    opened by pfreixes 10
  • Drop support for EOL Python

    Drop support for EOL Python

    Fixes https://github.com/jek/blinker/issues/46.

    EOL Python versions are no longer supported by the core Python team and no longer receive security updates.

    image

    https://en.wikipedia.org/wiki/CPython#Version_history

    They're also little used. Here's the pip installs for Blinker from PyPI for last month:

    | python_version | percent | download_count | | -------------- | ------: | -------------: | | 2.7 | 50.71% | 88,260 | | 3.6 | 28.01% | 48,749 | | 3.5 | 14.50% | 25,235 | | 3.4 | 6.41% | 11,153 | | 3.3 | 0.17% | 290 | | 3.7 | 0.13% | 234 | | 2.6 | 0.08% | 131 | | 3.2 | 0.00% | 2 |

    Source: pypinfo --start-date -49 --end-date -22 --percent --pip --markdown Blinker pyversion

    Dropping them eases the maintenance burden and allows more modern features of Python to be used, some of which is included here.

    opened by hugovk 7
  • Replace `\*` with `\\*` in docstrings

    Replace `\*` with `\\*` in docstrings

    For example,

    https://github.com/jek/blinker/blob/b5e9f0629200d2b2f62e13e595b802948bb4fefb/blinker/base.py#L250

    Causes the following deprecation warning.

    DeprecationWarning: invalid escape sequence \*
    

    Here's a reproduction.

    import warnings
    warnings.simplefilter("always")
    x = "\*\*kwargs"
    # <stdin>:1: DeprecationWarning: invalid escape sequence \*
    

    Instead, the \* should be replaced by \\*. The following does not raise a DeprecationWarning.

    import warnings
    warnings.simplefilter("always")
    x = "\\*\\*kwargs"
    

    Not a huge deal, but these warnings pollute my build logs.

    opened by ashwin153 6
  • Continuous Integration

    Continuous Integration

    Hello,

    It will be nice to add Continuous Integration. Please go to https://travis-ci.org/ and enable your blinker project

    add a .travis.yml file with

    language: python
    python:
      - "2.7"
      - "3.2"
      - "3.3"
      - "3.4"
    
    # command to install dependencies
    install:
      - "pip install ."
    
    # command to run tests
    script: nosetests
    

    then you can push your code.

    Kind regards

    opened by femtotrader 4
  • DeprecationWarning: invalid escape sequence \*

    DeprecationWarning: invalid escape sequence \*

    When running pytest on test suite of my work project I have the following warnings at the end of test run:

    .venv/lib/python3.8/site-packages/blinker/base.py:93: 11 warnings
      /usr/lib/publishing/.venv/lib/python3.8/site-packages/blinker/base.py:93: DeprecationWarning: invalid escape sequence \*
        """Connect *receiver* to signal events sent by *sender*.
    
    .venv/lib/python3.8/site-packages/blinker/base.py:161: 11 warnings
      /usr/lib/publishing/.venv/lib/python3.8/site-packages/blinker/base.py:161: DeprecationWarning: invalid escape sequence \*
        """Connect the decorated function as a receiver for *sender*.
    
    .venv/lib/python3.8/site-packages/blinker/base.py:242: 11 warnings
      /usr/lib/publishing/.venv/lib/python3.8/site-packages/blinker/base.py:242: DeprecationWarning: invalid escape sequence \*
        """Emit this signal on behalf of *sender*, passing on \*\*kwargs.
    

    I guess those docstrings should be r"""...""" strings to avoid such warnings. Or \* sequences should be simply replaced by *.

    Deps:

    • CPython 3.8.6
    • pytest 6.1.0
    • blinker 1.4
    opened by decaz 3
  • tox result is strange

    tox result is strange

      py25: commands succeeded  # no python2.5 on my system
      py26: commands succeeded  # no python2.6 on my system
      py27: commands succeeded  # ok
      py30: commands succeeded  # no python3.0 on my system
      py31: commands succeeded  # no python3.1 on my system
      py32: commands succeeded  # no python3.2 on my system
      py33: commands succeeded  # no python3.3 on my system
    ERROR:  py34: InterpreterNotFound: python3.4  # ok
    ERROR:  py35: InterpreterNotFound: python3.5  # ok
      py36: commands succeeded  # ok
    ERROR:  jython: InterpreterNotFound: jython  # ok
    

    So it says "succeeded" although there was no such python interpreter...

    opened by ThomasWaldmann 3
  • @_utilities.lazy_property isn't thread safe

    @_utilities.lazy_property isn't thread safe

    Just thought I'd let u know (from having made this same mistake myself),

    But the application of @_utilities.lazy_property isn't actually thread-safe.

    An example program you can try:

    import threading
    import thread
    
    import time
    
    from blinker import _utilities
    
    
    class SlowThing(object):
    
        @_utilities.lazy_property
        def b(self):
            print "starting reading 'b' thread %s" % thread.get_ident()
            time.sleep(0.5)
            print "finished reading 'b' thread %s" % thread.get_ident()
            return 1
    
    s = SlowThing()
    
    
    def _run():
        s.b
    
    
    threads = []
    for i in range(0, 5):
        t = threading.Thread(target=_run)
        threads.append(t)
        t.start()
    
    
    while threads:
        t = threads.pop()
        t.join()
    
    

    The output of this will create:

    starting reading 'b' thread 140684440516352
    starting reading 'b' thread 140684432123648
    starting reading 'b' thread 140684423730944
    starting reading 'b' thread 140684415338240
    starting reading 'b' thread 140684203915008
    finished reading 'b' thread 140684432123648
    finished reading 'b' thread 140684440516352
    finished reading 'b' thread 140684423730944
    finished reading 'b' thread 140684415338240
    finished reading 'b' thread 140684203915008
    

    So u can see there are many threads at the same time recomputing that property (in this case it doesn't matter, but in other cases it might?)

    Some code that I have made that does appear to work fine:

    Perhaps we can share it somehow...

    https://github.com/openstack/taskflow/blob/master/taskflow/utils/misc.py#L346

    opened by harlowja 3
  • Fixed memory leaks.

    Fixed memory leaks.

    I found a big memory leaks in my project. After studying the problem I have identified the source of the leaks is a dictionaries Signal._by_sender and Signal._by_receiver. I fixed this problem and create the pull request. Please, accept it and release new version of "blinker".

    opened by Cykooz 3
  • get rid of dead snakes

    get rid of dead snakes

    from setup.py / tox.ini:

    [tox]
    envlist = py25,py26,py27,py30,py31,py32,py33,py34,py35,jython
    
              'Programming Language :: Python :: 2',
              'Programming Language :: Python :: 2.4',
              'Programming Language :: Python :: 2.5',
              'Programming Language :: Python :: 2.6',
              'Programming Language :: Python :: 2.7',
              'Programming Language :: Python :: 3',
              'Programming Language :: Python :: 3.0',
              'Programming Language :: Python :: 3.1',
              'Programming Language :: Python :: 3.2',
              'Programming Language :: Python :: 3.3',
              'Programming Language :: Python :: 3.4',
              'Programming Language :: Python :: 3.5',
              'Programming Language :: Python :: 3.6',
    

    Python 2.6 didn't get new releases since 5 years, so I guess for a new blinker release everything older than 2.7 could be dropped.

    The last 3.2 release is also 4y old, so guess all < 3.3 could be dropped (if not even more).

    People still using ancient versions can still use the older blinker release(s).

    Also, tox and setup.py pypi metadata should be kept in sync.

    opened by ThomasWaldmann 2
  • Bump certifi from 2022.6.15 to 2022.12.7 in /docs

    Bump certifi from 2022.6.15 to 2022.12.7 in /docs

    Bumps certifi from 2022.6.15 to 2022.12.7.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Add a send_async method to the Signal

    Add a send_async method to the Signal

    This allows for signals to send to coroutine receivers by awaiting them. The _async_wrapper and _sync_wrapper allows for conversion of sync and async receivers as required if defined. If not defined a runtime error is raised.

    The wrappers are used to avoid any direct tie into asyncio, trio, greenbacks, asgiref, or other specific async implementation.

    opened by pgjones 4
  • Temporarily disable a signal in a block

    Temporarily disable a signal in a block

    I have an application that generates reports from a bunch of sources. When a report is generated, a Blinker signal report_created is called, and one of the receivers sends an email to subscribers of that report type.

    It sometimes happens, however, that we want to (re/)generate a large amount of reports. In such cases we don’t want email sending to happen. However, if an actual report gets generated meanwhile by the normal means, i want the receiver to be called, so i can’t just disconnect that receiver.

    What i could imagine is something like this:

    with report_created.disable():
        generate_a_lot_of_reports()
    

    As far as i understand, this is not possible in the current Blinker version, but please correct me if i’m wrong. Also, if this use case seems valid (ie. not a unicorn case, when only my project needs it) i’m willing to dig deeper and submit a PR for this.

    opened by gergelypolonkai 1
  • add type hints to the project

    add type hints to the project

    Having type hints for this library would make it possible to check its usage in applications with Mypy. I currently have a work-in-progress of those type hints.

    Before it can be accepted into python/typeshed, I need to get the permission from the maintainers, so is it OK if I submit Blinker stubs to typeshed?

    opened by bbc2 5
Releases(1.5)
  • 1.5(Jul 17, 2022)

    Blinker has moved to Pallets-Eco, an organization for community maintenance of projects related to Pallets, Flask, etc. If you use Blinker and are interested in helping maintain the project, please join us in Discord Chat https://discord.gg/pallets.

    This release fixes some compatibility with Python >= 3.7. Python < 3.7, including 2.7 and Jython, should still work for this release, but will no longer be supported in the next release.

    The documentation has moved to Read the Docs https://blinker.readthedocs.io.

    Source code(tar.gz)
    Source code(zip)
The Google Assistant on a rotary phone

Google Assistant Rotary Phone Shoutout to my dad who had this idea a year ago and I'm only now getting around to doing it. Notes This is the code used

rydercalmdown 10 Nov 04, 2022
Advanced IPv4 Subnet Calculator in Python3

Advanced IPv4 Subnet Calculator in Python3 Table of Contents Getting Started Installation How it works? SVI Configuration Template Previews Getting St

Osama Abbas 1 May 10, 2022
MoBioTools A simple yet versatile toolkit to automatically setup quantum mechanics/molecular mechanics

A simple yet versatile toolkit to setup quantum mechanical/molecular mechanical (QM/MM) calculations from molecular dynamics trajectories.

MoBioChem 17 Nov 27, 2022
Graphene Metanode is a locally hosted node for one account and several trading pairs, which uses minimal RAM resources.

Graphene Metanode is a locally hosted node for one account and several trading pairs, which uses minimal RAM resources. It provides the necessary user stream data and order book data for trading in a

litepresence 5 May 08, 2022
This tool don't used illegal ativity

ETHICALTOOL This tool for only educational purposes don't used illegal ativity @onlinehacking this tool for pkg update && pkg upgrade && pkg install g

Mrkarthick 4 Dec 23, 2021
Patch PL to disable LK verification. Patch LK to disable boot/recovery verification.

Simple Python(3) script to disable LK verification in Amazon Preloader images and boot/recovery image verification in Amazon LK ("Little Kernel") images.

Roger Ortiz 18 Mar 17, 2022
Minterpy - Multidimensional interpolation in Python.

minterpy is an open-source Python package for a multivariate generalization of the classical Newton and Lagrange interpolation schemes as well as related tasks.

Center for Advanced Systems Understanding 18 Jan 06, 2023
Clackety Keyboards Powered by Python

KMK: Clackety Keyboards Powered by Python KMK is a feature-rich and beginner-friendly firmware for computer keyboards written and configured in Circui

KMK Firmware 780 Jan 03, 2023
Turn crypto miner on/off depending on powerwall charge level

Mining Crypto with Tesla Solar and Powerwalls This script turns a crypto miner on and off when the Tesla Powerwall level drops/rises above a certain t

Matt 1 Nov 09, 2021
Eatlocal - This package helps users solve PyBites code challenges on their local machine

eatlocal This package helps the user solve Pybites code challenges locally. Inst

Russell 0 Jul 25, 2022
Project based on pure python with OOP

Object oriented programming review Object oriented programming (OOP) is among the most used programming paradigms (if not the most common) in the indu

Facundo Abrahan Cerimeli 1 May 09, 2022
Simple AoC helper program you can use to develop your own solutions in python.

AoC-Compabion Simple AoC helper program you can use to develop your own solutions in python. Simply install it in your python environment using pip fr

Alexander Vollmer 1 Dec 20, 2021
A set of tools for ripping music from Konami mobile games

Konami Mobile Ripping Toolset A set of tools for ripping music from Konami mobile games Contents nigger.py for niggering konami's website, ripping all

5 Oct 20, 2022
GDIT: Geometry Dash Info Tool

GDIT: Geometry Dash Info Tool This is the first large script that allows you to quickly get information from the Geometry Dash server

dezz0xY 2 Jan 09, 2022
Static bytecode simulator

SEA Static bytecode simulator for creating dependency/dependant based experimental bytecode format for CPython. Example a = random() if a = 5.0:

Batuhan Taskaya 23 Jun 10, 2022
E5 自动续期

请选择跳转 新版本系统 (2021-2-9采用): 以后更新都在AutoApi,采用v0.0版本号覆盖式更新 AutoApi : 最新版 保留1到2个稳定的简易版,防止萌新大范围报错 AutoApi'X' : 稳定版1 ( 即本版AutpApiP ) AutoApiP ( 即v5.0,稳定版 ) —

95 Feb 15, 2021
Access Modbus RTU via API call to Sungrow WiNet-S

SungrowModbusWebClient Access Modbus RTU via API call to Sungrow WiNet-S Class based on pymodbus.ModbusTcpClient, completely interchangeable, just rep

8 Oct 30, 2022
Python 101 Forever

🚀 Python 101 Forever 🚀 Official Python 101 Forever GitHub repository. START HERE - CHECK README SUBSCRIBE FOR UPDATES HERE Sponsors Contac

Hack Bulgaria 58 Nov 30, 2022
CPython extension implementing Shared Transactional Memory with native-looking interface

CPython extension implementing Shared Transactional Memory with native-looking interface

21 Jul 22, 2022
Todos os exercícios do Curso de Python, do canal Curso em Vídeo, resolvidos em Python, Javascript, Java, C++, C# e mais...

Exercícios - CeV Oferecido por Linguagens utilizadas atualmente O que vai encontrar aqui? 👀 Esse repositório é dedicado a armazenar todos os enunciad

Coding in Community 43 Nov 10, 2022