
    vg@              	       "   d 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Z
ddlmZ ddlmZ ddlmZmZmZmZmZmZmZmZ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/m0Z0 ddl1m2Z2 ddl3m4Z4m5Z5m6Z6 erddlm7Z7 ne8Z7 ejr                  e:      Z;ee<e<f   Z=de<dee<   fdZ> G d de?      Z@deddfdZA G d de?      ZBde<de*ddfdZCde<de*defdZDd e=dee<   fd!ZE G d" d#      ZF G d$ d%e7      ZGd&eGdeGfd'ZHeHd(d)dee&   fd*       ZI G d+ d)      ZJ G d, d-e      ZK	 d:d.e&d/ee<e?f   d0eed1      ddfd2ZL	 d;ded3eMdeJfd4ZNd.e&de*ded)   fd5ZO G d6 d7e      ZP G d8 d9      ZQy)<zO
The main purpose of this module is to expose LinkCollector.collect_sources().
    N)
HTMLParser)Values)TYPE_CHECKINGCallableDictIterableListMutableMapping
NamedTupleOptionalSequenceTupleUnion)requests)Response)
RetryErrorSSLError)NetworkConnectionError)Link)SearchScope)
PipSession)raise_for_status)is_archive_fileredact_auth_from_url)vcs   )CandidatesFromPage
LinkSourcebuild_source)Protocolurlreturnc                     t         j                  D ]6  }| j                         j                  |      s#| t	        |         dv s4|c S  y)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"   schemes     b/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/pip/_internal/index/collector.py_match_vcs_schemer+   7   sE    
 ++ 99;!!&)c#f+.>$.FM     c                   ,     e Zd Zdededdf fdZ xZS )_NotAPIContentcontent_typerequest_descr#   Nc                 B    t         |   ||       || _        || _        y N)super__init__r/   r0   )selfr/   r0   	__class__s      r*   r4   z_NotAPIContent.__init__C   s"    |4((r,   )__name__
__module____qualname__strr4   __classcell__r6   s   @r*   r.   r.   B   s"    )S ) ) ) )r,   r.   responsec                     | j                   j                  dd      }|j                         }|j                  d      ry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)r=   r/   content_type_ls      r*   _ensure_api_headerrG   I   s[     ##''	BL!'')N  	
 	
x'7'7'>'>
??r,   c                       e Zd Zy)_NotHTTPN)r7   r8   r9    r,   r*   rI   rI   _   s    r,   rI   sessionc                     t         j                  j                  |       \  }}}}}|dvr
t               |j	                  | d      }t        |       t        |       y)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urlsplitrI   headr   rG   )r"   rK   r)   netlocpathqueryfragmentresps           r*   _ensure_api_responserY   c   sV     -3LL,A,A#,F)FFD%&&j<<T<2DTtr,   c                    t        t        |       j                        rt        | |       t        j                  dt        |              |j                  | dj                  g d      dd      }t        |       t        |       t        j                  dt        |       |j                  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.
    rK   zGetting page %sz, )rA   z*application/vnd.pypi.simple.v1+html; q=0.1ztext/html; q=0.01z	max-age=0)AcceptzCache-Control)rB   zFetched page %s as %sr?   r@   )r   r   filenamerY   loggerdebugr   rC   joinr   rG   rB   )r"   rK   rX   s      r*   _get_simple_responsera   u   s     tCy))*S'2
LL"$8$=>;;ii( )+
  D4 T t
LLS!3 Kr,   rB   c                     | rHd| v rDt         j                  j                         }| d   |d<   |j                  d      }|rt	        |      S y)z=Determine if we have any encoding information in our headers.r?   zcontent-typecharsetN)emailmessageMessage	get_paramr:   )rB   mrc   s      r*   _get_encoding_from_headersri      sK    >W,MM!!##N3.++i(w<r,   c                   0    e Zd ZddZdedefdZdefdZy)CacheablePageContentr#   Nc                 .    |j                   sJ || _        y r2   )cache_link_parsingpager5   rn   s     r*   r4   zCacheablePageContent.__init__   s    &&&&	r,   otherc                     t        |t        |             xr- | j                  j                  |j                  j                  k(  S r2   )
isinstancetypern   r"   )r5   rp   s     r*   __eq__zCacheablePageContent.__eq__   s-    %d,P%**..1PPr,   c                 @    t        | j                  j                        S r2   )hashrn   r"   r5   s    r*   __hash__zCacheablePageContent.__hash__   s    DIIMM""r,   )rn   IndexContentr#   N)	r7   r8   r9   r4   objectboolrt   intrx   rJ   r,   r*   rk   rk      s)    QF Qt Q## #r,   rk   c                   "    e Zd Zdddee   fdZy)
ParseLinksrn   ry   r#   c                      y r2   rJ   ro   s     r*   __call__zParseLinks.__call__   s    r,   N)r7   r8   r9   r   r   r   rJ   r,   r*   r~   r~      s    ^  r,   r~   fnc                      t        j                  d      dt        dt        t           f fd       t        j
                         dddt        t           f f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`.
    N)maxsizecacheable_pager#   c                 :    t         | j                              S r2   )listrn   )r   r   s    r*   wrapperz*with_cached_index_content.<locals>.wrapper   s    B~**+,,r,   rn   ry   c                 `    | j                   r t        |             S t         |             S r2   )rm   rk   r   )rn   r   r   s    r*   wrapper_wrapperz2with_cached_index_content.<locals>.wrapper_wrapper   s+    ""/566BtH~r,   )	functools	lru_cacherk   r	   r   wraps)r   r   r   s   ` @r*   with_cached_index_contentr      sl     &- 4 -d - '- __Rn d  
 r,   rn   ry   c              #   T  K   | j                   j                         }|j                  d      r^t        j                  | j
                        }|j                  dg       D ])  }t        j                  || j                        }|&| + yt        | j                        }| j                  xs d}|j                  | j
                  j                  |             | j                  }|j                  xs |}|j                  D ]!  }	t        j                   |	||      }|| # yw)z\
    Parse a Simple API's Index Content, and yield its anchor elements as Link objects.
    rA   filesNzutf-8)page_urlbase_url)r/   r&   r'   jsonloadscontentrC   r   	from_jsonr"   HTMLLinkParserencodingfeeddecoder   anchorsfrom_element)
rn   rF   datafilelinkparserr   r"   r   anchors
             r*   parse_linksr      s      &&,,.N  !FGzz$,,'HHWb) 	D>>$1D|J		
 	DHH%F}}'H
KK##H-.
((C%#H..   #I<
	s   D&D(c                   F    e Zd ZdZ	 ddededee   dededdfd	Zdefd
Z	y)ry   z5Represents one response (or page), along with its URLr   r/   r   r"   rm   r#   Nc                 J    || _         || _        || _        || _        || _        y)am  
        :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.
        N)r   r/   r   r"   rm   )r5   r   r/   r   r"   rm   s         r*   r4   zIndexContent.__init__  s)     ( "4r,   c                 ,    t        | j                        S r2   )r   r"   rw   s    r*   __str__zIndexContent.__str__  s    #DHH--r,   T)
r7   r8   r9   __doc__bytesr:   r   r{   r4   r   rJ   r,   r*   ry   ry     sY    ? $(55 5 3-	5
 5 !5 
5*. .r,   c                        e Zd ZdZdeddf fdZdedeeeee   f      ddfdZ	deeeee   f      dee   fd	Z
 xZS )
r   zf
    HTMLParser that keeps the first base HREF and a list of all anchor
    elements' attributes.
    r"   r#   Nc                 P    t         |   d       || _        d | _        g | _        y )NT)convert_charrefs)r3   r4   r"   r   r   )r5   r"   r6   s     r*   r4   zHTMLLinkParser.__init__#  s(    $/'+79r,   tagattrsc                     |dk(  r(| j                   | j                  |      }||| _         y y |dk(  r%| j                  j                  t	        |             y y )Nbasea)r   get_hrefr   appenddict)r5   r   r   hrefs       r*   handle_starttagzHTMLLinkParser.handle_starttag*  sT    &=T]]2=='D $  CZLLU, r,   c                 *    |D ]  \  }}|dk(  s|c S  y )Nr   rJ   )r5   r   namevalues       r*   r   zHTMLLinkParser.get_href2  s&      	KD%v~	 r,   )r7   r8   r9   r   r:   r4   r	   r   r   r   r   r;   r<   s   @r*   r   r     ss    
:C :D :-3 -tE#x}:L4M/N -SW -d5hsm);#<= (3- r,   r   r   reasonmeth).Nc                 <    |t         j                  } |d| |       y )Nz%Could not fetch URL %s: %s - skipping)r^   r_   )r   r   r   s      r*   _handle_get_simple_failr   9  s    
 |||	0$?r,   rm   c                     t        | j                        }t        | j                  | j                  d   || j                  |      S )Nr?   )r   r"   rm   )ri   rB   ry   r   r"   )r=   rm   r   s      r*   _make_index_contentr   C  sE     *(*:*:;H(LL- r,   c                   | j                   j                  dd      d   }t        |      }|rt        j	                  d||        y t
        j                  j                  |      \  }}}}}}|dk(  rt        j                  j                  t
        j                  j                  |            rL|j                  d      s|dz  }t
        j                  j                  |d      }t        j                  d|       	 t!        ||	      }t#        || j$                  
      S # t&        $ r t        j	                  d|        Y y t(        $ r6}t        j	                  d| |j*                  |j,                         Y d }~y d }~wt.        $ r}t1        | |       Y d }~y d }~wt2        $ r}t1        | |       Y d }~y d }~wt4        $ r6}d}	|	t7        |      z  }	t1        | |	t        j8                         Y d }~y d }~wt:        j<                  $ r}t1        | d|        Y d }~y d }~wt:        j>                  $ r t1        | d       Y y w xY w)N#r   r   zICannot look at %s URL %s because it does not support lookup as web pages.r   /z
index.htmlz# file: URL is directory, getting %sr[   )rm   z`Skipping page %s because it looks like an archive, and cannot be checked by a HTTP HEAD request.zSkipping 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) r"   splitr+   r^   warningrP   rQ   urlparseosrU   isdirrD   url2pathnameendswithurljoinr_   ra   r   rm   rI   r.   r0   r/   r   r   r   r   r:   infor   ConnectionErrorTimeout)
r   rK   r"   
vcs_schemer)   _rU   rX   excr   s
             r*   _get_index_contentr   P  s   
((..a
 
#C #3'JW	

   &||44S9FAtQ1BGGMM&..*E*Ed*KL ||C 3JC
 ll""35:C@U#C9: #4D<S<STT9  
1	
8 /  
A 	
 	
,  " +c**   +c**   @G#c(f6;;??  ## B(:3%&@AA
 	  3k2 	3sT   9D H=>H=,E77H=FH= F11H==,G..H=H"H=<H=c                   :    e Zd ZU eee      ed<   eee      ed<   y)CollectedSources
find_links
index_urlsN)r7   r8   r9   r   r   r   __annotations__rJ   r,   r*   r   r     s"    *-..*-..r,   r   c            
           e Zd ZdZdededdfdZe	 ddedede	dd fd	       Z
edee   fd
       Zdedee   fdZdededefdZy)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.
    rK   search_scoper#   Nc                      || _         || _        y r2   )r   rK   )r5   rK   r   s      r*   r4   zLinkCollector.__init__  s    
 )r,   optionssuppress_no_indexc                 0   |j                   g|j                  z   }|j                  r0|s.t        j	                  ddj                  d |D                     g }|j                  xs g }t        j                  |||j                        }t        ||      }|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              3   2   K   | ]  }t        |        y wr2   r   ).0r"   s     r*   	<genexpr>z'LinkCollector.create.<locals>.<genexpr>  s     Is-c2Is   )r   r   no_index)rK   r   )
	index_urlextra_index_urlsr   r^   r_   r`   r   r   creater   )clsrK   r   r   r   r   r   link_collectors           r*   r   zLinkCollector.create  s     ''(7+C+CC
$5LL&IjII J ''-2
"))!!%%

 '%
 r,   c                 .    | j                   j                  S r2   )r   r   rw   s    r*   r   zLinkCollector.find_links  s      +++r,   locationc                 0    t        || j                        S )z>
        Fetch an HTML page containing package links.
        r[   )r   rK   )r5   r   s     r*   fetch_responsezLinkCollector.fetch_response  s     "(DLLAAr,   project_namecandidates_from_pagec                     t        j                   fd j                  j                        D              j	                         }t        j                   fd j
                  D              j	                         }t        j                  t        j                        rwt        j                  ||      D cg c]  }||j                  d|j                   ! }}t        |       d dg|z   }t        j                  dj                  |             t!        t#        |      t#        |            S c c}w )Nc           	   3   h   K   | ])  }t        |j                  j                  d d        + yw)Fr   page_validator
expand_dirrm   r   Nr    rK   is_secure_originr   locr   r   r5   s     r*   r   z0LinkCollector.collect_sources.<locals>.<genexpr>  sA      
4
  %9#||<< #() 
4
   /2c           	   3   h   K   | ])  }t        |j                  j                  d d        + yw)Tr   Nr   r   s     r*   r   z0LinkCollector.collect_sources.<locals>.<genexpr>  sA      
5
  %9#||<<#') 
5
r   z* z' location(s) to search for versions of :
)r   r   )collectionsOrderedDictr   get_index_urls_locationsvaluesr   r^   isEnabledForloggingDEBUG	itertoolschainr   r(   r_   r`   r   r   )r5   r   r   index_url_sourcesfind_links_sourcessliness   ```    r*   collect_sourceszLinkCollector.collect_sources  s2    (33 
4
 ((AA,O
4
 

 &( 	 )44 
5
 
5
 

 &( 	 w}}- #);=NO=QVV%7 QVVHE  u:, ##/.3 E LL5)*./-.
 	
s   >$D<)F)r7   r8   r9   r   r   r   r4   classmethodr   r{   r   propertyr	   r:   r   r   r   ry   r   r   r   r  rJ   r,   r*   r   r     s     " 
	 
 #(	   	
 
 B ,DI , ,Bt B0F B,
,
 1,
 
	,
r,   r   r2   r   )Rr   r   email.messagerd   r   r  r   r   r   urllib.parserP   urllib.requesthtml.parserr   optparser   typingr   r   r   r   r	   r
   r   r   r   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.vcsr   sourcesr   r   r    r!   rz   	getLoggerr7   r^   r:   ResponseHeadersr+   	Exceptionr.   rG   rI   rY   ra   ri   rk   r~   r   r   ry   r   r   r{   r   r   r   r   rJ   r,   r*   <module>r     s+         	   "     ! ) @ ; * 9 4 8 9 9 ! A AH			8	$ c*3 8C= )Y )@ @d @,	y 	c J 4 $<c <J <8 <~ HSM 	# 	# 
*  ( n $  8. .8Z > +/@
@#y.!@ 8I&
'@ 
	@ 48

,0

:T :z :h~>V :z/z /
i
 i
r,   