Changeset 399

Show
Ignore:
Timestamp:
Sun Jan 21 19:27:13 2007
Author:
djfroofy
Message:

- aspout module fully obsoleted
- added sa module for SQLAlchemy helper functions
- added warnings to Curried-related functions
- added migrate module

Files:

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 getlogger  
    10   #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, IFormatter  
    14 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.string  
    11   #import xix.utils.config  
    12   #import xix.utils.rules # we can't load this here due to config setup dependency  
    13    
    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(