ϪfFdZddlmZddlmZddlmZddlmZddl m Z ddl m Z ddl mZmZmZmZmZmZmZmZmZmZmZmZdd lmZmZdd lmZdd lm Z dd l!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'dd l(m)Z)m*Z*m+Z+ddl,m-Z-m.Z.edZ/eZ0 ee1e2e&e"e$e%ee0dfee0ee0ddfe#ee0eee0e3e0fe-f Z4 dZ5ddZ6ddZ7 ddZ8ddZ9ddZ: d d!dZ;d"dZ< d#dZ= d$dZ> d%dZ?d&dZ@y)'zu Context-free flattener/serializer for rendering Python objects, possibly complex or arbitrarily nested, as strings. ) annotations) iscoroutine)BytesIO)exc_info) extract_tb) GeneratorType) AnyCallable Coroutine GeneratorListMappingOptionalSequenceTupleTypeVarUnioncast)DeferredensureDeferred) nativeString)Failure)CDATACharRefCommentTagslot voidElements)FlattenerError UnfilledSlotUnsupportedType) IRenderableIRequestT.Nict|tr|jd}|jddjddjdd}|S)a Escape some character or UTF-8 byte data for inclusion in an HTML or XML document, by replacing metacharacters (C{&<>}) with their entity equivalents (C{&<>}). This is used as an input to L{_flattenElement}'s C{dataEscaper} parameter. @param data: The string to escape. @return: The quoted form of C{data}. If C{data} is L{str}, return a utf-8 encoded string. utf-8&s&s> isinstancestrencodereplacedatas 6/usr/lib/python3/dist-packages/twisted/web/_flatten.pyescapeForContentr2GsK${{7# <<h ' / /g > F FtW UD KcHt|tr|jdS|S)aG Escape some character or UTF-8 byte data for inclusion in the top level of an attribute. L{attributeEscapingDoneOutside} actually passes the data through unchanged, because L{writeWithAttributeEscaping} handles the quoting of the text within attributes outside the generator returned by L{_flattenElement}; this is used as the C{dataEscaper} argument to that L{_flattenElement} call so that that generator does not redundantly escape its text output. @param data: The string to escape. @return: The string, unchanged, except for encoding. r&)r+r,r-r/s r1attributeEscapingDoneOutsider5Zs"${{7## Kr3cdfd }|S)aU Decorate a C{write} callable so that all output written is properly quoted for inclusion within an XML attribute value. If a L{Tag } C{x} is flattened within the context of the contents of another L{Tag } C{y}, the metacharacters (C{<>&"}) delimiting C{x} should be passed through unchanged, but the textual content of C{x} should still be quoted, as usual. For example: C{&}. That is the default behavior of L{_flattenElement} when L{escapeForContent} is passed as the C{dataEscaper}. However, when a L{Tag } C{x} is flattened within the context of an I{attribute} of another L{Tag } C{y}, then the metacharacters delimiting C{x} should be quoted so that it can be parsed from the attribute's value. In the DOM itself, this is not a valid thing to do, but given that renderers and slots may be freely moved around in a L{twisted.web.template} template, it is a condition which may arise in a document and must be handled in a way which produces valid output. So, for example, you should be able to get C{}. This should also be true for other XML/HTML meta-constructs such as comments and CDATA, so if you were to serialize a L{comment } in an attribute you should get C{}. Therefore in order to capture these meta-characters, flattening is done with C{write} callable that is wrapped with L{writeWithAttributeEscaping}. The final case, and hopefully the much more common one as compared to serializing L{Tag } and arbitrary L{IRenderable} objects within an attribute, is to serialize a simple string, and those should be passed through for L{writeWithAttributeEscaping} to quote without applying a second, redundant level of quoting. @param write: A callable which will be invoked with the escaped L{bytes}. @return: A callable that writes data with escaping. cHt|jddy)N"s")r2r.)r0writes r1_writez*writeWithAttributeEscaping.._writes t$,,T9=>r3)r0bytesreturnNone)r9r:s` r1writeWithAttributeEscapingr?msR? Mr3cht|tr|jd}|jddS)z Escape CDATA for inclusion in a document. @param data: The string to escape. @return: The quoted form of C{data}. If C{data} is unicode, return a utf-8 encoded string. r&]]>s]]]]>r*r/s r1 escapedCDATArBs.${{7# << 2 33r3ct|tr|jd}|jdd}|r |dddk(r|dz }|S)a Within comments the sequence C{-->} can be mistaken as the end of the comment. To ensure consistent parsing and valid output the sequence is replaced with C{-->}. Furthermore, whitespace is added when a comment ends in a dash. This is done to break the connection of the ending C{-} with the closing C{-->}. @param data: The string to escape. @return: The quoted form of C{data}. If C{data} is unicode, return a utf-8 encoded string. r&-->s-->N- r*r/s r1escapedCommentrHsJ${{7# << *D RS T!   Kr3c\t|D]}|||vs ||cS||St|)zK Find the value of the named slot in the given stack of slot data. )reversedr )nameslotDatadefault slotFrames r1 _getSlotValuerOsGh'!  TY%6T? "!  N4  r3cbtfddfd }dfd }j||S)z Create a new L{Deferred} based on C{d} that will fire and fail with C{d}'s result or error, but will not modify C{d}'s callback type. c$jSN)cancel)_ds r1z_fork..s r3c*j||SrR)callback)resultd2s r1rXz_fork..callbacks F r3c*j||SrR)errback)failurerZs r1r\z_fork..errbacks 7r3)rYr$r<r$)r]rr<r)r addCallbacks)rUrXr\rZs` @r1_forkr_s/ 34BNN8W% Ir3c #K|||f dfd dfd }t|ttfr|||yt|tr,t |j |j }|yt|tr,|d|t|j|dyt|tr,|d|t|j|dyt|trÉj|j|j}|^|t!d|d |j#d } d| _|j%|} | | } | j'y|j(s|j*y|d t|j(tr|j(j-d } n |j(} || |j.j1D]V\} }t| tr| j-d } |d | zdz|t2t5||dX|j*st7| t8vr0|d|j*t:|d| zdzy|dyt|t<t>t@fr|D] }|yt|tBr(d|jDfz}||j-d yt|tFr|tI|ytK|rE|tGjLtOtPtFtRtTtRf|ytWjX|r|j} | |yt[|w)at Make C{root} slightly more flat by yielding all its immediate contents as strings, deferreds or generators that are recursive calls to itself. @param request: A request object which will be passed to L{IRenderable.render}. @param root: An object to be made flatter. This may be of type C{unicode}, L{str}, L{slot}, L{Tag }, L{tuple}, L{list}, L{types.GeneratorType}, L{Deferred}, or an object that implements L{IRenderable}. @param write: A callable which will be invoked with each L{bytes} produced by flattening C{root}. @param slotData: A L{list} of L{dict} mapping L{str} slot names to data with which those slots will be replaced. @param renderFactory: If not L{None}, an object that provides L{IRenderable}. @param dataEscaper: A 1-argument callable which takes L{bytes} or L{unicode} and returns L{bytes}, quoted as appropriate for the rendering context. This is really only one of two values: L{attributeEscapingDoneOutside} or L{escapeForContent}, depending on whether the rendering context is within an attribute or not. See the explanation in L{writeWithAttributeEscaping}. @return: An iterator that eventually writes L{bytes} to C{write}. It can yield other iterators or L{Deferred}s; if it yields another iterator, the caller will iterate it; if it yields a L{Deferred}, the result of that L{Deferred} will be another generator, in which case it is iterated. See L{_flattenTree} for the trampoline that consumes said values. c$t||||SrR)_flattenElement)newRoot dataEscaper renderFactoryr9requestrLs r1 keepGoingz"_flattenElement..keepGoings  WeX}k  r3c&|jSrR) addCallback)rYrgs r1keepGoingAsyncz'_flattenElement..keepGoingAsyncs!!),,r3s z&#%d;)re) rc Flattenablerd$Callable[[Union[bytes, str]], bytes]reOptional[IRenderable]r9Callable[[bytes], object]r<z@Generator[Union[Flattenable, Deferred[Flattenable]], None, None])rYDeferred[Flattenable]r<rp).r+r;r,rrOrKrMrrBr0rrHrappendrLrender ValueErrorclonelookupRenderMethodpoptagNamechildrenr- attributesitemsr5r?rrr2tuplelistrrordinalrr_r fromCoroutinerr rlobjectr" providedByr!)rfrootr9rLrerdrj slotValue rendererName rootClone renderMethodrYrwkvelementescapedrgs` ` @r1rbrbsnb=H/<+0   9 - )  J  -$ % k$ D$ !$))Xt||D  "" D%  l l499%& f D' " g nTYY'( f D#  &{{  #$ :<.I>? 5)I#I (;;LIL!'95FF# # LLN ||DMM* *  d dllC (ll))'2GllG gOO))+ DAq!S!HHW% $(U" #/7QRW7X  $K  ==L1E $KDMM+;< < %'/D( ) &M D5$ 6 7 %GG$ $ % D' "T\\O+ gnnW%& D( #U4[)) T   " "Yx 4fkIJDQ      %W%d33d##sOO$c x Kg d d fd }d fd t|||gdtg}|rS |dj}t|d}t |t r |d{}|j ||rS y7 #t$r|jY(t$r}|jg}|D]*} |j | jjd,|j jdt||ttdd}~wwxYww) a Make C{root} into an iterable of L{bytes} and L{Deferred} by doing a depth first traversal of the tree. @param request: A request object which will be passed to L{IRenderable.render}. @param root: An object to be made flatter. This may be of type C{unicode}, L{bytes}, L{slot}, L{Tag }, L{tuple}, L{list}, L{types.GeneratorType}, L{Deferred}, or something providing L{IRenderable}. @param write: A callable which will be invoked with each L{bytes} produced by flattening C{root}. @return: A C{Deferred}-returning coroutine that resolves to C{None}. rcfj|t|z tk\ryyrR)rqlen BUFFER_SIZE)bsbufbufSize flushBuffers r1 bufferedWritez#_flattenTree..bufferedWrites. 23r7 k ! M "r3cNdkDrdjdd=dyy)Nrr3)join)rrr9sr1rz!_flattenTree..flushBuffers+ Q; #((3- AG r3NrEr)rr;r<r=)r<r=)rbr2gi_framenextr+rrq StopIterationrv Exceptionf_localsrrr) rfrr9rstackframereroots generatorrrrs ` @@@r1 _flattenTreerss#( CG }b$@PQ-E  ""I&&E59oG'8, '- LL !' ,M(  IIK F IIKE" B  Y//88@A B LL/ 0 E:hjm+DE E  FsM,D:9B,B -B1D:D: BD7(D:*D72BD22D77D:c.tt|||S)a Incrementally write out a string representation of C{root} using C{write}. In order to create a string representation, C{root} will be decomposed into simpler objects which will themselves be decomposed and so on until strings or objects which can easily be converted to strings are encountered. @param request: A request object which will be passed to the C{render} method of any L{IRenderable} provider which is encountered. @param root: An object to be made flatter. This may be of type L{str}, L{bytes}, L{slot}, L{Tag }, L{tuple}, L{list}, L{types.GeneratorType}, L{Deferred}, or something that provides L{IRenderable}. @param write: A callable which will be invoked with each L{bytes} produced by flattening C{root}. @return: A L{Deferred} which will be called back with C{None} when C{root} has been completely flattened into C{write} or which will be errbacked if an unexpected exception occurs. )rr)rfrr9s r1flattenrs2 ,we< ==r3ctt||j}|jfdt t t |S)a Collate a string representation of C{root} into a single string. This is basically gluing L{flatten} to an L{io.BytesIO} and returning the results. See L{flatten} for the exact meanings of C{request} and C{root}. @return: A L{Deferred} which will be called back with a single UTF-8 encoded string as its result when C{root} has been completely flattened or which will be errbacked if an unexpected exception occurs. c$jSrR)getvalue)rTios r1rVzflattenString..s BKKMr3)rrr9rirrr;)rfrrUrs @r1 flattenStringrs< Brxx(AMM)*  ##r3)r0zUnion[bytes, str]r<r;)r9ror<zCallable[[bytes], None]rR)rKr,rLz-Sequence[Optional[Mapping[str, Flattenable]]]rMzOptional[Flattenable]r<rl)rU Deferred[T]r<r)rfOptional[IRequest]rrlr9rorLz)List[Optional[Mapping[str, Flattenable]]]rernrdrmr<zMGenerator[Union[Generator[Any, Any, Any], Deferred[Flattenable]], None, None])rfrrrlr9ror<r=)rfrrrlr9ror<zDeferred[None])rfrrrlr<zDeferred[bytes])A__doc__ __future__rinspectrrrsysr tracebackrtypesrtypingr r r r r rrrrrrrtwisted.internet.deferrrtwisted.python.compatrtwisted.python.failurertwisted.web._stanrrrrrrtwisted.web.errorrr r!twisted.web.iwebr"r#r$FlattenableRecursiver;r,rrlrr2r5r?rBrHrOr_rbrrrr>r3r1rs #     <.*NNKK2 CL      #$  "D$./  !" h+,f6JJK    &&, $,,^ 4.&*! !;!#! !"&N$ N$ N$ %N$8 N$ ) N$ 6 N$SN$bF F'2F;TF FR> >'2>;T>>8$r3