a
    $i                     @   sD  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ddlZejdkrddlmZ nddlmZ G dd de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    )recursive_repr)	urlencode)urljoin)
url_opener)extract_textdeepcopy)escape)etreeN)      r   )OrderedDictc                   @   s   e Zd Ze dd ZdS )r   c                 C   s*   | sd| j jf S d| j jt|  f S )zod.__repr__() <==> repr(od)z%s()z%s(%r))	__class____name__dictitemsself r   ]/var/www/staging/api/virtual_environments/venv/lib/python3.9/site-packages/pyquery/pyquery.py__repr__   s    zOrderedDict.__repr__N)r   
__module____qualname__r   r   r   r   r   r   r      s   r   c                 C   s   t | j }dd |D S )Nc                 S   s   g | ]}|j |jkr|jqS r   )kindPOSITIONAL_OR_KEYWORDname.0pr   r   r   
<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addr   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_aliases6   s    $
rB   c                 C   sp  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r@|S t|tj	rX|
 gS |durh|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")hasattrrC   r5   r   ZXMLSyntaxErrorrG   lxmlrI   
isinstanceZ_ElementTreegetroot	lxml.htmlrK   rL   Zfragments_fromstring
ValueErrorr2   )contextparserZcustom_parsermethresultrK   rL   r   r   r   rF   C   sF    








rF   c                 G   s   | |d | j j  S N)r8   co_argcountr&   r   r   r   callbackp   s    rY   c                   @   s   e Zd Zdd ZdS )	NoDefaultc                 C   s   dS )zclean representation in Sphinxz<NoDefault>r   r   r   r   r   r   u   s    zNoDefault.__repr__N)r   r   r   r   r   r   r   r   rZ   t   s   rZ   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 rW   )pgetpsetpdel)r   r\   r]   r^   r   r   r   __init__   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 rW   )r\   )propr(   kwargsinstancer   r   r   rD      s    z2FlexibleElement.__get__.<locals>._element.__call__c                    s    j tur  |S t d S rW   )r^   
no_defaultNotImplementedError)r`   r   rb   r   r   __delitem__   s    
z5FlexibleElement.__get__.<locals>._element.__delitem__c                    s   d j j S )Nz<flexible_element %s>)r\   r   )r`   r   r   r   r      s    z2FlexibleElement.__get__.<locals>._element.__repr__N)r   r   r   r;   rD   __getattr____getitem____setattr____setitem__rf   __delattr__r   r   rb   r   r   _element   s   rl   )object)r   rc   klassrl   r   rb   r   r=      s    zFlexibleElement.__get__c                 C   s"   | j tur|  || nt d S rW   )r]   rd   re   )r   rc   valuer   r   r   __set__   s    
zFlexibleElement.__set__N)r   r   r   r;   rd   r_   r=   rp   r   r   r   r   r[   ~   s   r[   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 )r>   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 )NrT   parentZcss_translator)rH   T)ZxhtmlF
namespacesfilenameencodingrt   urlopenerrI   zInvalid keyword arguments %scloser   r      z,You can't do that. Please, provide argumentsrr   )	_base_urlpoprT   _parentrd   _translator_translator_classrr   opengetr   rR   rF   rM   rx   	ExceptionlenrO   
basestringr   r2   r   _Element	TypeError_css_to_xpathextendxpathr_   )r   r(   ra   rI   elementsrv   rw   selectorrS   lengthr   resultstagr   r   r   r_      s    












zPyQuery.__init__descendant-or-self::c                 C   s   | dd}| j||S )Nz[@[)replacer~   Zcss_to_xpath)r   r   prefixr   r   r   r      s    zPyQuery._css_to_xpathc                 O   s   | d| j | j|i |S )Nrr   )
setdefaultrr   r   r   r(   ra   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   <rq   )r   rR   r   rO   str
startswith)r   r(   ra   r   rV   r   r   r   rD     s    

zPyQuery.__call__c                 C   s.   t || jsJ | | d d  |d d   S rW   )rO   r   r   r   otherr   r   r   __add__  s    zPyQuery.__add__c                 C   s&   t || jsJ | |dd  | S )z"Extend with another PyQuery objectN)rO   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
        rq   N)r   )r   r   Zelemselemr   r   r   r   $  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
IndexErrorrN   rI   xhtml_to_htmlr   rootr   r   r   r   6  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   r3   )r   r   elr   r   r   remove_namespacesH  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 ru   r   tostringr   r   er   r   r   r!   d  r1   z#PyQuery.__str__.<locals>.<listcomp>r4   r   r   r   r   __str__[  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!   h  s   z'PyQuery.__unicode__.<locals>.<listcomp>r   r   r   r   r   __unicode__f  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   )rN   rI   r   r   r   r   r   r   r!   t  s   z$PyQuery.__html__.<locals>.<listcomp>r   r   r   r   r   __html__k  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   r4   r3   appendr   AttributeErrorr2   r   )r   rr   cr   r   r   r   r   w  s    

zPyQuery.__repr__c                 C   s$   | j tur| j d  S | d  S )z$return the xml root element
        r   )r}   rd   r   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docinfort   r   r   r   r   rt     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::rz   r   )r   r   r   rr   reverser   r   )
r   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 rW   )	getparentr   r   r   r   r!     r1   z"PyQuery.parent.<locals>.<listcomp>Tr   r   r   r   r   r   r   rq     s
    zPyQuery.parentc                 C   s   |  |dd | D S )Nc                 S   s    g | ]}|  d ur|  qS rW   )getpreviousr   r   r   r   r!     r1   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 rW   )getnextr   r   r   r   r!     r1   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 rW   )r5   )r   methodr   currentr   r   r   	_traverse  s
    zPyQuery._traversec                 c   sN   | D ]D}g }|  }|d ur0|| |  }q|  |D ]
}|V  q<qd S rW   )r   r   r   )r   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!     r1   z%PyQuery._next_all.<locals>.<listcomp>r   r   r   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 rW   is_)r   r   r   r   <lambda>  r1   z$PyQuery.next_until.<locals>.<lambda>)r   	itertools	takewhiler   r   )r   r   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!     r1   z%PyQuery._prev_all.<locals>.<listcomp>r   r   r   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!     r1   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!   *  r1   z$PyQuery.children.<locals>.<listcomp>r   )r   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   )r   r   rV   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::*rz   r   )r   r   rr   r   )r   r   r   r   r   r   contentsB  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>]
        rD   r   thisr   N)	rM   r   r)   rY   	enumerater   r9   r   r   )r   r   r   r(   ir   	f_globalsr   r   r   filterP  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!   x  r1   z PyQuery.not_.<locals>.<listcomp>r   )setr   r   r   r   r   not_p  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   {  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 )rz   )r   r   rr   r   r   r   r   r   r!     s   z PyQuery.find.<locals>.<listcomp>r   )r   r   r   )r   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   )r   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   r9   rY   )r   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   r9   rY   rO   r2   r   r   r   )r   r'   r   r   r   rV   r   r   r   r   map  s     

zPyQuery.mapc                 C   s   t | S rW   r   r   r   r   r   r     s    zPyQuery.lengthc                 C   s   t | S rW   r   r   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>]
        )r}   r   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   ry   Invalid arguments %s %sN)	rd   r   r   r   rR   rO   r   r   remove_attr)r   r(   ra   mappingattrro   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)r   r   r   r   r   r   r     s    zPyQuery.remove_attr)r\   r^   c                 C   s   |  d|S )z"set/get height of element
        heightr   r   ro   r   r   r   r  5  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   )r   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!   \  r1   z%PyQuery.add_class.<locals>.<listcomp>r3   r   r   r4   )r   ro   r   r%   r   r  r   	add_classM  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/   )r3   r   r   difference_updater4   strip)r   ro   r   r%   r	  r   r   r   remove_class`  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!     r1   z(PyQuery.toggle_class.<locals>.<listcomp>c                    s   g | ]}| v r|qS r   r   r  r  r   r   r!     r1   c                    s   g | ]}| vr|qS r   r   r  )values_to_delr   r   r!     r1   r
  )r   ro   r   r%   Zvalues_to_addr   )r	  r  r   toggle_classx  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   ry   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  r3   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   )rd   r   rR   rO   r   keysr   r3   r   r   r   r   r4   r   )r   r(   ra   ro   r   r   r   r   r   )r   r  r   css  s<    




zPyQuery.css)r\   r]   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  r   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  r   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 )Nro   )r   r   )r.   or   r   r   r     r1   z1PyQuery.val.<locals>._get_value.<locals>.<lambda>zoption[selected]:lastro   optionz:checkbox,:radiooninput
r/   )	r   r   rI   r   r2   r   r   r   r   )r   selectedZselected_optionvalr   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 )Nro   r)  r#  )r   r   r   Z
removeAttr)r.   r   pq)r   r   ro   r   r   _make_option_selected  s    

z>PyQuery.val.<locals>._set_value.<locals>._make_option_selectedr%  ,r!  ro   )r   rO   r2   r   r   r4   textr   )r,  ro   r-  r   )r   ro   r   
_set_value  s    

	


zPyQuery.val.<locals>._set_valuer   N)rd   r   )r   ro   r+  r0  r   r   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)quotert   c                    s   g | ]}t j|fi  qS r   )r   r   r   ra   r   r   r!   Q  s   z PyQuery.html.<locals>.<listcomp><root></root>)rd   r   r   r/  r   r4   rO   r   r   rR   typeremoverF   rT   r   )	r   ro   ra   r   r   rI   Znew_htmlr   r   r   r2  r   rI   /  sF    





zPyQuery.htmlrI   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/   )rt   r   )tailr
   r   r   r   )r   r   Ze0r   r   r   
outer_htmlj  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   rI   r   r   r   ra   r   r   r   	<genexpr>  s   zPyQuery.text.<locals>.<genexpr>)rd   r4   r   r6  r/  )r   ro   ra   r   r   r   r:  r   r/    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 )Nr3  r4  r   z0Value must be string, PyQuery or Element. Got %rr/  r/   )rO   r   rF   rT   r   r   r   r>   r   rM   r/  )r   ro   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   r7  r/  r
   r2   r   )r   ro   r   r<  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   r7  r
   r2   )r   ro   r   r<  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   r7  r
   r2   r   r   r   )r   ro   r   r<  r   r   rq   r   r   r   r   after  s    zPyQuery.afterc                 C   s   | |  | S )z!insert nodes after value
        )rB  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   r7  r   r/  r
   r2   r   r   )	r   ro   r   r<  r   r   previousrq   r   r   r   r   before  s$    
zPyQuery.beforec                 C   s   | |  | S )z"insert nodes before value
        )rE  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!   B  r1   z PyQuery.wrap.<locals>.<listcomp>r>  N)
rO   r   rF   r
   r   r   iterchildrenr   Zaddnextr6  )	r   ro   nodesr   wrapperchildsr   rq   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   rG  r   r   r   r!   i  r1   z$PyQuery.wrap_all.<locals>.<listcomp>r>  TNFc                 S   s   g | ]}|qS r   r   rG  r   r   r   r!   y  r1   )rO   r   rF   r
   r   rH  r   rd   r   r   r6  )r   ro   rJ  r   rK  Zreplace_childsrq   r   r   r   r   wrap_allQ  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>

        rD   r/   )
rO   r>   r   rM   r   r   rE  r7  r   r6  )r   ro   r   r   rq   r   r   r   r   replace_with  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)r}   rd   rR   rO  )r   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	   r9  r   r   r   r!     r1   z!PyQuery.clone.<locals>.<listcomp>)r>   r   r   r   r   clone  s    zPyQuery.clonec                 C   s    | D ]}d|_ g |dd< q| S )zremove nodes content
        N)r/  )r   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/   )rd   r   r7  r   r/  r6  r   )r   rP  r   rq   r   r   r   r   r   r6    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   )r9   r   r,   r   r   fn  s    
z"PyQuery.Fn.__setattr__.<locals>.fn)r   r<   r>   )r   r   r'   rT  r   r,   r   ri     s    zPyQuery.Fn.__setattr__N)r   r   r   r;   ri   r   r   r   r   Fn  s   rU  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   ro   r   )r    r   r   r   r     r1   z)PyQuery.serialize_array.<locals>.<lambda>)r2   r   serialize_pairsr   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   rV  r   r   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')]
        )submitZbuttonimageresetfiler   formr   z)#%s :not([form]):input, [form="%s"]:inputz:not([form]):inputZfieldsetz:inputz[name]:enabled:not(button)r/   c                 S   s   d|  S )Nz:not([type="%s"])r   )sr   r   r   r   3  r1   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_unchecked7  s    

z6PyQuery.serialize_pairs.<locals>._filter_out_uncheckedc                    s    j d | ddfS )Nr   r(  
)r   r   )r   )fieldr   r   r   L  r1   r   r(  rb  )r   r   r   r   r   rP   r   r4   r   r   r*  rO   r2   r   r   r   )	r   Z_submitter_typesr   Zform_idr   r   ra  retr*  r   )r`  rc  r   rV    sD    




zPyQuery.serialize_pairsc                 C   s\   t  }|  D ]H\}}||vr(|||< qt|| tsH|| |g||< q|| | q|S )aq  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   rV  rO   r2   r   )r   rd  r   r*  r   r   r   serialize_dictS  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)r{   r}   rd   base_urlr   r   r   r   rf  l  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 rW   )r   )r   ZschemaZ
attr_valuer   r   r;    s   zIPyQuery.make_links_absolute.<locals>.repl.<locals>.rep.<locals>.<genexpr>)ztel:zcallto:zsms:)r   anyr   r  )r   r   )r   rf  r   rg  r   rep  s    
z6PyQuery.make_links_absolute.<locals>.repl.<locals>.repr   )r   ri  rf  r   r  r   repl  s    z)PyQuery.make_links_absolute.<locals>.replahreflinkscriptsrcZimgZiframer^  action)rf  rR   r   )r   rf  rk  r   rj  r   make_links_absoluteu  s    zPyQuery.make_links_absolute)r   )N)FF)N)N)N)N)N)N)N)N)N)N)rI   )N)^r   r   r   r;   r   r   r_   r   r   rD   r2   r   _appendr   r   r   r   r   r   r   r   r   r   propertyr   rt   r   rq   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   r[   rd   r  r  r  r  r  r  r  r  r   r*  rI   r8  r/  r=  r?  r@  rA  rB  rC  rE  rF  rM  rN  rO  rQ  rR  rS  r6  rm   rU  rT  rW  rY  rV  re  rf  rr  r   r   r   r   r>      s   Y











 !
$




'	a;0



#
0

	 

B

r>   )NN)*Zcssselectpatchr   reprlibr   urllib.parser   r   Zopenersr   r/  r   copyr
   rI   r   rN   r   rQ   r"   r   r6   sysversion_infocollectionsr   ZBaseOrderedDictr   bytesr   r)   r-   r   r*   rB   rF   rY   rm   rZ   rd   r[   r2   r>   r   r   r   r   <module>   sT   

-!            