Mercurial > traipse_dev
diff orpg/tools/decorators.py @ 72:8bc955faf819 ornery-dev
Fixing a few mistakes from the last update. When Controls is finished I will be happy because users won't miss an file change due to these small updates.
author | sirebral |
---|---|
date | Thu, 20 Aug 2009 03:45:45 -0500 |
parents | |
children | 37a11fea3304 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/orpg/tools/decorators.py Thu Aug 20 03:45:45 2009 -0500 @@ -0,0 +1,146 @@ +import warnings +import functools + +from orpg.orpgCore import * + +def deprecated(msg=None): + """ + This is a decorator which can be used to mark functions + as deprecated. It will result in a warning being emitted + when the function is used. + """ + def wrap(func): + @functools.wraps(func) + def new_func(*args, **kwargs): + out = msg + if not out: + out = "Call to deprecated function %s." + else: + out = "Call to deprecated function %s.\n" + out + + warnings.warn_explicit( + out % (func.__name__), + category=DeprecationWarning, + filename=func.func_code.co_filename, + lineno=func.func_code.co_firstlineno + 1 + ) + return func(*args, **kwargs) + return new_func + return wrap + +def pending_deprecation(msg=None): + """ + This is a decorator which can be used to mark functions + as deprecated. It will result in a warning being emitted + when the function is used. + """ + def wrap(func): + @functools.wraps(func) + def new_func(*args, **kwargs): + out = msg + if not out: + out = "%s is Pending Deprecation." + else: + out = "%s is Pending Deprecation.\n" + out + + warnings.warn_explicit( + out % (func.__name__), + category=PendingDeprecationWarning, + filename=func.func_code.co_filename, + lineno=func.func_code.co_firstlineno + 1 + ) + return func(*args, **kwargs) + return new_func + return wrap + +def synchronized(lock): + """ + Synchronization decorator. + """ + + @functools.wraps(func) + def new_func(*args, **kwargs): + lock.acquire() + try: + return func(*args, **kwargs) + finally: + lock.release() + return new_func + +class memoized(object): + """ + Decorator that caches a function's return value each time it is called. + If called later with the same arguments, the cached value is returned, and + not re-evaluated. + """ + def __init__(self, func): + self.func = func + self.cache = {} + + def __call__(self, *args, **kwargs): + try: + return self.cache[args + kwargs.values()] + except KeyError: + self.cache[args] = value = self.func(*args, **kwargs) + return value + except TypeError: + # uncachable -- for instance, passing a list as an argument. + # Better to not cache than to blow up entirely. + return self.func(*args) + def __repr__(self): + """ + Return the function's docstring. + """ + return self.func.__doc__ + +def debugging(func): + """ + Decorator to print Enter/Exit debugging info + """ + + @functools.wraps(func) + def new_func(*args, **kwargs): + from orpg.tools.orpg_log import logger + + if not ORPG_DEBUG & logger.log_level: + return func(*args, **kwargs) + + if str(args[0].__class__).startswith('<class'): + cls = args[0].__class__.__name__ + args_s = "self" + if len(args) > 1: + args_s += ', ' + ', '.join([str(attr) for attr in args[1:]]) + kwargs_s = "" + for k,v in kwargs.iteritems(): + kwargs_s += ', ' + k + '=' + str(v) + + call_str = '%(cls)s->%(fnc)s(%(args)s%(kwargs)s)' % { + 'cls':cls, + 'fnc':func.__name__, + 'args':args_s, + 'kwargs':kwargs_s} + try: + logger.debug("Enter " + call_str) + return func(*args, **kwargs) + finally: + logger.debug("Exit " + call_str) + else: + try: + logger.debug("Enter " + func.__name__) + return func(*args, **kwargs) + finally: + logger.debug("Exit " + func.__name__) + return new_func + +""" +Cannot use this decorator till we stop supporting py2.5 +as class decorators did not land till py2.6 I am just adding it here +So when we do we can convert all singleton classes to use it +""" +def singleton(cls): + instances = {} + def getinstance(): + if cls not in instances: + instances[cls] = cls() + return instances[cls] + return getinstance