{ "info": { "author": "yakobu", "author_email": "ronenya4321@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Natural Language :: English", "Operating System :: POSIX", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development :: Pre-processors" ], "description": "Recursive Decorator\n===================\n\n.. image:: https://img.shields.io/github/license/yakobu/recursive_decorator.svg\n :alt: GitHub license\n :target: https://github.com/yakobu/recursive_decorator\n.. image:: https://badge.fury.io/py/recursive-decorator.svg\n :target: https://badge.fury.io/py/recursive-decorator\n.. image:: https://travis-ci.org/yakobu/recursive_decorator.svg?branch=master\n :target: https://travis-ci.org/yakobu/recursive_decorator\n.. image:: https://coveralls.io/repos/github/yakobu/recursive_decorator/badge.svg?branch=master\n :target: https://coveralls.io/github/yakobu/recursive_decorator?branch=master\n\n\n\nDecorator to apply a given decorator recursively on all function, inside a function/method, recursively.\n\nWhat is ``recursive_decorator``?\n--------------------------------\n\n``recursive_decorator`` is a decorator that allows us to **decorate/trasform all functions along the stack call** at runtime, motivated by the need to add/transform logics, to known\\unknown functions, along the stack calls.\n\nNotes:\n++++++\n* Functions/Methods will not be replaced, new instances will be returned.\n* Function/Methods cannot be wrapped more then once with same transformer/decorator.\n\n\nInstalling\n----------\n.. code-block:: console\n\n $ pip install recursive_decorator\n\n\nUsage\n-----\nimport recursive_decorator\n\n.. code-block:: python\n\n from recursive_decorator import recursive_decorator\n\ndefine your decorator to apply recursively on all functions.\n\n.. code-block:: python\n\n >>> def decorator(f):\n ...: def wrapper(*args, **kwargs):\n ...: print(f.__name__)\n ...: return f(*args, **kwargs)\n ...: return wrapper\n\n\nNow using your decorator on function without using recursive_decorator will leads to the following output\n\n.. code-block:: python\n\n >>> @decorator\n ...:def main_function():\n ...: sub_function()\n\n >>> main_function()\n main_function\n\n\nUsing recursive_decorator leads to\n\n.. code-block:: python\n\n >>> @recursive_decorator(decorator)\n ...:def main_function():\n ...: sub_function()\n\n >>> main_function()\n main_function\n sub_function\n\n\nFurthermore, if sub_function has function calls, they will decorated to\n\n.. code-block:: python\n\n >>> def sub_function():\n ...: another_function()\n\n >>> @recursive_decorator(decorator)\n ...:def main_function():\n ...: sub_function()\n\n >>> main_function()\n main_function\n sub_function\n another_function\n\n\nand so on...\n\n\nExamples\n--------\n\nStop on Execption\n+++++++++++++++++\n\nWe can wrap all functions with try except...\n\n.. code-block:: python\n\n >>> import sys\n >>> import ipdb\n >>> from recursive_decorator import recursive_decorator\n\n >>> def wrap_function_with_try_except(f):\n ...: def transformed_func(*args, **kwargs):\n ...: try:\n ...: return f(*args, **kwargs)\n ...: except:\n ...: ipdb.set_trace(sys._getframe().f_back)\n ...: return transformed_func\n\n >>> def throws_exception():\n ...: raise Exception\n\n\n >>> @recursive_decorator(wrap_function_with_try_except)\n ...:def function():\n ...: throws_exception()\n ...: pass\n\n >>> function()\n 21 throws_exception()\n ---> 22 pass\n 23\n\nIf function will throw an error... ipdb session will start.\n\n\nProfiler\n++++++++\n\nWe can set time profiler for all running functions.\n\n.. code-block:: python\n\n >>> import time\n\n >>> from recursive_decorator import recursive_decorator\n\n\n >>> def duration_transformer(f):\n ...: def transformed_func(*args, **kwargs):\n ...: start_time = time.time()\n ...: value = f(*args, **kwargs)\n ...: end_time = time.time()\n ...: print(\"function {} duration is {} minutes\"\n ...: .format(f.__name__, end_time - start_time))\n ...: return value\n ...: return transformed_func\n\n\n >>> def waiting_function():\n ...: time.sleep(5)\n\n\n >>> @recursive_decorator(duration_transformer)\n ...:def function():\n ...: waiting_function()\n\n >>> function()\n function waiting_function duration is 5.00511908531189 minutes\n function function duration is 5.006134510040283 minutes\n\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ronen-y/recursive_decorator", "keywords": "decorator recursive recursive_decorator recursive-decorator", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "recursive-decorator", "package_url": "https://pypi.org/project/recursive-decorator/", "platform": "", "project_url": "https://pypi.org/project/recursive-decorator/", "project_urls": { "Homepage": "https://github.com/ronen-y/recursive_decorator" }, "release_url": "https://pypi.org/project/recursive-decorator/1.0.7/", "requires_dist": [ "codetransformer", "cached-property", "mock; extra == 'dev'", "flake8; extra == 'dev'", "pytest; extra == 'dev'", "pytest-cov; extra == 'dev'" ], "requires_python": "", "summary": "Decorator to apply given decorator recursively on functions", "version": "1.0.7" }, "last_serial": 4208775, "releases": { "1.0.1": [ { "comment_text": "", "digests": { "md5": "afcd545fbfe64ac3f20324c95b835d37", "sha256": "e92c348bc137eff2a7f7b34fb54d03b83d7eb213b5ce98727b16221121c70c4d" }, "downloads": -1, "filename": "recursive_decorator-1.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "afcd545fbfe64ac3f20324c95b835d37", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6875, "upload_time": "2018-08-24T09:44:02", "url": "https://files.pythonhosted.org/packages/f6/cb/a63f3bd92f76662167e05859422ca9d8419ce3e949fc174f0039232bdbe0/recursive_decorator-1.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f2ee625f45ea4c145b49ecdc0eecabd4", "sha256": "3e82ba30e5c15d646765f8835deffa2ccd18319ed466c3e2879be5495807a1c8" }, "downloads": -1, "filename": "recursive_decorator-1.0.1.tar.gz", "has_sig": false, "md5_digest": "f2ee625f45ea4c145b49ecdc0eecabd4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5820, "upload_time": "2018-08-24T09:44:05", "url": "https://files.pythonhosted.org/packages/60/36/42d66e4cf54ca3ee7e76187d2bb88a63d0809545f78128004952d21541b9/recursive_decorator-1.0.1.tar.gz" } ], "1.0.5": [ { "comment_text": "", "digests": { "md5": "a78416fa20e4ac6a334ae2c70dcc2b97", "sha256": "9952b3a1500dd45198c8719053eaa336a4c45ec2123df0ed19a1872a98a05023" }, "downloads": -1, "filename": "recursive_decorator-1.0.5-py3-none-any.whl", "has_sig": false, "md5_digest": "a78416fa20e4ac6a334ae2c70dcc2b97", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6876, "upload_time": "2018-08-24T10:19:04", "url": "https://files.pythonhosted.org/packages/32/99/c2ec7c368ae37b185d71cabd2785933f2c5c6157a7e5373440bf1c7c29e0/recursive_decorator-1.0.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "669ff2a8d12f5e9d14db8c69bb897d51", "sha256": "b81f232af6781334a18d4025ffb201db07cc66b6d485ab1f6adcbe375f247376" }, "downloads": -1, "filename": "recursive_decorator-1.0.5.tar.gz", "has_sig": false, "md5_digest": "669ff2a8d12f5e9d14db8c69bb897d51", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5818, "upload_time": "2018-08-24T10:19:05", "url": "https://files.pythonhosted.org/packages/d9/93/4b8b8fa3effad91d45feb68143f22fe52b4ff484d9a3899fe2fa87105693/recursive_decorator-1.0.5.tar.gz" } ], "1.0.6": [ { "comment_text": "", "digests": { "md5": "a5bcc96faa015e80dda451ef2d91c8cb", "sha256": "1bbe98dc4c1d3550546b0b84affc80361d1e6b71e9ea9e28f8594c514cb7d0df" }, "downloads": -1, "filename": "recursive_decorator-1.0.6-py3-none-any.whl", "has_sig": false, "md5_digest": "a5bcc96faa015e80dda451ef2d91c8cb", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6934, "upload_time": "2018-08-26T17:13:58", "url": "https://files.pythonhosted.org/packages/61/f6/b3904dbec7b2cc2d12aeac25117924988bf16e63524bba8e5aad71e89c37/recursive_decorator-1.0.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9c3fd99f3b95ea2481bfe28b668ac20e", "sha256": "0537602acf81ddc7d6cb76970c60ee1516678a4aba172dc773c3e21c2469a3e9" }, "downloads": -1, "filename": "recursive_decorator-1.0.6.tar.gz", "has_sig": false, "md5_digest": "9c3fd99f3b95ea2481bfe28b668ac20e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5896, "upload_time": "2018-08-26T17:13:59", "url": "https://files.pythonhosted.org/packages/78/c1/043d88cc4d4fff36b065113bd28c5522ff585419099ea86aef447acd6d51/recursive_decorator-1.0.6.tar.gz" } ], "1.0.7": [ { "comment_text": "", "digests": { "md5": "30cf4eee8b1056848bd90dda61f04a24", "sha256": "5a6b840a67f01bd295e62e3995647de6a6d89fdb407a93d751c2537d887eefdf" }, "downloads": -1, "filename": "recursive_decorator-1.0.7-py3-none-any.whl", "has_sig": false, "md5_digest": "30cf4eee8b1056848bd90dda61f04a24", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6919, "upload_time": "2018-08-26T17:30:42", "url": "https://files.pythonhosted.org/packages/37/0c/6580dbfb6a01d8e0e752d5994ed26780359f5d97ad15443888b424994418/recursive_decorator-1.0.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "49e52072ae05b6add66891454e2d5133", "sha256": "41d88e3424c6ea14eee4dc56799193aa2ea4602bfb2f35edb93f524e73c61c91" }, "downloads": -1, "filename": "recursive_decorator-1.0.7.tar.gz", "has_sig": false, "md5_digest": "49e52072ae05b6add66891454e2d5133", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5877, "upload_time": "2018-08-26T17:30:43", "url": "https://files.pythonhosted.org/packages/ef/8b/065d1e80ed4f3d4eb2d13a443b7f484f28ea09dfe1a19b8318cf71a02e78/recursive_decorator-1.0.7.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "30cf4eee8b1056848bd90dda61f04a24", "sha256": "5a6b840a67f01bd295e62e3995647de6a6d89fdb407a93d751c2537d887eefdf" }, "downloads": -1, "filename": "recursive_decorator-1.0.7-py3-none-any.whl", "has_sig": false, "md5_digest": "30cf4eee8b1056848bd90dda61f04a24", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6919, "upload_time": "2018-08-26T17:30:42", "url": "https://files.pythonhosted.org/packages/37/0c/6580dbfb6a01d8e0e752d5994ed26780359f5d97ad15443888b424994418/recursive_decorator-1.0.7-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "49e52072ae05b6add66891454e2d5133", "sha256": "41d88e3424c6ea14eee4dc56799193aa2ea4602bfb2f35edb93f524e73c61c91" }, "downloads": -1, "filename": "recursive_decorator-1.0.7.tar.gz", "has_sig": false, "md5_digest": "49e52072ae05b6add66891454e2d5133", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5877, "upload_time": "2018-08-26T17:30:43", "url": "https://files.pythonhosted.org/packages/ef/8b/065d1e80ed4f3d4eb2d13a443b7f484f28ea09dfe1a19b8318cf71a02e78/recursive_decorator-1.0.7.tar.gz" } ] }