o
    ¯bÐ@  ã                   @   sþ  d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZmZmZmZmZmZmZmZmZmZmZmZ ddlmZmZ dd	lmZ dd
lmZ ddlm Z m!Z!m"Z"m#Z#m$Z$m%Z% ddl&m'Z'm(Z(m)Z) ddl*m+Z+m,Z, edƒZ-eZ.	 ee/e0e$e e"e#ee.df ee. ee.ddf e!ee. eee. e1e.f e+f Z2	 dee/e0f de/fdd„Z3dee/e0f de/fdd„Z4dee/ge1f dee/gdf fdd„Z5dee/e0f de/fdd„Z6dee/e0f de/fdd„Z7	d2de0deeee0e2f   d ee2 de2fd!d"„Z8d#ee- dee- fd$d%„Z9d&ee, d'e2dee/ge1f deeee0e2f   d(ee+ d)eee/e0f ge/f deeeee2 f ddf fd*d+„Z:d&ee, d'e2dee/ge1f ddfd,d-„Z;d&ee, d'e2dee/ge1f ded fd.d/„Z<d&ee, d'e2dee/ fd0d1„Z=dS )3zu
Context-free flattener/serializer for rendering Python objects, possibly
complex or arbitrarily nested, as strings.
é    )Úiscoroutine)ÚBytesIO)Úexc_info)Ú
extract_tb)ÚGeneratorType)ÚAnyÚCallableÚ	CoroutineÚ	GeneratorÚListÚMappingÚOptionalÚSequenceÚTupleÚTypeVarÚUnionÚcast)ÚDeferredÚensureDeferred)ÚnativeString)ÚFailure)ÚCDATAÚCharRefÚCommentÚTagÚslotÚvoidElements)ÚFlattenerErrorÚUnfilledSlotÚUnsupportedType)ÚIRenderableÚIRequestÚT.NÚdataÚreturnc                 C   s4   t | tƒr
|  d¡} |  dd¡ dd¡ dd¡} | 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{&amp;&lt;&gt;}).

    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   &amp;ó   <s   &lt;ó   >ó   &gt;©Ú
isinstanceÚstrÚencodeÚreplace©r#   © r0   ú6/usr/lib/python3/dist-packages/twisted/web/_flatten.pyÚescapeForContentC   s   

r2   c                 C   s   t | tƒr
|  d¡S | 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/   r0   r0   r1   ÚattributeEscapingDoneOutsideV   s   

r3   Úwritec                    s   dt ddf‡ fdd„}|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 <twisted.web.template.Tag>} C{x} is flattened within the context
    of the contents of another L{Tag <twisted.web.template.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{<y><x>&amp;</x></y>}.  That is the default behavior
    of L{_flattenElement} when L{escapeForContent} is passed as the
    C{dataEscaper}.

    However, when a L{Tag <twisted.web.template.Tag>} C{x} is flattened within
    the context of an I{attribute} of another L{Tag <twisted.web.template.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{<y attr="&lt;x /&gt;"
    />}.  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
    <twisted.web.template.Comment>} in an attribute you should get C{<y
    attr="&lt;-- comment --&gt;" />}.  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 <twisted.web.template.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.
    r#   r$   Nc                    s   ˆ t | ƒ dd¡ƒ d S )Nó   "s   &quot;)r2   r.   r/   ©r4   r0   r1   Ú_write’   s   z*writeWithAttributeEscaping.<locals>._write)Úbytes)r4   r7   r0   r6   r1   ÚwriteWithAttributeEscapingi   s   )r9   c                 C   s    t | tƒr
|  d¡} |  dd¡S )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   ]]]]><![CDATA[>r*   r/   r0   r0   r1   ÚescapedCDATA˜   s   
	
r;   c                 C   sH   t | tƒr
|  d¡} |  dd¡ dd¡} | r"| dd… dkr"| d	7 } | S )
zÇ
    Escape a comment 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   --s   - - r(   r)   éÿÿÿÿNó   -ó    r*   r/   r0   r0   r1   ÚescapedComment¦   s   
	
r?   ÚnameÚslotDataÚdefaultc                 C   sD   |ddd… D ]}|dur| |v r||    S q|dur|S t | ƒ‚)zK
    Find the value of the named slot in the given stack of slot data.
    Nr<   )r   )r@   rA   rB   Ú	slotFramer0   r0   r1   Ú_getSlotValue·   s   €rD   Údc                    sL   t ‡ fdd„ƒ‰dtdtf‡fdd„}dtdtf‡fdd	„}ˆ  ||¡ ˆ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                    ó   ˆ   ¡ S ©N)Úcancel©Ú_)rE   r0   r1   Ú<lambda>Í   ó    z_fork.<locals>.<lambda>Úresultr$   c                    ó   ˆ   | ¡ | S rG   )Úcallback©rM   ©Úd2r0   r1   rO   Ï   ó   
z_fork.<locals>.callbackÚfailurec                    rN   rG   )Úerrback)rT   rQ   r0   r1   rU   Ó   rS   z_fork.<locals>.errback)r   r"   r   ÚaddCallbacks)rE   rO   rU   r0   )rE   rR   r1   Ú_forkÈ   s
   rW   ÚrequestÚrootÚrenderFactoryÚdataEscaperc                 #   sV  � |||fdt dttttf gtf dtt dttgtf dtttt	t f ddf f
‡‡fdd„‰ d	t	t  dt	t  f‡ fd
d„}t
|ttfƒrP|||ƒƒ dS t
|tƒrdt|jˆ|jƒ}ˆ |ƒV  dS t
|tƒrz|dƒ |t|jƒƒ |dƒ dS t
|tƒr�|dƒ |t|jƒƒ |dƒ dS t
|tƒ�r@ˆ |j¡ |j}|durÌ|du r¯td|› d�ƒ‚| d¡}	d|	_| |¡}
|
ˆ|	ƒ}ˆ |ƒV  ˆ ¡  dS |js×ˆ |jƒV  dS |dƒ t
|jtƒrè|j d¡}n|j}||ƒ |j  ¡ D ]%\}}t
|tƒ�r| d¡}|d| d ƒ ˆ |t!t"|ƒd�V  |dƒ qô|j�s%t#|ƒt$v�r:|dƒ ˆ |jt%ƒV  |d| d ƒ dS |dƒ dS t
|t&t't(fƒ�rV|D ]}ˆ |ƒV  �qKdS t
|t)ƒ�rkd|j*f }|| d¡ƒ dS t
|t	ƒ�rz|t+|ƒƒV  dS t,|ƒ�r“|t	 -t.t/t	t  tt f |ƒ¡ƒV  dS t 0|¡�r§| ˆ¡}ˆ ||d�V  dS t1|ƒ‚)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 <twisted.web.template.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.
    ÚnewRootr[   rZ   r4   r$   Nc                    s   t ˆ | |ˆ||ƒS rG   )Ú_flattenElement)r\   r[   rZ   r4   )rX   rA   r0   r1   Ú	keepGoing
  s   ÿz"_flattenElement.<locals>.keepGoingrM   c                    s
   |   ˆ ¡S rG   )ÚaddCallbackrP   )r^   r0   r1   ÚkeepGoingAsync  s   
z'_flattenElement.<locals>.keepGoingAsyncs	   <![CDATA[r:   s   <!--s   -->z$Tag wants to be rendered by method "z)" but is not contained in any IRenderableFr'   Úasciir>   s   ="r6   r5   r(   s   </s    />z&#%d;)rZ   )2ÚFlattenabler   r   r8   r,   r   r    Úobjectr
   r   r+   r   rD   r@   rB   r   r;   r#   r   r?   r   ÚappendrA   ÚrenderÚ
ValueErrorÚcloneÚlookupRenderMethodÚpopÚtagNameÚchildrenr-   Ú
attributesÚitemsr3   r9   r   r   r2   ÚtupleÚlistr   r   ÚordinalrW   r   ÚfromCoroutiner   r	   Ú
providedByr   )rX   rY   r4   rA   rZ   r[   r`   Ú	slotValueÚrendererNameÚ	rootCloneÚrenderMethodrM   rj   ÚkÚvÚelementÚescapedr0   )r^   rX   rA   r1   r]   Û   s¨   €1üÿþýüû




ÿ





ÿ
ÿ
ÿ
ÿ
r]   c           	   
   Ã   sÞ   �t | ||g dtƒg}|rmz|d j}t|d ƒ}t|tƒr#|I dH }W n? ty1   | ¡  Y n8 tyc } z'| ¡  g }|D ]}| 	|jj
d ¡ q@| 	|j
d ¡ t||ttƒ d ƒƒ‚d}~ww | 	|¡ |sdS dS )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 <twisted.web.template.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}.
    Nr<   rY   é   )r]   r2   Úgi_frameÚnextr+   r   ÚStopIterationri   Ú	Exceptionrd   Úf_localsr   r   r   )	rX   rY   r4   ÚstackÚframery   ÚeÚrootsÚ	generatorr0   r0   r1   Ú_flattenTreel  s.   €ÿ


€€ú
ðr†   c                 C   s   t t| ||ƒƒ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 <twisted.web.template.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.
    )r   r†   )rX   rY   r4   r0   r0   r1   Úflatten–  s   r‡   c                    s4   t ƒ ‰ t| |ˆ jƒ}| ‡ fdd„¡ t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                    rF   rG   )ÚgetvaluerI   ©Úior0   r1   rK   À  rL   zflattenString.<locals>.<lambda>)r   r‡   r4   r_   r   r   r8   )rX   rY   rE   r0   r‰   r1   ÚflattenString²  s   r‹   rG   )>Ú__doc__Úinspectr   rŠ   r   Úsysr   Ú	tracebackr   Útypesr   Útypingr   r   r	   r
   r   r   r   r   r   r   r   r   Útwisted.internet.deferr   r   Útwisted.python.compatr   Útwisted.python.failurer   Útwisted.web._stanr   r   r   r   r   r   Útwisted.web.errorr   r   r   Útwisted.web.iwebr    r!   r"   ÚFlattenableRecursiver8   r,   rc   rb   r2   r3   r9   r;   r?   rD   rW   r]   r†   r‡   r‹   r0   r0   r0   r1   Ú<module>   s°   8 
ôÿÿ
þ/ýÿþý
üÿþýüûú

ö ÿÿÿ
þ*ÿÿÿ
þ"