Mercurial > traipse_dev
comparison 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 |
comparison
equal
deleted
inserted
replaced
71:449a8900f9ac | 72:8bc955faf819 |
---|---|
1 import warnings | |
2 import functools | |
3 | |
4 from orpg.orpgCore import * | |
5 | |
6 def deprecated(msg=None): | |
7 """ | |
8 This is a decorator which can be used to mark functions | |
9 as deprecated. It will result in a warning being emitted | |
10 when the function is used. | |
11 """ | |
12 def wrap(func): | |
13 @functools.wraps(func) | |
14 def new_func(*args, **kwargs): | |
15 out = msg | |
16 if not out: | |
17 out = "Call to deprecated function %s." | |
18 else: | |
19 out = "Call to deprecated function %s.\n" + out | |
20 | |
21 warnings.warn_explicit( | |
22 out % (func.__name__), | |
23 category=DeprecationWarning, | |
24 filename=func.func_code.co_filename, | |
25 lineno=func.func_code.co_firstlineno + 1 | |
26 ) | |
27 return func(*args, **kwargs) | |
28 return new_func | |
29 return wrap | |
30 | |
31 def pending_deprecation(msg=None): | |
32 """ | |
33 This is a decorator which can be used to mark functions | |
34 as deprecated. It will result in a warning being emitted | |
35 when the function is used. | |
36 """ | |
37 def wrap(func): | |
38 @functools.wraps(func) | |
39 def new_func(*args, **kwargs): | |
40 out = msg | |
41 if not out: | |
42 out = "%s is Pending Deprecation." | |
43 else: | |
44 out = "%s is Pending Deprecation.\n" + out | |
45 | |
46 warnings.warn_explicit( | |
47 out % (func.__name__), | |
48 category=PendingDeprecationWarning, | |
49 filename=func.func_code.co_filename, | |
50 lineno=func.func_code.co_firstlineno + 1 | |
51 ) | |
52 return func(*args, **kwargs) | |
53 return new_func | |
54 return wrap | |
55 | |
56 def synchronized(lock): | |
57 """ | |
58 Synchronization decorator. | |
59 """ | |
60 | |
61 @functools.wraps(func) | |
62 def new_func(*args, **kwargs): | |
63 lock.acquire() | |
64 try: | |
65 return func(*args, **kwargs) | |
66 finally: | |
67 lock.release() | |
68 return new_func | |
69 | |
70 class memoized(object): | |
71 """ | |
72 Decorator that caches a function's return value each time it is called. | |
73 If called later with the same arguments, the cached value is returned, and | |
74 not re-evaluated. | |
75 """ | |
76 def __init__(self, func): | |
77 self.func = func | |
78 self.cache = {} | |
79 | |
80 def __call__(self, *args, **kwargs): | |
81 try: | |
82 return self.cache[args + kwargs.values()] | |
83 except KeyError: | |
84 self.cache[args] = value = self.func(*args, **kwargs) | |
85 return value | |
86 except TypeError: | |
87 # uncachable -- for instance, passing a list as an argument. | |
88 # Better to not cache than to blow up entirely. | |
89 return self.func(*args) | |
90 def __repr__(self): | |
91 """ | |
92 Return the function's docstring. | |
93 """ | |
94 return self.func.__doc__ | |
95 | |
96 def debugging(func): | |
97 """ | |
98 Decorator to print Enter/Exit debugging info | |
99 """ | |
100 | |
101 @functools.wraps(func) | |
102 def new_func(*args, **kwargs): | |
103 from orpg.tools.orpg_log import logger | |
104 | |
105 if not ORPG_DEBUG & logger.log_level: | |
106 return func(*args, **kwargs) | |
107 | |
108 if str(args[0].__class__).startswith('<class'): | |
109 cls = args[0].__class__.__name__ | |
110 args_s = "self" | |
111 if len(args) > 1: | |
112 args_s += ', ' + ', '.join([str(attr) for attr in args[1:]]) | |
113 kwargs_s = "" | |
114 for k,v in kwargs.iteritems(): | |
115 kwargs_s += ', ' + k + '=' + str(v) | |
116 | |
117 call_str = '%(cls)s->%(fnc)s(%(args)s%(kwargs)s)' % { | |
118 'cls':cls, | |
119 'fnc':func.__name__, | |
120 'args':args_s, | |
121 'kwargs':kwargs_s} | |
122 try: | |
123 logger.debug("Enter " + call_str) | |
124 return func(*args, **kwargs) | |
125 finally: | |
126 logger.debug("Exit " + call_str) | |
127 else: | |
128 try: | |
129 logger.debug("Enter " + func.__name__) | |
130 return func(*args, **kwargs) | |
131 finally: | |
132 logger.debug("Exit " + func.__name__) | |
133 return new_func | |
134 | |
135 """ | |
136 Cannot use this decorator till we stop supporting py2.5 | |
137 as class decorators did not land till py2.6 I am just adding it here | |
138 So when we do we can convert all singleton classes to use it | |
139 """ | |
140 def singleton(cls): | |
141 instances = {} | |
142 def getinstance(): | |
143 if cls not in instances: | |
144 instances[cls] = cls() | |
145 return instances[cls] | |
146 return getinstance |