U W[H @sLdZddlmZmZddlZddlZzddlmZWn ek rTddlmZYnXz ddl Z Wnddl Z YnXddl m Z m Z ddlmZddlmZmZmZGd d d ZGd d d eZGd ddeZGdddeZGdddZGdddZeZeeeeeee de!e e"g Z#ze#$e%Wne&k rJYnXGdddZ'GdddZ(GdddZ)GdddZ*ddZ+Gdd d e,Z-e.d!Z/d"d#Z0d$d%Z1d&d'Z2d(d)Z3d*d+Z4Gd,d-d-Z5d.d/Z6d;d0d1Z7zdd2lm8Z9m:Z;Wnek r dZ9dZ;YnXd3d4ZGd9d:d:Z?dS)sr>cCstdt|S)zDPass me an AO, I'll return a nicely-formatted source representation.zapp = ) indentifyr&)aorrrrsrc@seZdZdZdS)r1z&A dictionary was not formattable. N)rrr__doc__rrrrr1sr1z[a-zA-Z_][a-zA-Z0-9_]*$cCsrg}t|}||D]J\}}t|ts:td|t|sPtd||d|t |fqd |S)Nz%r ain't a stringz%r ain't an identifierz %s=%s,) listitemssortrr*r1rmatchappendr&join)doutrEkvrrrr0s      r0cCs2t|dr|St|}|tkr*t|S|tkrdg}|D]"\}}|dt|t|fq@|t |rtdpvdd |S|t krdg}|D]}|dt|q|t |rd pd d |S|t krd g}|D]}|dt|q|t |rd pd d |St d||fdS)Nr{z %s: %s,z }}rC[z %s,z ]](z ))z/Unsupported type %s when trying to prettify %s.)hasattrrtype_SIMPLE_BUILTINSreprr/rErIr&r3rJrDtupler")r.trLrMrNxrrrr&s0     r&c Csg}g}d|g}t|jD]`\}}\}}\}} } |dkrD||n|dkrT||dkrp|dt|q||qd|S)NrC)rQrSrO)rRrTrPz )rpoprIr3rJ) srLstacklZ tokenTypeZ tokenStringZstartRowZ startColumnZendRowZ endColumnZ logicalLinerrrr@s  r@cCs t|S)zG Pass me an Abstract Object Tree, and I'll unjelly it for you. ) AOTUnjellierunjelly)aotrrrunjellyFromAOTsrdc Csjttttttttd}t|dr*| }n|}t |dd}t |||d|krZt |dSt d|dS)z Pass me a string of code or a filename that defines an 'app' variable (in terms of Abstract Objects!), and I'll execute it and unjelly the resulting AOT for you, returning a newly unpersisted Application object! )r rrrrrr!r>readzexecZappz'%s needs to define an 'app', it didn't!N)r rrrrrr!r>rUrecompileevalrdr6)Z stringOrFilenssourcecoderrrunjellyFromSources"     rlc@sHeZdZdZddZddZddZdd Zd d Zd d Z ddZ dS)razWI handle the unjellying of an Abstract Object Tree. See AOTUnjellier.unjellyAO cCsi|_g|_g|_dSr ) referencesr_ afterUnjellyrrrrrszAOTUnjellier.__init__cCst}||d||S)zUnjelly a node, later. r)rZ_Defer unjellyInto)rZnoderKrrr unjellyLater#szAOTUnjellier.unjellyLatercCs.||}|||<t|tjr*||||S)zvUtility method for unjellying one object into another. This automates the handling of backreferences. ) unjellyAOrrNotKnown addDependant)rr.ZlocrAorrrro*s    zAOTUnjellier.unjellyIntocCs:t|tjr dg}||dn|g}|j||fdS)Nr))rrrrrsrnrI)rcallableresultr`rrr callAfter4s  zAOTUnjellier.callAftercCs||j||dS)zUtility method for unjellying into instances of attributes. Use this rather than unjellyAO unless you like surprising bugs! Alternatively, you can use unjellyInto on your instance's __dict__. N)ro__dict__)rr$ZattrNamerArrrunjellyAttribute<szAOTUnjellier.unjellyAttributecCs,|j|t|}|tkr |S|tkrZg}|D]$}|d||t|d|q0|S|tkrg}t}|D]2}|dt||t|d|t j rnt j }qn||S|t kri}| D].\}}t |} || d||| d|q|S|j} | tkrt|jS| ttfks*t| tr6t|jS| tkr|j} t|j} ||j} | | jkr| dkr~t| | St| t j rt | | | St| | | Snt dnl| t!krt|j}||j"}t#|dr|$|}nt%|}t#|dr|&|j'|n||_|S| t(kr||j)}|j*}|j+,|}|dkrZ||j+|<nBt|t j r~|-|||j+|<n|dkrnt.d|||f|S| t/kr|j*}|j+,|}|dkrt 0|}||j+|<|S|S| t1krt|j2}|3|j"4dd |}|St d ||jd =dS) zaUnjelly an Abstract Object and everything it contains. I return the real object. Nr)rzinstance method changed__new__ __setstate__z1Multiple references with the same ID: %s, %s, %s!cSs||Sr r)rvZ_lrrrz(AOTUnjellier.unjellyAO..zUnsupported AOT type: %s)5r_rIrVrWrDror3rYrrrrZ_Tupler/rEZ_DictKeyAndValue __class__rrZ namedModulerrr issubclassZ namedObjectrr#rqr$rxgetattrZ_InstanceMethodr r"r r,rUrz_OldStyleInstancerwr{rr.r4rmgetZresolveDependantsr6r!Z _Dereferencer>r?rpZ addCallback)rrArZr`r[Ztuple_rKrMrNZkvdcZim_nameim_classim_selfr#r,r%rtZrefkeyrefr8Zderr?rrrrqEs                                      zAOTUnjellier.unjellyAOc Cspz:dg}||d||jD]\}}||dq|dWStdtdtt|jYnXdS)Nr+Error jellying object! Stacktrace follows:: )rornrmsgrJmaprXr_)rrAr`funcrNrrrrbs  zAOTUnjellier.unjellyN) rrrrBrrprorwryrqrbrrrrras  hracCs t|S)z-Convert an object to an Abstract Object Tree.) AOTJellierjelly)r.rrr jellyToAOTsrcCs.t|}|r"|t|dnt|SdS)z Pass me an object and, optionally, a file object. I'll convert the object to an AOT either return it (if no file was specified) or write it to the file. zutf-8N)rwriterencode)r.filercrrr jellyToSourcesr) ClassType InstanceTypecCstr |jjS|jS)z Get the associated class of the given method object. @param methodObject: a bound method @type methodObject: L{types.MethodType} @return: a class @rtype: L{types.ClassType} or L{type} )r __self__rrZ methodObjectrrr_classOfMethods rcCstr |jS|jS)z Get the associated function of the given method object. @param methodObject: a bound method @type methodObject: L{types.MethodType} @return: the function implementing C{methodObject} @rtype: L{types.FunctionType} )r __func__Zim_funcrrrr _funcOfMethods rcCstr |jS|jS)z Get the object that a bound method is bound to. @param methodObject: a bound method @type methodObject: L{types.MethodType} @return: the C{self} passed to C{methodObject} @rtype: L{object} )r rrrrrr _selfOfMethods rc@s,eZdZddZddZddZddZd S) rcCsi|_d|_g|_dS)Nr)prepared_ref_idr_rrrrr szAOTJellier.__init__cCs||jt|<dS)zaI prepare an object for later referencing, by storing its id() and its _AORef in a cache.N)rid)rZaorefobjectrrr prepareForRefszAOTJellier.prepareForRefc sHt}jt|tkr(n|tjkr\ttj t t  tn|tjkrttj n|tkrtt nt|trtt n|tjkrtt nvtjkrjt}|jr|j}njd_j}||t|Stfdd}|tkr\ fddDn|t!kr~ t!t"j n|t#kri}$D]\}} || |<q |n||t%j&krt%j&|\} }  t't |  | n@t(dr|)n&t(dr.|j*nt+d|j jd =S) z+I turn an object into an AOT and return it.r)cs"ttj|dSr )r:r rqualr jellyToAO)r,r.Zretvalrrr _stateFromIsz(AOTJellier.jellyToAO.._stateFromcsg|]}|qSr)r).0rtrrr Osz(AOTJellier.jellyToAO.. __getstate__rxzUnsupported type: %sr~),rVr_rIrXrWtypes MethodTyperrrrrrrr ModuleTyper_OldStyleClassrr FunctionTyperZ fullFuncNamerrr4rr9r!rrrDr:rYrr/rEcopy_regdispatch_tabler>rUrrxr") rr.ZobjTypeZoldRefkeyrrKrMrNZ unpickleFuncr,rrrrsb                   zAOTJellier.jellyToAOcCs@z||}|WStdtd|jYnXdS)Nrr)rrrrJr_)rr.rArrrrjs  zAOTJellier.jellyN)rrrrrrrrrrrrsVr)N)@rBZ __future__rrrrerr ImportErrorrcopyregZtwisted.pythonrrZtwisted.persistedrZtwisted.python.compatr r r r rrrrr(r+boolbytesintfloatcomplexrVsliceEllipsisrWrIZlong NameErrorr rr!r>r Exceptionr1rgrGr0r&r@rdrlrarrrrrrrrrrrrrrsv      !'