o
    6‘ði?  ã                   @  sR  d 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ddl	Z	ddl
Z
ddlZddlmZmZmZ ddlmZ ddlmZ ddlmZ ddlmZmZmZ dd	lmZ dd
lmZ ddlm Z 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l0m1Z1 ddl2m3Z3 ddl4m5Z5m6Z6m7Z7 e	 8e9¡Z:ee;e;f Z<dTdd„Z=G dd„ de>ƒZ?dUd"d#„Z@G d$d%„ d%e>ƒZAdVd(d)„ZBdWd*d+„ZCdXd.d/„ZDG d0d1„ d1ƒZEG d2d3„ d3eƒZFdYd5d6„ZGeGdZd:d;„ƒZHed<d=�G d>d8„ d8ƒƒZIG d?d@„ d@eƒZJ	d[d\dGdH„ZK	<d]d^dKdL„ZLd_dNdO„ZMG dPdQ„ dQeƒZNG dRdS„ dSƒZOdS )`zO
The main purpose of this module is to expose LinkCollector.collect_sources().
é    )ÚannotationsN)ÚIterableÚMutableMappingÚSequence)Ú	dataclass)Ú
HTMLParser)ÚValues)ÚCallableÚ
NamedTupleÚProtocol)Úrequests)ÚResponse)Ú
RetryErrorÚSSLError)ÚNetworkConnectionError)ÚLink)ÚSearchScope)Ú
PipSession)Úraise_for_status)Úis_archive_file©Úredact_auth_from_url)Úurl_to_path)Úvcsé   )ÚCandidatesFromPageÚ
LinkSourceÚbuild_sourceÚurlÚstrÚreturnú
str | Nonec                 C  s6   t jD ]}|  ¡  |¡r| t|ƒ dv r|  S qdS )zgLook for VCS schemes in the URL.

    Returns the matched VCS scheme, or None if there's no match.
    z+:N)r   ÚschemesÚlowerÚ
startswithÚlen)r   Úscheme© r'   ú\/root/parts/websockify/install/lib/python3.10/site-packages/pip/_internal/index/collector.pyÚ_match_vcs_scheme.   s
   
€r)   c                      s   e Zd Zd‡ fdd„Z‡  ZS )	Ú_NotAPIContentÚcontent_typer   Úrequest_descr    ÚNonec                   s   t ƒ  ||¡ || _|| _d S ©N)ÚsuperÚ__init__r+   r,   )Úselfr+   r,   ©Ú	__class__r'   r(   r0   :   s   
z_NotAPIContent.__init__)r+   r   r,   r   r    r-   )Ú__name__Ú
__module__Ú__qualname__r0   Ú__classcell__r'   r'   r2   r(   r*   9   s    r*   Úresponser   r-   c                 C  s2   | j  dd¡}| ¡ }| d¡rdS t|| jjƒ‚)z°
    Check the Content-Type header to ensure the response contains a Simple
    API Response.

    Raises `_NotAPIContent` if the content type is not a valid content-type.
    úContent-TypeÚUnknown)z	text/htmlz#application/vnd.pypi.simple.v1+htmlú#application/vnd.pypi.simple.v1+jsonN)ÚheadersÚgetr#   r$   r*   ÚrequestÚmethod)r8   r+   Úcontent_type_lr'   r'   r(   Ú_ensure_api_header@   s   ÿrA   c                   @  s   e Zd ZdS )Ú_NotHTTPN)r4   r5   r6   r'   r'   r'   r(   rB   V   s    rB   Úsessionr   c                 C  sF   t j | ¡\}}}}}|dvrtƒ ‚|j| dd�}t|ƒ t|ƒ dS )zõ
    Send a HEAD request to the URL, and ensure the response contains a simple
    API Response.

    Raises `_NotHTTP` if the URL is not available for a HEAD request, or
    `_NotAPIContent` if the content type is not a valid content type.
    >   ÚhttpÚhttpsT)Úallow_redirectsN)ÚurllibÚparseÚurlsplitrB   Úheadr   rA   )r   rC   r&   ÚnetlocÚpathÚqueryÚfragmentÚrespr'   r'   r(   Ú_ensure_api_responseZ   s   rP   c                 C  sx   t t| ƒjƒrt| |d� t dt| ƒ¡ |j| d g d¢¡ddœd�}t	|ƒ t
|ƒ t dt| ƒ|j d	d
¡¡ |S )aY  Access an Simple API response with GET, and return the response.

    This consists of three parts:

    1. If the URL looks suspiciously like an archive, send a HEAD first to
       check the Content-Type is HTML or Simple API, to avoid downloading a
       large file. Raise `_NotHTTP` if the content type cannot be determined, or
       `_NotAPIContent` if it is not HTML or a Simple API.
    2. Actually perform the request. Raise HTTP exceptions on network failures.
    3. Check the Content-Type header to make sure we got a Simple API response,
       and raise `_NotAPIContent` otherwise.
    ©rC   zGetting page %sz, )r;   z*application/vnd.pypi.simple.v1+html; q=0.1ztext/html; q=0.01z	max-age=0)ÚAcceptzCache-Control)r<   zFetched page %s as %sr9   r:   )r   r   ÚfilenamerP   ÚloggerÚdebugr   r=   Újoinr   rA   r<   )r   rC   rO   r'   r'   r(   Ú_get_simple_responsel   s&   ÿëþýrW   r<   ÚResponseHeadersc                 C  s<   | rd| v rt j ¡ }| d |d< | d¡}|rt|ƒS dS )z=Determine if we have any encoding information in our headers.r9   zcontent-typeÚcharsetN)ÚemailÚmessageÚMessageÚ	get_paramr   )r<   ÚmrY   r'   r'   r(   Ú_get_encoding_from_headers«   s   

r_   c                   @  s*   e Zd Zddd„Zdd
d„Zddd„ZdS )ÚCacheablePageContentÚpageÚIndexContentr    r-   c                 C  s   |j sJ ‚|| _d S r.   )Úcache_link_parsingra   ©r1   ra   r'   r'   r(   r0   ·   s   

zCacheablePageContent.__init__ÚotherÚobjectÚboolc                 C  s   t |t| ƒƒo| jj|jjkS r.   )Ú
isinstanceÚtypera   r   )r1   re   r'   r'   r(   Ú__eq__»   s   zCacheablePageContent.__eq__Úintc                 C  s   t | jjƒS r.   )Úhashra   r   ©r1   r'   r'   r(   Ú__hash__¾   s   zCacheablePageContent.__hash__N)ra   rb   r    r-   )re   rf   r    rg   )r    rk   )r4   r5   r6   r0   rj   rn   r'   r'   r'   r(   r`   ¶   s    

r`   c                   @  s   e Zd Zddd„ZdS )	Ú
ParseLinksra   rb   r    úIterable[Link]c                 C  s   d S r.   r'   rd   r'   r'   r(   Ú__call__Ã   s    zParseLinks.__call__N©ra   rb   r    rp   )r4   r5   r6   rq   r'   r'   r'   r(   ro   Â   s    ro   Úfnc                   s2   t jd‡ fdd„ƒ‰t  ˆ ¡d‡ ‡fd	d
„ƒ}|S )zÚ
    Given a function that parses an Iterable[Link] from an IndexContent, cache the
    function's result (keyed by CacheablePageContent), unless the IndexContent
    `page` has `page.cache_link_parsing == False`.
    Úcacheable_pager`   r    ú
list[Link]c                   s   t ˆ | jƒƒS r.   )Úlistra   )rt   )rs   r'   r(   ÚwrapperÍ   s   z*with_cached_index_content.<locals>.wrapperra   rb   c                   s   | j r	ˆt| ƒƒS tˆ | ƒƒS r.   )rc   r`   rv   )ra   ©rs   rw   r'   r(   Úwrapper_wrapperÑ   s   z2with_cached_index_content.<locals>.wrapper_wrapperN)rt   r`   r    ru   )ra   rb   r    ru   )Ú	functoolsÚcacheÚwraps)rs   ry   r'   rx   r(   Úwith_cached_index_contentÆ   s
   r}   ra   rb   rp   c           
      c  s¼   � | j  ¡ }| d¡r+t | j¡}| dg ¡D ]}t || j	¡}|du r%q|V  qdS t
| j	ƒ}| jp4d}| | j |¡¡ | j	}|jpE|}|jD ]}	tj|	||d�}|du rXqI|V  qIdS )z\
    Parse a Simple API's Index Content, and yield its anchor elements as Link objects.
    r;   ÚfilesNzutf-8)Úpage_urlÚbase_url)r+   r#   r$   ÚjsonÚloadsÚcontentr=   r   Ú	from_jsonr   ÚHTMLLinkParserÚencodingÚfeedÚdecoder€   ÚanchorsÚfrom_element)
ra   r@   ÚdataÚfileÚlinkÚparserr†   r   r€   Úanchorr'   r'   r(   Úparse_linksÚ   s*   €





ür�   T)Úfrozenc                   @  sH   e Zd ZU dZded< ded< ded< ded< d	Zd
ed< ddd„ZdS )rb   aŒ  Represents one response (or page), along with its URL.

    :param encoding: the encoding to decode the given content.
    :param url: the URL from which the HTML was downloaded.
    :param cache_link_parsing: whether links parsed from this page's url
                               should be cached. PyPI index urls should
                               have this set to False, for example.
    Úbytesrƒ   r   r+   r!   r†   r   Trg   rc   r    c                 C  s
   t | jƒS r.   )r   r   rm   r'   r'   r(   Ú__str__  s   
zIndexContent.__str__N)r    r   )r4   r5   r6   Ú__doc__Ú__annotations__rc   r“   r'   r'   r'   r(   rb   ÷   s   
 	c                      s6   e Zd ZdZd‡ fdd„Zddd„Zddd„Z‡  ZS )r…   zf
    HTMLParser that keeps the first base HREF and a list of all anchor
    elements' attributes.
    r   r   r    r-   c                   s$   t ƒ jdd� || _d | _g | _d S )NT)Úconvert_charrefs)r/   r0   r   r€   r‰   )r1   r   r2   r'   r(   r0     s   
zHTMLLinkParser.__init__ÚtagÚattrsúlist[tuple[str, str | None]]c                 C  sR   |dkr| j d u r|  |¡}|d ur|| _ d S d S |dkr'| j t|ƒ¡ d S d S )NÚbaseÚa)r€   Úget_hrefr‰   ÚappendÚdict)r1   r—   r˜   Úhrefr'   r'   r(   Úhandle_starttag  s   

ÿÿzHTMLLinkParser.handle_starttagr!   c                 C  s"   |D ]\}}|dkr|  S qd S )NrŸ   r'   )r1   r˜   ÚnameÚvaluer'   r'   r(   rœ   !  s
   ÿzHTMLLinkParser.get_href)r   r   r    r-   )r—   r   r˜   r™   r    r-   )r˜   r™   r    r!   )r4   r5   r6   r”   r0   r    rœ   r7   r'   r'   r2   r(   r…     s
    
r…   r�   r   Úreasonústr | ExceptionÚmethúCallable[..., None] | Nonec                 C  s   |d u rt j}|d| |ƒ d S )Nz%Could not fetch URL %s: %s - skipping)rT   rU   )r�   r£   r¥   r'   r'   r(   Ú_handle_get_simple_fail(  s   r§   rc   rg   c                 C  s&   t | jƒ}t| j| jd || j|d�S )Nr9   )r†   r   rc   )r_   r<   rb   rƒ   r   )r8   rc   r†   r'   r'   r(   Ú_make_index_content2  s   
ûr¨   úIndexContent | Nonec             
   C  sâ  | j  dd¡d }t|ƒ}|rt d|| ¡ d S | d¡r;tj t	|ƒ¡r;| 
d¡s.|d7 }tj |d¡}t d|¡ zt||d	�}W n¦ tyS   t d
| ¡ Y d S  tyo } zt d| |j|j¡ W Y d }~d S d }~w ty† } zt| |ƒ W Y d }~d S d }~w ty� } zt| |ƒ W Y d }~d S d }~w ty¿ } zd}|t|ƒ7 }t| |tjd� W Y d }~d S d }~w tjyÚ } zt| d|› �ƒ W Y d }~d S d }~w tjyé   t| dƒ Y d S w t|| jd�S )Nú#r   r   zICannot look at %s URL %s because it does not support lookup as web pages.zfile:ú/z
index.htmlz# file: URL is directory, getting %srQ   z`Skipping page %s because it looks like an archive, and cannot be checked by a HTTP HEAD request.zºSkipping page %s because the %s request got Content-Type: %s. The only supported Content-Types are application/vnd.pypi.simple.v1+json, application/vnd.pypi.simple.v1+html, and text/htmlz4There was a problem confirming the ssl certificate: )r¥   zconnection error: z	timed out)rc   )r   Úsplitr)   rT   Úwarningr$   ÚosrL   Úisdirr   ÚendswithrG   rH   ÚurljoinrU   rW   rB   r*   r,   r+   r   r§   r   r   r   Úinfor   ÚConnectionErrorÚTimeoutr¨   rc   )r�   rC   r   Ú
vcs_schemerO   Úexcr£   r'   r'   r(   Ú_get_index_content?  sl   ý
ýéú€ò€ô€ö€ú€üür·   c                   @  s   e Zd ZU ded< ded< dS )ÚCollectedSourceszSequence[LinkSource | None]Ú
find_linksÚ
index_urlsN)r4   r5   r6   r•   r'   r'   r'   r(   r¸   {  s   
 r¸   c                   @  sN   e Zd ZdZd!dd	„Ze	
d"d#dd„ƒZed$dd„ƒZd%dd„Z	d&dd„Z
d S )'ÚLinkCollectorzµ
    Responsible for collecting Link objects from all configured locations,
    making network requests as needed.

    The class's main method is its collect_sources() method.
    rC   r   Úsearch_scoper   r    r-   c                 C  s   || _ || _d S r.   )r¼   rC   )r1   rC   r¼   r'   r'   r(   r0   ˆ  s   
zLinkCollector.__init__FÚoptionsr   Úsuppress_no_indexrg   c                 C  sd   |j g|j }|jr|st dd dd„ |D ƒ¡¡ g }|jp g }tj|||jd�}t	||d�}|S )zÆ
        :param session: The Session to use to make requests.
        :param suppress_no_index: Whether to ignore the --no-index option
            when constructing the SearchScope object.
        zIgnoring indexes: %sú,c                 s  s   � | ]}t |ƒV  qd S r.   r   )Ú.0r   r'   r'   r(   Ú	<genexpr>   s   € z'LinkCollector.create.<locals>.<genexpr>)r¹   rº   Úno_index)rC   r¼   )
Ú	index_urlÚextra_index_urlsrÂ   rT   rU   rV   r¹   r   Úcreater»   )ÚclsrC   r½   r¾   rº   r¹   r¼   Úlink_collectorr'   r'   r(   rÅ   �  s$   
þ
ýþzLinkCollector.createú	list[str]c                 C  s   | j jS r.   )r¼   r¹   rm   r'   r'   r(   r¹   ²  s   zLinkCollector.find_linksÚlocationr   r©   c                 C  s   t || jd�S )z>
        Fetch an HTML page containing package links.
        rQ   )r·   rC   )r1   rÉ   r'   r'   r(   Úfetch_response¶  s   zLinkCollector.fetch_responseÚproject_namer   Úcandidates_from_pager   r¸   c                   sª   t  ‡ ‡‡fdd„ˆj ˆ¡D ƒ¡ ¡ }t  ‡ ‡‡fdd„ˆjD ƒ¡ ¡ }t tj	¡rKdd„ t
 ||¡D ƒ}t|ƒ› dˆ› d�g| }t d |¡¡ tt|ƒt|ƒd	�S )
Nc              	   3  ó(   � | ]}t |ˆ ˆjjd d ˆd�V  qdS )F©rÌ   Úpage_validatorÚ
expand_dirrc   rË   N©r   rC   Úis_secure_origin©rÀ   Úloc©rÌ   rË   r1   r'   r(   rÁ   Â  ó   € 	øú
ÿz0LinkCollector.collect_sources.<locals>.<genexpr>c              	   3  rÍ   )TrÎ   NrÑ   rÓ   rÕ   r'   r(   rÁ   Í  rÖ   c                 S  s*   g | ]}|d ur|j d urd|j › �‘qS )Nz* )r�   )rÀ   Úsr'   r'   r(   Ú
<listcomp>Ú  s
    
þz1LinkCollector.collect_sources.<locals>.<listcomp>z' location(s) to search for versions of ú:Ú
)r¹   rº   )ÚcollectionsÚOrderedDictr¼   Úget_index_urls_locationsÚvaluesr¹   rT   ÚisEnabledForÚloggingÚDEBUGÚ	itertoolsÚchainr%   rU   rV   r¸   rv   )r1   rË   rÌ   Úindex_url_sourcesÚfind_links_sourcesÚlinesr'   rÕ   r(   Úcollect_sources¼  s2   
	÷
ö	÷
ö
þ
ÿÿýþzLinkCollector.collect_sourcesN)rC   r   r¼   r   r    r-   )F)rC   r   r½   r   r¾   rg   r    r»   )r    rÈ   )rÉ   r   r    r©   )rË   r   rÌ   r   r    r¸   )r4   r5   r6   r”   r0   ÚclassmethodrÅ   Úpropertyr¹   rÊ   rç   r'   r'   r'   r(   r»   €  s    
ü!
r»   )r   r   r    r!   )r8   r   r    r-   )r   r   rC   r   r    r-   )r   r   rC   r   r    r   )r<   rX   r    r!   )rs   ro   r    ro   rr   r.   )r�   r   r£   r¤   r¥   r¦   r    r-   )T)r8   r   rc   rg   r    rb   )r�   r   rC   r   r    r©   )Pr”   Ú
__future__r   rÛ   Úemail.messagerZ   rz   râ   r�   rà   r®   Úurllib.parserG   Úcollections.abcr   r   r   Údataclassesr   Úhtml.parserr   Úoptparser   Útypingr	   r
   r   Úpip._vendorr   Úpip._vendor.requestsr   Úpip._vendor.requests.exceptionsr   r   Úpip._internal.exceptionsr   Úpip._internal.models.linkr   Ú!pip._internal.models.search_scoper   Úpip._internal.network.sessionr   Úpip._internal.network.utilsr   Úpip._internal.utils.filetypesr   Úpip._internal.utils.miscr   Úpip._internal.utils.urlsr   Úpip._internal.vcsr   Úsourcesr   r   r   Ú	getLoggerr4   rT   r   rX   r)   Ú	Exceptionr*   rA   rB   rP   rW   r_   r`   ro   r}   r�   rb   r…   r§   r¨   r·   r¸   r»   r'   r'   r'   r(   Ú<module>   sh    





?
ýÿ
<