added pli.misc.namespace experimental module...
[pli.git] / pli / functional.py
blob0ab6287b70f375aea19d3ae4fd8097fec52add15
1 #=======================================================================
3 __version__ = '''0.5.08'''
4 __sub_version__ = '''20040328151509'''
5 __copyright__ = '''(c) Alex A. Naanou 2003'''
8 #-----------------------------------------------------------------------
10 from __future__ import generators
11 import new
14 #-----------------------------------------------------------------------
15 #---------------------------------------------------------------apply---
16 apply = lambda func, *pargs, **nargs: func(*pargs, **nargs)
19 #--------------------------------------------------------------lcurry---
20 lcurry = lambda func, *pargs, **nargs:\
21 lambda *p, **n:\
22 func(*pargs + p, **dict(nargs.items() + n.items()))
25 #---------------------------------------------------------------curry---
26 curry = lcurry
29 #--------------------------------------------------------------rcurry---
30 # NOTE: this adds the curried args to the tail...
31 rcurry = lambda func, *pargs, **nargs:\
32 lambda *p, **n:\
33 func(*p + pargs, **dict(nargs.items() + n.items()))
36 #-----------------------------------------------------------fastcurry---
37 # Originally written by Alex Martelli
38 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/229472
39 # NOTE: though this is faster, it is also less flexible then the above
40 # variants.
41 # NOTE: here 'arg' can not be None.
42 fastcurry = lambda func, arg:\
43 new.instancemethod(func, arg, object)
46 #--------------------------------------------------------------LCurry---
47 class LCurry(object):
48 '''
49 this is the left curry class.
50 '''
51 def __new__(cls, func, *args, **kw):
52 obj = object.__new__(cls)
53 if isinstance(func, LCurry) or isinstance(func, RCurry):
54 obj._curry_func = func._curry_func
55 obj._curry_args = (func._curry_args[0] + args, func._curry_args[1])
56 obj._curry_kw = kw = kw.copy()
57 kw.update(func._curry_kw)
58 else:
59 obj._curry_func = func
60 obj._curry_args = (args, ())
61 obj._curry_kw = kw.copy()
62 return obj
63 def __call__(self, *args, **kw):
64 self._curry_func(*self._curry_args[0] + args + self._curry_args[1], **dict(self._curry_kw.items() + kw.items()))
67 #---------------------------------------------------------------Curry---
68 Curry = LCurry
71 #--------------------------------------------------------------RCurry---
72 class RCurry(object):
73 '''
74 this is the right curry class.
75 '''
76 def __new__(cls, func, *args, **kw):
77 obj = object.__new__(cls)
78 if isinstance(func, LCurry) or isinstance(func, RCurry):
79 obj._curry_func = func._curry_func
80 obj._curry_args = (func._curry_args[0] ,func._curry_args[1] + args)
81 obj._curry_kw = kw = kw.copy()
82 kw.update(func._curry_kw)
83 else:
84 obj._curry_func = func
85 obj._curry_args = ((), args)
86 obj._curry_kw = kw.copy()
87 return obj
88 def __call__(self, *args, **kw):
89 self._curry_func(*self._curry_args[0] + args + self._curry_args[1], **dict(self._curry_kw.items() + kw.items()))
92 #--------------------------------------------------------------negate---
93 # this will return a function that will return the oposite result
94 # (boolean) to the original....
95 negate = lambda f:\
96 lambda *p, **n: not f(*p, **n)
99 #------------------------------------------------------raise_on_false---
100 def raise_on_false(func, exception=Exception, name=None, msg=''):
102 this will return a function wraping func so as to raise exception(msg) if it returns false.
104 # sanity checks... ##!! TEST !!##
105 if func == None:
106 raise TypeError, 'func must not be None.'
107 if hasattr(func, '_raise_on_false_wrapped') and func._raise_on_false_wrapped:
108 raise TypeError, '%s is already wrapped, won\'t wrap agen.' % func
110 # define the function code...
111 func_txt = """def %(function_name)s(*p, **n):
112 '''wrapper of %(function_object)s callable.'''
113 res = func(*p, **n)
114 if not res:
115 raise exception, msg
116 return res"""
117 # genreate a good name if one is not given...
118 if name == None:
119 name = hasattr(func, '__name__') and func.__name__ != '<lambda>' and func.__name__ or 'Unnamed'
120 exec (func_txt % {'function_name':name, 'function_object':func}) in locals(), globals()
121 f = eval(name)
122 # marck the predicate returned... (to avoid repeated wrapping (see
123 # above))...
124 f._raise_on_false_wrapped = True
125 return f
128 ###------------------------------------------------------------iterator---
129 ##class _iterator(object):
130 ## '''
131 ## '''
132 ## def __init__(self, iter_next, iter_init, *p, **n):
133 ## '''
134 ## '''
135 ## init(self, *p, **n)
136 ## self.next = new.instancemethod(iter_next, self, iterator)
137 ## def __iter__(self):
138 ## return self
142 #-----------------------------------------------------------------------
143 ##!! THE FOLLOWING ARE EXPERIMENTAL !!##
144 #--------------------------------------------------------getclasstree---
145 def getclasstree(cls, predicate=None):
146 l = []
147 for c in cls.__subclasses__():
148 if predicate != None and predicate(c):
149 l += [(c, getclasstree(c, predicate))]
150 elif predicate == None:
151 l += [(c, getclasstree(c))]
152 return l
155 #---------------------------------------------------classtreeiterdown---
156 # this is my first recursive iterator... :)
157 def classtreeiterdown(cls, predicate=None):
159 this will iterate the inheritance tree branch down.
161 for c in cls.__subclasses__():
162 if predicate != None and predicate(c):
163 yield c
164 for cls in classtreeiterdown(c, predicate):
165 yield cls
166 elif predicate == None:
167 yield c
168 for cls in classtreeiterdown(c):
169 yield cls
172 #-----------------------------------------------------classtreeiterup---
173 def classtreeiterup(cls, predicate=None):
175 this will iterate the inheritance tree up.
177 NOTE: this will not remove duplicate classes.
179 for c in cls.__bases__:
180 if predicate != None and predicate(c):
181 yield c
182 for cls in classtreeiterup(c, predicate):
183 yield cls
184 elif predicate == None:
185 yield c
186 for cls in classtreeiterup(c):
187 yield cls
191 #=======================================================================
192 # vim:set ts=4 sw=4 nowrap :