a
    xd                     @   s  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
 ddlmZ dd	lmZ dd
lmZ ddlZddlZddlZddlZeefZdd Zdd Ze Zdd ZdddZdd ZG dd deZ e  Z![ G dd deZ"G dd de#Z$ee$ dS )   )JQueryTranslator    )OrderedDict)	urlencode)urljoin)
url_opener)extract_textdeepcopy)escape)etreeNc                 C   s   t | j }dd |D S )Nc                 S   s   g | ]}|j |jkr|jqS  )kindPOSITIONAL_OR_KEYWORDname.0pr   r   G/var/www/html/Ranjet/env/lib/python3.9/site-packages/pyquery/pyquery.py
<listcomp>   s   zgetargspec.<locals>.<listcomp>)inspect	signature
parametersvaluesfuncargsr   r   r   
getargspec   s    r   c                 C   s   t | j | S )z4decorator for methods who required a camelcase alias)_camel_case_aliasesadd__name__r   r   r   r   with_camel_case_alias   s    r"   c                 C   s   t D ]v}t|d}|d ddd |dd D  }t| |}t|j|j||j	}d|j
 |_t| ||d|  qdS )	z add camelcase aliases to PyQuery_r    c                 S   s   g | ]}|  qS r   )titler   r   r   r   r   (       z,build_camel_case_aliases.<locals>.<listcomp>r   Nz-Alias for :func:`~pyquery.pyquery.PyQuery.%s`)r   listsplitjoingetattrtypesFunctionType__code____globals____defaults__r    __doc__setattr__get__)PyQueryaliaspartsr   r   fr   r   r   build_camel_case_aliases$   s    $
r7   c                 C   sr  t | drt | jdrd}nd}|du r(|du rztt|| }W n8 tjy|   t | drh| d ttj|| }Y n0 t|tj	r|
 gS |gS n|dkrtt|}nx|d	krttj|}nb|d
krddlm} t||}nB|dkrddlm} t||}n |dkrtjj}ntd| || }t|tu rB|S t|tj	rZ|
 gS |durj|gS g S dS )z/use html parser if we don't have clean xml
    read__call__parse
fromstringNseekr   xmlhtmlhtml5)html5parserZsoup)
soupparserZhtml_fragmentszNo such parser: "%s")hasattrr8   r*   r   ZXMLSyntaxErrorr<   lxmlr>   
isinstanceZ_ElementTreegetroot	lxml.htmlr@   rA   Zfragments_fromstring
ValueErrortyper'   )contextparserZcustom_parsermethresultr@   rA   r   r   r   r;   1   sF    








r;   c                 G   s   | |d | j j  S N)r-   co_argcountr   r   r   r   callback^   s    rO   c                   @   s   e Zd Zdd ZdS )	NoDefaultc                 C   s   dS )zclean representation in Sphinxz<NoDefault>r   selfr   r   r   __repr__c   s    zNoDefault.__repr__N)r    
__module____qualname__rS   r   r   r   r   rP   b   s   rP   c                   @   s.   e Zd ZdZeefddZdd Zdd ZdS )	FlexibleElementz property to allow a flexible apic                 C   s   || _ || _|| _d S rM   )pgetpsetpdel)rR   rW   rX   rY   r   r   r   __init__n   s    zFlexibleElement.__init__c                    s   G  fdddt }| S )Nc                       sL   e Zd ZdZ fddZe Z Z ZZ fddZ	e	Z
fddZdS )	z)FlexibleElement.__get__.<locals>._elementzOreal element to support set/get/del attr and item and js call
            stylec                    s   j  g|R i |S rM   )rW   )propr   kwargsinstancerR   r   r   r9   w   s    z2FlexibleElement.__get__.<locals>._element.__call__c                    s    j tur  |S t d S rM   )rY   
no_defaultNotImplementedError)r[   r   r]   r   r   __delitem__{   s    
z5FlexibleElement.__get__.<locals>._element.__delitem__c                    s   d j j S )Nz<flexible_element %s>)rW   r    )r[   rQ   r   r   rS      s    z2FlexibleElement.__get__.<locals>._element.__repr__N)r    rT   rU   r0   r9   __getattr____getitem____setattr____setitem__ra   __delattr__rS   r   r]   r   r   _elementt   s   rg   )object)rR   r^   klassrg   r   r]   r   r2   s   s    zFlexibleElement.__get__c                 C   s"   | j tur|  || nt d S rM   )rX   r_   r`   )rR   r^   valuer   r   r   __set__   s    
zFlexibleElement.__set__N)r    rT   rU   r0   r_   rZ   r2   rk   r   r   r   r   rV   l   s   rV   c                   @   sP  e Zd ZdZeZdd ZdddZdd Zd	d
 Z	e
jZe
jZdd Zdd ZdddZdd Zdd Zdd Zdd Zdd Zdd Zedd Zed d! Zdd#d$Zdd%d&Zdd'd(Zdd)d*Zd+d, Zd-d. Zd/d0 Z e!dd1d2Z"e!dd3d4Z#d5d6 Z$e!dd7d8Z%dd9d:Z&dd;d<Z'dd=d>Z(dd?d@Z)dAdB Z*dCdD Z+dEdF Z,dGdH Z-dIdJ Z.dKdL Z/dMdN Z0dOdP Z1edQdR Z2dSdT Z3dUdV Z4dWdX Z5e!dYdZ Z6e7e5e6d[Z5e8fd\d]Z9e8fd^d_Z:e!d`da Z;e!dbdc Z<e!ddde Z=e!dfdg Z>dhdi Z?e7e?e?djZ?dkdl Z@dmdn ZAe8fdodpZBe8fdqdrZCe!ddtduZDe8fdvdwZEdxdy ZFdzd{ Ze!d|d} ZGd~d ZHe!dd ZIdd ZJe!dd ZKdd ZLe!dd ZMdd ZNe!dd ZOe!dd ZPe!dd ZQdd ZRdd ZSe8fddZTG dd deUZVeV ZWe!dd ZXdd ZYe!dd ZZe!dd Z[edd Z\dddZ]dS )r3   zThe main class
    c                 O   sx  d }g }d | _ |dd | _d|v r2|d| _nt| _d|v rN|d| _n>| jdv rh| jdd| _n$| jtur~| jj| _n| jdd| _|dd | _|rbd	|v rt|d	 |	d
d}ndd|v r|d}d|v r|d}||fi |}n
t
||}| jsd| _|| _ ntd| t|| j}t|drhz|  W n ty\   Y n0 nt }}t|}	|	dkr|d }n|	dkr|\}}ntdt|trzt|| j}W n ty    Y n0 nLt|| jr|d d  }n0t|tr|}nt|tjr|g}nt||rh|turh| |}
g }|D ]}||j|
| jd qF|}t| | d S )NrJ   parentZcss_translator)r=   T)ZxhtmlF
namespacesfilenameencodingro   urlopenerr>   zInvalid keyword arguments %scloser   r      z,You can't do that. Please, provide argumentsrm   )	_base_urlpoprJ   _parentr_   _translator_translator_classrm   opengetr   rG   r;   rB   rs   	ExceptionlenrD   
basestring	__class__r'   r   _Element	TypeError_css_to_xpathextendxpathrZ   )rR   r   r\   r>   elementsrq   rr   selectorrI   lengthr   resultstagr   r   r   rZ      s    












zPyQuery.__init__descendant-or-self::c                 C   s   | dd}| j||S )Nz[@[)replacery   Zcss_to_xpath)rR   r   prefixr   r   r   r      s    zPyQuery._css_to_xpathc                 O   s   | d| j | j|i |S )Nrm   )
setdefaultrm   r   rR   r   r\   r   r   r   _copy   s    zPyQuery._copyc                 O   sx   t |}|dkrtd|d dkr.| g S t |dkr`t|d tr`|d ds`|| f7 }| j|d| i|}|S )z&return a new PyQuery instance
        r   z$You must provide at least a selectorr$   r   <rl   )r~   rG   r   rD   str
startswith)rR   r   r\   r   rL   r   r   r   r9      s    

zPyQuery.__call__c                 C   s.   t || jsJ | | d d  |d d   S rM   )rD   r   r   rR   otherr   r   r   __add__  s    zPyQuery.__add__c                 C   s&   t || jsJ | |dd  | S )z"Extend with another PyQuery objectN)rD   r   _extendr   r   r   r   r     s    zPyQuery.extendNc                 c   s4   |r| |pg }n| }|D ]}| j || dV  qdS )al  Iter over elements. Return PyQuery objects:

            >>> d = PyQuery('<div><span>foo</span><span>bar</span></div>')
            >>> [i.text() for i in d.items('span')]
            ['foo', 'bar']
            >>> [i.text() for i in d('span').items()]
            ['foo', 'bar']
            >>> list(d.items('a')) == list(d('a').items())
            True
        rl   N)r   )rR   r   elemselemr   r   r   items  s
    zPyQuery.itemsc                 C   s4   z| d   }W n ty"   Y n0 tj| | S )a  Remove xhtml namespace:

            >>> doc = PyQuery(
            ...         '<html xmlns="http://www.w3.org/1999/xhtml"></html>')
            >>> doc
            [<{http://www.w3.org/1999/xhtml}html>]
            >>> doc.xhtml_to_html()
            [<html>]
        r   )getroottree
IndexErrorrC   r>   xhtml_to_htmlrR   rootr   r   r   r   $  s    
zPyQuery.xhtml_to_htmlc                 C   sX   z| d   }W n ty"   Y n20 |dD ]$}|jdr.|jddd |_q.| S )zRemove all namespaces:

            >>> doc = PyQuery('<foo xmlns="http://example.com/foo"></foo>')
            >>> doc
            [<{http://example.com/foo}foo>]
            >>> doc.remove_namespaces()
            [<foo>]
        r   z{*}*{}r   )r   r   iterr   r   r(   )rR   r   elr   r   r   remove_namespaces6  s    	zPyQuery.remove_namespacesc                 C   s   d dd | D S )zxml representation of current nodes::

            >>> xml = PyQuery(
            ...   '<script><![[CDATA[ ]></script>', parser='html_fragments')
            >>> print(str(xml))
            <script>&lt;![[CDATA[ ]&gt;</script>

        r$   c                 S   s   g | ]}t j|td qS rp   r   tostringr   r   er   r   r   r   R  r&   z#PyQuery.__str__.<locals>.<listcomp>r)   rQ   r   r   r   __str__I  s    	zPyQuery.__str__c                 C   s   d dd | D S )z#xml representation of current nodesr$   c                 S   s   g | ]}t j|td qS r   r   r   r   r   r   r   V  s   z'PyQuery.__unicode__.<locals>.<listcomp>r   rQ   r   r   r   __unicode__T  s    
zPyQuery.__unicode__c                 C   s   d dd | D S )zhtml representation of current nodes::

            >>> html = PyQuery(
            ...   '<script><![[CDATA[ ]></script>', parser='html_fragments')
            >>> print(html.__html__())
            <script><![[CDATA[ ]></script>

        r$   c                 S   s   g | ]}t jj|td qS r   )rC   r>   r   r   r   r   r   r   r   b  s   z$PyQuery.__html__.<locals>.<listcomp>r   rQ   r   r   r   __html__Y  s    	
zPyQuery.__html__c                 C   s   g }zt| D ]Z}| d}|r0dd|d p2d}| d}|rJd| pLd}|d|j||f  q
dd	| d
 W S  ty   t|  Y S 0 d S )Nclass. r$   id#z<%s%s%s>r   z, ])r|   r)   r(   appendr   AttributeErrorr'   rS   )rR   rr   cr   r   r   r   rS   e  s    

zPyQuery.__repr__c                 C   s$   | j tur| j d  S | d  S )z$return the xml root element
        r   )rx   r_   r   rQ   r   r   r   r   r  s    
zPyQuery.rootc                 C   s   | j }|dur| j jjS dS )z4return the xml encoding of the root element
        N)r   Zdocinforo   r   r   r   r   ro   z  s    zPyQuery.encodingFc           
      C   s   |du r|}n0|  |d}g }|D ]}||j|| jd q"|rJ|  |rr|}g }|D ]}	|	|vrZ||	 qZ| j|| dS )z]Filters the selection set only, as opposed to also including
           descendants.
        Nzself::ru   r   )r   r   r   rm   reverser   r   )
rR   r   r   r   uniquer   r   r   Zresult_listitemr   r   r   _filter_only  s    zPyQuery._filter_onlyc                 C   s   | j |dd | D ddS )Nc                 S   s    g | ]}|  d ur|  qS rM   )	getparentr   r   r   r   r     r&   z"PyQuery.parent.<locals>.<listcomp>Tr   r   rR   r   r   r   r   rl     s
    zPyQuery.parentc                 C   s   |  |dd | D S )Nc                 S   s    g | ]}|  d ur|  qS rM   )getpreviousr   r   r   r   r     r&   z PyQuery.prev.<locals>.<listcomp>r   r   r   r   r   prev  s    zPyQuery.prevc                 C   s   |  |dd | D S )Nc                 S   s    g | ]}|  d ur|  qS rM   )getnextr   r   r   r   r     r&   z PyQuery.next.<locals>.<listcomp>r   r   r   r   r   next  s    zPyQuery.nextc                 c   s6   | D ],}t || }|d ur|V  t || }qqd S rM   )r*   )rR   methodr   currentr   r   r   	_traverse  s
    zPyQuery._traversec                 c   sN   | D ]D}g }|  }|d ur0|| |  }q|  |D ]
}|V  q<qd S rM   )r   r   r   )rR   r   Z	this_listr   jr   r   r   _traverse_parent_topdown  s    

z PyQuery._traverse_parent_topdownc                 C   s   dd |  dD S )Nc                 S   s   g | ]}|qS r   r   r   r   r   r   r     r&   z%PyQuery._next_all.<locals>.<listcomp>r   r   rQ   r   r   r   	_next_all  s    zPyQuery._next_allc                 C   s   |  ||  S )z
        >>> h = '<span><p class="hello">Hi</p><p>Bye</p><img scr=""/></span>'
        >>> d = PyQuery(h)
        >>> d('p:last').next_all()
        [<img>]
        >>> d('p:last').nextAll()
        [<img>]
        )r   r   r   r   r   r   next_all  s    
zPyQuery.next_allc              	      s.   |  |dd t fdd|   D S )z
        >>> h = '''
        ... <h2>Greeting 1</h2>
        ... <p>Hello!</p><p>World!</p>
        ... <h2>Greeting 2</h2><p>Bye!</p>
        ... '''
        >>> d = PyQuery(h)
        >>> d('h2:first').nextUntil('h2')
        [<p>, <p>]
        c                 S   s   g | ]}|D ]}|qqS r   r   )r   qr   r   r   r   r     s   z&PyQuery.next_until.<locals>.<listcomp>c                    s   |    S rM   is_)r   r   r   r   <lambda>  r&   z$PyQuery.next_until.<locals>.<lambda>)r   	itertools	takewhiler   r   )rR   r   Zfilter_r   r   r   
next_until  s    zPyQuery.next_untilc                 C   s   dd |  dD S )Nc                 S   s   g | ]}|qS r   r   r   r   r   r   r     r&   z%PyQuery._prev_all.<locals>.<listcomp>r   r   rQ   r   r   r   	_prev_all  s    zPyQuery._prev_allc                 C   s   | j ||  ddS )z
        >>> h = '<span><p class="hello">Hi</p><p>Bye</p><img scr=""/></span>'
        >>> d = PyQuery(h)
        >>> d('p:last').prev_all()
        [<p.hello>]
        >>> d('p:last').prevAll()
        [<p.hello>]
        T)r   )r   r   r   r   r   r   prev_all  s    
zPyQuery.prev_allc                 C   s   |  ||  |   S )z
         >>> h = '<span><p class="hello">Hi</p><p>Bye</p><img scr=""/></span>'
         >>> d = PyQuery(h)
         >>> d('.hello').siblings()
         [<p>, <img>]
         >>> d('.hello').siblings('img')
         [<img>]

        )r   r   r   r   r   r   r   siblings  s    
zPyQuery.siblingsc                 C   s   | j |dd |  D ddS )z
        >>> d = PyQuery('<span><p class="hello">Hi</p><p>Bye</p></span>')
        >>> d('p').parents()
        [<span>]
        >>> d('.hello').parents('span')
        [<span>]
        >>> d('.hello').parents('p')
        []
        c                 S   s   g | ]}|qS r   r   r   r   r   r   r     r&   z#PyQuery.parents.<locals>.<listcomp>Tr   )r   r   r   r   r   r   parents  s
    
zPyQuery.parentsc                 C   s   dd | D }|  ||S )aG  Filter elements that are direct children of self using optional
        selector:

            >>> d = PyQuery('<span><p class="hello">Hi</p><p>Bye</p></span>')
            >>> d
            [<span>]
            >>> d.children()
            [<p.hello>, <p>]
            >>> d.children('.hello')
            [<p.hello>]
        c                 S   s   g | ]}|  D ]}|qqS r   )getchildrenr   r   childr   r   r   r     r&   z$PyQuery.children.<locals>.<listcomp>r   )rR   r   r   r   r   r   children  s    zPyQuery.childrenc                 C   sP   g }| D ]8}|dur.|  ||s.| }q|dur|| q| j || dS )aC  
        >>> d = PyQuery(
        ...  '<div class="hello"><p>This is a '
        ...  '<strong class="hello">test</strong></p></div>')
        >>> d('strong').closest('div')
        [<div.hello>]
        >>> d('strong').closest('.hello')
        [<strong.hello>]
        >>> d('strong').closest('form')
        []
        Nr   )r   r   r   r   )rR   r   rL   r   r   r   r   closest  s    
zPyQuery.closestc                 C   s2   g }| D ]}| |jd| jd q| j|| dS )z
        Return contents (with text nodes):

            >>> d = PyQuery('hello <b>bold</b>')
            >>> d.contents()  # doctest: +ELLIPSIS
            ['hello ', <Element b at ...>]
        zchild::text()|child::*ru   r   )r   r   rm   r   )rR   r   r   r   r   r   contents0  s    

zPyQuery.contentsc                 C   s   t |ds| || S g }tt}zVt| D ]4\}}t|dkrJ||jd< t|||r,|| q,W |j}d|v r|d= n|j}d|v r|d= 0 | j|| dS dS )a  Filter elements in self using selector (string or function):

            >>> d = PyQuery('<p class="hello">Hi</p><p>Bye</p>')
            >>> d('p')
            [<p.hello>, <p>]
            >>> d('p').filter('.hello')
            [<p.hello>]
            >>> d('p').filter(lambda i: i == 1)
            [<p>]
            >>> d('p').filter(lambda i: PyQuery(this).text() == 'Hi')
            [<p.hello>]
            >>> d('p').filter(lambda i, this: PyQuery(this).text() == 'Hi')
            [<p.hello>]
        r9   r   thisr   N)	rB   r   r   rO   	enumerater~   r.   r   r   )rR   r   r   r   ir   	f_globalsr   r   r   filter>  s"    

zPyQuery.filterc                    s,   t | ||  | j fdd| D | dS )zReturn elements that don't match the given selector:

            >>> d = PyQuery('<p class="hello">Hi</p><p>Bye</p><div></div>')
            >>> d('p').not_('.hello')
            [<p>]
        c                    s   g | ]}| vr|qS r   r   r   excluder   r   r   f  r&   z PyQuery.not_.<locals>.<listcomp>r   )setr   r   r   r   r   not_^  s    zPyQuery.not_c                 C   s   t | || S )al  Returns True if selector matches at least one current element, else
        False:

            >>> d = PyQuery('<p class="hello"><span>Hi</span></p><p>Bye</p>')
            >>> d('p').eq(0).is_('.hello')
            True

            >>> d('p').eq(0).is_('span')
            False

            >>> d('p').eq(1).is_('.hello')
            False

        ..
        )boolr   r   r   r   r   r   i  s    zPyQuery.is_c                    sD     | fdd D }g }|D ]}|| q& j| dS )a&  Find elements using selector traversing down from self:

            >>> m = '<p><span><em>Whoah!</em></span></p><p><em> there</em></p>'
            >>> d = PyQuery(m)
            >>> d('p').find('em')
            [<em>, <em>]
            >>> d('p').eq(1).find('em')
            [<em>]
        c                    s*   g | ]"}|  D ]}|j jd qqS )ru   )r   r   rm   r   rR   r   r   r   r     s   z PyQuery.find.<locals>.<listcomp>r   )r   r   r   )rR   r   r   r   r   r   r   r   find{  s    

zPyQuery.findc                 C   s2   z| | }W n t y"   g }Y n0 | j|| dS )a.  Return PyQuery of only the element with the provided index::

            >>> d = PyQuery('<p class="hello">Hi</p><p>Bye</p><div></div>')
            >>> d('p').eq(0)
            [<p.hello>]
            >>> d('p').eq(1)
            [<p>]
            >>> d('p').eq(2)
            []

        ..
        r   )r   r   )rR   indexr   r   r   r   eq  s
    
z
PyQuery.eqc                 C   sd   zHt | D ]&\}}||jd< t|||du r
 q2q
W |j}d|v r`|d= n|j}d|v r^|d= 0 | S )z!apply func on each nodes
        r   F)r   r.   rO   )rR   r   r   elementr   r   r   r   each  s    
zPyQuery.eachc                 C   s   g }zht | D ]F\}}||jd< t|||}|durt|tsJ|| q|| qW |j}d|v r|d= n|j}d|v r|d= 0 | j|| dS )a;  Returns a new PyQuery after transforming current items with func.

        func should take two arguments - 'index' and 'element'.  Elements can
        also be referred to as 'this' inside of func::

            >>> d = PyQuery('<p class="hello">Hi there</p><p>Bye</p><br />')
            >>> d('p').map(lambda i, e: PyQuery(e).text())
            ['Hi there', 'Bye']

            >>> d('p').map(lambda i, e: len(PyQuery(this).text()))
            [8, 3]

            >>> d('p').map(lambda i, e: PyQuery(this).text().split())
            ['Hi', 'there', 'Bye']

        r   Nr   )r   r.   rO   rD   r'   r   r   r   )rR   r   r   r   r   rL   r   r   r   r   map  s     

zPyQuery.mapc                 C   s   t | S rM   r~   rQ   r   r   r   r     s    zPyQuery.lengthc                 C   s   t | S rM   r   rQ   r   r   r   size  s    zPyQuery.sizec                 C   s   | j S )a  Break out of a level of traversal and return to the parent level.

            >>> m = '<p><span><em>Whoah!</em></span></p><p><em> there</em></p>'
            >>> d = PyQuery(m)
            >>> d('p').eq(1).find('em').end().end()
            [<p>, <p>]
        )rx   rQ   r   r   r   end  s    zPyQuery.endc                 O   s  ddd}t  }}t|}|dkr8|d }|||}nZ|dkrV|\}}|||}n<|ri }| D ]\}}|||||< qfntd||f | sdS t|tr| D ]"}	| D ]\}
}|	|
| qqn@|t u r| d |S |du r| |S | D ]}	|	||  q| S )	z Attributes manipulation
        r   for)class_Zfor_r   r   rt   Invalid arguments %s %sN)	r_   r~   r|   r   rG   rD   dictr   remove_attr)rR   r   r\   mappingattrrj   r   kvr   keyr   r   r   r     s6    


zPyQuery.attrc              	   C   s.   | D ]$}z|j |= W q ty&   Y q0 q| S )zRemove an attribute::

            >>> d = PyQuery('<div id="myid"></div>')
            >>> d.remove_attr('id')
            [<div>]
            >>> d.removeAttr('id')
            [<div>]

        ..
        )attribKeyError)rR   r   r   r   r   r   r     s    zPyQuery.remove_attr)rW   rY   c                 C   s   |  d|S )z"set/get height of element
        heightr   rR   rj   r   r   r   r   #  s    zPyQuery.heightc                 C   s   |  d|S )z!set/get width of element
        widthr  r  r   r   r   r  (  s    zPyQuery.widthc                 C   s   |  d| S )zReturn True if element has class::

            >>> d = PyQuery('<div class="myclass"></div>')
            >>> d.has_class('myclass')
            True
            >>> d.hasClass('myclass')
            True

        ..
        z.%sr   )rR   r   r   r   r   	has_class-  s    zPyQuery.has_classc                    sR   | D ]H}| d}|dpd     fdd|D 7  |dd  q| S )zAdd a css class to elements::

            >>> d = PyQuery('<div></div>')
            >>> d.add_class('myclass')
            [<div.myclass>]
            >>> d.addClass('myclass')
            [<div.myclass>]

        ..
        r   r   r$   c                    s   g | ]}| vr|qS r   r   r   r   classesr   r   r   J  r&   z%PyQuery.add_class.<locals>.<listcomp>r(   r|   r   r)   )rR   rj   r   r   r   r  r   	add_class;  s    
zPyQuery.add_classc                 C   sz   | D ]p}| d}t|dp d  }|| |dg d|}| r^|d| q|dr|d| q| S )zRemove a css class to elements::

            >>> d = PyQuery('<div class="myclass"></div>')
            >>> d.remove_class('myclass')
            [<div>]
            >>> d.removeClass('myclass')
            [<div>]

        ..
        r   r   r$   )r(   r   r|   difference_updater)   strip)rR   rj   r   r   r  r   r   r   remove_classN  s    



zPyQuery.remove_classc                    sz   | D ]p}| d}|dpd    fdd|D } fdd|D fdd D   |7  |dd  q| S )zToggle a css class to elements

            >>> d = PyQuery('<div></div>')
            >>> d.toggle_class('myclass')
            [<div.myclass>]
            >>> d.toggleClass('myclass')
            [<div>]

        r   r   r$   c                    s   g | ]}| vr|qS r   r   r  r  r   r   r   t  r&   z(PyQuery.toggle_class.<locals>.<listcomp>c                    s   g | ]}| v r|qS r   r   r  r  r   r   r   u  r&   c                    s   g | ]}| vr|qS r   r   r  )values_to_delr   r   r   v  r&   r  )rR   rj   r   r   Zvalues_to_addr   )r  r  r   toggle_classf  s    
zPyQuery.toggle_classc                    sH  t   }t|}|dkr"|d  n,|dkr4|\ }n|r>| ntd||f t tr| D ]z}dd   D fdd|dpd	d
D }  D ]&\}}|	dd}|
d||f  q|dd| q\njt|trD 	dd | D ]L} fdd|dpd	d
D }|
d |f  |dd| q| S )z$css attributes manipulation
        r   r   rt   r   c                 S   s   g | ]}|  d dqS )r#   -)r  r   )r   r   r   r   r   r     s   zPyQuery.css.<locals>.<listcomp>c                    s2   g | ]*}|  r|d d    vr|  qS :r   r  r(   r   r   )stripped_keysr   r   r     s   styler$   ;r#   r  z%s: %sz; c                    s6   g | ].}|  r|d d      ks|  qS r  r  r  r  r   r   r     s   )r_   r~   rG   rD   r   keysr|   r(   r   r   r   r   r)   r   )rR   r   r\   rj   r   r   r   r   r   )r   r  r   css{  s<    




zPyQuery.css)rW   rX   c                 C   s   |  ddS )zAdd display:none to elements style:

            >>> print(PyQuery('<div style="display:none;"/>').hide())
            <div style="display: none"/>

        displaynoner  rQ   r   r   r   hide  s    zPyQuery.hidec                 C   s   |  ddS )zAdd display:block to elements style:

            >>> print(PyQuery('<div />').show())
            <div style="display: block"/>

        r  blockr  rQ   r   r   r   show  s    zPyQuery.showc                    sH    fdd} fdd}|t u r6t rD| d S n| |  S dS )a  Set the attribute value::

            >>> d = PyQuery('<input />')
            >>> d.val('Youhou')
            [<input>]

        Get the attribute value::

            >>> d.val()
            'Youhou'

        Set the selected values for a `select` element with the `multiple`
        attribute::

            >>> d = PyQuery('''
            ...             <select multiple>
            ...                 <option value="you"><option value="hou">
            ...             </select>
            ...             ''')
            >>> d.val(['you', 'hou'])
            [<select>]

        Get the selected values for a `select` element with the `multiple`
        attribute::

            >>> d.val()
            ['you', 'hou']

        c                    s   | j dkr |  S | j dkrd| jv rP | d}t| fddS  | d}|rl|dS  | d	dS nZ d
r | d}|d u rdS |S n.| j dkr܈ | d}|r|ddS dS  | dpdS )Ntextareaselectmultiplezoption[selected]c                    s     |dS )Nrj   )r   r   )r#   orQ   r   r   r     r&   z1PyQuery.val.<locals>._get_value.<locals>.<lambda>zoption[selected]:lastrj   optionz:checkbox,:radiooninput
r$   )	r   r   r>   r   r'   r   r   r   r   )r   selectedZselected_optionvalrQ   r   r   
_get_value  s*    






zPyQuery.val.<locals>._get_valuec                    s   | D ]  j dkrHtts"g fdd} d| qttr\d j dkrx  q d qd S )Nr   c                    sH     |}|dv r:|dd djvrDd d = n
|d d S )Nrj   r'  r!  )r   r   r   Z
removeAttr)r#   r   pq)rR   r   rj   r   r   _make_option_selected  s    

z>PyQuery.val.<locals>._set_value.<locals>._make_option_selectedr#  ,r  rj   )r   rD   r'   r   r   r)   textr   )r*  rj   r+  rQ   )r   rj   r   
_set_value  s    

	


zPyQuery.val.<locals>._set_valuer   N)r_   r~   )rR   rj   r)  r.  r   rQ   r   r(    s     
zPyQuery.valc           	         s  |t u rj| sdS | d }| }t|jp*ddd}|s:|S d vrJt d< |d fdd|D 7 }|S t|| jrt|}n&t|tr|}n|sd}nt	t
|| D ]R}| D ]}|| qtd	| d
 | jd }| }|r|| |j|_q| S )ak  Get or set the html representation of sub nodes.

        Get the text value::

            >>> d = PyQuery('<div><span>toto</span></div>')
            >>> print(d.html())
            <span>toto</span>

        Extra args are passed to ``lxml.etree.tostring``::

            >>> d = PyQuery('<div><span></span></div>')
            >>> print(d.html())
            <span/>
            >>> print(d.html(method='html'))
            <span></span>

        Set the text value::

            >>> d.html('<span>Youhou !</span>')
            [<div>]
            >>> print(d)
            <div><span>Youhou !</span></div>
        Nr   r$   F)quotero   c                    s   g | ]}t j|fi  qS r   )r   r   r   r\   r   r   r   ?  s   z PyQuery.html.<locals>.<listcomp><root></root>)r_   r   r   r-  r   r)   rD   r   r   rG   rH   remover;   rJ   r   )	rR   rj   r\   r   r   r>   Znew_htmlr   r   r   r0  r   r>     sF    





zPyQuery.htmlr>   c                 C   s4   | sdS | d }|j r$t|}d|_ tj|t|dS )a  Get the html representation of the first selected element::

            >>> d = PyQuery('<div><span class="red">toto</span> rocks</div>')
            >>> print(d('span'))
            <span class="red">toto</span> rocks
            >>> print(d('span').outer_html())
            <span class="red">toto</span>
            >>> print(d('span').outerHtml())
            <span class="red">toto</span>

            >>> S = PyQuery('<p>Only <b>me</b> & myself</p>')
            >>> print(S('b').outer_html())
            <b>me</b>

        ..
        Nr   r$   )ro   r   )tailr
   r   r   r   )rR   r   Ze0r   r   r   
outer_htmlX  s    zPyQuery.outer_htmlc                    sV   |t u r*sdS d fddD S D ]"}| D ]}|| q:||_q.S )a  Get or set the text representation of sub nodes.

        Get the text value::

            >>> doc = PyQuery('<div><span>toto</span><span>tata</span></div>')
            >>> print(doc.text())
            tototata
            >>> doc = PyQuery('''<div><span>toto</span>
            ...               <span>tata</span></div>''')
            >>> print(doc.text())
            toto tata

        Get the text value, without squashing newlines::

            >>> doc = PyQuery('''<div><span>toto</span>
            ...               <span>tata</span></div>''')
            >>> print(doc.text(squash_space=False))
            toto
            tata

        Set the text value::

            >>> doc.text('Youhou !')
            [<div>]
            >>> print(doc)
            <div>Youhou !</div>

        r$   r   c                 3   s6   | ].}|j d kr| nt|fi  V  qdS )r  N)r   r   r>   r   r   r   r\   rR   r   r   	<genexpr>  s   zPyQuery.text.<locals>.<genexpr>)r_   r)   r   r3  r-  )rR   rj   r\   r   r   r   r7  r   r-  s  s    zPyQuery.textc                 C   s   t |tr$td| d | jd }n4t |tjr<| |}nt |trL|}ntd| t	|drvt |j
trv|j
}nd}||fS )Nr1  r2  r   z0Value must be string, PyQuery or Element. Got %rr-  r$   )rD   r   r;   rJ   r   r   r   r3   r   rB   r-  )rR   rj   r   	root_textr   r   r   	_get_root  s"    

zPyQuery._get_rootc                 C   s   |  |\}}t| D ]p\}}t|dkrN|d }|js>d|_| j|7  _n|jsZd|_| j|7  _|dkr|tt|}|| q| S )z#append value to each nodes
        r   r$   )r:  r   r~   r4  r-  r
   r'   r   )rR   rj   r   r9  r   r   Z
last_childr   r   r   r     s    zPyQuery.appendc                 C   s   | |  | S )zappend nodes to value
        )r   r  r   r   r   	append_to  s    
zPyQuery.append_toc                 C   s   |  |\}}t| D ]p\}}|js*d|_t|dkrJ|j|d _||_n||j |_|dkrjtt|}||dd< |dt| }q| S )zprepend value to nodes
        r$   r   r;  N)r:  r   r-  r~   r4  r
   r'   )rR   rj   r   r9  r   r   r   r   r   prepend  s    zPyQuery.prependc                 C   s   | |  | S )zprepend nodes to value
        )r=  r  r   r   r   
prepend_to  s    
zPyQuery.prepend_toc                 C   s   |  |\}}t| D ]h\}}|js*d|_| j|7  _|dkrLtt|}| }||d }||||< ||t| }q| S )zadd value after nodes
        r$   r   r   )r:  r   r4  r
   r'   r   r   r~   )rR   rj   r   r9  r   r   rl   r   r   r   r   after  s    zPyQuery.afterc                 C   s   | |  | S )z!insert nodes after value
        )r?  r  r   r   r   insert_after  s    
zPyQuery.insert_afterc           	      C   s   |  |\}}t| D ]\}}| }|durJ|js:d|_| j|7  _n"| }|js^d|_| j|7  _|dkrtt|}| }||}||||< ||t	| }q| S )z"insert value before nodes
        Nr$   r   )
r:  r   r   r4  r   r-  r
   r'   r   r~   )	rR   rj   r   r9  r   r   previousrl   r   r   r   r   before  s$    
zPyQuery.beforec                 C   s   | |  | S )z"insert nodes before value
        )rB  r  r   r   r   insert_before  s    
zPyQuery.insert_beforec           	      C   s   t |tsJ t|d }g }| D ]}t|}| sF|t| n(dd | D }|d }|t| || | }|dur"| D ]$}||u r|| |	|  q"qq"|| dd< | S )a  A string of HTML that will be created on the fly and wrapped around
        each target:

            >>> d = PyQuery('<span>youhou</span>')
            >>> d.wrap('<div></div>')
            [<div>]
            >>> print(d)
            <div><span>youhou</span></div>

        r   c                 S   s   g | ]}|qS r   r   r   r   r   r   r   r   0  r&   z PyQuery.wrap.<locals>.<listcomp>r;  N)
rD   r   r;   r
   r   r   iterchildrenr   Zaddnextr3  )	rR   rj   nodesr   wrapperchildsr   rl   tr   r   r   wrap  s(    


zPyQuery.wrapc                 C   s   | s| S t |tsJ t|d }t|}| s8|}ndd | D }|d }d}| d  }|du rnt}| D ]"}|t| | |urrd}qr|tur|rdd | D }t	|t	| kr| D ]}|
| q|| |g| dd< | S )	a  Wrap all the elements in the matched set into a single wrapper
        element::

            >>> d = PyQuery('<div><span>Hey</span><span>you !</span></div>')
            >>> print(d('span').wrap_all('<div id="wrapper"></div>'))
            <div id="wrapper"><span>Hey</span><span>you !</span></div>

            >>> d = PyQuery('<div><span>Hey</span><span>you !</span></div>')
            >>> print(d('span').wrapAll('<div id="wrapper"></div>'))
            <div id="wrapper"><span>Hey</span><span>you !</span></div>

        ..
        r   c                 S   s   g | ]}|qS r   r   rD  r   r   r   r   W  r&   z$PyQuery.wrap_all.<locals>.<listcomp>r;  TNFc                 S   s   g | ]}|qS r   r   rD  r   r   r   r   g  r&   )rD   r   r;   r
   r   rE  r   r_   r   r~   r3  )rR   rj   rG  r   rH  Zreplace_childsrl   r   r   r   r   wrap_all?  s2    
zPyQuery.wrap_allc                 C   s   t |trt|}t|drbt| D ]:\}}| |||||jpFd  | }|	| q$n6| D ]0}| |||jp~d  | }|	| qf| S )a$  replace nodes by value:

            >>> doc = PyQuery("<html><div /></html>")
            >>> node = PyQuery("<span />")
            >>> child = doc.find('div')
            >>> child.replace_with(node)
            [<div>]
            >>> print(doc)
            <html><span/></html>

        r9   r$   )
rD   r3   r   rB   r   r   rB  r4  r   r3  )rR   rj   r   r   rl   r   r   r   r   replace_withp  s    


zPyQuery.replace_withc                 C   s&   | j tu rtd|  ||  | S )zreplace nodes by expr
        z6replaceAll can only be used with an object with parent)rx   r_   rG   rL  )rR   exprr   r   r   replace_all  s    
zPyQuery.replace_allc                 C   s   t dd | D S )zreturn a copy of nodes
        c                 S   s   g | ]}t |qS r   r	   r6  r   r   r   r     r&   z!PyQuery.clone.<locals>.<listcomp>)r3   rQ   r   r   r   clone  s    zPyQuery.clonec                 C   s    | D ]}d|_ g |dd< q| S )zremove nodes content
        N)r-  )rR   r   r   r   r   empty  s    zPyQuery.emptyc                 C   s   |t u r~| D ]n}| }|dur|jrp| }|du rT|jsBd|_| j|j7  _n|js`d|_| j|j7  _|| qn| || }|  | S )a?  Remove nodes:

             >>> h = (
             ... '<div>Maybe <em>she</em> does <strong>NOT</strong> know</div>'
             ... )
             >>> d = PyQuery(h)
             >>> d('strong').remove()
             [<strong>]
             >>> print(d)
             <div>Maybe <em>she</em> does  know</div>
        Nr$   )r_   r   r4  r   r-  r3  r   )rR   rM  r   rl   r   r   r   r   r   r3    s"    zPyQuery.removec                   @   s   e Zd ZdZdd ZdS )z
PyQuery.Fna  Hook for defining custom function (like the jQuery.fn):

        .. sourcecode:: python

         >>> fn = lambda: this.map(lambda i, el: PyQuery(this).outerHtml())
         >>> PyQuery.fn.listOuterHtml = fn
         >>> S = PyQuery(
         ...   '<ol>   <li>Coffee</li>   <li>Tea</li>   <li>Milk</li>   </ol>')
         >>> S('li').listOuterHtml()
         ['<li>Coffee</li>', '<li>Tea</li>', '<li>Milk</li>']

        c                    s"    fdd}||_ tt|| d S )Nc                    s   |  j d<  |i |S )Nr   )r.   r   r!   r   r   fn  s    
z"PyQuery.Fn.__setattr__.<locals>.fn)r    r1   r3   )rR   r   r   rQ  r   r!   r   rd     s    zPyQuery.Fn.__setattr__N)r    rT   rU   r0   rd   r   r   r   r   Fn  s   rR  c                 C   s   t tdd |  S )a  Serialize form elements as an array of dictionaries, whose structure
        mirrors that produced by the jQuery API. Notably, it does not handle
        the deprecated `keygen` form element.

            >>> d = PyQuery('<form><input name="order" value="spam"></form>')
            >>> d.serialize_array() == [{'name': 'order', 'value': 'spam'}]
            True
            >>> d.serializeArray() == [{'name': 'order', 'value': 'spam'}]
            True
        c                 S   s   | d | d dS )Nr   r   )r   rj   r   )r   r   r   r   r     r&   z)PyQuery.serialize_array.<locals>.<lambda>)r'   r   serialize_pairsrQ   r   r   r   serialize_array  s    zPyQuery.serialize_arrayc                 C   s   t |  ddS )aJ  Serialize form elements as a URL-encoded string.

            >>> h = (
            ... '<form><input name="order" value="spam">'
            ... '<input name="order2" value="baked beans"></form>'
            ... )
            >>> d = PyQuery(h)
            >>> d.serialize()
            'order=spam&order2=baked%20beans'
        +z%20)r   rS  r   rQ   r   r   r   	serialize  s    zPyQuery.serializec           	         s>  g d}|  g  |  D ]}|d jdkrr|d}|rb|  |j } |d||f  q |d q|d jdkr |d q | qd	}|d
tdd |7 } 	|  fdd} 	| g } D ]X|  
 pd
}t|tr|tfdd| q|jd |ddf q|S )aQ  Serialize form elements as an array of 2-tuples conventional for
        typical URL-parsing operations in Python.

            >>> d = PyQuery('<form><input name="order" value="spam"></form>')
            >>> d.serialize_pairs()
            [('order', 'spam')]
            >>> d.serializePairs()
            [('order', 'spam')]
        )Zsubmitbuttonimageresetfiler   formr   z)#%s :not([form]):input, [form="%s"]:inputz:not([form]):inputfieldsetz:inputz[name]:enabled:not(button)r$   c                 S   s   d|  S )Nz:not([type="%s"])r   )sr   r   r   r   !  r&   z)PyQuery.serialize_pairs.<locals>.<lambda>c                    s"     |}|d o |d S )Nz:checkbox:not(:checked)z:radio:not(:checked))r   r   )r#   r   )controlsr   r   _filter_out_unchecked%  s    

z6PyQuery.serialize_pairs.<locals>._filter_out_uncheckedc                    s    j d | ddfS )Nr   r&  
)r   r   )r   )fieldr   r   r   :  r&   r   r&  r`  )r   r   r   r   r   rE   r   r)   r   r   r(  rD   r'   r   r   r   )	rR   Z_submitter_typesr   Zform_idr   r   r_  retr(  r   )r^  ra  r   rS    sD    




zPyQuery.serialize_pairsc                 C   s\   t  }|  D ]H\}}||vr(|||< qt|| tsH|| |g||< q|| | q|S )ay  Serialize form elements as an ordered dictionary. Multiple values
        corresponding to the same input name are concatenated into one list.

            >>> d = PyQuery('''<form>
            ...             <input name="order" value="spam">
            ...             <input name="order" value="eggs">
            ...             <input name="order2" value="ham">
            ...             </form>''')
            >>> d.serialize_dict()
            OrderedDict([('order', ['spam', 'eggs']), ('order2', 'ham')])
            >>> d.serializeDict()
            OrderedDict([('order', ['spam', 'eggs']), ('order2', 'ham')])
        )r   rS  rD   r'   r   )rR   rb  r   r(  r   r   r   serialize_dictA  s    
zPyQuery.serialize_dictc                 C   s&   | j dur| j S | jtur"| jjS dS )zJReturn the url of current html document or None if not available.
        N)rv   rx   r_   base_urlrQ   r   r   r   rd  Z  s    

zPyQuery.base_urlc                    s    du rj   du rtd fdd}d|d d|d d|d	 d
|d	 d|d	 d|d S )z!Make all links absolute.
        Nz]You need a base URL to make your linksabsolute. It can be provided by the base_url parameter.c                    s    fdd}|S )Nc                    sN   |   d u rd S t fdddD r4d S | t  S )Nc                 3   s   | ]}  |V  qd S rM   )r   )r   Zschema
attr_valuer   r   r8  u  s   zIPyQuery.make_links_absolute.<locals>.repl.<locals>.rep.<locals>.<genexpr>)ztel:zcallto:zsms:)r   anyr   r  )r   r   )r   rd  rR   re  r   repn  s    
z6PyQuery.make_links_absolute.<locals>.repl.<locals>.repr   )r   rh  rd  rR   r  r   replm  s    z)PyQuery.make_links_absolute.<locals>.replahreflinkscriptsrcimgiframer[  action)rd  rG   r   )rR   rd  rj  r   ri  r   make_links_absolutec  s    zPyQuery.make_links_absolute)r   )N)FF)N)N)N)N)N)N)N)N)N)N)r>   )N)^r    rT   rU   r0   r   rz   rZ   r   r   r9   r'   r   _appendr   r   r   r   r   r   r   r   r   rS   propertyr   ro   r   rl   r   r   r   r   r   r"   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rV   r_   r   r  r  r	  r  r  r  r  r  r(  r>   r5  r-  r:  r<  r=  r>  r?  r@  rB  rC  rJ  rK  rL  rN  rO  rP  r3  rh   rR  rQ  rT  rV  rS  rc  rd  rs  r   r   r   r   r3      s   Y











 !
$




'	a;0



#
0

	 

B

r3   )NN)%Zcssselectpatchr   collectionsr   urllib.parser   r   Zopenersr   r-  r   copyr
   r>   r   rC   r   rF   r   r   r+   r   bytesr   r   r"   r   r   r7   r;   rO   rh   rP   r_   rV   r'   r3   r   r   r   r   <module>   sJ   
-!            