Skip to content

Instantly share code, notes, and snippets.

@mihneasim
Created December 17, 2014 07:18
Show Gist options
  • Save mihneasim/0b62c91ee2ca13e2b464 to your computer and use it in GitHub Desktop.
Save mihneasim/0b62c91ee2ca13e2b464 to your computer and use it in GitHub Desktop.
Call before and call after - Python decorators
from functools import wraps
def call_before(before_func, *args, **kwargs):
def call_before_decorator(func):
@wraps(func)
def wrapping(*args2, **kwargs2):
before_func(*args, **kwargs)
return func(*args2, **kwargs2)
return wrapping
return call_before_decorator
def call_after(after_func, *args, **kwargs):
def call_after_decorator(func):
@wraps(func)
def wrapping(*args2, **kwargs2):
try:
result = func(*args2, **kwargs2)
finally:
after_func(*args, **kwargs)
return result
return wrapping
return call_after_decorator
# And use them chained:
def log_enter_exit(logger, message=""):
def enter_exit_decorator(func):
@wraps(func)
@call_before(logger.debug, "Calling %s - %s", func.__name__, message)
@call_after(logger.debug, "Called %s - %s", func.__name__, message)
def wrapping(*args, **kwargs):
return func(*args, **kwargs)
return wrapping
return enter_exit_decorator
# Tests, because tests:
import mock
import unittest
from commons.decorators import *
class DecoratorsTestCase(unittest.TestCase):
def test_callbefore(self):
a = []
def append(where, what):
where.append(what)
@call_before(append, a, 3)
def extend(where, what):
where.extend(what)
return where
self.assertEqual(extend(a, [4, 5]), [3, 4, 5])
self.assertEqual(extend(a, [6]), [3, 4, 5, 3, 6])
self.assertEqual(extend([], [1, 2]), [1, 2])
self.assertEqual(a, [3, 4, 5, 3, 6, 3])
def test_callafter(self):
a = []
def append(where, what):
where.append(what)
@call_after(append, a, 6)
def extend(where, what):
where.extend(what)
return list(where)
self.assertEqual(extend(a, [4, 5]), [4, 5])
self.assertEqual(a, [4, 5, 6])
self.assertEqual(extend(a, [7]), [4, 5, 6, 7])
self.assertEqual(a, [4, 5, 6, 7, 6])
self.assertEqual(extend([], [1, 2]), [1, 2])
self.assertEqual(a, [4, 5, 6, 7, 6, 6])
def test_log_enter_exit(self):
logger = mock.Mock()
messages = []
def debug(pattern, *args, **kwargs):
messages.append(pattern % args)
logger.debug.side_effect = debug
logger.debug("Testing my %s", "mock")
self.assertEqual(messages[0], "Testing my mock")
@log_enter_exit(logger, "Whoaa")
def append(arg):
messages.append(arg)
return 3
self.assertEqual(append(666), 3)
self.assertEqual(messages[-3], "Calling append - Whoaa")
self.assertEqual(messages[-2], 666)
self.assertEqual(messages[-1], "Called append - Whoaa")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment