1 from Lib import ImmDict
\r
4 def fully_dynamic_metaclass(name, bases, dict):
\r
6 a meta class that enables special methods to be accessed like regular names
\r
7 (via __getattr__), like it used to be in old-style classes.
\r
11 "__hash__", "__len__", "__iter__", "next", "__reversed__",
\r
12 "__add__", "__iadd__", "__radd__", "__sub__", "__isub__", "__rsub__", "__mul__",
\r
13 "__imul__", "__rmul__", "__div__", "__idiv__", "__rdiv__", "__truediv__",
\r
14 "__itruediv__", "__rtruediv__", "__floordiv__", "__ifloordiv__", "__rfloorfiv__",
\r
15 "__pow__", "__ipow__", "__rpow__", "__lshift__", "__ilshift__", "__rlshift__",
\r
16 "__rshift__", "__irshift__", "__rrshift__", "__and__", "__iand__", "__rand__",
\r
17 "__or__", "__ior__", "__ror__", "__xor__", "__ixor__", "__rxor__", "__mod__",
\r
18 "__imod__", "__rmod__", "__divmod__", "__idivmod__", "__rdivmod__", "__pos__",
\r
19 "__neg__", "__int__", "__float__", "__long__", "__oct__", "__hex__", "__coerce__",
\r
20 "__eq__", "__ne__", "__le__", "__ge__", "__lt__", "__gt__", "__cmp__",
\r
23 # i added '__class__' to the special attributes, but it broke some things
\r
24 # (like dir), so we'll have to live without it
\r
25 special_attributes = ["__doc__", "__module__"]
\r
27 def make_method(name):
\r
28 def caller(self, *a, **k):
\r
29 return self.__getattr__(name)(*a, **k)
\r
32 def make_property(name):
\r
34 return self.__getattr__(name)
\r
35 def setter(self, value):
\r
36 self.__setattr__(name, value)
\r
38 self.__delattr__(name)
\r
39 return property(getter, setter, deller)
\r
42 for sn in special_methods:
\r
43 classdict[sn] = make_method(sn)
\r
44 classdict.update(dict)
\r
45 for sa in special_attributes:
\r
46 classdict[sa] = make_property(sa)
\r
47 return type(name, bases, classdict)
\r
49 class NetProxy(object):
\r
50 """NetProxy - convey local operations to the remote object. this is an abstract class"""
\r
51 __metaclass__ = fully_dynamic_metaclass
\r
53 def __init__(self, conn, oid):
\r
54 self.__dict__["____conn"] = conn
\r
55 self.__dict__["____oid"] = oid
\r
57 def __request__(self, handler, *args):
\r
58 raise NotImplementedError()
\r
60 def __call__(self, *args, **kwargs):
\r
61 return self.__request__("handle_call", args, ImmDict(kwargs))
\r
63 def __delattr__(self, *args):
\r
64 return self.__request__("handle_delattr", *args)
\r
65 def __getattr__(self, *args):
\r
66 return self.__request__("handle_getattr", *args)
\r
67 def __setattr__(self, *args):
\r
68 return self.__request__("handle_setattr", *args)
\r
70 def __delitem__(self, *args):
\r
71 return self.__request__("handle_delitem", *args)
\r
72 def __getitem__(self, *args):
\r
73 return self.__request__("handle_getitem", *args)
\r
74 def __setitem__(self, *args):
\r
75 return self.__request__("handle_setitem", *args)
\r
78 def __repr__(self, *args):
\r
79 return self.__request__("handle_repr", *args)
\r
80 def __str__(self, *args):
\r
81 return self.__request__("handle_str", *args)
\r
82 def __nonzero__(self, *args):
\r
83 return self.__request__("handle_bool", *args)
\r
85 class NetProxyWrapper(NetProxy):
\r
86 """a netproxy that wraps an inner netproxy"""
\r
87 __doc__ = NetProxy.__doc__
\r
89 def __init__(self, proxy):
\r
90 NetProxy.__init__(self, proxy.__dict__["____conn"], proxy.__dict__["____oid"])
\r
91 # we must keep the original proxy alive
\r
92 self.__dict__["____original_proxy"] = proxy
\r
94 def _dummy_callback(*args, **kw):
\r
97 class SyncNetProxy(NetProxy):
\r
98 """the default, synchronous netproxy"""
\r
99 __doc__ = NetProxy.__doc__
\r
101 def __init__(self, conn, oid):
\r
102 NetProxy.__init__(self, conn, oid)
\r
103 self.__dict__["____conn"].sync_request("handle_incref", self.__dict__["____oid"])
\r
107 # decref'ing is done asynchronously, because we dont need to wait for the remote
\r
108 # object to die. moreover, we dont care if it fails, because that would mean the
\r
109 # connection is broken, so the remote object is already dead
\r
110 self.__dict__["____conn"].async_request(_dummy_callback, "handle_decref", self.__dict__["____oid"])
\r
114 def __request__(self, handler, *args):
\r
115 return self.__dict__["____conn"].sync_request(handler, self.__dict__["____oid"], *args)
\r