DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
proxy.py
Go to the documentation of this file.
1#!/usr/bin/env python
2
3
4"""Proxing/Delegation tools
5
6Provide several tools to implement proxying/delegation of objects. The proxying
7instances expose the same public interface of the proxied object, but avoiding
8inheritance. This allows to control the reference counts of the proxied object.
9
10"""
11# Explicit proxying mechanism not using metaclasses
12
13
14class Proxy(object):
15 """A very basic holder class
16
17 Just holds the reference to a provided object.
18
19 """
20
21 def __init__(self, obj):
22 super(Proxy, self).__init__()
23 self._obj = obj
24
25
26def make_proxy_class(theclass):
27 """Builds a delegation class out of a given type.
28
29 Uses the Proxy class to generate a new proxy class exposing the same
30 interface of the provided class and delegating the method calls to
31 the hosted object instance.
32
33 """
34 def make_method(name):
35 def method(self, *args, **kwds):
36 return getattr(self._obj, name)(*args, **kwds)
37 return method
38
39 base = Proxy
40 namespace = {}
41 for methodname in dir(theclass):
42 if not methodname.startswith('__'):
43 namespace[methodname] = make_method(methodname)
44
45 proxyclass = type("%s%s" % (theclass.__name__, base.__name__),
46 (base,), namespace)
47
48 return proxyclass
49
50
51# We do use a function instead of a class for the meta definition to avoid
52# problems with inheritance of the constructed classes. In fact, using a
53# function the type of the resulting classes is still 'type', therefore
54# the meta functionalities are not implemented in the subclasses
55
56def _DelegateMetaFunction(clsName, bases, atts):
57 """ Implements a delegation pattern using a metaclass approach
58
59 A class using this meta mechanism should have 'memberclass' class attribute
60 initialized at the class of the instance to proxied. The metaclass will
61 make sure the delegate class will expose all the public methods of the
62 proxied one.
63 Moreover, the metaclass will provide the delegate class with a '__init__'
64 function instantiating a 'memberclass' object, storing it in 'self._obj'.
65 The delegate class constructor method will therefore accept all the
66 arguments accepted by the proxied class constructor.
67 The delegate class uses slots
68
69 """
70 memberclass = atts['memberclass']
71
72 def make_method(name):
73 def method(self, *args, **kwds):
74 return getattr(self._obj, name)(*args, **kwds)
75 method.__name__ = name
76 return method
77
78 for methodname in dir(memberclass):
79 if not methodname.startswith('__'):
80 atts[methodname] = make_method(methodname)
81
82 atts['__slots__'] = ['_obj', ]
83
84 def initfun(self, *args, **kwds):
85 # We force the proxied and delegate __init__
86 # functions take the same arguments
87 # This can be easily changed with some input from the
88 # delegate class
89 obj = memberclass(*args, **kwds)
90 self._obj = obj
91
92 initfun.__doc__ = \
93 """Instantiate %s and store the instance in 'self._obj'
94
95 """ % str(memberclass)
96 initfun.__name__ = '__init__'
97
98 atts['__init__'] = initfun
99
100 return type(clsName, bases, atts)
__init__(self, obj)
Definition proxy.py:21
make_proxy_class(theclass)
Definition proxy.py:26
_DelegateMetaFunction(clsName, bases, atts)
Definition proxy.py:56