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)
Block when attacker want to bypass the limit of request

Block when attacker want to bypass the limit of request

iFanpS 1 Dec 01, 2021
Python-Kite: Simple python code to make kite pattern

Python-Kite Simple python code to make kite pattern. Getting Started These instr

Anoint 0 Mar 22, 2022
Syntax highlighting for yarn.lock and bun.lockb files

Yarn.lock Syntax Highlighting Syntax highlighting for yarn.lock and bun.lockb files Installation Plugin is not publushed yet on Package Control, to in

Alexander Kuznetsov 4 Jul 06, 2022
School helper, helps you at your pyllabus's.

pyllabus, helps you at your syllabus's... WARNING: It won't run without config.py! You should add config.py yourself, it will include your APIKEY. e.g

Ahmet Efe AKYAZI 6 Aug 07, 2022
Skull shaped MOSFET cells for the Efabless's 130nm process

SkullFET Skull shaped MOSFET cells for the Efabless's 130nm process List of cells Inverter Copyright (C) 2021 Uri Shaked

Wokwi 3 Dec 14, 2022
Projeto para ajudar no aprendizado da linguagem Pyhon

Economize Este projeto tem o intuito de criar desáfios para a codificação em Python, fazendo com que haja um maior entendimento da linguagem em seu to

Lucas Cunha Rodrigues 1 Dec 16, 2021
Covid-19-Trends - A project that me and my friends created as the CSC110 Final Project at UofT

Covid-19-Trends Introduction The COVID-19 pandemic has caused severe financial s

1 Jan 07, 2022
E5自动续期

AutoApi v6.3 (2021-2-18) ———— E5自动续期 AutoApi系列: AutoApi(v1.0) 、 AutoApiSecret(v2.0) 、 AutoApiSR(v3.0) 、 AutoApiS(v4.0) 、 AutoApiP(v5.0) 说明 E5自动续期程序,但是

34 Feb 20, 2021
Python Freecell Solver

freecell Python Freecell Solver Very early version right now. You can pick a board by changing the file path in freecell.py If you want to play a game

Ben Kaufman 1 Nov 26, 2021
清晰易读的7x7像素点阵中文字体和取模工具

FontChinese7x7 上古神器 III : 7x7像素点阵中文字体 想要在低分辨率屏幕上显示中文, 却发现中文字体实在是太大? 找了全网发现字体库最小也只有12x12? 甚至是好不容易找到了一个8x8字体, 结果发现字体收费且明确说明不得以任何形式嵌入到软件当中? 那就让这个项目来解决你的问

Angelic47 72 Dec 12, 2022
A program that analyzes data from inertia measurement units installeed in aircraft and generates g-exceedance curves

A program that analyzes data from inertia measurement units installeed in aircraft and generates g-exceedance curves

Pooya 1 Nov 23, 2021
This code can help you with auto update for-TV-advertisements in the store.

Auto-update-files-for-TV-advertisements-in-the-store This code can help you with auto update for-TV-advertisements in the store. It was write for Rasp

Max 2 Feb 20, 2022
Little tool in python to watch anime from the terminal (the better way to watch anime)

anipy-cli Little tool in python to watch anime from the terminal (the better way to watch anime) Has a resume playback function when picking from Hist

sdao 97 Dec 29, 2022
Set of scripts that schedules employees for shifts throughout the week based on availability, shift times, and shift necessities

Automatic-Scheduler Set of scripts that schedules employees for shifts throughout the week based on availability, shift times, and shift necessities *

Matthew 1 May 01, 2022
An OrpheusDL Tidal module

OrpheusDL - Tidal A Tidal module for the OrpheusDL modular archival music program Report Bug · Request Feature Table of content About OrpheusDL - Tida

Daniel 54 Dec 29, 2022
Modern robots.txt Parser for Python

Robots Exclusion Protocol Parser for Python Robots.txt parsing in Python. Goals Fetching -- helper utilities for fetching and parsing robots.txts, inc

Moz 176 Dec 16, 2022
The learning agent learns firstly approaching to the football and then kicking the football to the target position

Football Court This project utilized Pytorch and Tensorflow so that the learning agent learns firstly approaching to the football and then kicking the

1 Nov 19, 2021
Tutor plugin for integration of Open edX with a Richie course catalog

Richie plugin for Tutor This is a plugin to integrate Richie, the learning portal CMS, with Open edX. The integration takes the form of a Tutor plugin

Overhang.IO 2 Sep 08, 2022
Simple kivy project to help new kivy users build android apps with python.

Kivy Calculator A Simple Calculator made with kivy framework.Works on all platforms from Windows/linux to android. Description Simple kivy project to

Oussama Ben Sassi 6 Oct 06, 2022
Convert ldapdomaindump to Bloodhound

ldd2bh Usage usage: ldd2bh.py [-h] [-i INPUT_FOLDER] [-o OUTPUT_FOLDER] [-a] [-u] [-c] [-g] [-d] Convert ldapdomaindump to Bloodhoun

64 Oct 30, 2022