o
    /h̄                     @   sV  d Z g ZddlZddlZddlZddlZddlmZ ddl	m
Z
 ddlZddlmZmZmZ ddlmZ zddlmZ W n eyK   ddlmZ Y nw e ZG d	d
 d
ZG dd deZG dd deZG dd deZG dd deeZG dd dZG dd dZG dd dZG dd dZ G dd de Z!	d!ddZ"G dd  d Z#dS )"zBbase classes and helper functions for css and stylesheets packages    N)chain)unique_everseen   )codecerrorhandler	tokenize2	normalize)_defaultFetcherc                   @   s.   e Zd ZdZe ZejZ	dd Z
dd ZdS )
_BaseClasszi
    Base class for Base, Base2 and _NewBase.

    **Base and Base2 will be removed in the future!**
    c                 C   s&   t | dr| jrtjd| j dS )z>Raise xml.dom.NoModificationAllowedErr if rule/... is readonly	_readonlyz%s is readonly.TF)hasattrr   xmldomNoModificationAllowedErr	__class__self r   A/var/www/html/myenv/lib/python3.10/site-packages/cssutils/util.py_checkReadonly$   s   z_BaseClass._checkReadonlyc                 C   s*   |sdS t |tr|S ddd |D S )z
        Return string value of t (t may be a string, a list of token tuples
        or a single tuple in format (type, value, line, col).
        Mainly used to get a string value of t for error messages.
         c                 S   s   g | ]}|d  qS )r   r   ).0xr   r   r   
<listcomp>6       z(_BaseClass._valuestr.<locals>.<listcomp>)
isinstancestrjoin)r   tr   r   r   	_valuestr+   s
   
z_BaseClass._valuestrN)__name__
__module____qualname____doc__r   ErrorHandler_logr   CSSProductions_prodsr   r    r   r   r   r   r      s    r   c                   @   s>   e Zd ZdZdd Zdd Zdd Zdd	d
Zedd Z	dS )_NewBasezi
    New base class for classes using ProdParser.

    **Currently CSSValue and related ones only.**
    c                 C      t  | _d S NSeq_seqr   r   r   r   __init__@      z_NewBase.__init__c                 C   s   d|_ || _dS )z'Set value of ``seq`` which is readonly.TN)r   r.   )r   newseqr   r   r   _setSeqC      
z_NewBase._setSeqc                 C   s   | j   d S r+   )r.   clearr   r   r   r   	_clearSeqH      z_NewBase._clearSeqFc                 C   s
   t |dS )z8Get a writeable Seq() which is used to set ``seq`` later)readonly)r-   r   r7   r   r   r   _tempSeqK   s   
z_NewBase._tempSeqc                 C      | j S )z,Internal readonly attribute, **DO NOT USE**!r.   r   r   r   r   seqO      z_NewBase.seqNF)
r!   r"   r#   r$   r/   r2   r5   r9   propertyr<   r   r   r   r   r)   9   s    
r)   c                   @   P   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd ZdS )_NewListBaseaR  
    (EXPERIMENTAL)
    A base class used for list classes like stylesheets.MediaList

    adds list like behaviour running on inhering class' property ``seq``

    - item in x => bool
    - len(x) => integer
    - get, set and del x[i]
    - for item in x
    - append(item)

    some methods must be overwritten in inheriting class
    c                 C   r*   r+   r,   r   r   r   r   r/   e   r0   z_NewListBase.__init__c                 C   s    | j D ]
}||jkr dS qdS )NTFr.   value)r   itemitr   r   r   __contains__h   s
   

z_NewListBase.__contains__c                 C      | j |= d S r+   r;   r   indexr   r   r   __delitem__n   r0   z_NewListBase.__delitem__c                 C   s   | j | jS r+   rB   rH   r   r   r   __getitem__q   r0   z_NewListBase.__getitem__c                        fdd}| S )Nc                  3   s     j D ]} | jV  qd S r+   rB   r   r   r   r   genu   s   

z"_NewListBase.__iter__.<locals>.genr   r   rN   r   r   r   __iter__t   s   z_NewListBase.__iter__c                 C   
   t | jS r+   lenr.   r   r   r   r   __len__{      
z_NewListBase.__len__c                 C      t zmust be overwrittenNotImplementedErrorr   rI   rD   r   r   r   __setitem__~      z_NewListBase.__setitem__c                 C   rV   rW   rX   r   rD   r   r   r   append   r\   z_NewListBase.appendNr!   r"   r#   r$   r/   rF   rJ   rK   rP   rT   r[   r^   r   r   r   r   rA   U   s    rA   c                   @   s   e Zd ZdZe Zg g g g g g g g g g g dZedd Z	dd Z
dd Zdd
dZdd ZdddZdd Zdd Z															dddZdddZ						dddZd	S )Basea  
    **Superceded by _NewBase**

    **Superceded by Base2 which is used for new seq handling class.**

    Base class for most CSS and StyleSheets classes

    Contains helper methods for inheriting classes helping parsing

    ``_normalize`` is static as used by Preferences.
    )
backgroundborderzborder-leftzborder-rightz
border-topzborder-bottomcuefontz
list-styleoutlinepausec                 C   s   t | S )a  
        normalizes x, namely:

        - remove any \ before non unicode sequences (0-9a-zA-Z) so for
          x=="c\olor\" return "color" (unicode escape sequences should have
          been resolved by the tokenizer already)
        - lowercase
        r   rM   r   r   r   
_normalize   s   
zBase._normalizec                 C   s2   t |tr|d t| j|d fS |t| jdfS )z
        returns tuple (text, dict-of-namespaces) or if no namespaces are
        in cssText returns (cssText, {})

        used in Selector, SelectorList, CSSStyleRule, CSSMediaRule and
        CSSStyleSheet
        r   r   )log)r   tuple_SimpleNamespacesr&   )r   text_namespaces_tupler   r   r   _splitNamespacesOff   s
   

zBase._splitNamespacesOffc                 C   s6   |sdS t |tr| j|S t |tr|gS t|S )zw
        returns tokens of textortokens which may already be tokens in which
        case simply returns input
        N)r   r   _Base__tokenizer2tokenizeri   iter)r   textortokensr   r   r   
_tokenize2   s   

zBase._tokenize2Nc              
   C   s(   zt |W S  tttfy   | Y S w )z>returns next token in generator tokenizer or the default value)nextStopIterationAttributeError	TypeError)r   	tokenizerdefaultr   r   r   
_nexttoken   s
   
zBase._nexttokenc                 C   s   |r|d S dS )zreturns type of Tokenizer tokenr   Nr   )r   tokenr   r   r   _type   s   z
Base._typeFc                 C   s&   |r|rt |d S |r|d S dS )z returns value of Tokenizer tokenr   N)r`   rg   )r   ry   r	   r   r   r   _tokenvalue   s
   zBase._tokenvaluec                 C   s0   |r|d }| d|d  |d dd S dS )z
        for STRING returns the actual content without surrounding "" or ''
        and without respective escapes, e.g.::

             "with " char" => with " char
        r   \r   N)replacer   ry   rC   r   r   r   _stringtokenvalue   s    zBase._stringtokenvaluec                 C   s`   |r.|d dd   }|r,|d dv r,|d |d kr,|d|d  |d dd }|S dS )z
        for URI returns the actual content without surrounding url()
        or url(""), url('') and without respective escapes, e.g.::

             url(""") => "
        r      r}   r   z'"r|   N)stripr~   r   r   r   r   _uritokenvalue   s     zBase._uritokenvaluec                 C   sX  d}d}d } }}|rd}d}nM|rd}d}nF|rd}d}n?|r&d}d	}n8|r/d}d}d	}n/|r4d}n*|	r9d
}n%|
r>d}n |rCd}n|rSd}|rR|  |dkrRd}n|rZd}d}n|r^d}g }|r|| |d }d|krt|d7 }nd|kr}|d7 }nd|kr|d7 }|r|D ]}|\}}}}d|kr||  nyd|kr|d7 }n2d|kr|d8 }n)d|kr|d7 }n d|kr|d8 }nd|kstjj|kr|d7 }nd|kr|d8 }|| ||  kr|  krdkrn n
||v s||v r n|r|dkr||  krdkrn q||v r nq|r*|r&|dd |d fS |dfS |S )z
        returns tokens upto end of atrule and end index
        end is defined by parameters, might be ; } ) or other

        default looks for ending "}" and ";"
        z;}r   r   {r}   }r   ;)STRINGz:;z;!][),(EOFN)r{   r^   r`   r(   FUNCTION)r   rv   
starttokenblockstartonlyblockendonlymediaendonlyimportmediaqueryendonlymediaqueryendonly	semicolonpropertynameendonlypropertyvalueendonlypropertypriorityendonlyselectorattendonlyfuncendonlylistseponlyseparateEndendsendtypesbracebracketparantresulttokensvalry   typlinecolr   r   r   _tokensupto2  s   









"

zBase._tokensupto2c                    sJ   d fdd	}ddd}ddd}ddd	}||||d
}| | |S ):  
        adds default productions if not already present, used by
        _parse only

        each production should return the next expected token
        normaly a name like "uri" or "EOF"
        some have no expectation like S or COMMENT, so simply return
        the current value of self.__expected
        Nc                    sP   | dkrt j }|||_|jr|| | S d d< jjd|d | S )!default impl for unexpected @ruler   F
wellformedExpected EOF.ry   )	cssutilscssCSSUnknownRuler   cssTextr   r^   r&   errorexpectedr<   ry   rv   rulenewr   r   r   	ATKEYWORD  s   

z.Base._adddefaultproductions.<locals>.ATKEYWORDc                 S   s   | tj|g | S )z<default implementation for COMMENT token adds CSSCommentRule)r^   r   r   
CSSCommentr   r<   ry   rv   r   r   r   COMMENT  s   z,Base._adddefaultproductions.<locals>.COMMENTc                 S   s   | S )z0default implementation for S token, does nothingr   r   r   r   r   S  r\   z&Base._adddefaultproductions.<locals>.Sc                 S      dS z$default implementation for EOF tokenr   r   r   r   r   r   r     r\   z(Base._adddefaultproductions.<locals>.EOFr   r   r   r   r+   NNNNupdate)r   productionsr   r   r   r   r   pr   r   r   _adddefaultproductions  s   



zBase._adddefaultproductionsc                    s   d} r fdd}	t  g}
n}
|
r=| ||}|
D ]}||d |}|r2||||}qd}| jd|  q||fS )a  
        puts parsed tokens in seq by calling a production with
            (seq, tokenizer, token)

        expected
            a name what token or value is expected next, e.g. 'uri'
        seq
            to add rules etc to
        tokenizer
            call tokenizer.next() to get next token
        productions
            callbacks {tokentype: callback}
        default
            default callback if tokentype not in productions
        new
            used to init default productions
        initialtoken
            will be used together with tokenizer running 1st this token
            and then all tokens in tokenizer

        returns (wellformed, expected) which the last prod might have set
        Tc                   3   s     V  E dH  dS )z*Build new tokenizer including initialtokenNr   r   initialtokenrv   r   r   tokens  s   zBase._parse.<locals>.tokensr   Fz!Unexpected token (%s, %s, %s, %s))r   r   getr&   r   )r   r   r<   rv   r   rw   r   r   r   r   fulltokenizerprodsry   r   r   r   r   _parse  s    zBase._parser+   r>   )NFFFFFFFFFFFFFNNN)r!   r"   r#   r$   r   	Tokenizerrm   _SHORTHANDPROPERTIESstaticmethodrg   rl   rq   rx   rz   r{   r   r   r   r   r   r   r   r   r   r`      sX    


	

x5r`   c                   @   s"   e Zd ZdZdd ZdddZdS )Base2zK
    **Superceded by _NewBase.**

    Base class for new seq handling.
    c                 C   r*   r+   r,   r   r   r   r   r/     r0   zBase2.__init__Nc                    sV   d fdd	}d fdd	}d fdd	}ddd	}||||d
}| | |S )r   Nc                    sf   | dkr%t j }|||_|jr#|j|t jjj|d |d d | S d d< j	j
d|d | S )	r   r         )r   r   Fr   r   r   )r   r   r   r   r   r   r^   CSSRuleUNKNOWN_RULEr&   r   r   r   r   r   r     s   
z/Base2._adddefaultproductions.<locals>.ATKEYWORDc                    s:   | dkrd d< j jd|d |tj|gd | S )z5default impl, adds CSSCommentRule if not token == EOFr   Fr   zExpected EOF but found comment.r   r   )r&   r   r^   r   r   r   r   r   r   r   r     s
   z-Base2._adddefaultproductions.<locals>.COMMENTc                    s$   | dkrd d< j jd|d | S )z.default impl, does nothing if not token == EOFr   Fr   z"Expected EOF but found whitespace.r   )r&   r   r   r   r   r   r     s   z'Base2._adddefaultproductions.<locals>.Sc                 S   r   r   r   r   r   r   r   r   %  r\   z)Base2._adddefaultproductions.<locals>.EOFr   r+   r   r   )r   r   r   r   r   r   r   defaultproductionsr   r   r   r     s   

zBase2._adddefaultproductionsr+   )r!   r"   r#   r$   r/   r   r   r   r   r   r     s    r   c                   @   s   e Zd ZdZd#ddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zd$ddZdd Zdd Zd%ddZd&ddZdd  Zd'd!d"ZdS )(r-   z
    property seq of Base2 inheriting classes, holds a list of Item objects.

    used only by Selector for now

    is normally readonly, only writable during parsing
    Tc                 C   s   g | _ || _dS )z
        only way to write to a Seq is to initialize it with new items
        each itemtuple has (value, type, line) where line is optional
        N)r.   r   r8   r   r   r   r/   <  s   
zSeq.__init__c                 C   s*   d | j| jjddd | jD | jS )z8returns a repr same as a list of tuples of (value, type)z(cssutils.{}.{}([
    {}], readonly={!r})z,
    c                 S   s   g | ]}d | qS )%rr   )r   rD   r   r   r   r   I  r   z Seq.__repr__.<locals>.<listcomp>)formatr"   r   r!   r   r.   r   r   r   r   r   __repr__D  s   zSeq.__repr__c                 C   s   g }| D ]$}t |jtr||j qt |tr!||jd  q|t| qd| j d| jj dt	| d|d| j
dt| dd	S )
Nr   z
<cssutils..z object length=z items=z
 readonly= at 0xr   >)r   rC   r   r^   ri   reprr"   r   r!   rS   r   id)r   valsvr   r   r   __str__M  s   
<zSeq.__str__c                 C   rG   r+   r;   r   ir   r   r   rJ   Y  r0   zSeq.__delitem__c                 C   
   | j | S r+   r;   r   r   r   r   rK   \  rU   zSeq.__getitem__c                 C   s$   |\}}}}t ||||| j|< d S r+   )Itemr.   )r   r   xxx_todo_changemer   r   r   r   r   r   r   r[   _  s   zSeq.__setitem__c                 C   rQ   r+   )ro   r.   r   r   r   r   rP   c  rU   zSeq.__iter__c                 C   rQ   r+   rR   r   r   r   r   rT   f  rU   zSeq.__len__Nc                 C   sB   | j rtdt|tr| j| dS | jt|||| dS )zIf not readonly add new Item()Seq is readonly.N)r   rt   r   r   r.   r^   )r   r   r   r   r   r   r   r   r^   i  s
   
z
Seq.appendc                 C   s   | j rtd| j| dS )z.if not readonly add item which must be an Itemr   N)r   rt   r.   r^   r]   r   r   r   
appendItems  s   zSeq.appendItemc                 C   s   | j d d = d S r+   r;   r   r   r   r   r4   z  s   z	Seq.clearc                 C   s   | j |t|||| dS )z4Insert new Item() at index # even if readony!? TODO!N)r.   insertr   r   rI   r   r   r   r   r   r   r   r   }  s   z
Seq.insertr}   c                 C   s&   | j rtdt||||| j|< dS )zm
        if not readonly replace Item at index with new Item or
        simply replace value or type
        r   N)r   rt   r   r.   r   r   r   r   r~     s   zSeq.replacec                 C   sL   | j r | j d jtjjkr$| j d= | j r"| j d jtjjksdS dS dS dS )ztrims S items from end of Seqr}   N)r.   typer   r'   r   r   r   r   r   rstrip  s   *z
Seq.rstripc                 C   s<   | j rtd| j| }t|j| |j|j|j| j|< dS )zA
        if not readonly append to Item's value at index
        r   N)r   rt   r.   r   rC   r   r   r   )r   r   rI   oldr   r   r   appendToVal  s   
$zSeq.appendToVal)Tr   NN)r}   NNNN)Nr}   )r!   r"   r#   r$   r/   r   r   rJ   rK   r[   rP   rT   r^   r   r4   r   r~   r   r   r   r   r   r   r-   3  s"    
	




r-   c                   @   sR   e Zd ZdZdddZedd Zedd Zedd Zed	d Z	d
d Z
dS )r   at  
    an item in the seq list of classes (successor to tuple items in old seq)

    each item has attributes:

    type
        a sematic type like "element", "attribute"
    value
        the actual value which may be a string, number etc or an instance
        of e.g. a CSSComment
    *line*
        **NOT IMPLEMENTED YET, may contain the line in the source later**
    Nc                 C   s   || _ || _|| _|| _d S r+   )_Item__value_Item__type_Item__line
_Item__col)r   rC   r   r   r   r   r   r   r/     s   
zItem.__init__c                 C   r:   r+   )r   r   r   r   r   <lambda>      zItem.<lambda>c                 C   r:   r+   )r   r   r   r   r   r     r   c                 C   r:   r+   )r   r   r   r   r   r     r   c                 C   r:   r+   )r   r   r   r   r   r     r   c                 C   s6   | j  d| jj d| jd| jd| jd| jdS )Nr   z(value=z, type=z, line=z, col=r   )r"   r   r!   r   r   r   r   r   r   r   r   r     s   6zItem.__repr__r   )r!   r"   r#   r$   r/   r?   r   rC   r   r   r   r   r   r   r   r     s    
r   c                   @   r@   )ListSeqas  
    (EXPERIMENTAL)
    A base class used for list classes like cssutils.css.SelectorList or
    stylesheets.MediaList

    adds list like behaviour running on inhering class' property ``seq``

    - item in x => bool
    - len(x) => integer
    - get, set and del x[i]
    - for item in x
    - append(item)

    some methods must be overwritten in inheriting class
    c                 C   s
   g | _ d S r+   r<   r   r   r   r   r/     rU   zListSeq.__init__c                 C   
   || j v S r+   r   r]   r   r   r   rF     rU   zListSeq.__contains__c                 C   rG   r+   r   rH   r   r   r   rJ     r0   zListSeq.__delitem__c                 C   r   r+   r   rH   r   r   r   rK     rU   zListSeq.__getitem__c                    rL   )Nc                   3   s     j E d H  d S r+   r   r   r   r   r   rN     s   zListSeq.__iter__.<locals>.genr   rO   r   r   r   rP     s   zListSeq.__iter__c                 C   rQ   r+   )rS   r<   r   r   r   r   rT     rU   zListSeq.__len__c                 C   rV   rW   rX   rZ   r   r   r   r[     r\   zListSeq.__setitem__c                 C   rV   rW   rX   r]   r   r   r   r^     r\   zListSeq.appendNr_   r   r   r   r   r     s    r   c                   @   s   e Zd ZdZd#ddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zedd Zdd Zdd Zdd Zdd Zdd  Zd!d" ZdS )$_Namespacesa  
    A dictionary like wrapper for @namespace rules used in a CSSStyleSheet.
    Works on effective namespaces, so e.g. if::

        @namespace p1 "uri";
        @namespace p2 "uri";

    only the second rule is effective and kept.

    namespaces
        a dictionary {prefix: namespaceURI} containing the effective namespaces
        only. These are the latest set in the CSSStyleSheet.
    parentStyleSheet
        the parent CSSStyleSheet
    Nc                 G   s   || _ || _dS )z5no initial values are set, only the relevant sheet isN)parentStyleSheetr&   )r   r   rh   argsr   r   r   r/     r3   z_Namespaces.__init__c                 C   s
   d| j  S )Nr   
namespacesr   r   r   r   r     rU   z_Namespaces.__repr__c                 C   r   r+   r   r   prefixr   r   r   rF     rU   z_Namespaces.__contains__c                 C   s`   |  |}ttdd | jjD ]\}}||kr!| j|  dS q| jjd| tj	j
d dS )z6deletes CSSNamespaceRule(s) with rule.prefix == prefixc                 S      | j | jkS r+   r   NAMESPACE_RULErr   r   r   r   	      z)_Namespaces.__delitem__.<locals>.<lambda>NPrefix %s not found.r   )_Namespaces__findrule	enumeratefilterr   cssRules
deleteRuler&   r   r   r   NamespaceErr)r   r   delruler   r   r   r   r   rJ     s   
z_Namespaces.__delitem__c                 C   s:   z| j | W S  ty   | jjd| tjjd Y d S w )Nr  r  )r   KeyErrorr&   r   r   r   r  r   r   r   r   rK     s
   z_Namespaces.__getitem__c                 C   s
   | j  S r+   )r   rP   r   r   r   r   rP     rU   z_Namespaces.__iter__c                 C   rQ   r+   )rS   r   r   r   r   r   rT     rU   z_Namespaces.__len__c                 C   s^   |  |}|s| jjtjj||ddd dS || jv r||_|t| j	 v r-||_
dS dS )zDreplaces prefix or sets new rule, may raise NoModificationAllowedErrr   namespaceURIT)inOrderN)r  r   
insertRuler   r   CSSNamespaceRuler   r  listvaluesr   )r   r   r  r   r   r   r   r[     s   



z_Namespaces.__setitem__c                    s,    pd t  fddt| jj}t|d S )Nr   c                    s   | j | jko
| j kS r+   )r   r  r   r  r   r   r   r   0      z(_Namespaces.__findrule.<locals>.<lambda>)r	  reversedr   r
  rr   )r   r   foundr   r  r   
__findrule+  s   


z_Namespaces.__findrulec                 C   s6   t dd t| jj}t|tdd}dd |D S )zg
        A property holding only effective @namespace rules in
        self.parentStyleSheets.
        c                 S   r   r+   r   r  r   r   r   r   <  r  z(_Namespaces.namespaces.<locals>.<lambda>r  )keyc                 S   s   i | ]}|j |jqS r   r  )r   r   r   r   r   
<dictcomp>C  r  z*_Namespaces.namespaces.<locals>.<dictcomp>)r	  r  r   r
  r   operator
attrgetter)r   ns_rulesunique_rulesr   r   r   r   5  s   
z_Namespaces.namespacesc                 C   s   | j ||S r+   )r   r   )r   r   rw   r   r   r   r   E  r6   z_Namespaces.getc                 C      t | j S r+   )r  r   itemsr   r   r   r   r"  H  r6   z_Namespaces.itemsc                 C   r!  r+   )r  r   keysr   r   r   r   r#  K  r6   z_Namespaces.keysc                 C   r!  r+   )r  r   r  r   r   r   r   r  N  r6   z_Namespaces.valuesc                 C   s4   t | j D ]\}}||kr|  S qtd| )zm
        returns effective prefix for given namespaceURI or raises IndexError
        if this cannot be foundzNamespaceURI %s not found.)r  r   r"  
IndexError)r   r  r   urir   r   r   prefixForNamespaceURIQ  s
   z!_Namespaces.prefixForNamespaceURIc                 C   s(   d| j j dt| jdt| ddS )N<cssutils.util.z object parentStyleSheet=r   r   r   )r   r!   r   r   r   r   r   r   r   r   Z  s   (z_Namespaces.__str__r+   )r!   r"   r#   r$   r/   r   rF   rJ   rK   rP   rT   r[   r  r?   r   r   r"  r#  r  r&  r   r   r   r   r   r     s&    


	r   c                       sF   e Zd ZdZd fdd	Zdd Zedd Zd	d
 Zdd Z	  Z
S )rj   zk
    namespaces used in objects like Selector as long as they are not connected
    to a CSSStyleSheet
    Nc                    s   t  jd|d t| | _dS )initN)r   rh   )superr/   dict_SimpleNamespaces__namespaces)r   rh   r   r   r   r   r/   d  s   z_SimpleNamespaces.__init__c                 C   s   || j |< d S r+   r+  )r   r   r  r   r   r   r[   i  r6   z_SimpleNamespaces.__setitem__c                 C   r:   )z.Dict Wrapper for self.sheets @namespace rules.r-  r   r   r   r   r   l  r=   z_SimpleNamespaces.namespacesc                 C   s$   d| j j d| jdt| ddS )Nr'  z object namespaces=r   r   r   )r   r!   r   r   r   r   r   r   r   q  s   $z_SimpleNamespaces.__str__c                 C   s   d| j j d| jdS )Nzcssutils.util.r   r   )r   r!   r   r   r   r   r   r   t  s   z_SimpleNamespaces.__repr__r+   )r!   r"   r#   r$   r/   r[   r?   r   r   r   __classcell__r   r   r,  r   rj   ^  s    
rj   c              
   C   s>  d}|st }|| }|rt|dkr|d dur|\}}|r#d}|}n-|r*d}|}n&t|tr7t|\}	}
nt|\}	}
|
rEd}|	}n|rLd}|}nd}d}t|trX|}n@z$ztdd ||d	d }W n t	yz   |
|ru|nd}Y nw W n ty } ztj|d
d d}W Y d}~nd}~ww |||fS dS )a1  
    Read cssText from url and decode it using all relevant methods (HTTP
    header, BOM, @charset). Returns

    - encoding used to decode text (which is needed to set encoding of
      stylesheet properly)
    - type of encoding (how it was retrieved, see list below)
    - decodedCssText

    ``fetcher``
        see cssutils.CSSParser.setFetcher for details
    ``overrideEncoding``
        If given this encoding is used and all other encoding information is
        ignored (HTTP, BOM etc)
    ``parentEncoding``
        Encoding of parent stylesheet (while e.g. reading @import references
        sheets) or document if available.

    Priority or encoding information
    --------------------------------
    **cssutils only**: 0. overrideEncoding

    1. An HTTP "charset" parameter in a "Content-Type" field (or similar
       parameters in other protocols)
    2. BOM and/or @charset (see below)
    3. <link charset=""> or other metadata from the linking mechanism (if any)
    4. charset of referring style sheet or document (if any)
    5. Assume UTF-8

    Nr   r   r   r      zutf-8r   )encodingT)
neverraiser   )r
   rS   r   r   r   detectencoding_unicodedetectencoding_strcodecslookuprt   decodeUnicodeDecodeErrorrh   warn)urlfetcheroverrideEncodingparentEncodingenctyper  httpEncodingcontentr0  contentEncodingexplicitdecodedCssTexter   r   r   _readUrlx  sV   !


rD  c                   @   sv   e Zd ZdZdZdddZdd Zdd	d
ZdddZdddZ	dddZ
dddZdddZdddZdddZdS )	LazyRegexa  A class to represent a lazily compiled regular expression.

    The interface is kept similar to a `re.compile`ed object from the standard
    regex library.

    :ivar pattern: The original regular expression.
    :ivar flags: Flags of the regular expression.
    :ivar matcher: The compiled regular expression, or None if it is not yet
                   compiled.
    :ivar groups: The number of capturing groups in the pattern, or None.
    :ivar groupindex: A dictionary mapping any symbolic group names defined by
                      `(?P<id>)` to group numbers. The dictionary is empty if
                      no symbolic groups were used in the pattern. None if the
                      pattern is not yet compiled.
    )patternflagsmatchergroups
groupindexr   c                 C   s"   || _ d | _|| _d | _d | _d S r+   )rF  rH  rG  rI  rJ  )r   rF  rG  r   r   r   r/     s
   
zLazyRegex.__init__c                 C   sB   | j durdS t| j| j| _ | j j| _| j j| _| j j| _dS )zzMake sure that the expression is compiled.

        If self.matcher is already a compiled expression, do nothing.
        N)rH  recompilerF  rG  rI  rJ  r   r   r   r   ensure  s   


zLazyRegex.ensureNc                 C   s   |  |||S )z Shortcut for self.match(string).)matchr   stringposendposr   r   r   __call__  s   zLazyRegex.__call__c                 C   4   |    |du r
d}|du rt|}| j|||S )zzAttempt to do a match of the regular expression.

        This is similar to the `.match` method of `re` objects.
        Nr   )rM  rS   rH  rN  rO  r   r   r   rN       zLazyRegex.matchc                 C   rT  )zmSearch the string for the pattern.

        This is similar to the `.search` method of `re` objects.
        Nr   )rM  rS   rH  searchrO  r   r   r   rV    rU  zLazyRegex.searchc                 C   s   |    | j||S )zjSplit the string at the pattern.

        This is similar to the `.split` method of `re` objects.
        )rM  rH  split)r   rP  maxsplitr   r   r   rW    s   zLazyRegex.splitc                 C   rT  )zFind all instances of the pattern in the given string.

        This is similar to the `.findall` method of `re` objects.
        Nr   )rM  rS   rH  findallrO  r   r   r   rY    rU  zLazyRegex.findallc                 C   rT  )zFind all instances of the pattern in the given string.

        Returns an iterator.

        This is similar to the `.finditer` method of `re` objects.
        Nr   )rM  rS   rH  finditerrO  r   r   r   rZ  (  s   zLazyRegex.finditerc                 C      |    | j|||S )zReplace all occurences of the pattern with the given replacement.

        This is similar to the `.sub` method of `re` objects.
        )rM  rH  subr   replrP  countr   r   r   r\  6     zLazyRegex.subc                 C   r[  )zReplace all occurences of the pattern with the given replacement.

        This is similar to the `.subn` method of `re` objects.
        )rM  rH  subnr]  r   r   r   ra  >  r`  zLazyRegex.subn)r   r   )r!   r"   r#   r$   	__slots__r/   rM  rS  rN  rV  rW  rY  rZ  r\  ra  r   r   r   r   rE    s    







rE  r   )$r$   __all__r4  r  rK  xml.domr   	itertoolsr   more_itertoolsr   r   r   r   r   r   helperr	   	_fetchgaer
   ImportError_fetchr%   rh   r   r)   rA   r`   r   r-   r   r   r   rj   rD  rE  r   r   r   r   <module>   s@    2  iEi/u
Z