{ "info": { "author": "Dmitry Vakhrushev", "author_email": "self@kr41.net", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "Green Rocket\n============\n\nGreen Rocket is a simple and compact implementation of Observer\n(or Publish/Subscribe) design pattern via signals.\n\nCreate specific signal using base one:\n\n.. code-block:: pycon\n\n >>> from greenrocket import Signal\n >>> class MySignal(Signal):\n ... pass\n ...\n\nSubscribe handler:\n\n.. code-block:: pycon\n\n >>> @MySignal.subscribe\n ... def handler(signal):\n ... print('handler: ' + repr(signal))\n ...\n\nFire signal:\n\n.. code-block:: pycon\n\n >>> MySignal().fire()\n handler: MySignal()\n\nIf you are using ``asyncio``, you can also use coroutines as handlers\nand fire signal asynchronously using ``await Signal.afire()`` or\n``yield from Signal().afire()``. Method ``afire()`` works well with\nsynchronous handlers too.\n\nNote, that signal propagates over inheritance, i.e. all subscribers of base\nsignal will be called when child one is fired:\n\n.. code-block:: pycon\n\n >>> @Signal.subscribe\n ... def base_handler(signal):\n ... print('base_handler: ' + repr(signal))\n ...\n >>> MySignal().fire()\n handler: MySignal()\n base_handler: MySignal()\n\nUnsubscribe handler:\n\n.. code-block:: pycon\n\n >>> MySignal.unsubscribe(handler)\n >>> MySignal().fire()\n base_handler: MySignal()\n\nThe handler is subscribed using weak reference. So if you create and subscribe\na handler in local scope (for example inside a generator), it will be\nunsubscribed automatically.\n\n.. code-block:: pycon\n\n >>> def gen():\n ... @MySignal.subscribe\n ... def local_handler(signal):\n ... print('local_handler: ' + repr(signal))\n ... yield 1\n ...\n >>> for value in gen():\n ... MySignal(value=value).fire()\n ...\n local_handler: MySignal(value=1)\n base_handler: MySignal(value=1)\n >>> import gc # PyPy fails the following test without\n >>> _ = gc.collect() # explicit call of garbage collector.\n >>> MySignal(value=2).fire()\n base_handler: MySignal(value=2)\n >>> Signal.unsubscribe(base_handler)\n\nAs you can see above, signal constructor accepts keyword arguments. These\narguments are available as signal's attributes:\n\n.. code-block:: pycon\n\n >>> s = MySignal(a=1, b=2)\n >>> s.a\n 1\n >>> s.b\n 2\n\nSignal suppresses any exception which is raised on handler call. It uses\nlogger named ``greenrocket`` from standard ``logging`` module to log errors and\ndebug information.\n\nThe library also provides ``Watchman`` class as a convenient way for testing\nsignals.\n\nCreate watchman for specific signal:\n\n.. code-block:: pycon\n\n >>> from greenrocket import Watchman\n >>> watchman = Watchman(MySignal)\n\nFire signal:\n\n.. code-block:: pycon\n\n >>> MySignal(x=1).fire()\n\nTest signal:\n\n.. code-block:: pycon\n\n >>> watchman.assert_fired_with(x=1)\n >>> watchman.assert_fired_with(x=2) # DOCTEST: +ellipsis\n Traceback (most recent call last):\n ...\n AssertionError: Failed assertion on MySignal.x: 1 != 2\n >>> watchman.assert_fired_with(x=1, y=2) # DOCTEST: +ellipsis\n Traceback (most recent call last):\n ...\n AssertionError: MySignal has no attribute y\n\nWatchman object saves each fired signal to its log:\n\n.. code-block:: pycon\n\n >>> watchman.log\n [MySignal(x=1)]\n >>> MySignal(x=2).fire()\n >>> watchman.log\n [MySignal(x=1), MySignal(x=2)]\n\nThe method ``assert_fired_with`` tests the last signal from\nthe log by default:\n\n.. code-block:: pycon\n\n >>> watchman.assert_fired_with(x=2)\n\nBut you can specify which one to test:\n\n.. code-block:: pycon\n\n >>> watchman.assert_fired_with(-2, x=1)\n\n\n\nCHANGES\n=======\n\n0.30\n----\n\n* Added ``Signal.afire()`` method that returns awaitable to support\n coroutine-based signal handlers\n* Dropped Python 2.6 and 3.2 support\n\n0.22\n----\n\n* Added `Watchman` class as a testing helper\n\n0.21\n----\n\n* Removed distribute dependency\n* Improved tests\n\n0.20\n----\n\n* Changed handler subscription mechanism from subscription by reference to\n subscription by weak reference\n\n0.11\n----\n\n* Fixed logger loose on program termination\n\n0.1\n---\n\n* Initial release", "description_content_type": null, "docs_url": null, "download_url": "https://bitbucket.org/kr41/greenrocket/downloads", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://bitbucket.org/kr41/greenrocket", "keywords": "signal observer publisher subscriber asyncio", "license": "BSD", "maintainer": null, "maintainer_email": null, "name": "GreenRocket", "package_url": "https://pypi.org/project/GreenRocket/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/GreenRocket/", "project_urls": { "Download": "https://bitbucket.org/kr41/greenrocket/downloads", "Homepage": "https://bitbucket.org/kr41/greenrocket" }, "release_url": "https://pypi.org/project/GreenRocket/0.30/", "requires_dist": null, "requires_python": null, "summary": "A simple and compact implementation of Observer design pattern", "version": "0.30" }, "last_serial": 2549898, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "9b4c092d02487d8c9bae313ebaf2cb0e", "sha256": "a7cf2774748dd1d2c257c85c69102e8b2ae8bbf4aeb70143cc6a2b33d1231cb9" }, "downloads": -1, "filename": "GreenRocket-0.1.tar.gz", "has_sig": false, "md5_digest": "9b4c092d02487d8c9bae313ebaf2cb0e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3379, "upload_time": "2013-02-28T17:05:33", "url": "https://files.pythonhosted.org/packages/83/4c/3e668724893e295502fa954d788891e1545a95241d3eda4c032a8ca84bf9/GreenRocket-0.1.tar.gz" } ], "0.11": [ { "comment_text": "", "digests": { "md5": "468a30bd8851c43237669fd1927dc8a7", "sha256": "aa81d23e1a1e1138942e77d48006a0900fa6e3c4e681191075298bb1275bd1df" }, "downloads": -1, "filename": "GreenRocket-0.11.tar.gz", "has_sig": false, "md5_digest": "468a30bd8851c43237669fd1927dc8a7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3381, "upload_time": "2013-02-28T17:06:28", "url": "https://files.pythonhosted.org/packages/25/19/68d1336b8d40a4a7d77f0935bc6bd20b9a2ca43593b0f7574dfd98f74a9a/GreenRocket-0.11.tar.gz" } ], "0.20": [ { "comment_text": "", "digests": { "md5": "1e1d11f45deb2d007dea1a142ae89112", "sha256": "7fdcf9cba366c691d3ab471dbe27211ae47f7ef1464a9a302f494a55e57b9cc6" }, "downloads": -1, "filename": "GreenRocket-0.20.tar.gz", "has_sig": false, "md5_digest": "1e1d11f45deb2d007dea1a142ae89112", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8833, "upload_time": "2013-06-25T19:53:11", "url": "https://files.pythonhosted.org/packages/24/ba/560fc1e36abfdbbeea284cfa8e76de44e9608cc071cc2364fb5fe507a2b9/GreenRocket-0.20.tar.gz" } ], "0.21": [ { "comment_text": "", "digests": { "md5": "77a9afd367f798fdbf569626a8551673", "sha256": "74b1eee168d6b6b97c93b4e50e50994be20a5c26224aa337de458e4a0430458e" }, "downloads": -1, "filename": "GreenRocket-0.21.tar.gz", "has_sig": false, "md5_digest": "77a9afd367f798fdbf569626a8551673", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4146, "upload_time": "2014-11-24T18:51:07", "url": "https://files.pythonhosted.org/packages/90/e4/1dc88b6eaa50bac01567717d59dda17106dfd6a37066e3dff2bd288543d4/GreenRocket-0.21.tar.gz" } ], "0.22": [ { "comment_text": "", "digests": { "md5": "24a594ebbb60b308ed532c0911e1dfca", "sha256": "adcb06d8d46d69abe8268396412aa76a664c795726480b20b8729251a9085372" }, "downloads": -1, "filename": "GreenRocket-0.22.tar.gz", "has_sig": false, "md5_digest": "24a594ebbb60b308ed532c0911e1dfca", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4988, "upload_time": "2015-04-04T15:13:18", "url": "https://files.pythonhosted.org/packages/4b/c7/cc5af6c0b83e658e2267142cceca670ab709bfb313ee41621ed7f0e3e229/GreenRocket-0.22.tar.gz" } ], "0.30": [ { "comment_text": "", "digests": { "md5": "69cfdd2a3a09d9e78e26bc6a9df96119", "sha256": "57a729e8a3d31e34f1eabed3570a34645d7f38cefb4678d809cead293720dbae" }, "downloads": -1, "filename": "GreenRocket-0.30.tar.gz", "has_sig": false, "md5_digest": "69cfdd2a3a09d9e78e26bc6a9df96119", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5392, "upload_time": "2017-01-02T14:52:19", "url": "https://files.pythonhosted.org/packages/b6/8b/55faeb7889eed5d22b467e17380f966aea5aa97484a79990aaee80f51af9/GreenRocket-0.30.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "69cfdd2a3a09d9e78e26bc6a9df96119", "sha256": "57a729e8a3d31e34f1eabed3570a34645d7f38cefb4678d809cead293720dbae" }, "downloads": -1, "filename": "GreenRocket-0.30.tar.gz", "has_sig": false, "md5_digest": "69cfdd2a3a09d9e78e26bc6a9df96119", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5392, "upload_time": "2017-01-02T14:52:19", "url": "https://files.pythonhosted.org/packages/b6/8b/55faeb7889eed5d22b467e17380f966aea5aa97484a79990aaee80f51af9/GreenRocket-0.30.tar.gz" } ] }