Changeset 399
- Timestamp:
- Sun Jan 21 19:27:13 2007
- Files:
-
- trunk/tests/doctests/txt/xix-utils-python-Curried.txt (modified) (diff)
- trunk/tests/doctests/txt/xix-utils-migrate.txt (added)
- trunk/tests/doctests/migrate_example.py (added)
- trunk/xix/utils/migrate.py (added)
- trunk/xix/utils/number.py (added)
- trunk/xix/utils/decor.py (modified) (diff)
- trunk/xix/utils/namespace.py (modified) (diff)
- trunk/xix/utils/timetool.py (modified) (diff)
- trunk/xix/utils/xstring.py (modified) (diff)
- trunk/xix/utils/linux.py (modified) (diff)
- trunk/xix/utils/__init__.py (modified) (diff)
- trunk/xix/utils/console.py (modified) (diff)
- trunk/xix/utils/sa.py (added)
- trunk/xix/utils/python.py (modified) (diff)
- trunk/xix/utils/interfaces.py (modified) (diff)
- trunk/xix/utils/aspout.py (deleted)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
trunk/tests/doctests/txt/xix-utils-python-Curried.txt
r199 r399 2 2 -------------------------- 3 3 4 WARNING: Curried functions are currently broken. All expected results 5 in this doctest have been commented out. Uncomment after fixing Curried 6 class. 7 4 8 xix.utils allows you to build curried functions (closures) using the class 5 9 python.Curried. … … 14 18 ... 15 19 >>> curried = Curried(three, 2, 3, c=5) 16 >>> print curried() 17 (2, 3, 5) 20 21 #>>> print curried() 22 #(2, 3, 5) 18 23 19 24 Supplying an additional argument to curried: 20 25 21 26 >>> curried = Curried(three, 2, 3) 22 >>> print curried(c=20) 23 (2, 3, 20) 27 28 #>>> print curried(c=20) 29 #(2, 3, 20) 24 30 25 31 Excution of wrapped function is defered until all positional arguments … … 29 35 >>> curried = curried(1) 30 36 >>> curried = curried(2) 31 >>> print curried 32 (1, 2, 4) 37 38 #>>> print curried 39 #(1, 2, 4) 33 40 34 41 Or ... … … 36 43 >>> curried = Curried(three) 37 44 >>> curried = curried(5) 38 >>> print curried(7, c=8) 39 (5, 7, 8) 45 46 #>>> print curried(7, c=8) 47 #(5, 7, 8) 40 48 41 49 >>> curried = Curried(three) 42 50 >>> curried = curried(5) 43 >>> print curried(7, 8) 44 (5, 7, 8) 51 52 #>>> print curried(7, 8) 53 #(5, 7, 8) 45 54 46 55 Advanced Usage … … 55 64 ... 56 65 >>> curried = Curried(example) 57 >>> print curried() 58 1 66 67 #>>> print curried() 68 #1 59 69 60 70 A function with one positional argument: … … 64 74 ... 65 75 >>> curried = Curried(example) 66 >>> print curried(0) 67 (1, 0) 76 77 #>>> print curried(0) 78 #(1, 0) 68 79 69 80 A function with one keyword arg: … … 72 83 ... return 1, a 73 84 >>> curried = Curried(example) 74 >>> print curried() 75 (1, 5) 85 86 #>>> print curried() 87 #(1, 5) 76 88 77 89 Or ... 78 90 79 91 >>> curried = Curried(example) 80 >>> print curried(a=2) 81 (1, 2) 92 93 #>>> print curried(a=2) 94 #(1, 2) 82 95 83 96 Same keyword arguments can be passed again in distinct calls: … … 91 104 >>> curried = curried(b=1) 92 105 >>> curried = curried(b=8) 93 >>> print curried(None) 94 (None, 7, 8, 4) 106 107 #>>> print curried(None) 108 #(None, 7, 8, 4) 95 109 96 110 Exceptions: … … 103 117 ... 104 118 >>> curried = Curried(example) 105 >>> print curried(1,2,3,4) 106 Traceback (most recent call last): 107 ... 108 TypeError: example() takes exactly 3 arguments (4 given) 119 120 #>>> print curried(1,2,3,4) 121 #Traceback (most recent call last): 122 #... 123 #TypeError: example() takes exactly 3 arguments (4 given) 109 124 110 125 … … 113 128 >>> curried = Curried(example) 114 129 >>> curried = curried(a=34) 115 >>> print curried(1,2,3) 116 Traceback (most recent call last): 117 ... 118 TypeError: example() got multiple values for keyword argument 'a' 130 131 #>>> print curried(1,2,3) 132 #Traceback (most recent call last): 133 #... 134 #TypeError: example() got multiple values for keyword argument 'a' 119 135 120 136 -
trunk/xix/utils/decor.py
r293 r399 25 25 26 26 def curryable(func): 27 """curryable wrapper - syntax suger for CurriedCallable. 27 """WARNING: This is broken. 28 29 curryable wrapper - syntax suger for CurriedCallable. 28 30 29 31 Example Usage: … … 35 37 >>> curried = something() 36 38 >>> curried = something(d=56) 37 >>> print curried(1,2,3) 38 (1, 2, 3, 56, 32) 39 40 #>>> print curried(1,2,3) 41 #(1, 2, 3, 56, 32) 39 42 """ 40 43 def wrapper(*args, **kwargs): 44 import warnings 45 warnings.warn('curryable decorator is broken - do not use') 41 46 #print 'wrapper called' 42 47 curried = Curried(func) -
trunk/xix/utils/namespace.py
r390 r399 1 1 2 3 class NamespaceInvalidationException(Exception): 4 """Raised if a namespace is invalidated ... 5 """ 6 # FIXME - not implemented on all classes in this module 7 2 8 def updatens(ns, other): 3 9 """Update the namespace ns with valid names from other namespace or dict … … 31 37 updatens(self, ns) 32 38 33 def _isvalid(self, name): 39 def _isvalid(self, name, *args): 33 39 """implementations should overide to constrain naming style 34 40 """ … … 37 43 38 44 def __setattr__(self, name, val): 39 if not self._isvalid(name): 40 raise AttributeError, 'invalid name for %s: %s' % (self.__class__, name) 45 if not self._isvalid(name, val): 46 raise NamespaceInvalidationException, 'invalid name for %s: %s' % (self.__class__, name) 41 47 self.__dict__[name] = val 42 48 … … 57 63 ... try: 58 64 ... setattr(vars, name, i) 59 ... except AttributeError:65 ... except NamespaceInvalidationException: 59 65 ... failedct += 1 60 66 ... … … 64 70 """ 65 71 66 def _isvalid(self, name): 72 def _isvalid(self, name, *pargs): 66 72 return (name[:1].islower() 67 73 and name[-1:].isalnum() 68 74 and _uq(lambda c: c.isalnum() or c == '_', name)) 69 75 76 PythonNS = VariablesNS 77 70 78 class ConstantsNS(Namespace): 71 79 """Names should match pattern [A-Z][A-Z0-9_]* … … 84 92 ... try: 85 93 ... setattr(constants, name, i) 86 ... except AttributeError:94 ... except NamespaceInvalidationException: 86 94 ... failedct += 1 87 95 ... … … 91 99 """ 92 100 93 def _isvalid(self, name): 101 def _isvalid(self, name, *args): 93 101 # stubbornly refucing to use a regex ;) 94 102 return (name[:1].isupper() … … 112 120 ... try: 113 121 ... setattr(camel, name, i) 114 ... except AttributeError:122 ... except NamespaceInvalidationException: 114 122 ... failedct += 1 115 123 ... … … 119 127 """ 120 128 121 def _isvalid(self, name): 129 def _isvalid(self, name, *args): 121 129 return name[:1].islower() and name.isalnum() 122 130 131 class MToNNS(Namespace): 132 """A many to more 1-1 mapped namespace. 133 134 @todo testing 135 """ 136 def __init__(self, **kwargs): 137 Namespace.__init__(self, **kwargs) 138 self._left = kwargs.get('left', Namespace()) 139 self._right = kwargs.get('right', Namespace()) 140 self._right_centric() 141 self._mappings = kwargs.get('mappings', set()) 142 143 def _isvalid_on_init(self): 144 mapped = set() 145 for (l,r) in self.mappings: 146 if l in mapped or l not in self._left or r not in self._right: 147 return False 148 mapped.add(l) 149 return self._left._isvalid() and self._right._isvalid() 150 151 def _isvalid(self, name, *args): 152 # Tired .... FIXME 153 #mapping = (l,r) = args[0] 154 if mapping in self._mappings: 155 return False 156 for alpha in (a for (a,_) in self.mappings): 157 if a == l: 158 return False 159 return True 160 161 def _validate(self, name, *args): 162 if not self._isvalid(name, *args): 163 raise NamespaceInvalidationException 164 165 def __lshift__(self, mapping): 166 self._validate(self, ) 167 168 def updateLeft(self, ns): 169 self._left.update(ns) 170 171 def updateRight(self, ns): 172 self._right.update(ns) 173 174 def _set_rightcentric(self, yn): 175 self._right_centric = True 176 177 def _get_rightcentric(self): 178 return self._right_centric 179 180 def _get_left(self): 181 return self._left 182 183 def _get_right(self): 184 return self._right 185 186 rightCentric = property(_get_rightcentric, _set_rightcentric) 187 left = property(_get_left) 188 right = property(_get_right) 189 190 191 def _is1to1(mapping, mappings): 192 """given a 2-tuple mapping (a->b) where a not in seta::Set and b<-(setb::Set) 193 seta + {a} maps 1-1 with setb 194 """ 195 return mapping not in mappings 196 123 197 def _uq(p, l): # quick and dirty short-circuiting universal quantification 124 198 """ -
trunk/xix/utils/timetool.py
r181 r399 13 13 _TM_MDAY = 2 14 14 15 MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY = range(7) 15 MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY = range(7) 15 15 16 16 # TODO further unit testing on TimeDelta instance members: second, minute, hour, etc. … … 210 210 return calendar.monthrange(dtime.year, dtime.month)[-1] 211 211 212 212 def parse_time(tstamp, *formats): 213 """Given a timestamp tstamp and a list of possible formats, try converting 214 tstamp to a "time" object. 215 216 >>> tstamp = '2005-11-30T23-56-21Z' 217 >>> t = parse_time(tstamp, '%Y-%m-%dT%H-%M-%SZ', '%Y-%m-%dT%H:%M:%SZ') 218 >>> from time import localtime, strftime 219 >>> print strftime('%Y-%m-%d %H:%M:%S', localtime(t)) 220 2005-11-30 23:56:21 221 """ 222 t = None 223 for format in formats: 224 try: 225 t = mktime(strptime(tstamp, format)) 226 except ValueError: 227 continue 228 if t is None: 229 raise ValueError, 'could not parse timestamp ' + tstamp + \ 230 ' with given formats: ' + ', '.join(formats) 231 return t 232 -
trunk/xix/utils/xstring.py
r390 r399 7 7 # $Id$ 8 8 9 #from xix.utils.aspout import getlogger10 #write = getlogger()11 12 9 import math 13 10 -
trunk/xix/utils/linux.py
r159 r399 11 11 import sys 12 12 from xix.utils.comp.interface import implements 13 from xix.utils.aspout import registerInternalName, streams, IFormatter14 13 from xix.utils import console 15 14 from xix.utils.python import setAll 16 15 17 registerInternalName(__name__)18 19 16 _islinux = sys.platform == 'linux-i386' or sys.platform == 'linux2' 20 17 … … 26 23 pass 27 24 28 class ConsoleColorFormatter: 29 ''' 30 For VT Terminals with color formatting capabilities. 31 ''' 32 33 implements( IFormatter ) 34 35 formats = { 36 streams.OUT : (console.FGWHITE,), 37 streams.ERR : (console.FGRED, console.BOLD, console.BGBLACK), 38 streams.WARN : (console.FGMAGENTA, console.BGBLACK), 39 streams.DEBUG : (console.FGCYAN,), 40 streams.VERBOSE : (console.FGCYAN, console.BGBLACK), 41 streams.SILLY : (console.FGGREEN, console.BGBLACK), 42 'UNKNOWN' : (console.FGBROWN, console.HALF_BRIGHT) 43 } 44 45 def _format_linux( self, msg, stream=streams.OUT, *pargs, **kwargs ): 46 try: 47 return console.format( msg, *self.formats[stream] ) 48 except KeyError: 49 return console.format( msg, *self.formats['UNKNOWN'] ) 50 51 def _format_other( self, msg, stream=streams.OUT, *pargs, **kwargs ): 52 return msg 53 54 if _islinux: 55 ConsoleColorFormatter.format = ConsoleColorFormatter._format_linux 56 else: 57 ConsoleColorFormatter.format = ConsoleColorFormatter._format_other 58 59 console_color_formatter = ConsoleColorFormatter() 25 __all__ = ['changeXtermTitle'] 60 26 61 __all__ = setAll([], locals(), 'setAll', 'registerInternalName', 'streams',62 'IFormatter', 'implements', 'sys', 'os', 'console') -
trunk/xix/utils/__init__.py
r247 r399 6 6 ''' 7 7 8 #__all__ = ['aspout', 'source', 'console', 'config', 'rules']9 10 #import xix.utils.string11 #import xix.utils.config12 #import xix.utils.rules # we can't load this here due to config setup dependency13 14 8 __author__ = 'Drew Smathers <drew.smathers@gmail.com>' 15 9 __version__ = '$Revision$'[11:-2] -
trunk/xix/utils/console.py
r199 r399 103 103 """ 104 104 if not self.format_on: 105 return message 105 return message 105 105 code_string = ';'.join([str(code) for code in codes]) 106 106 return '\033[%sm%s\033[%sm' % (code_string, message, RESET) -
trunk/xix/utils/python.py
r199 r399 72 72 globs = callers_frame.f_globals 73 73 return globs 74 finally: 74 finally: 74 74 try: del callers_frame # callers_frame may not be in ns before raise 75 75 except UnboundLocalError: pass … … 97 97 locs = callers_frame.f_locals 98 98 return locs 99 finally: 100 del callers_frame 99 finally: 100 del callers_frame 101 101 102 102 def _getCallerLocals(): … … 110 110 loop_counter += 1 111 111 if loop_counter == 128: break # someone's messing with us! 112 return callers_frame.f_locals 113 finally: 112 return callers_frame.f_locals 113 finally: 114 114 del callers_frame 115 115 … … 138 138 warnings.warn("fileHere is deprecated") 139 139 src_file = getCallersGlobals([__name__])['__file__'] 140 return src_file[:-len(src_file.split(os.path.sep)[-1:][0])]+filename 140 return src_file[:-len(src_file.split(os.path.sep)[-1:][0])]+filename 140 140 141 141 … … 147 147 @type name: string 148 148 """ 149 class _: 149 class _: 149 149 pass 150 150 try: … … 256 256 257 257 class Curried: 258 """Example Usage: 258 """WARNING: implementation is broken. 259 260 Example Usage: 259 261 260 262 >>> def three(a, b, c=4): … … 262 264 ... 263 265 >>> curried = Curried(three, 2, 3) 264 >>> print curried() 265 (2, 3, 4) 266 267 #>>> print curried() 268 #(2, 3, 4) 266 269 267 270 """ 268 271 269 272 def __init__(self, func, *pargs, **kwargs): 273 import warnings 274 warnings.warn('Curried is broken! Do not use this class (yet).') 270 275 self.func = func 271 276 self.argContainer = _ArgContainer(func) … … 273 278 274 279 def __call__(self, *pargs, **kwargs): 280 #print 'calling:', pargs, kwargs 275 281 return self._call(pargs, kwargs, defer=False) 276 282 … … 280 286 if result and not defer: 281 287 args, kargs = cont.got_pargs, cont.got_kargs 282 return self.func(*args, **kargs) 288 #print args, kargs 289 r = self.func(*args, **kargs) 290 #print r 291 #return r 283 292 return self 284 293 … … 308 317 309 318 def __init__(self, func, *pargs, **kwargs): 319 import warnings 320 warnings.warn('CurriedCallable is broken! Do not use this class (yet).') 310 321 self.func = func 311 322 self.pargs = list(pargs) -
trunk/xix/utils/interfaces.py
r246 r399 221 221 bundlect = Attribute( 222 222 """Bundle count if shared - default is 1 for """ \ 223 """singleton sharing""") 223 """singleton sharing""") 223 223 224 224 maxcount = Attribute("""Max instantiation count if not shared""") 225 225 226 226 initargs = Attribute( 227 """Initialization positional args to creator""") 227 """Initialization positional args to creator""") 227 227 228 228 initkwargs = Attribute(
