
    w:id                        d Z ddlmZ ddlZddlmZ ddlZddlmZm	Z	m
Z
 ddlmZmZ g dZdZ G d	 d
e          Z G d de          Zej        Zej        Zej        Zej        Zej        Zej        Zej        Zej        Zej        Zej        Zej        Zd Z G d de           Z! G d de
          Z"	 ddl#m"Z" n# e$$ r Y nw xY we"j%        Z%d Z& G d de          Z' e'd          Z( G d de
          Z)dS )z#Core classes for markup processing.    )reduceN)chain)
stringreprstring_types	text_type)stripentities	striptags)StreamMarkupescapeunescapeAttrs	NamespaceQNamezrestructuredtext enc                        e Zd ZdZg Zi Zd ZdS )StreamEventKindz#A kind of event on a markup stream.c                 j    | j                             |t                              | |                    S N)
_instances
setdefaultstr__new__)clsvals     C/var/www/html/trac/venv/lib/python3.11/site-packages/genshi/core.pyr   zStreamEventKind.__new__"   s(    ~((ckk#s.C.CDDD    N)__name__
__module____qualname____doc__	__slots__r   r    r   r   r   r      s8        --IJE E E E Er   r   c                   P   e Zd ZdZddgZ ed          Z ed          Z ed          Z ed          Z	 ed          Z
 ed	          Z ed
          Z ed          Z ed          Z ed          Z ed          ZddZd Zd Zd ZddZddZddZd Zd Zd ZdS )r
   a.  Represents a stream of markup events.
    
    This class is basically an iterator over the events.
    
    Stream events are tuples of the form::
    
      (kind, data, position)
    
    where ``kind`` is the event kind (such as `START`, `END`, `TEXT`, etc),
    ``data`` depends on the kind of event, and ``position`` is a
    ``(filename, line, offset)`` tuple that contains the location of the
    original element or text in the input. If the original location is unknown,
    ``position`` is ``(None, -1, -1)``.
    
    Also provided are ways to serialize the stream to text. The `serialize()`
    method will return an iterator over generated strings, while `render()`
    returns the complete generated text at once. Both accept various parameters
    that impact the way the stream is serialized.
    events
serializerSTARTENDTEXTXML_DECLDOCTYPESTART_NSEND_NSSTART_CDATA	END_CDATAPICOMMENTNc                 "    || _         || _        dS )a:  Initialize the stream with a sequence of markup events.
        
        :param events: a sequence or iterable providing the events
        :param serializer: the default serialization method to use for this
                           stream

        :note: Changed in 0.5: added the `serializer` argument
        N)r$   r%   )selfr$   r%   s      r   __init__zStream.__init__H   s     $r   c                 *    t          | j                  S r   )iterr$   r2   s    r   __iter__zStream.__iter__T   s    DK   r   c                 Z    t          t           ||                     | j                  S )a  Override the "bitwise or" operator to apply filters or serializers
        to the stream, providing a syntax similar to pipes on Unix shells.
        
        Assume the following stream produced by the `HTML` function:
        
        >>> from genshi.input import HTML
        >>> html = HTML('''<p onclick="alert('Whoa')">Hello, world!</p>''', encoding='utf-8')
        >>> print(html)
        <p onclick="alert('Whoa')">Hello, world!</p>
        
        A filter such as the HTML sanitizer can be applied to that stream using
        the pipe notation as follows:
        
        >>> from genshi.filters import HTMLSanitizer
        >>> sanitizer = HTMLSanitizer()
        >>> print(html | sanitizer)
        <p>Hello, world!</p>
        
        Filters can be any function that accepts and produces a stream (where
        a stream is anything that iterates over events):
        
        >>> def uppercase(stream):
        ...     for kind, data, pos in stream:
        ...         if kind is TEXT:
        ...             data = data.upper()
        ...         yield kind, data, pos
        >>> print(html | sanitizer | uppercase)
        <p>HELLO, WORLD!</p>
        
        Serializers can also be used with this notation:
        
        >>> from genshi.output import TextSerializer
        >>> output = TextSerializer()
        >>> print(html | sanitizer | uppercase | output)
        HELLO, WORLD!
        
        Commonly, serializers should be used at the end of the "pipeline";
        using them somewhere in the middle may produce unexpected results.
        
        :param function: the callable object that should be applied as a filter
        :return: the filtered stream
        :rtype: `Stream`
        )r%   )r
   _ensurer%   )r2   functions     r   __or__zStream.__or__W   s*    X ghhtnn--$/JJJJr   c                 >    t          t          j        | f|z             S )aL  Apply filters to the stream.
        
        This method returns a new stream with the given filters applied. The
        filters must be callables that accept the stream object as parameter,
        and return the filtered stream.
        
        The call::
        
            stream.filter(filter1, filter2)
        
        is equivalent to::
        
            stream | filter1 | filter2
        
        :param filters: one or more callable objects that should be applied as
                        filters
        :return: the filtered stream
        :rtype: `Stream`
        )r   operatoror_)r2   filterss     r   filterzStream.filter   s    ( hlTGg$5666r   c                 `    ddl m} |	| j        pd} | j        dd|i|} |||||          S )a  Return a string representation of the stream.
        
        Any additional keyword arguments are passed to the serializer, and thus
        depend on the `method` parameter value.
        
        :param method: determines how the stream is serialized; can be either
                       "xml", "xhtml", "html", "text", or a custom serializer
                       class; if `None`, the default serialization method of
                       the stream is used
        :param encoding: how the output string should be encoded; if set to
                         `None`, this method returns a `unicode` object
        :param out: a file-like object that the output should be written to
                    instead of being returned as one big string; note that if
                    this is a file or socket (or similar), the `encoding` must
                    not be `None` (that is, the output must be encoded)
        :return: a `str` or `unicode` object (depending on the `encoding`
                 parameter), or `None` if the `out` parameter is provided
        :rtype: `basestring`
        
        :see: XMLSerializer, XHTMLSerializer, HTMLSerializer, TextSerializer
        :note: Changed in 0.5: added the `out` parameter
        r   )encodeNxmlmethod)rD   encodingoutr"   )genshi.outputrB   r%   	serialize)r2   rD   rE   rF   kwargsrB   	generators          r   renderzStream.render   s\    . 	)(((((>_-F"DN;;&;F;;	visKKKKr   c                 N    ddl m}  ||                              | ||          S )aT  Return a new stream that contains the events matching the given
        XPath expression.
        
        >>> from genshi import HTML
        >>> stream = HTML('<doc><elem>foo</elem><elem>bar</elem></doc>', encoding='utf-8')
        >>> print(stream.select('elem'))
        <elem>foo</elem><elem>bar</elem>
        >>> print(stream.select('elem/text()'))
        foobar
        
        Note that the outermost element of the stream becomes the *context
        node* for the XPath test. That means that the expression "doc" would
        not match anything in the example above, because it only tests against
        child elements of the outermost element:
        
        >>> print(stream.select('doc'))
        <BLANKLINE>
        
        You can use the "." expression to match the context node itself
        (although that usually makes little sense):
        
        >>> print(stream.select('.'))
        <doc><elem>foo</elem><elem>bar</elem></doc>
        
        :param path: a string containing the XPath expression
        :param namespaces: mapping of namespace prefixes used in the path
        :param variables: mapping of variable names to values
        :return: the selected substream
        :rtype: `Stream`
        :raises PathSyntaxError: if the given path expression is invalid or not
                                 supported
        r   )Path)genshi.pathrM   select)r2   path
namespaces	variablesrM   s        r   rO   zStream.select   s7    B 	%$$$$$tDzz  z9===r   rC   c                 b    ddl m} |	| j        pd}  ||fi |t          |                     S )a  Generate strings corresponding to a specific serialization of the
        stream.
        
        Unlike the `render()` method, this method is a generator that returns
        the serialized output incrementally, as opposed to returning a single
        string.
        
        Any additional keyword arguments are passed to the serializer, and thus
        depend on the `method` parameter value.
        
        :param method: determines how the stream is serialized; can be either
                       "xml", "xhtml", "html", "text", or a custom serializer
                       class; if `None`, the default serialization method of
                       the stream is used
        :return: an iterator over the serialization results (`Markup` or
                 `unicode` objects, depending on the serialization method)
        :rtype: ``iterator``
        :see: XMLSerializer, XHTMLSerializer, HTMLSerializer, TextSerializer
        r   )get_serializerNrC   )rG   rT   r%   r9   )r2   rD   rI   rT   s       r   rH   zStream.serialize   sO    ( 	100000>_-F/~~f////>>>r   c                 *    |                                  S r   rK   r6   s    r   __str__zStream.__str__   s    {{}}r   c                 .    |                      d           S )N)rE   rV   r6   s    r   __unicode__zStream.__unicode__   s    {{D{)))r   c                     | S r   r"   r6   s    r   __html__zStream.__html__   s    r   r   )NNN)NN)rC   )r   r   r   r    r!   r   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r3   r7   r;   r@   rK   rO   rH   rW   rY   r[   r"   r   r   r
   r
   &   s        & <(IOG$$E
/%
 
 C?6""Dz**Hoi((Gz**H_X&&F!/-00K,,I			Boi((G
% 
% 
% 
%! ! !,K ,K ,K\7 7 7,L L L L:"> "> "> ">H? ? ? ?2  * * *    r   r
   c              #     K   t          |           } 	 t          |           }n# t          $ r Y dS w xY wt          |          t          ust          |          dk    rVt          |g|           D ]B}t          |d          r|                                }nt          t          |          df}|V  CdS |V  | D ]}|V  dS )z@Ensure that every item on the stream is actually a markup event.N   totupleNr`   )r5   nextStopIterationtypetuplelenr   hasattrr^   r(   r   )streamevents     r   r9   r9     s      &\\FV   
 E{{%3u::??E7F++ 	 	Eui(( ?i..>KKKK KKK   s   # 
11c                   H    e Zd ZdZg Zd Zd Zd Zd Zd Z	d Z
dd	Zd
 ZdS )r   a?  Immutable sequence type that stores the attributes of an element.
    
    Ordering of the attributes is preserved, while access by name is also
    supported.
    
    >>> attrs = Attrs([('href', '#'), ('title', 'Foo')])
    >>> attrs
    Attrs([('href', '#'), ('title', 'Foo')])
    
    >>> 'href' in attrs
    True
    >>> 'tabindex' in attrs
    False
    >>> attrs.get('title')
    'Foo'
    
    Instances may not be manipulated directly. Instead, the operators ``|`` and
    ``-`` can be used to produce new instances that have specific attributes
    added, replaced or removed.
    
    To remove an attribute, use the ``-`` operator. The right hand side can be
    either a string or a set/sequence of strings, identifying the name(s) of
    the attribute(s) to remove:
    
    >>> attrs - 'title'
    Attrs([('href', '#')])
    >>> attrs - ('title', 'href')
    Attrs()
    
    The original instance is not modified, but the operator can of course be
    used with an assignment:

    >>> attrs
    Attrs([('href', '#'), ('title', 'Foo')])
    >>> attrs -= 'title'
    >>> attrs
    Attrs([('href', '#')])
    
    To add a new attribute, use the ``|`` operator, where the right hand value
    is a sequence of ``(name, value)`` tuples (which includes `Attrs`
    instances):
    
    >>> attrs | [('title', 'Bar')]
    Attrs([('href', '#'), ('title', 'Bar')])
    
    If the attributes already contain an attribute with a given name, the value
    of that attribute is replaced:
    
    >>> attrs | [('href', 'http://example.org/')]
    Attrs([('href', 'http://example.org/')])
    c                 (    | D ]\  }}||k    r dS dS )zReturn whether the list includes an attribute with the specified
        name.
        
        :return: `True` if the list includes the attribute
        :rtype: `bool`
        TFr"   )r2   nameattr_s       r   __contains__zAttrs.__contains__\  s1      	 	GD!t||tt ur   c                     t                               | |          }t          |          t          u rt	          |          S |S )zReturn an item or slice of the attributes list.
        
        >>> attrs = Attrs([('href', '#'), ('title', 'Foo')])
        >>> attrs[1]
        ('title', 'Foo')
        >>> attrs[1:]
        Attrs([('title', 'Foo')])
        )rd   __getitem__rc   slicer   )r2   iitemss      r   rp   zAttrs.__getitem__h  s;     !!$**77e<<r   c                 T    t          t                              | ||                    S )zReturn a slice of the attributes list.
        
        >>> attrs = Attrs([('href', '#'), ('title', 'Foo')])
        >>> attrs[1:]
        Attrs([('title', 'Foo')])
        )r   rd   __getslice__)r2   rr   js      r   ru   zAttrs.__getslice__v  s$     U''a33444r   c                      t          d |D                       t           fd|D                       t          fd D              fd|D             z             S )a)  Return a new instance that contains the attributes in `attrs` in
        addition to any already existing attributes. Any attributes in the new
        set that have a value of `None` are removed.
        
        :return: a new instance with the merged attributes
        :rtype: `Attrs`
        c                     g | ]	\  }}||
S r   r"   ).0anavs      r   
<listcomp>z Attrs.__or__.<locals>.<listcomp>  s    ;;;VR
b


r   c                 *    g | ]\  }}|v 	|||fS r   r"   )ry   rz   r{   r2   s      r   r|   z Attrs.__or__.<locals>.<listcomp>  s5     : : :VR::". R*8..r   c                 N    g | ]!\  }}|v	|                     ||          f"S r"   )get)ry   snsvremovereplaces      r   r|   z Attrs.__or__.<locals>.<listcomp>  sD     + + +FB6)) 7;;r2../)))r   c                 .    g | ]\  }}|v	|v||fS r"   r"   )ry   rz   r{   r   r2   s      r   r|   z Attrs.__or__.<locals>.<listcomp>  s=     > > >62r4Bf,<,< 2h,<,<,<r   )setdictr   )r2   attrsr   r   s   ` @@r   r;   zAttrs.__or__  s     ;;u;;;<< : : : :u : : : ; ; + + + + +d + + +> > > > >U > > >> ? ? 	?r   c                 N    | sdS dd                     d | D                       z  S )NzAttrs()zAttrs([%s])z, c                 ,    g | ]}t          |          S r"   )repr)ry   items     r   r|   z"Attrs.__repr__.<locals>.<listcomp>  s    )F)F)F$t**)F)F)Fr   )joinr6   s    r   __repr__zAttrs.__repr__  s5     	9tyy)F)F)F)F)FGGGGr   c                 j    t          t                    rft          fd| D                       S )zReturn a new instance with all attributes with a name in `names` are
        removed.
        
        :param names: the names of the attributes to remove
        :return: a new instance with the attribute removed
        :rtype: `Attrs`
        c                 &    g | ]\  }}|v	||fS r"   r"   )ry   rk   r   namess      r   r|   z!Attrs.__sub__.<locals>.<listcomp>  s+    MMMidC4u;L;LtSk;L;L;Lr   )
isinstancer   r   )r2   r   s    `r   __sub__zAttrs.__sub__  sA     e\** 	HEMMMM4MMMNNNr   Nc                 *    | D ]\  }}||k    r|c S |S )a  Return the value of the attribute with the specified name, or the
        value of the `default` parameter if no such attribute is found.
        
        :param name: the name of the attribute
        :param default: the value to return when the attribute does not exist
        :return: the attribute value, or the `default` value if that attribute
                 does not exist
        :rtype: `object`
        r"   )r2   rk   defaultrl   values        r   r   z	Attrs.get  s3       	 	KD%t|| r   c                 P    t           d                    d | D                       dfS )a[  Return the attributes as a markup event.
        
        The returned event is a `TEXT` event, the data is the value of all
        attributes joined together.
        
        >>> Attrs([('href', '#'), ('title', 'Foo')]).totuple()
        ('TEXT', '#Foo', (None, -1, -1))
        
        :return: a `TEXT` event
        :rtype: `tuple`
         c                     g | ]
}|d          S )   r"   )ry   xs     r   r|   z!Attrs.totuple.<locals>.<listcomp>  s    111qad111r   r_   )r(   r   r6   s    r   r^   zAttrs.totuple  s,     RWW11D11122NBBr   r   )r   r   r   r    r!   rn   rp   ru   r;   r   r   r   r^   r"   r   r   r   r   &  s        2 2f I
 
 
  5 5 5? ? ? H H H

O 
O 
O   C C C C Cr   r   c                   l    e Zd ZdZg Zd Zd Zd Zd ZeZ	d Z
ddZedd	            Zd
 ZddZd ZdS )r   zeMarks a string as being safe for inclusion in HTML/XML output without
    needing to be escaped.
    c                 `    t          t          j        | t          |                              S r   r   r   __add__r   r2   others     r   r   zMarkup.__add__  s#    i'fUmm<<===r   c                 `    t          t          j        t          |          |                     S r   r   r   s     r   __radd__zMarkup.__radd__  s#    i'ut<<===r   c           
         t          |t                    rUt          t          |                                t	          t
          |                                                              }nNt          |t          t          f          r#t          t	          t
          |                    }nt          |          }t          t          j        | |                    S r   )r   r   zipkeysmapr   valueslistrd   r   r   __mod__)r2   argss     r   r   zMarkup.__mod__  s    dD!! 	 DIIKKVT[[]])C)CDDEEDDtUm,, 	 VT**++DD$<<Di'd33444r   c                 F    t          t          j        | |                    S r   )r   r   __mul__)r2   nums     r   r   zMarkup.__mul__  s    i'c22333r   c                 \    dt          |           j        dt          j        |           dS )N< >)rc   r   r   r   r6   s    r   r   zMarkup.__repr__  s/      JJ///1CD1I1I1I1IJJr   Tc                 d    fd|D             }t          t          j        | |                    S )aA  Return a `Markup` object which is the concatenation of the strings
        in the given sequence, where this `Markup` object is the separator
        between the joined elements.
        
        Any element in the sequence that is not a `Markup` instance is
        automatically escaped.
        
        :param seq: the sequence of strings to join
        :param escape_quotes: whether double quote characters in the elements
                              should be escaped
        :return: the joined `Markup` object
        :rtype: `Markup`
        :see: `escape`
        c                 2    g | ]}t          |           S ))quotes)r   )ry   r   escape_quotess     r   r|   zMarkup.join.<locals>.<listcomp>  s&    LLL];;;LLLr   )r   r   r   )r2   seqr   escaped_itemss     ` r   r   zMarkup.join  s9     MLLLLLLinT=99:::r   c                 \   |s
 |             S t          |          | u r|S t          |d          r | |                                          S |                    dd                              dd                              dd          }|r|                    dd	          } | |          S )
a  Create a Markup instance from a string and escape special characters
        it may contain (<, >, & and ").
        
        >>> escape('"1 < 2"')
        <Markup '&#34;1 &lt; 2&#34;'>
        
        If the `quotes` parameter is set to `False`, the " character is left
        as is. Escaping quotes is generally only required for strings that are
        to be used in attribute values.
        
        >>> escape('"1 < 2"', quotes=False)
        <Markup '"1 &lt; 2"'>
        
        :param text: the text to escape
        :param quotes: if ``True``, double quote characters are escaped in
                       addition to the other special characters
        :return: the escaped `Markup` string
        :rtype: `Markup`
        r[   &&amp;r   &lt;r   &gt;"&#34;)rc   rf   r[   r   )r   textr   s      r   r   zMarkup.escape  s    *  	355L::K4$$ 	(3t}}'''||C))GC((GC(( 	  	.<<W--Ds4yyr   c                     | sdS t          |                               dd                              dd                              dd                              dd	          S )
zReverse-escapes &, <, >, and " and returns a `unicode` object.
        
        >>> Markup('1 &lt; 2').unescape()
        '1 < 2'
        
        :return: the unescaped string
        :rtype: `unicode`
        :see: `genshi.core.unescape`
        r   r   r   r   r   r   r   r   r   )r   r   r6   s    r   r   zMarkup.unescape  s\      	2&&w44&wvs33&wvs33&ww44	5r   Fc                 >    t          t          | |                    S )a  Return a copy of the text with any character or numeric entities
        replaced by the equivalent UTF-8 characters.
        
        If the `keepxmlentities` parameter is provided and evaluates to `True`,
        the core XML entities (``&amp;``, ``&apos;``, ``&gt;``, ``&lt;`` and
        ``&quot;``) are not stripped.
        
        :return: a `Markup` instance with entities removed
        :rtype: `Markup`
        :see: `genshi.util.stripentities`
        )keepxmlentities)r   r   )r2   r   s     r   r   zMarkup.stripentities   s     mD/JJJKKKr   c                 :    t          t          |                     S )zReturn a copy of the text with all XML/HTML tags removed.
        
        :return: a `Markup` instance with all tags removed
        :rtype: `Markup`
        :see: `genshi.util.striptags`
        )r   r	   r6   s    r   r	   zMarkup.striptags.  s     ioo&&&r   N)T)F)r   r   r   r    r!   r   r   r   r   __rmul__r   r   classmethodr   r   r   r	   r"   r   r   r   r     s          I> > >> > >5 5 54 4 4HK K K; ; ; ;$       [ D5 5 5"L L L L' ' ' ' 'r   r   )r   c                 X    t          | t                    s| S |                                 S )ao  Reverse-escapes &, <, >, and " and returns a `unicode` object.
    
    >>> unescape(Markup('1 &lt; 2'))
    '1 < 2'
    
    If the provided `text` object is not a `Markup` instance, it is returned
    unchanged.
    
    >>> unescape('1 &lt; 2')
    '1 &lt; 2'
    
    :param text: the text to unescape
    :return: the unescsaped string
    :rtype: `unicode`
    )r   r   r   )r   s    r   r   r   A  s)      dF## ==??r   c                       e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 ZeZd Zej        d         dk    rd Znd Zd Zd ZdS )r   a  Utility class creating and testing elements with a namespace.
    
    Internally, namespace URIs are encoded in the `QName` of any element or
    attribute, the namespace URI being enclosed in curly braces. This class
    helps create and test these strings.
    
    A `Namespace` object is instantiated with the namespace URI.
    
    >>> html = Namespace('http://www.w3.org/1999/xhtml')
    >>> html
    Namespace('http://www.w3.org/1999/xhtml')
    >>> html.uri
    'http://www.w3.org/1999/xhtml'
    
    The `Namespace` object can than be used to generate `QName` objects with
    that namespace:
    
    >>> html.body
    QName('http://www.w3.org/1999/xhtml}body')
    >>> html.body.localname
    'body'
    >>> html.body.namespace
    'http://www.w3.org/1999/xhtml'
    
    The same works using item access notation, which is useful for element or
    attribute names that are not valid Python identifiers:
    
    >>> html['body']
    QName('http://www.w3.org/1999/xhtml}body')
    
    A `Namespace` object can also be used to test whether a specific `QName`
    belongs to that namespace using the ``in`` operator:
    
    >>> qname = html.body
    >>> qname in html
    True
    >>> qname in Namespace('http://www.w3.org/2002/06/xhtml2')
    False
    c                 \    t          |          | u r|S t                              |           S r   )rc   objectr   )r   uris     r   r   zNamespace.__new__~  s*    99J~~c"""r   c                     | j         fS r   r   r6   s    r   __getnewargs__zNamespace.__getnewargs__  s    {r   c                     | j         S r   r   r6   s    r   __getstate__zNamespace.__getstate__  	    xr   c                     || _         d S r   r   r2   r   s     r   __setstate__zNamespace.__setstate__  s    r   c                 .    t          |          | _        d S r   )r   r   r   s     r   r3   zNamespace.__init__  s    S>>r   c                 "    |j         | j        k    S r   )	namespacer   )r2   qnames     r   rn   zNamespace.__contains__  s    $(**r   c                     | |k     S r   r"   r   s     r   __ne__zNamespace.__ne__  s    5=  r   c                 b    t          |t                    r| j        |j        k    S | j        |k    S r   )r   r   r   r   s     r   __eq__zNamespace.__eq__  s0    eY'' 	)8uy((x5  r   c                 6    t          | j        dz   |z             S )N})r   r   )r2   rk   s     r   rp   zNamespace.__getitem__  s    TX^d*+++r   c                 *    t          | j                  S r   )hashr   r6   s    r   __hash__zNamespace.__hash__  s    DH~~r   r      c                 Z    t          |           j        dt          | j                  dS N())rc   r   r   r   r6   s    r   r   zNamespace.__repr__  s,    #Dzz222Jtx4H4H4H4HIIr   c                 @    t          |           j        d| j        dS r   )rc   r   r   r6   s    r   r   zNamespace.__repr__  s"    #Dzz222DHHH==r   c                 6    | j                             d          S )Nzutf-8)r   rB   r6   s    r   rW   zNamespace.__str__  s    xw'''r   c                     | j         S r   r   r6   s    r   rY   zNamespace.__unicode__  r   r   N)r   r   r   r    r   r   r   r   r3   rn   r   r   rp   __getattr__r   sysversion_infor   rW   rY   r"   r   r   r   r   V  s       & &N# # #
      " " "+ + +! ! !! ! !
, , ,K   a	J 	J 	J 	J	> 	> 	>( ( (    r   r   z$http://www.w3.org/XML/1998/namespacec                   X    e Zd ZdZddgZd Zd Zej        d         dk    rd Z	d
S d	 Z	d
S )r   a  A qualified element or attribute name.
    
    The unicode value of instances of this class contains the qualified name of
    the element or attribute, in the form ``{namespace-uri}local-name``. The
    namespace URI can be obtained through the additional `namespace` attribute,
    while the local name can be accessed through the `localname` attribute.
    
    >>> qname = QName('foo')
    >>> qname
    QName('foo')
    >>> qname.localname
    'foo'
    >>> qname.namespace
    
    >>> qname = QName('http://www.w3.org/1999/xhtml}body')
    >>> qname
    QName('http://www.w3.org/1999/xhtml}body')
    >>> qname.localname
    'body'
    >>> qname.namespace
    'http://www.w3.org/1999/xhtml'
    r   	localnamec                    t          |          | u r|S |                    d          }|                    dd          }t          |          dk    r;t	          j        | d|z            }t          t          |          \  |_        |_        n1t	          j        | |          }dt	          |          c|_        |_        |S )zCreate the `QName` instance.
        
        :param qname: the qualified name as a string of the form
                      ``{namespace-uri}local-name``, where the leading curly
                      brace is optional
        {r   r   z{%sN)	rc   lstripsplitre   r   r   r   r   r   )r   r   partsr2   s       r   r   zQName.__new__  s     ;;#LS!!C##u::>>$S%%-88D-0E-B-B*DNDNN$S%00D-19U3C3C*DNDNr   c                 .    |                      d          fS )Nr   )r   r6   s    r   r   zQName.__getnewargs__  s    C  ""r   r   r   c                 v    t          |           j        dt          |                     d                    dS Nr   r   r   )rc   r   r   r   r6   s    r   r   zQName.__repr__  s6    #Dzz222Jt{{3?O?O4P4P4P4PQQr   c                 \    t          |           j        d|                     d          dS r   )rc   r   r   r6   s    r   r   zQName.__repr__  s.    #Dzz222DKK4D4D4D4DEEr   N)
r   r   r   r    r!   r   r   r   r   r   r"   r   r   r   r     s         , k*I  (# # # a	R 	R 	R 	R 	R	F 	F 	F 	F 	Fr   r   )*r    	functoolsr   r   	itertoolsr   r=   genshi.compatr   r   r   genshi.utilr   r	   __all____docformat__r   r   r   r
   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r9   rd   r   r   genshi._speedupsImportErrorr   r   r   XML_NAMESPACEr   r"   r   r   <module>r      s   * )       



        = = = = = = = = = = 0 0 0 0 0 0 0 0  %E E E E Ec E E EV V V V VV V V Vr 	j{?
.?	 	Y
.  4UC UC UC UC UCE UC UC UCpw' w' w' w' w'Y w' w' w't	''''''' 	 	 	D	 
  *W W W W W W W Wv 	@AA6F 6F 6F 6F 6FI 6F 6F 6F 6F 6Fs   8B? ?CC