;ò 1;c@sùdkTdkTdkZdZd„Zdfd„ƒYZdefd„ƒYZdfd „ƒYZd efd „ƒYZd efd „ƒYZ defd„ƒYZ ddd„Z ddd„Z d„Z d„Zd„Zd„Zedd„ZdS((s*Ns0.8.0cCs#yt|tƒSWn dSnXdS(sA Returns 1 if *thing* is a Lazy expression, 0 otherwise. iN(s isinstancesthingsLazy(sthing((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pysisLazys sLazycBs tZdZd„Zd„ZRS(s. Abstract base class for lazy things. cCs t‚dS(s Forces this lazy object to evaulate itself fully. Returns the final, strict version of the object, if appropriate. For instance, LazyExpr.eval returns the result of evaluating its expression, and LazyTuple.eval returns a normal tuple. N(sNotImplementedError(sself((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pyseval*scCs t‚dS(s^ Should return 1 if the object has been fully evaluated, 0 otherwise. N(sNotImplementedError(sself((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys isEvaluated3s(s__name__s __module__s__doc__sevals isEvaluated(((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pysLazy&s  sLazyExprcBsßtZdZhhd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z d „Z d „Z d „Z d „Zd „Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z!d „Z"d!„Z#d"„Z$d#„Z%d$„Z&d%„Z'd&„Z(d'„Z)d(„Z*d)„Z+d*„Z,d+„Z-d,„Z.d-„Z/d.„Z0d/„Z1d0„Z2d1„Z3d2„Z4d3„Z5RS(4sà Lazy expressions are expressions which are not computed until needed. Many functional languages (Haskell, Scheme, OCaml, etc.) provide support for this as a language feature, but a large class of those things can be simulated in Python with this class and/or LazyTuple. Things that will force a lazy expression *expr* to be evaluated: - *expr*.eval() - any value comparison, such as *expr* < 5, or *expr* == "abc" - any sort of operation such as slicing, getattrs, or mathematical opertions, **unless the other operands involved are also lazy.** - calling str(*expr*). Same for int, float, long. A lazy expression is evaluated in the namespaces of the code which constructed it, unless the defaults are overridden. For example: a = 5 laz = LazyExpr("a * 5") a = 7 assert laz == 25 #Now laz can be used in any context, and will always evaluate to 25, even if #a changes or goes out of scope. cCsÀt|ƒtjot|d|dƒ}n||id<| p| oXtƒi }|i |i f\}}| o|iƒ}n| o|iƒ}q¢n||id<||idSdS(sE Will cause evaluation, unless *other* is also lazy. sself.eval() << other.eval()N(sisLazysothersLazyExprsselfseval(sselfsother((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys __lshift__Âs cCs-t|ƒotdƒSn|iƒ|?SdS(sE Will cause evaluation, unless *other* is also lazy. sself.eval() >> other.eval()N(sisLazysothersLazyExprsselfseval(sselfsother((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys __rshift__Ês cCs-t|ƒotdƒSn|iƒ|@SdS(sE Will cause evaluation, unless *other* is also lazy. sself.eval() & other.eval()N(sisLazysothersLazyExprsselfseval(sselfsother((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__and__Òs cCs-t|ƒotdƒSn|iƒ|ASdS(sE Will cause evaluation, unless *other* is also lazy. sself.eval() ^ other.eval()N(sisLazysothersLazyExprsselfseval(sselfsother((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__xor__Ús cCst|ƒotdƒSndS(sE Will cause evaluation, unless *other* is also lazy. sself.eval() | other.eval()N(sisLazysothersLazyExpr(sselfsother((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__or__ás cCs-t|ƒotdƒSn||iƒSdS(sE Will cause evaluation, unless *other* is also lazy. sother.eval() + self.eval()N(sisLazysothersLazyExprsselfseval(sselfsother((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__radd__ès cCs-t|ƒotdƒSn||iƒSdS(sE Will cause evaluation, unless *other* is also lazy. sother.eval() - self.eval()N(sisLazysothersLazyExprsselfseval(sselfsother((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__rsub__ðs cCs3t|ƒotdƒSnt||iƒƒSdS(sE Will cause evaluation, unless *other* is also lazy. s!divmod(other.eval(), self.eval())N(sisLazysothersLazyExprsdivmodsselfseval(sselfsother((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys __rdivmod__øs cCs2t|ƒotdƒSnt||iƒƒSdS(sE Will cause evaluation, unless *other* is also lazy. spow(other.eval(), self.eval())N(sisLazysothersLazyExprspowsselfseval(sselfsother((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__rpow__s cCs-t|ƒotdƒSn||iƒ>SdS(sE Will cause evaluation, unless *other* is also lazy. sother.eval() << self.eval()N(sisLazysothersLazyExprsselfseval(sselfsother((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys __rlshift__s cCs-t|ƒotdƒSn||iƒ?SdS(sE Will cause evaluation, unless *other* is also lazy. sother.eval() >> self.eval()N(sisLazysothersLazyExprsselfseval(sselfsother((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys __rrshift__s cCs-t|ƒotdƒSn||iƒ@SdS(sE Will cause evaluation, unless *other* is also lazy. sother.eval() & self.eval()N(sisLazysothersLazyExprsselfseval(sselfsother((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__rand__s cCs-t|ƒotdƒSn||iƒASdS(sE Will cause evaluation, unless *other* is also lazy. sother.eval() ^ self.eval()N(sisLazysothersLazyExprsselfseval(sselfsother((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__rxor__ s cCs-t|ƒotdƒSn||iƒBSdS(sE Will cause evaluation, unless *other* is also lazy. sother.eval() | self.eval()N(sisLazysothersLazyExprsselfseval(sselfsother((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__ror__(s cCs|iƒ SdS(s( Will cause evaluation. N(sselfseval(sself((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__neg__0scCs|iƒ SdS(s( Will cause evaluation. N(sselfseval(sself((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__pos__6scCst|iƒƒSdS(s( Will cause evaluation. N(sabssselfseval(sself((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__abs__<scCs|iƒ SdS(s( Will cause evaluation. N(sselfseval(sself((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys __invert__BscCst|iƒƒSdS(s( Will cause evaluation. N(scomplexsselfseval(sself((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys __complex__HscCst|iƒƒSdS(s( Will cause evaluation. N(soctsselfseval(sself((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__oct__NscCst|iƒƒSdS(s( Will cause evaluation. N(shexsselfseval(sself((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__hex__TscCs)t|ƒotdƒSn tdƒSdS(s0 Does **not** cause evaluation. sself.eval()[ntx.eval()]sself.eval()[ntx]N(sisLazysntxsLazyExpr(sselfsntx((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys __getitem__Zs cCstdƒSdS(s0 Does **not** cause evaluation. sself.eval()[i:j]N(sLazyExpr(sselfsisj((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys __getslice__cscCs|iƒ||5dS(s( Will cause evaluation. N(sselfsevalsisj(sselfsisj((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys __delslice__iscCs||iƒ|t||ƒD]-\}}t||ƒott |ƒSqÝqÝWdSndSdS(Niiÿÿÿÿi( sselfsothers isinstances LazySequences isTerminatingstypescmpslenslazyzipssthingsothingsstring(sselfsotherssthingsothing((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__cmp__òs&      (s__name__s __module__s__doc__s isTerminatings__str__s__mul__s__add__s__cmp__(((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys LazySequenceÏs     s LazyTuplecBsStZdZedd„Zd„Zd„Zd„Zd„Zd„Z d„Z RS( s¸ Lazy tuples (equivalent to lazy lists in functional languages) are sequences whose values are calculated on demand. In a normal (strict) tuple, every value in the tuple must be known at the time it is constructed, and it has a definite length. Not so with LazyTuples, which may have potentially infinite length, and the value at a given index is computed only when needed for some other calculation. In this implementation, a function is defined which takes two arguments, an index, and the LazyTuple the index is being done on. Whatever this function returns is the value of the LazyTuple at that index. The function will only be called once for each index, and the cached value will be used in subsequent indexing operations. For example: #Build a lazy list of squares: def square(index, seq): return index * index >>>laz = LazyList(itemFunc = square) >>>print laz[2] 4 >>> #But this is a simple case which can be extrapolated directly from the #index. A better example: def factorial(index, seq): if index == 0: return 1 else: return seq[index -1] * index >>>laz = LazyList(itemFunc = factorial) >>>laz[3] 6 >>> In this last example, laz[3] caused factorial to be called with index == 3, which in turn forced the evaluation (because it's necessary for factorial construction) of all the indices prior to 3. In the first example, no other indices need to be computed. Note that neither of these examples *terminates*, that is they are both of infinite length (actually they'll overflow from integer multiplication eventually, but's that's not important for this discussion). When dealing with infinite tuples, a few rules apply: - *lazytuple*.isTerminating() will return 1 if the tuple has definite length, 0 otherwise. - len(*lazytuple*) will raise a RuntimeError if the list is infinite. - if *lazytuple*: will always be true for an infinite tuple. - LazyTuples may be compared normally. - iteration over a LazyTuple with for works fine, but if the tuple doesn't terminate, neither will your loop! iÿÿÿÿcCs(||_g|_d|_||_dS(s *itemFunc* is a function which takes two arguments, *index* and *sequence*, and is used to generate the value at an arbitrary index. If *length* is zero or more, then this is a bounded (finite) LazyTuple. A *length* of -1 indicates a (possibly) infinite tuple, a -2 value indicates a tuple which will eventually terminate, but its exact length is not known at this time. Storage space is never duplicated for LazyTuples and slices taken from them. iN(sitemFuncsselfs _itemFuncs_memos _evaluatedslengths_length(sselfsitemFuncslength((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__init__Ds    cCs!|idjp |idjSdS(sQ Return 1 if this is a finite tuple, 0 if it is infinitely long. iiþÿÿÿN(sselfs_length(sself((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys isTerminatingUscCs!|idjo ||ijo t|‚n|djot|ƒ|}nt|iƒ|jo.|i|}|tj o|i|Sq’ny|i||ƒ}Wntj o||_‚nXt|iƒ|jo,|ii tg|dt|iƒƒn||i|<|SdS(Nii( sselfs_lengthsis IndexErrorslens_memosvals Uncomputeds _itemFuncsextend(sselfsisval((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys __getitem__[s"     , cCs¨dG|G|GH|tijo |}nd}|idjoN||ijo t|‚n||ijo |tijo t|‚q‹ntd|d|d|ƒSdS(Ns LT getsliceiÿÿÿÿissourcesstartsend( sisjssyssmaxintssliceEndsselfs_lengths IndexErrors LazySlice(sselfsisjssliceEnd((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys __getslice__~s    cCsQ|iƒ o td‚n|idjo |iSn|iƒt|iƒSdS(Ns1Non-terminating structure, cannot evaluate len().i(sselfs isTerminatings RuntimeErrors_lengthsevalslens_memo(sself((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__len__Œs    cCsdSdS(Ni((sself((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys __nonzero__•scCs”|idjo td‚n|i oOd}xFno:y|||d}Wq1tj od|_Pq1Xq8Wnt|iƒ|_|iSdS(Niÿÿÿÿs'Cannot eval a non-terminating sequence.ii(sselfs_lengths RuntimeErrors _evaluatedsis IndexErrorstuples_memo(sselfsi((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pyseval˜s   ( s__name__s __module__s__doc__sNones__init__s isTerminatings __getitem__s __getslice__s__len__s __nonzero__seval(((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys LazyTuple s :  #  s LazySlicecBsGtZd„Zd„Zd„Zd„Zd„Zd„Zd„ZRS(NcCs(||_||_||_d|_dS(s iN(sstartsselfs_startsends_endssources_sources _evaluated(sselfssourcesstartsend((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__init__­s    cCs!|idjp |iiƒSdS(su Return 1 if this is a finite tuple, 0 if it is infinitely long. A value of 2 means unknown. iN(sselfs_ends_sources isTerminating(sself((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys isTerminatingµscCs|djoC||ijp |idjo|i||iSqt|‚nµ|idjod|iiƒ o t|‚n|iiƒt|iƒ||ijo|i|Sqt|‚nA|i|i |}|djo|i||iSn t|‚dS(Ni( sisselfs_ends_sources_starts IndexErrors isTerminatingsevalslensstartsadjusted(sselfsisadjusted((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys __getitem__¼s       cCs²dG|G|GH|i|}|tijodG|iGH|i}nY|idjo ||ijo t |‚n,|djo|i|}n|i|}t |i ||ƒSdS(Ns LS getslicesMax slice, end is:i( sisjsselfs_startsnewStartssyssmaxints_endsnewEnds IndexErrors LazySlices_source(sselfsisjsnewStartsnewEnd((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys __getslice__Òs        cCsU|iƒ o td‚n|idjo|i|iSn|iƒt|ƒSdS(Ns1Non-terminating structure, cannot evaluate len().i(sselfs isTerminatings RuntimeErrors_ends_startsevalslen(sself((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__len__âs   cCs#|i|ijodSndSdS(Nii(sselfs_starts_end(sself((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys __nonzero__ëscCs¡|idjo td‚n|i oXd}xOnoCy|||d}Wq1tj od|_||_Pq1Xq8Wnt|ii|i |i!ƒSdS(Nis'Cannot eval a non-terminating sequence.i( sselfs_ends RuntimeErrors _evaluatedsis IndexErrorstuples_sources_memos_start(sselfsi((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pysevalñs    ( s__name__s __module__s__init__s isTerminatings __getitem__s __getslice__s__len__s __nonzero__seval(((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys LazySlice¬s     iicCs)|djo|Sn||d|SdS(sC An index function for LazyTuples of consecutive integers. iiN(sindexs startFromsseqsstep(sindexsseqs startFromsstep((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pysintegerss cCst||||ƒSdS(sJ An index function for LazyTuples of consecutive natural numbers. N(sintegerssindexsseqs startFromsstep(sindexsseqs startFromsstep((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pysnaturals scCsit|tƒo'|iƒot|ƒ}qCd}n t|ƒ}||d„}td|d|ƒSdS(sË Lazy equivalent for the map builtin function. lazymap returns a LazyTuple whose contents are computed on demand by applying *func* to seq[i], where i is the index that's being accessed. iÿÿÿÿcCs|||ƒS(N(sfsorigsindex(sindexssequencesorigsf((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys ssitemFuncslengthN( s isinstancesseqs LazySequences isTerminatingslenslengthsfuncs newItemFuncs LazyTuple(sfuncsseqs newItemFuncslength((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pyslazymaps   cCssd}dfd„ƒY}t|tƒo!|iƒo d}qPd}nd}td||||ƒd|ƒSdS( sð Lazy equivalent for the filter builtin function. lazyfilter returns a LazyTuple whose contents are computed on demand by filtering as much of the original sequence as necessary to reach a value for the necessary index. is filterhelpercBstZd„Zd„ZRS(NcCs||_||_||_dS(N(sseqsselfsseqIndexsfunc(sselfsseqsseqIndexsfunc((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__init__,s  cCsKxDno<|i|i}|id|_|i|ƒo|Sqq WdS(Ni(sselfsseqsseqIndexsvalsfunc(sselfsindexssequencesval((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys__call__1s (s__name__s __module__s__init__s__call__(((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys filterhelper+s iþÿÿÿiÿÿÿÿsitemFuncslengthN( sseqIndexs filterhelpers isinstancesseqs LazySequences isTerminatingslengths LazyTuplesfunc(sfuncsseqs filterhelpersseqIndexslength((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys lazyfilter#s    cCs9t|tƒo |iƒ o td‚ntdƒSdS(sƒ Lazy equivalent for the reduce builtin function. lazyreduce can only be applied to terminating (non-infinite) tuples. sCannot reduce infinite tuple.sreduce(func, tuple(seq))N(s isinstancesseqs LazyTuples isTerminatings RuntimeErrorsLazyExpr(sfuncsseq((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys lazyreduce@s cGs|d„}td|ƒSdS(s7 Lazy equivalent for the zip builtin function. cCs6g}x|D]}|i||ƒq Wt|ƒSdS(N(stupsorigseqssorigsappendsindexstuple(sindexsseqsorigseqsstupsorig((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys newItemFuncMs sitemFuncN(sseqss newItemFuncs LazyTuple(sseqss newItemFunc((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pyslazyzipIs cCsC|o |}n|}t|ƒo|o|iƒ}n|SdS(sO Functional equivalent for the if(else) statement. Note that unlike a real if, both truepart and falsepart will be evaluated, unless of couse they are Lazy. If they are lazy, only the selected expression will be returned. To get the selected lazy expression to be evaluated, call with *force* = 1 Example: >>> def printAndReturn(arg): ... print arg ... return arg ... >>> when(0, printAndReturn(0), printAndReturn(1)) 0 1 1 #Note printAndReturn was called twice. >>> when(0, LazyExpr("printAndReturn(0)"), LazyExpr("printAndReturn(1)")) Lazy expr: printAndReturn(1) >>> when(0, LazyExpr("printAndReturn(0)"), LazyExpr("printAndReturn(1)"), 1) 1 1 #because of the last (force) parameter, the chosen lazy expression was #evaluated before returning. >>> N(sexprstruepartsretvals falsepartsisLazysforceseval(sexprstrueparts falsepartsforcesretval((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pyswhenVs (stypess functionalssyss __version__sisLazysLazysLazyExprs Uncomputeds LazySequences LazyTuples LazySlicesintegerssnaturalsslazymaps lazyfilters lazyreduceslazyzipsNoneswhen(s LazySlicesLazyslazymaps lazyreduces LazyTuplesintegersswhens UncomputedsLazyExprssyssnaturalss LazySequencesisLazyslazyzips __version__s lazyfilter((s7/mnt/gmirror/ports/devel/py-xoltar-toolkit/work/lazy.pys?s$  ÿŽ:£W