*** empty log message ***
[pli.git] / pli / interface / objects.py
blob784354c4d9a56060b7026bed5c4f1fbf40dc87a4
1 #=======================================================================
3 __version__ = '''0.0.09'''
4 __sub_version__ = '''20041018182000'''
5 __copyright__ = '''(c) Alex A. Naanou 2003'''
8 #-----------------------------------------------------------------------
10 import pli.logictypes as logictypes
11 ##import pli.interface.interface as interface
12 import interface
13 ##import pli.interface.utils as iutils
14 import pli.pattern.proxy.generic as proxy
18 #-----------------------------------------------------------------------
19 #-------------------------------------------------------------strhelp---
20 ##!!! ugly... revise!
21 # Q: should this be in this module??
22 def strhelp(obj):
23 '''
24 '''
25 e_res = []
26 res = []
27 interf = interface.getinterfaces(obj)
28 format = logictypes.DictUnion(*interf)
29 for n, d in format.iteritems():
30 if not d.get('readable', True) or n == '*':
31 continue
32 t = d.get('type', None)
33 if t == None:
34 if 'predicate' in d:
35 t = d['predicate'].__name__
36 else:
37 t = 'Any type'
38 elif hasattr(t, '__name__'):
39 t = t.__name__
40 if d.get('essential', False):
41 e_res += [ ' %s (%s):\t\t%s\n' % (n, t, d.get('doc', 'no doc.')) ]
42 else:
43 res += [ ' %s (%s):\t\t%s\n' % (n, t, d.get('doc', 'no doc.')) ]
44 e_res.sort()
45 res.sort()
46 if '*' in format:
47 d = format['*']
48 t = d.get('type', None)
49 if t == None and 'predicate' in d:
50 t = d['predicate'].__name__
51 else:
52 t = 'Any type'
53 res += [ ' %s (%s):\t\t%s\n' % ('*', t, d.get('doc', 'no doc.')) ]
54 return 'Object of %s %s \n%s\n\nEssential Attributes:\n%s\nOptional Attributes:\n%s\n' \
55 % (obj.__class__.__name__, interf, obj.__doc__, ''.join(e_res), ''.join(res))
60 #-----------------------------------------------------------------------
61 # TODO make it possible to change the __implemments__ attr name...
62 #---------------------------------------------ObjectWithInterfaceInit---
63 class ObjectWithInterfaceInit(object):
64 '''
65 this will setup the object according to the interface.
66 '''
67 # this defines the objects' interface.
68 # NOTE: if this is None interface support will be disabled.
69 __implemments__ = None
71 def __new__(cls, *p, **n):
72 '''
73 '''
74 obj = object.__new__(cls, *p, **n)
75 ogetattribute = object.__getattribute__
76 _interface = obj.__implemments__
77 if _interface != None:
78 ogetattribute(obj, '__dict__').update(interface.createdictusing(obj, _interface))
79 return obj
80 # pli protocols...
81 __help__ = classmethod(strhelp)
84 #-------------------------------------------------ObjectWithInterface---
85 class ObjectWithInterface(ObjectWithInterfaceInit):
86 '''
87 this is a basic object with interface support.
88 '''
89 # this defines the objects' interface.
90 # NOTE: if this is None interface support will be disabled.
91 __implemments__ = None
93 def __getattribute__(self, name):
94 '''
95 '''
96 if name in ('__implemments__',) or \
97 not hasattr(self, '__implemments__') or self.__implemments__ == None or \
98 interface.isreadable(self, name):
99 return super(ObjectWithInterface, self).__getattribute__(name)
100 raise interface.InterfaceError, 'can\'t read attribute "%s".' % name
101 def __setattr__(self, name, value):
104 ## if name in ('__implemments__',):
105 ## return super(ObjectWithInterface, self).__setattr__(name, value)
106 if not hasattr(self, '__implemments__') or self.__implemments__ == None or \
107 interface.iswritable(self, name) and interface.isvaluecompatible(self, name, value):
108 ## return super(ObjectWithInterface, self).__setattr__(name, value)
109 return super(ObjectWithInterface, self).__setattr__(name, interface.getvalue(self, name, value))
110 raise interface.InterfaceError, 'can\'t write value "%s" to attribute "%s".' % (value, name)
111 def __delattr__(self, name):
114 if not hasattr(self, '__implemments__') or self.__implemments__ == None or \
115 interface.isdeletable(self, name):
116 return super(ObjectWithInterface, self).__delattr__(name)
117 raise interface.InterfaceError, 'can\'t delete attribute "%s".' % name
121 #----------------------------------------------AbstractInterfaceProxy---
122 class AbstractInterfaceProxy(proxy.AbstractProxy):
125 NOTE: this was not intended for direct use...
127 # NOTE: this is hardcoded in the derived classes, thus changing this
128 # is not recommended.
129 # XXX is the fact of this being hardcoded good???
130 __proxy_target_attr_name__ = '__source__'
133 #--------------------------------------------------ProxyWithInterface---
134 # TODO move this to pli.pattern.proxy (???)
135 class ProxyWithInterface(AbstractInterfaceProxy):
138 __implemments__ = None
140 __source__ = None
142 def __init__(self, source):
145 self.__source__ = source
146 def __getattr__(self, name):
149 if not hasattr(self, '__implemments__') or self.__implemments__ == None or \
150 interface.isreadable(self, name):
151 return getattr(self.__source__, name)
152 raise interface.InterfaceError, 'can\'t read attribute "%s".' % name
153 def __setattr__(self, name, value):
156 if name in ('__source__', '__implemments__'):
157 return super(ProxyWithInterface, self).__setattr__(name, value)
158 if not hasattr(self, '__implemments__') or self.__implemments__ == None or \
159 interface.iswritable(self, name) and interface.isvaluecompatible(self, name, value):
160 ## return setattr(self.__source__, name, value)
161 source = self.__source__
162 return setattr(source, name, interface.getvalue(source, name, value))
163 raise interface.InterfaceError, 'can\'t write value "%s" to attribute "%s".' % (value, name)
164 def __delattr__(self, name):
167 if not hasattr(self, '__implemments__') or self.__implemments__ == None or \
168 interface.isdeletable(self, name):
169 delattr(self.__source__, name)
170 raise interface.InterfaceError, 'can\'t delete attribute "%s".' % name
171 # pli protocols...
172 __help__ = classmethod(strhelp)
175 #------------------------------------------------------InterfaceProxy---
176 class InterfaceProxy(ProxyWithInterface):
179 def __init__(self, source, interface=None):
182 ## super(InterfaceProxy, self).__init__(source)
183 self.__source__ = source
184 if interface != None:
185 self.__implemments__ = interface
186 elif hasattr(source, '__implemments__'):
187 self.__implemments__ = source.__implemments__
190 #---------------------------------------------RecursiveInterfaceProxy---
191 ##!!! test...
192 class RecursiveInterfaceProxy(proxy.GetattrRecursiveProxyMixin, InterfaceProxy):
195 ## def __call__():
196 ## '''
197 ## '''
198 ## pass
202 #=======================================================================
203 if __name__ == '__main__':
205 class O(ObjectWithInterface):
206 interface.inherit(iname='IO')
207 interface.add('xxx', type=int, default=0)
208 interface.add('xx0', type=int, default=0)
209 interface.add('xx1', type=int, default=0)
210 interface.add('xx2', type=int, default=0)
211 interface.add('xx3', type=int, default=0)
212 interface.add('xx4', type=int, default=0)
213 interface.add('xx5', type=int, default=0)
214 interface.add('xx6', type=int, default=0)
215 interface.add('xx7', type=int, default=0)
216 interface.add('xx8', type=int, default=0)
217 interface.add('xx9', type=int, default=0)
219 ## interface.hide('xxx')
220 interface.hide('xx0')
222 interface.add('*')
224 def f(self):
225 print '!!!'
227 o = O()
229 def f():
230 print 'mooo!'
232 o.f = f
234 print '123'
236 print o.xxx
238 o.xxx = 123
240 print o.xxx
242 print hasattr(o, '__implemments__')
243 print hasattr(O, '__implemments__')
245 o.f()
247 print o.__help__()
251 #=======================================================================
252 # vim:set ts=4 sw=4 nowrap :