Skip to content

Instantly share code, notes, and snippets.

@smitsgit
Last active July 9, 2020 09:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smitsgit/ecc09a1ac5bc478ad9a3e02e63d1bff6 to your computer and use it in GitHub Desktop.
Save smitsgit/ecc09a1ac5bc478ad9a3e02e63d1bff6 to your computer and use it in GitHub Desktop.
# Collection of useful python decorators
# Taken from https://eli.thegreenplace.net/2012/08/22/easy-tracing-of-nested-function-calls-in-python
# Easy tracing of nested function calls in Python
import sys
from functools import wraps
class TraceCalls(object):
""" Use as a decorator on functions that should be traced. Several
functions can be decorated - they will all be indented according
to their call depth.
"""
def __init__(self, stream=sys.stdout, indent_step=2, show_ret=False):
self.stream = stream
self.indent_step = indent_step
self.show_ret = show_ret
# This is a class attribute since we want to share the indentation
# level between different traced functions, in case they call
# each other.
TraceCalls.cur_indent = 0
def __call__(self, fn):
@wraps(fn)
def wrapper(*args, **kwargs):
indent = ' ' * TraceCalls.cur_indent
argstr = ', '.join(
[repr(a) for a in args] +
["%s=%s" % (a, repr(b)) for a, b in kwargs.items()])
self.stream.write('%s%s(%s)\n' % (indent, fn.__name__, argstr))
TraceCalls.cur_indent += self.indent_step
ret = fn(*args, **kwargs)
TraceCalls.cur_indent -= self.indent_step
if self.show_ret:
self.stream.write('%s--> %s\n' % (indent, ret))
return ret
return wrapper
import sys
from functools import wraps
class TraceCalls(object):
""" Use as a decorator on functions that should be traced. Several
functions can be decorated - they will all be indented according
to their call depth.
"""
def __init__(self, stream=sys.stdout, indent_step=4, show_ret=False, debug=False):
self.stream = stream
self.indent_step = indent_step
self.show_ret = show_ret
self.debug = debug
# This is a class attribute since we want to share the indentation
# level between different traced functions, in case they call
# each other.
TraceCalls.cur_indent = 0
def __call__(self, fn):
@wraps(fn)
def wrapper(*args, **kwargs):
if self.debug:
indent = ' ' * TraceCalls.cur_indent
argstr = ', '.join(
[str(a) for a in args[1:]] +
["%s=%s" % (a, repr(b)) for a, b in kwargs.items()])
self.stream.write('\n%s BEGIN %s(%s)\n' % (indent, fn.__name__, argstr))
TraceCalls.cur_indent += self.indent_step
ret = fn(*args, **kwargs)
if self.debug:
TraceCalls.cur_indent -= self.indent_step
self.stream.write('%s END %s(%s)\n\n' % (indent, fn.__name__, argstr))
if self.show_ret:
self.stream.write('%s--> %s\n' % (indent, ret))
return ret
return wrapper
############################################################################################
# Logging decorator
from functools import wraps
import logging
def debug(func):
log = logging.getLogger(func.__module__)
@wraps
def wrapper(*args, **kwargs):
log.debug(func.__qualname__)
return func(*args, **kwargs)
return wrapper
#####################################################################################################
# Decorator with arguments
# Taken from https://pyvideo.org/pycon-us-2013/python-3-metaprogramming.html
from functools import wraps
def debug(prefix=''):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
msg = f"{prefix} {func.__name__}"
print(msg)
return func(*args, **kwargs)
return wrapper
return decorator
# Interesting reformulation of the above decorator
def newdbug(func=None, *, prefix=''):
if func is None:
return partial(debug, prefix=prefix)
msg = f"{prefix} {func.__name__}"
@wraps(func)
def wrapper(*args, **kwargs):
print(msg)
return func(*args, **kwargs)
return wrapper
###########################################################################################################
# Debug class attribute look up
def debugmethods(cls):
orig_getattribute = cls.__getattribute__
def __getattribute__(self, name):
print("Get ", name)
return orig_getattribute(self, name)
cls.__getattribute__ = __getattribute__
return cls
#############################################################################################################
# dependency
def get_db(autocommit=False):
db: Session = sessionLocal()
try:
yield db
if autocommit:
db.commit()
except Exception:
db.rollback()
raise
finally:
db.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment