Skip to main content

Decorator to apply given decorator recursively on functions

Project description

GitHub license https://badge.fury.io/py/recursive-decorator.svg https://travis-ci.org/yakobu/recursive_decorator.svg?branch=master https://coveralls.io/repos/github/yakobu/recursive_decorator/badge.svg?branch=master

Decorator to apply a given decorator recursively on all function, inside a function/method, recursively.

What is recursive_decorator?

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 knownunknown functions, along the stack calls.

Notes:

  • Functions/Methods will not be replaced, new instances will be returned.

  • Function/Methods cannot be wrapped more then once with same transformer/decorator.

Installing

$ pip install recursive_decorator

Usage

import recursive_decorator

from recursive_decorator import recursive_decorator

define your decorator to apply recursively on all functions.

>>> def decorator(f):
...:    def wrapper(*args, **kwargs):
...:        print(f.__name__)
...:        return f(*args, **kwargs)
...:    return wrapper

Now using your decorator on function without using recursive_decorator will leads to the following output

>>> @decorator
...:def main_function():
...:   sub_function()

>>> main_function()
main_function

Using recursive_decorator leads to

>>> @recursive_decorator(decorator)
...:def main_function():
...:   sub_function()

>>> main_function()
main_function
sub_function

Furthermore, if sub_function has function calls, they will decorated to

>>> def sub_function():
...:    another_function()

>>> @recursive_decorator(decorator)
...:def main_function():
...:   sub_function()

>>> main_function()
main_function
sub_function
another_function

and so on…

Examples

Stop on Execption

We can wrap all functions with try except…

  >>> import sys
  >>> import ipdb
  >>> from recursive_decorator import recursive_decorator

  >>> def wrap_function_with_try_except(f):
  ...:    def transformed_func(*args, **kwargs):
  ...:        try:
  ...:            return f(*args, **kwargs)
  ...:        except:
  ...:            ipdb.set_trace(sys._getframe().f_back)
  ...:    return transformed_func

  >>> def throws_exception():
  ...:    raise Exception


  >>> @recursive_decorator(wrap_function_with_try_except)
  ...:def function():
  ...:    throws_exception()
  ...:    pass

  >>> function()
     21     throws_exception()
---> 22     pass
     23

If function will throw an error… ipdb session will start.

Profiler

We can set time profiler for all running functions.

>>> import time

>>> from recursive_decorator import recursive_decorator


>>> def duration_transformer(f):
...:    def transformed_func(*args, **kwargs):
...:        start_time = time.time()
...:        value = f(*args, **kwargs)
...:        end_time = time.time()
...:        print("function {} duration is {} minutes"
...:              .format(f.__name__, end_time - start_time))
...:        return value
...:    return transformed_func


>>> def waiting_function():
...:    time.sleep(5)


>>> @recursive_decorator(duration_transformer)
...:def function():
...:    waiting_function()

>>> function()
function waiting_function duration is 5.00511908531189 minutes
function function duration is 5.006134510040283 minutes

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

recursive_decorator-1.0.7.tar.gz (5.9 kB view hashes)

Uploaded Source

Built Distribution

recursive_decorator-1.0.7-py3-none-any.whl (6.9 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page