1 #=======================================================================
3 __version__
= '''0.0.09'''
4 __sub_version__
= '''20081027154102'''
5 __copyright__
= '''(c) Alex A. Naanou 2003'''
8 #-----------------------------------------------------------------------
15 #-----------------------------------------------------------------------
16 #----------------------------------------createmethodwrappersinobject---
17 ##!!! REVISE (rewrite or remove) !!!##
18 def createmethodwrappersinobject(source_obj
, method_list
, wrapper
, target_obj
):
20 this will attach methods mentioned in method_list to the target object
21 that will wrap methods of the source object.
23 WARNING: this will render the target object unpicklable...
24 NOTE: this can be used for classes...
26 for meth
in method_list
:
27 if hasattr(source_obj
, meth
):
28 setattr(target_obj
, meth
, wrapper(getattr(source_dict
, meth
)))
32 #------------------------------------------------createmethodwrappers---
33 ##!!! REVISE (rewrite or remove) !!!##
34 def createmethodwrappers(source_dict
, method_list
, wrapper
, target_dict
=None):
36 this will wrap methods mentioned in method_list from the source dict and
37 will return a dict containing the wrappers (will update and return target_dict
40 if target_dict
!= None:
44 for meth
in method_list
:
45 if meth
in source_dict
:
46 res
[meth
] = wrapper(source_dict
[meth
])
51 #-----------------------------------------------------------------------
52 # XXX attempt to get the class name form the context...
54 def superproxymethod(methodname
, source_attr
, class_name
, exceptions
=Exception, depth
=1, decorators
=()):
56 create a proxy to the method name in the containing namespace.
58 the constructed proxy will attempt to call an existing method, and
59 in case it fails with exceptions, it will call the alternative from
62 NOTE: method name can either be a string or a touple of two strings, a source
63 and target method names.
64 NOTE: this will add the method_name to the containing namespace.
65 NOTE: source_attr is to be used as the attr name referencing the source object.
67 # text of the new function....
69 def %(method_name)s(self, *p, **n):
71 this is the proxy to %(method_name)s method.
74 return super(%(class_name)s, self).%(method_name)s(*p, **n)
75 except (%(exceptions)s):
76 return self.%(source_attr)s.%(target_method_name)s(*p, **n)
77 proxy = %(method_name)s'''
79 # get the method name and target name...
80 if type(method_name
) in (tuple, list):
81 if len(method_name
) != 2:
82 raise TypeError, 'name must either be a string or a sequence of two (got: %s).' % method_name
83 method_name
, target_method_name
= method_name
[0], method_name
[-1]
85 target_method_name
= method_name
86 # execute the above code...
88 'method_name': method_name
,
89 'target_method_name': target_method_name
,
90 'source_attr': source_attr
,
91 'class_name': class_name
,
92 'exceptions': type(exceptions
) in (tuple, list) \
93 and ', '.join([ e
.__name
__ for e
in exceptions
]) \
94 or exceptions
.__name
__,
96 # run the decorators...
100 sys
._getframe
(depth
).f_locals
[method_name
] = proxy
103 #---------------------------------------------------------proxymethod---
104 # NOTE: the interface changed, so if you used something like this:
105 # proxymethod('some_method', 'attr', target_method_name='method', ...)
106 # you should now do it like this:
107 # proxymethod(('some_method', 'method'), 'attr', ...)
108 # TODO create a version of this with super call...
109 # TODO move depth to the end of the args...
110 # XXX as soon as we can construct a function in pure python this will
111 # need to be rewritten...
112 def proxymethod(method_name
, source_attr
, doc
='', depth
=1, decorators
=(), explicit_self
=False):
114 create a proxy to the method name in the containing namespace.
117 method_name - the name of the method to proxy or a tuple of two strings first
118 is the name of the local method and the second is the name of the
120 source_attr - attribute to which to proxy the method call. if this is set to
121 None the the method will be called directly to the current object.
122 doc - the doc string to use for the constructed function.
123 decorators - sequence of decorators to apply to the constructed function.
124 explicit_self - if true, pass the self to the target explicitly.
126 depth - frame depth, used for name setting (use at your own risk).
128 NOTE: this will add the method_name to the containing namespace.
129 NOTE: source_attr is to be used as the attr name referencing the source object.
131 # text of the new function....
133 def %(method_name)s(self, *p, **n):
135 this is a proxy to self.%(source_attr)s.%(target_method_name)s method.
137 return self.%(source_attr)s%(target_method_name)s(%(self_arg)s*p, **n)
139 # add the result to a predictable name in the NS.
140 proxy = %(method_name)s'''
142 # get the method name and target name...
143 if type(method_name
) in (tuple, list):
144 if len(method_name
) != 2:
145 raise TypeError, 'name must either be a string or a sequence of two (got: %s).' % method_name
146 method_name
, target_method_name
= method_name
[0], method_name
[-1]
148 target_method_name
= method_name
149 # prepare the source attr...
150 if source_attr
== None:
159 # explicit self passing...
160 if explicit_self
is True:
164 # execute the above code...
167 'method_name': method_name
,
168 'target_method_name': target_method_name
,
169 'source_attr': source_attr
,
170 'self_arg': self_arg
})
171 # run the decorators...
175 sys
._getframe
(depth
).f_locals
[method_name
] = proxy
178 #--------------------------------------------------------proxymethods---
179 def proxymethods(names
, source_attr
, decorators
=(), explicit_self
=False, depth
=1):
181 generate a direct proxy for each name.
183 for more details see docs for proxymethod(...)
186 proxymethod(name
, source_attr
, depth
=depth
+1,
187 decorators
=decorators
, explicit_self
=explicit_self
)
191 #-----------------------------------------------------------------------
192 #-------------------------------------------------------proxyproperty---
193 def proxyproperty(name
, source_attr
, depth
=1, local_attr_tpl
='_%s'):
195 create a property that will fetch the attr name form an object
196 referenced by .source_attr if no local value is defined, otherwise
199 NOTE: this will shadow inherited or overwrite local existing attributes
201 NOTE: this supports local data stored in ._<name> attr (default)
202 NOTE: local_attr_tpl controls the attribute name to store the data
203 in the local namespace (must contain a string containing exactly
206 local_attr
= local_attr_tpl
% name
208 if hasattr(self
, local_attr
):
209 return getattr(self
, local_attr
)
210 return getattr(getattr(self
, source_attr
), name
)
211 def setter(self
, val
):
212 setattr(self
, local_attr
, val
)
214 if hasattr(self
, local_attr
):
215 delattr(self
, local_attr
)
217 sys
._getframe
(depth
).f_locals
[name
] \
224 #-----------------------------------------------------proxyproperties---
225 def proxyproperties(names
, source_attr
, local_attr_tpl
='_%s'):
227 shorthad for multiple proxyproperty use with the same source_attr.
230 proxyproperty(name
, source_attr
, depth
=2, local_attr_tpl
=local_attr_tpl
)
234 #-----------------------------------------------------------------------
235 #------------------------------------------------------swapmethodself---
236 def swapmethodself(meth
, wrapper
, use_wrapper_as_class
=True):
239 return new
.instancemethod(meth
.im_func
,
241 use_wrapper_as_class
and \
242 wrapper
or meth
.im_class
)
245 #------------------------------------------------------wrapmethodself---
246 def wrapmethodself(meth
, wrapper
, use_wrapper_as_class
=True):
249 return new
.instancemethod(meth
.im_func
,
250 wrapper(meth
.im_self
),
251 use_wrapper_as_class
and \
252 wrapper
or meth
.im_class
)
256 #=======================================================================
257 # vim:set ts=4 sw=4 nowrap :