Initial revision
[blender.git] / intern / python / modules / mcf / utils / dummy.py
1 '''
2 Dummy Class, intended as an abstract class for the creation
3 of base/builtin classes with slightly altered functionality
4 uses _base as the name of an instance of the base datatype,
5 mapping all special functions to that name.
6
7 >>> from mcf.utils import dummy
8
9 >>> j = dummy.Dummy({})
10
11 >>> j['this'] = 23
12
13 >>> j
14
15 {'this': 23}
16
17 >>> class example(dummy.Dummy):
18
19 ...     def __repr__(self):
20
21 ...             return '<example: %s>'%`self._base`
22
23 >>> k = example([])
24
25 >>> k # uses the __repr__ function
26
27 <example: []>
28
29 >>> k.append # finds the attribute of the _base
30
31 <built-in method append of list object at 501830>
32
33 '''
34 import types, copy
35
36 class Dummy:
37         'Abstract class for slightly altering functionality of objects (including builtins)'
38         def __init__(self, val=None):
39                 'Initialisation, should be overridden'
40                 if val and type(val)== types.InstanceType and hasattr(val, '_base'):
41                         # Dict is used because subclasses often want to override
42                         # the setattr function
43                         self.__dict__['_base']=copy.copy(val.__dict__['_base'])
44                 else:
45                         self.__dict__['_base'] = val
46         def __repr__(self):
47                 'Return a string representation'
48                 return repr(self._base)
49         def __str__(self):
50                 'Convert to a string'
51                 return str(self._base)
52         def __cmp__(self,other):
53                 'Compare to other value'
54                 # altered 98.03.17 from if...elif...else statement
55                 return cmp(self._base, other)
56         def __getitem__(self, key):
57                 'Get an item by index'
58                 return self._base[key]
59         def __setitem__(self, key, val):
60                 'Set an item by index'
61                 self._base[key]=val
62         def __len__(self):
63                 'return the length of the self'
64                 return len(self._base)
65         def __delitem__(self, key):
66                 'remove an item by index'
67                 del(self._base[key])
68         def __getslice__(self, i, j):
69                 'retrieve a slice by indexes'
70                 return self._base[i:j]
71         def __setslice__(self, i, j, val):
72                 'set a slice by indexes to values'
73                 self._base[i:j]=val
74         def __delslice__(self, i, j):
75                 'remove a slice by indexes'
76                 del(self._base[i:j])
77         def __nonzero__(self):
78                 if self._base:
79                         return 1
80                 else:
81                         return 0
82         def __getattr__(self, attr):
83                 'find an attribute when normal lookup fails, will raise a KeyError if missing _base attribute'
84                 try:
85                         return getattr( self.__dict__['_base'], attr)
86                 except (AttributeError, KeyError):
87                         try:
88                                 return self.__dict__['_base'][attr]
89                         except (KeyError,TypeError):
90                                 pass
91                 raise AttributeError, attr