1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
"""
application level support module for transparent proxies.
"""
from __pypy__ import tproxy
from types import MethodType
_dummy = object()
origtype = type
def make_proxy(controller, type=_dummy, obj=_dummy):
""" return a tranparent proxy controlled by the given
'controller' callable. The proxy will appear
as a completely regular instance of the given
type but all operations on it are send to the
specified controller - which receives on
ProxyOperation instance on each such call.
A non-specified type will default to type(obj)
if obj is specified.
"""
if type is _dummy:
if obj is _dummy:
raise TypeError("you must specify a type or an instance obj of it")
type = origtype(obj)
def perform(opname, *args, **kwargs):
operation = ProxyOperation(tp, obj, opname, args, kwargs)
return controller(operation)
tp = tproxy(type, perform)
return tp
class ProxyOperation(object):
def __init__(self, proxyobj, obj, opname, args, kwargs):
self.proxyobj = proxyobj
self.opname = opname
self.args = args
self.kwargs = kwargs
if obj is not _dummy:
self.obj = obj
def delegate(self):
""" return result from delegating this operation to the
underyling self.obj - which must exist and is usually
provided through the initial make_proxy(..., obj=...)
creation.
"""
try:
obj = getattr(self, 'obj')
except AttributeError:
raise TypeError("proxy does not have an underlying 'obj', "
"cannot delegate")
objattr = getattr(obj, self.opname)
res = objattr(*self.args, **self.kwargs)
if self.opname == "__getattribute__":
if (isinstance(res, MethodType) and
res.im_self is self.instance):
res = MethodType(res.im_func, self.proxyobj, res.im_class)
if res is self.obj:
res = self.proxyobj
return res
def __repr__(self):
args = ", ".join([repr(x) for x in self.args])
args = "<0x%x>, " % id(self.proxyobj) + args
if self.kwargs:
args += ", ".join(["%s=%r" % item
for item in self.kwargs.items()])
return "<ProxyOperation %s.%s(%s)>" %(
type(self.proxyobj).__name__, self.opname, args)
|