o
    Zh                     @  s  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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 ddlmZ ddl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)m*Z*m+Z+m,Z, dd	l-m.Z. d
dl/m0Z0m1Z1 ddl2m3Z3 ddl4m5Z5 e6dZ7e6dej8Z9e6dZ:e6dej8j;Z<d= Z>g dZ?dZ@dejA dejBjC dejBjD ZEdd ZFdd ZGdd ZHdFddZIdFd d!ZJdFd"d#ZKde#dfd$d%ZLd&d' ZMe6d(ej8ZN	 eMd)d* ZOG d+d, d,ZPG d-d. d.ePZQG d/d0 d0e%ZRe6d1jSZTd2d3 ZUd4d5 ZVdGd6d7ZWd8d9 ZXG d:d; d;eZYG d<d= d=ejZZ[ej\j]fd>d?Z^d@dA Z_eWe@e^Z^dBdC Z`dDdE ZadS )Hz$PyPI and direct package downloading.    )annotationsN)	translatewraps)
NamedTupleunique_everseen)BINARY_DISTCHECKOUT_DISTDEVELOP_DISTEGG_DISTSOURCE_DISTDistributionEnvironmentRequirementfind_distributionsnormalize_pathparse_version	safe_namesafe_versionto_filename)Wheel   )_cfg_read_utf8_with_fallback_read_utf8_with_fallback)log)DistutilsErrorz^egg=([-A-Za-z0-9_.+!]+)$zhref\s*=\s*['"]?([^'"> ]+)z<a href="([^"#]+)">([^<]+)</a>\n\s+\(<a (?:title="MD5 hash"\n\s+)href="[^?]+\?:action=show_md5&amp;digest=([0-9a-f]{32})">md5</a>\)z([-+.a-z0-9]{2,}):z.tar.gz .tar.bz2 .tar .zip .tgz)PackageIndexdistros_for_urlparse_bdist_wininstinterpret_distro_name   zsetuptools/z Python-urllib/.c              
   C  s6   zt | W S  ty } ztd| |d }~ww )Nz/Not a URL, existing file, or requirement spec: )r   parse
ValueErrorr   )spece r'   O/var/www/html/lang_env/lib/python3.10/site-packages/setuptools/package_index.pyparse_requirement_argH   s   r)   c                 C  s   |   }d\}}}|drS|dr| dd }d}n7|ddr1| d	d
 }| dd }d}n"|dr?| dd }d}n|ddrS| d	d
 }| dd }d}|||fS )z=Return (base,pyversion) or (None,None) for possible .exe name)NNN.exez
.win32.exeNiwin32z	.win32-pyiiz.win-amd64.exeiz	win-amd64z.win-amd64-pyi)lowerendswith
startswith)namer-   basepy_verplatr'   r'   r(   r   Q   s$   




r   c           	      C  sx   t j| }|\}}}}}}t j|dd }|dkr,|dkr,t j|dd }d|v r8|dd\}}||fS )N/zsourceforge.netdownload#r   )urllibr#   urlparseunquotesplit)	urlparts_schemeserverpath_parameters_queryfragmentr1   r'   r'   r(   egg_info_for_urli   s   rE   c                 c  sZ    t | \}}t| ||E dH  |r)t|}|r+t| |d|tdE dH  dS dS dS )zEYield egg or source distribution objects that might be found at a URLNr   )
precedence)rE   distros_for_locationEGG_FRAGMENTmatchr    groupr
   )r=   metadatar1   rD   rI   r'   r'   r(   r   t   s   
r   c                 C  s   | dr|dd }| drd|v rt| ||gS | dr<d|v r<t|}| s/g S t| |j|jtd dgS | d	rUt|\}}}|durUt	| |||t
|S tD ]}| |ro|dt|  }t	| ||  S qWg S )
z:Yield egg or source distribution objects based on basename.egg.zipNr,   z.egg-z.whlr   )locationproject_nameversionrF   r*   )r.   r   from_locationr   is_compatiblerO   rP   r   r   r    r	   
EXTENSIONSlen)rN   basenamerK   wheelZwin_baser2   platformextr'   r'   r(   rG      s6   

	
rG   c                 C  s   t t| tj| |S )zEYield possible egg or source distribution objects based on a filename)rG   r   osrA   rU   )filenamerK   r'   r'   r(   distros_for_filename   s   r[   c              	   c  s    | d}|stdd |dd D rdS tt|D ]}|| dd  r+ nqt|}t| |d|d| d||d |||dV  dS )zGenerate the interpretation of a source distro name

    Note: if `location` is a filesystem filename, you should call
    ``pkg_resources.normalize_path()`` on it before passing it to this
    routine!
    rM   c                 s  s    | ]	}t d |V  qdS )z	py\d\.\d$N)rerI   ).0pr'   r'   r(   	<genexpr>   s    z(interpret_distro_name.<locals>.<genexpr>   Nr   )
py_versionrF   rW   )r<   anyrangerT   isdigitr   join)rN   rU   rK   ra   rF   rW   r>   r^   r'   r'   r(   r       s$   

r    c                   s   t   fdd}|S )zs
    Wrap a function returning an iterable such that the resulting iterable
    only ever yields unique items.
    c                    s   t  | i |S Nr   )argskwargsfuncr'   r(   wrapper   s   zunique_values.<locals>.wrapperr   )rj   rk   r'   ri   r(   unique_values   s   rl   z3<([^>]*\srel\s{0,10}=\s{0,10}['"]?([^'" >]+)[^>]*)>c              	   c  s    t |D ]2}| \}}tttj| d}d|v s#d|v r8t	|D ]}t
j| t|dV  q(qdD ] }||}|dkr[t	||}|r[t
j| t|dV  q;dS )zEFind rel="homepage" and rel="download" links in `page`, yielding URLs,Zhomepager6   r   )z<th>Home Pagez<th>Download URLr5   N)RELfinditergroupssetmapstrstripr-   r<   HREFr9   r#   urljoin
htmldecoderJ   findsearch)r=   pagerI   tagrelZrelsposr'   r'   r(   find_external_links   s    
r~   c                   @  s(   e Zd ZdZdd Zdd Zdd ZdS )	ContentCheckerzP
    A null content checker that defines the interface for checking content
    c                 C     dS )z3
        Feed a block of data to the hash.
        Nr'   selfblockr'   r'   r(   feed      zContentChecker.feedc                 C  r   )zC
        Check the hash. Return False if validation fails.
        Tr'   r   r'   r'   r(   is_valid   r   zContentChecker.is_validc                 C  r   )zu
        Call reporter with information about the checker (hash name)
        substituted into the template.
        Nr'   )r   reportertemplater'   r'   r(   report  s   zContentChecker.reportN)__name__
__module____qualname____doc__r   r   r   r'   r'   r'   r(   r      s
    r   c                   @  sD   e Zd ZedZdddZedd Zdd	 Z	d
d Z
dd ZdS )HashCheckerzK(?P<hash_name>sha1|sha224|sha384|sha256|sha512|md5)=(?P<expected>[a-f0-9]+)returnNonec                 C  s   || _ t|| _|| _d S rf   )	hash_namehashlibnewhashexpected)r   r   r   r'   r'   r(   __init__  s   
zHashChecker.__init__c                 C  sB   t j|d }|st S | j|}|st S | di | S )z5Construct a (possibly null) ContentChecker from a URLr5   Nr'   )r9   r#   r:   r   patternry   	groupdict)clsr=   rD   rI   r'   r'   r(   from_url  s   zHashChecker.from_urlc                 C  s   | j | d S rf   )r   updater   r'   r'   r(   r   !     zHashChecker.feedc                 C  s   | j  | jkS rf   )r   	hexdigestr   r   r'   r'   r(   r   $  r   zHashChecker.is_validc                 C  s   || j  }||S rf   )r   )r   r   r   msgr'   r'   r(   r   '  s   
zHashChecker.reportNr   r   )r   r   r   r\   compiler   r   classmethodr   r   r   r   r'   r'   r'   r(   r     s    


r   c                      s  e Zd ZdZ				d\d] fddZ fddZd^d_ddZd^d`ddZd^daddZdbddZ	dbddZ
dd Zd d! Zdbd"d#Zdcdbd$d%Zdbd&d'Zdc fd(d)	Zdbd*d+Zdbd,d-Zd.d/ Zdbd0d1Zd2d3 Z				ddded8d9Z	dfdgd;d<Zd=d> Zd?Zd@dA ZdbdBdCZdcdDdEZdFdG ZedHdI ZdJdK Z dLdM Z!dbdNdOZ"dPdQ Z#dRdS Z$edTdU Z%dbdVdWZ&dbdXdYZ'dbdZd[Z(  Z)S )hr   z;A distribution index that scans web pages for download URLshttps://pypi.org/simple/*NT	index_urlrs   
verify_sslboolr   r   c                   sl   t  j|i | |dd |d   | _i | _i | _i | _td	t
t|j| _g | _tjj| _d S )Nr4   |)superr   r.   r   scanned_urlsfetched_urlspackage_pagesr\   r   re   rr   r   rI   allowsto_scanr9   requesturlopenopener)r   r   hostsZ	ca_bundler   rg   kw	__class__r'   r(   r   /  s   	zPackageIndex.__init__c                   s0   zt |j W n
 ty   Y d S w t |S rf   )r   rP   	Exceptionr   add)r   distr   r'   r(   r   A  s   zPackageIndex.addFretrievec                 C  s  || j v r	|s	dS d| j |< t|s| | dS tt|}|r.| |s(dS | d| |s7|r7|| jv rAtt| j	| dS | |sMd| j|< dS | 
d| d| j|< d}| ||| }|du rhdS t|tjjr}|jdkr}| 
d|j  d| j|j< d|jd	d
 vr|  dS |j}| }t|tst|tjjrd}n|jdpd}||d}|  t|D ]}	tj|t|	 d}
| !|
 q|"| j#rt$|dddkr| %||}dS dS dS )z<Evaluate a URL as a possible download, and maybe retrieve itNTzFound link: %sz
Reading %sz<Download error on %s: %%s -- Some packages may not be found!i  zAuthentication error: htmlcontent-type zlatin-1charsetignorer   code  )&r   
URL_SCHEMEprocess_filenamelistr   url_okdebugr   rr   r   infoopen_url
isinstancer9   error	HTTPErrorr   r   r=   headersgetr-   closereadrs   	get_paramdecoderu   ro   r#   rv   rw   rJ   process_urlr/   r   getattrprocess_index)r   r=   r   diststmplfr1   rz   r   rI   linkr'   r'   r(   r   J  sV   






zPackageIndex.process_urlnestedc                 C  s   t j|s| d| d S t j|r/|s/t j|}t |D ]}| t j||d q!t	|}|rE| 
d| tt| j| d S d S )NzNot found: %sTz	Found: %s)rY   rA   existswarnisdirrealpathlistdirr   re   r[   r   r   rr   r   )r   fnr   rA   itemr   r'   r'   r(   r     s   zPackageIndex.process_filenamefatalc                 C  s`   t |}|o|d dk}|s| tj|d rdS d}|r(t|| | || dS )Nr   fileTz
Note: Bypassing %s (disallowed host; see https://setuptools.pypa.io/en/latest/deprecated/easy_install.html#restricting-downloads-with-allow-hosts for details).
F)	r   rJ   r-   r   r9   r#   r:   r   r   )r   r=   r   sis_filer   r'   r'   r(   r     s   zPackageIndex.url_okc                 C  s2   t tjj|}dd |D }tt| j| d S )Nc                 s  s2    | ]}t |D ]}|d r	||fV  q	qdS )z	.egg-linkN)rY   r   r.   )r]   rA   entryr'   r'   r(   r_     s    z.PackageIndex.scan_egg_links.<locals>.<genexpr>)filterrY   rA   r   r   	itertoolsstarmapscan_egg_link)r   search_pathdirsZ	egg_linksr'   r'   r(   scan_egg_links  s
   zPackageIndex.scan_egg_linksc                 C  s   t tj||}ttd ttj|	 }t
|dkrd S |\}}ttj||D ]}tjj|g|R  |_t|_| | q+d S )Nr`   )r   rY   rA   re   r   r   rr   rs   rt   
splitlinesrT   r   rN   r   rF   r   )r   rA   r   contentlinesZegg_pathZ_setup_pathr   r'   r'   r(   r     s   zPackageIndex.scan_egg_linkc                 C  s   d}| | js
|S tttjj|t| jd  d}t|dks)d|d v r+|S t	|d }t
|d }d| j| i |< t|t|fS )NNNr4   r`   r8   r   r   T)r/   r   r   rr   r9   r#   r;   rT   r<   r   r   r   
setdefaultr-   r   )r   r   ZNO_MATCH_SENTINELr>   pkgverr'   r'   r(   _scan  s   &zPackageIndex._scanc           	   
   C  s   t |D ]}z| tj|t|d W q ty!   Y qw | |\}}|s-dS t	||D ]&}t
|\}}|drS|sS|rN|d| d| 7 }n| | | | q2tdd |S )z#Process the contents of a PyPI pager   r   .pyz#egg=rM   c                 S  s   dj | ddd S )Nz<a href="{}#md5={}">{}</a>r      r`   )formatrJ   )mr'   r'   r(   <lambda>      z,PackageIndex.process_index.<locals>.<lambda>)ru   ro   r   r9   r#   rv   rw   rJ   r$   r~   rE   r.   need_version_infoscan_urlPYPI_MD5sub)	r   r=   rz   rI   r   r   new_urlr1   fragr'   r'   r(   r     s&   "
zPackageIndex.process_indexc                 C  s   |  d| d S )NzPPage at %s links to .py file(s) without version info; an index scan is required.)scan_allr   r=   r'   r'   r(   r     s   zPackageIndex.need_version_infoc                 G  s<   | j | jvr|r| j|g|R   | d | | j  d S )Nz6Scanning index of all packages (this may take a while))r   r   r   r   r   r   r   rg   r'   r'   r(   r    s
   
zPackageIndex.scan_allc                 C  sz   |  | j|j d  | j|js|  | j|j d  | j|js)| | t| j|jdD ]}|  | q3d S )Nr4   r'   )	r   r   unsafe_namer   r   keyrO   not_found_in_indexr   )r   requirementr=   r'   r'   r(   find_packages  s   
zPackageIndex.find_packagesc                   sN   |    | | | |j D ]}||v r|  S | d|| qt ||S )Nz%s does not match %s)prescanr  r  r   r   obtain)r   r  	installerr   r   r'   r(   r
    s   
zPackageIndex.obtainc                 C  sR   | | jd|  | s'|  t| t|jj dtj	
| ddS )z-
        checker is a ContentChecker
        zValidating %s checksum for z validation failed for z; possible download problem?N)r   r   r   r   rY   unlinkr   r   r0   rA   rU   )r   checkerrZ   tfpr'   r'   r(   
check_hash  s   
zPackageIndex.check_hashc                 C  sN   |D ]"}| j du st|r|dstt|r| | q| j | qdS )z;Add `urls` to the list that will be prescanned for searchesNfile:)r   r   r/   r   r   r   append)r   urlsr=   r'   r'   r(   add_find_links  s   

zPackageIndex.add_find_linksc                 C  s"   | j rtt| j| j  d| _ dS )z7Scan urls scheduled for prescanning (e.g. --find-links)N)r   r   rr   r   r   r'   r'   r(   r	  (  s   
zPackageIndex.prescanc                 C  s<   | |j  r| jd}}n| jd}}|||j |   d S )Nz#Couldn't retrieve index page for %rz3Couldn't find index page for %r (maybe misspelled?))r  r   r   r  r  )r   r  methr   r'   r'   r(   r  .  s
   
zPackageIndex.not_found_in_indexc                 C  sv   t |ts1t|}|r%| ||}t|\}}|dr#| |||}|S tj	|r-|S t
|}t| ||ddS )a  Locate and/or download `spec` to `tmpdir`, returning a local path

        `spec` may be a ``Requirement`` object, or a string containing a URL,
        an existing local filename, or a project/version requirement spec
        (i.e. the string form of a ``Requirement`` object).  If it is the URL
        of a .py file with an unambiguous ``#egg=name-version`` tag (i.e., one
        that escapes ``-`` as ``_`` throughout), a trivial ``setup.py`` is
        automatically created alongside the downloaded file.

        If `spec` is a ``Requirement`` object or a string containing a
        project/version requirement spec, this method returns the location of
        a matching distribution (possibly after downloading it to `tmpdir`).
        If `spec` is a locally existing file or directory name, it is simply
        returned unchanged.  If `spec` is a URL, it is downloaded to a subpath
        of `tmpdir`, and the local filename is returned.  Various errors may be
        raised if a problem occurs during downloading.
        r   rN   N)r   r   r   _download_urlrE   r.   	gen_setuprY   rA   r   r)   r   fetch_distribution)r   r%   tmpdirschemefoundr1   rD   r'   r'   r(   r6   6  s   

zPackageIndex.download
force_scansource
develop_okDistribution | Nonec           	        s    d| t d}dd fdd}|r&  | ||}|s1|dur1|||}|du rBjdur>  ||}|du rQ|sQ| ||}|du rbdr\dp]d	| dS  d
| |j|jdS )a|  Obtain a distribution suitable for fulfilling `requirement`

        `requirement` must be a ``pkg_resources.Requirement`` instance.
        If necessary, or if the `force_scan` flag is set, the requirement is
        searched for in the (online) package index as well as the locally
        installed packages.  If a distribution matching `requirement` is found,
        the returned distribution's ``location`` is the value you would have
        gotten from calling the ``download()`` method with the matching
        distribution's URL or filename.  If no matching distribution is found,
        ``None`` is returned.

        If the `source` flag is set, only source distributions and source
        checkout links will be considered.  Unless the `develop_ok` flag is
        set, development and system eggs (i.e., those using the ``.egg-info``
        format) will be ignored.
        zSearching for %sNenvEnvironment | Nonec                   s   |d u r}|| j  D ]<}|jtkr$ s$|vr#d| | q|| v o/|jtkp/ }|rG|j}||_t	j
|jrG|  S qd S )Nz&Skipping development or system egg: %s)r  rF   r   r   r   r   r6   rN   download_locationrY   rA   r   )reqr  r   testlocr  r   Zskippedr  r  r'   r(   rx   v  s&   
z-PackageIndex.fetch_distribution.<locals>.findz:No local packages or working download links found for %s%sza source distribution of r   zBest match: %s)rN   rf   )r  r   )r   rq   r	  r  r   r   cloner!  )	r   r  r  r  r  r  Zlocal_indexr   rx   r'   r%  r(   r  X  s4   




zPackageIndex.fetch_distribution
str | Nonec                 C  s"   |  ||||}|dur|jS dS )a3  Obtain a file suitable for fulfilling `requirement`

        DEPRECATED; use the ``fetch_distribution()`` method now instead.  For
        backward compatibility, this routine is identical but returns the
        ``location`` of the downloaded distribution instead of a distribution
        object.
        N)r  rN   )r   r  r  r  r  r   r'   r'   r(   fetch  s   
zPackageIndex.fetchc           	      C  s"  t |}|rdd t||dd D pg }t|dkrtj|}tj||krGtj	||}tj
|r?tj||sGt|| |}ttj	|dddd$}|d|d	 jd
|d	 jdtj|d	 d W d    |S 1 szw   Y  |S |rtd|d|td)Nc                 S  s   g | ]}|j r|qS r'   )rP   )r]   dr'   r'   r(   
<listcomp>  s    z*PackageIndex.gen_setup.<locals>.<listcomp>r   zsetup.pywzutf-8)encodingz(from setuptools import setup
setup(name=r   z
, version=z, py_modules=[z])
z9Can't unambiguously interpret project/version identifier zI; any dashes in the name or version should be escaped using underscores. zpCan't process plain .py files without an '#egg=name-version' suffix to enable automatic setup script generation.)rH   rI   r    rJ   rT   rY   rA   rU   dirnamere   r   samefileshutilcopy2openwriterO   rP   splitextr   )	r   rZ   rD   r  rI   r   rU   dstr   r'   r'   r(   r    sL   


zPackageIndex.gen_setupi    c                 C  s:  |  d| d }zt|}| |}t|tjjr)td| d|j	 d|j
 |  }d}| j}d}d|v rM|d}	ttt|	}| ||||| t|d	1}
	 ||}|rs|| |
| |d7 }| ||||| nnqT| |||
 W d    n1 sw   Y  |W |r|  S S |r|  w w )NzDownloading %szCan't download :  r   r5   zcontent-lengthzContent-LengthwbTr   )r   r   r   r   r   r9   r   r   r   r   r   dl_blocksizeget_allmaxrr   int
reporthookr1  r   r   r2  r  r   )r   r=   rZ   fpr  r   blocknumbssizesizesr  r   r'   r'   r(   _download_to  sB   





	

zPackageIndex._download_toc                 C  s   d S rf   r'   )r   r=   rZ   r>  Zblksizer@  r'   r'   r(   r<       zPackageIndex.reporthookc              
   C  s  | dr	t|S zt|| jW S  ttjjfyE } z%ddd |j	D }|r0| 
|| n
t| d| |W Y d }~d S d }~w tjjyZ } z|W  Y d }~S d }~w tjjy } z|rm| 
||j ntd| d|j |W Y d }~d S d }~w tjjy } z|r| 
||j nt| d|j |W Y d }~d S d }~w tjjtfy } z|r| 
|| ntd| d| |W Y d }~d S d }~ww )Nr  r6  c                 S  s   g | ]}t |qS r'   )rs   )r]   argr'   r'   r(   r*    r   z)PackageIndex.open_url.<locals>.<listcomp>zDownload error for r5  z7 returned a bad status line. The server might be down, )r/   
local_openopen_with_authr   r$   httpclient
InvalidURLre   rg   r   r   r9   r   r   URLErrorreasonBadStatusLinelineHTTPExceptionOSError)r   r=   warningvr   r'   r'   r(   r   
  sN   
zPackageIndex.open_urlc                 C  sv   t |\}}|rd|v r|dddd}d|v snd}|dr(|d d }tj||}| ||p:| ||S )Nz..r"   \_Z__downloaded__rL   r,   )rE   replacer.   rY   rA   re   _download_vcs_download_other)r   r=   r  r0   Z	_fragmentrZ   r'   r'   r(   r  *  s   
zPackageIndex._download_urlc                 C  sL   t j| j}|d\}}}tddgdgt|  }tt|h|@ dS )a  
        >>> rvcs = PackageIndex._resolve_vcs
        >>> rvcs('git+http://foo/bar')
        'git'
        >>> rvcs('hg+https://foo/bar')
        'hg'
        >>> rvcs('git:myhost')
        'git'
        >>> rvcs('hg:myhost')
        >>> rvcs('http://foo/bar')
        +svngithgN)	r9   r#   urlsplitr  	partitionrq   r   nextiter)r=   r  presep_postallowedr'   r'   r(   _resolve_vcs;  s   zPackageIndex._resolve_vcsc              
   C  s   |  |}|s	d S |dkrtd| |d\}}}| |\}}| d| d| d|  t|dd||g t|d	|d
d|g|d|dd	d|dgd}|d urb| d|  t||  |S )NrX  z/Invalid config, SVN download is not supported: r8   zDoing z clone from z to r&  z--quietz-Ccheckoutz--cwdupz-rz-q)rY  rZ  zChecking out )rc  r   r\  _vcs_split_rev_from_urlr   
subprocess
check_calldict)r   r=   Zspec_filenamevcsrZ   rS  revZco_commandsr'   r'   r(   rU  N  s&   
zPackageIndex._download_vcsc                 C  sD   t j|j}|dkrt jt j|jS | |d | 	||S )Nr   T)
r9   r#   r[  r  r   url2pathnamer:   rA   r   _attempt_download)r   r=   rZ   r  r'   r'   r(   rV  g  s
   zPackageIndex._download_otherc                 C  s   |  |d d S )NT)r   r  r'   r'   r(   r   o  r   zPackageIndex.scan_urlc                 C  s2   |  ||}d|dd v r| |||S |S )Nr   r   r   )rB  r   r-   _invalid_download_html)r   r=   rZ   r   r'   r'   r(   rm  r  s   zPackageIndex._attempt_downloadc                 C  s   t | td| )NzUnexpected HTML page found at )rY   r  r   )r   r=   r   rZ   r'   r'   r(   rn  y  s   
z#PackageIndex._invalid_download_htmlc                 C  st   t j| }|jddd }|jd\}}}|d\}}}|r&||fn|df\}}	|j||dd	 }
|
|	fS )	a  
        Given a possible VCS URL, return a clean URL and resolved revision if any.

        >>> vsrfu = PackageIndex._vcs_split_rev_from_url
        >>> vsrfu('git+https://github.com/pypa/setuptools@v69.0.0#egg-info=setuptools')
        ('https://github.com/pypa/setuptools', 'v69.0.0')
        >>> vsrfu('git+https://github.com/pypa/setuptools#egg-info=setuptools')
        ('https://github.com/pypa/setuptools', None)
        >>> vsrfu('http://foo/bar')
        ('http://foo/bar', None)
        rW  r   r5   r8   @Nr   )r  rA   rD   )
r9   r#   r[  r  r<   rA   r\  
rpartition_replacegeturl)r=   r>   Zclean_schemeZno_fragment_pathrS  r_  r`  postZ
clean_pathrk  resolvedr'   r'   r(   rf  }  s   z$PackageIndex._vcs_split_rev_from_urlc                 G     t j|g|R   d S rf   )r   r   r  r'   r'   r(   r        zPackageIndex.debugc                 G  ru  rf   )r   r   r  r'   r'   r(   r     rv  zPackageIndex.infoc                 G  ru  rf   )r   r   r  r'   r'   r(   r     rv  zPackageIndex.warn)r   r   NT)r   rs   r   r   r   r   )F)r   r   r   r   )r   r   r   r   )r   r   r   r   r   rf   )FFFN)r  r   r  r   r  r   r   r  )FF)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  r6   r  r(  r  r8  rB  r<  r   r  staticmethodrc  rU  rV  r   rm  rn  rf  r   r   r   __classcell__r'   r'   r   r(   r   ,  sb    	5





	

&S)
"
 




r   z!&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?c                 C  s   |  d}t|S )Nr   )rJ   r   unescape)rI   whatr'   r'   r(   decode_entity  s   

r{  c                 C  s
   t t| S )a  
    Decode HTML entities in the given text.

    >>> htmldecode(
    ...     'https://../package_name-0.1.2.tar.gz'
    ...     '?tokena=A&amp;tokenb=B">package_name-0.1.2.tar.gz')
    'https://../package_name-0.1.2.tar.gz?tokena=A&tokenb=B">package_name-0.1.2.tar.gz'
    )
entity_subr{  )textr'   r'   r(   rw     s   
	rw   c                   s    fdd}|S )Nc                   s    fdd}|S )Nc               	     s:   t  }t  z | i |W t | S t | w rf   )socketgetdefaulttimeoutsetdefaulttimeout)rg   rh   Zold_timeout)rj   timeoutr'   r(   _socket_timeout  s
   
z@socket_timeout.<locals>._socket_timeout.<locals>._socket_timeoutr'   )rj   r  r  ri   r(   r    s   z'socket_timeout.<locals>._socket_timeoutr'   )r  r  r'   r  r(   socket_timeout  s   r  c                 C  s2   t j| }| }t|}| }|ddS )a9  
    Encode auth from a URL suitable for an HTTP header.
    >>> str(_encode_auth('username%3Apassword'))
    'dXNlcm5hbWU6cGFzc3dvcmQ='

    Long auth strings should not cause a newline to be inserted.
    >>> long_auth = 'username:' + 'password'*10
    >>> chr(10) in str(_encode_auth(long_auth))
    False
    
r   )r9   r#   r;   encodebase64	b64encoder   rT  )authZauth_sZ
auth_bytesZencoded_bytesencodedr'   r'   r(   _encode_auth  s
   
r  c                   @  s,   e Zd ZU dZded< ded< d	ddZdS )

Credentialz
    A username/password pair.

    Displayed separated by `:`.
    >>> str(Credential('username', 'password'))
    'username:password'
    rs   usernamepasswordr   c                 C  s   | j  d| j S )N:)r  r  r   r'   r'   r(   __str__  s   zCredential.__str__N)r   rs   )r   r   r   r   __annotations__r  r'   r'   r'   r(   r    s
   
 r  c                      s8   e Zd Z fddZedd Zdd Zdd Z  ZS )	
PyPIConfigc                   sP   t g dd}t | tjtjdd}tj|r&t	| | dS dS )z%
        Load from ~/.pypirc
        )r  r  
repositoryr   ~z.pypircN)
ri  fromkeysr   r   rY   rA   re   
expanduserr   r   )r   defaultsrcr   r'   r(   r     s   zPyPIConfig.__init__c                   s&    fdd   D }tt j|S )Nc                   s    g | ]}  |d  r|qS )r  )r   rt   )r]   sectionr   r'   r(   r*    s    z2PyPIConfig.creds_by_repository.<locals>.<listcomp>)sectionsri  rr   _get_repo_cred)r   Zsections_with_repositoriesr'   r   r(   creds_by_repository  s   
zPyPIConfig.creds_by_repositoryc                 C  s6   |  |d }|t|  |d |  |d fS )Nr  r  r  )r   rt   r  )r   r  repor'   r'   r(   r    s
   zPyPIConfig._get_repo_credc                 C  s*   | j  D ]\}}||r|  S qdS )z
        If the URL indicated appears to be a repository defined in this
        config, return the credential for that repository.
        N)r  itemsr/   )r   r=   r  credr'   r'   r(   find_credential  s
   
zPyPIConfig.find_credential)	r   r   r   r   propertyr  r  r  rx  r'   r'   r   r(   r    s    
	r  c                 C  s>  t j| }|\}}}}}}|drtjd|dv r$t|\}	}
nd\}	}
|	sDt 	| }|rDt
|}	|j| f}tjdg|R   |	rgdt|	 }	||
||||f}t j|}t j|}|d|	 nt j| }|dt ||}|	rt j|j\}}}}}}||kr||
kr||||||f}t j||_|S )	z4Open a urllib2 request, handling HTTP authenticationr  znonnumeric port: '')rG  httpsr   z*Authenticating as %s for %s (from .pypirc)zBasic Authorizationz
User-Agent)r9   r#   r:   r.   rG  rH  rI  
_splituserr  r  rs   r  r   r   r  
urlunparser   Request
add_header
user_agentr=   )r=   r   parsedr  netlocrA   paramsqueryr   r  addressr  r   r>   r   r   r=  s2Zh2Zpath2Zparam2Zquery2Zfrag2r'   r'   r(   rF    s8   

rF  c                 C  s$   |  d\}}} |r|| fS d| fS )zNsplituser('user[:passwd]@host[:port]')
    --> 'user[:passwd]', 'host[:port]'.ro  N)rp  )hostuserdelimr'   r'   r(   r  I  s   r  c                 C  s   | S rf   r'   )r=   r'   r'   r(   
fix_sf_urlT  rC  r  c                 C  s  t j| \}}}}}}t j|}tj|rt j| S |	drktj
|rkg }t|D ])}	tj||	}
|	dkrCt|
} n#tj
|
rM|	d7 }	|d|	 d|	 d q0d}|j| d|d}d	\}}nd
\}}}ddi}t|}t j| ||||S )z7Read a local path, with special support for directoriesr4   z
index.htmlz	<a href="z">z</a>zB<html><head><title>{url}</title></head><body>{files}</body></html>r  )r=   files)   OK)r   zPath not foundz	Not foundr   z	text/html)r9   r#   r:   r   rl  rY   rA   isfiler   r.   r   r   re   r   r  r   ioStringIOr   r   )r=   r?   Z_serverrA   Z_paramrC   Z_fragrZ   r  r   filepathbodyr   statusmessager   Zbody_streamr'   r'   r(   rE  X  s*   


rE  rf   )r!   )br   
__future__r   r  configparserr   r   http.clientrG  r  r   rY   r\   r/  r~  rg  sysurllib.errorr9   urllib.parseurllib.requestfnmatchr   	functoolsr   typingr   Zmore_itertoolsr   
setuptoolspkg_resourcesr	   r
   r   r   r   r   r   r   r   r   r   r   r   r   Zsetuptools.wheelr   Zunicode_utilsr   r   	distutilsr   Zdistutils.errorsr   r   rH   Iru   r   rI   r   r<   rS   __all__Z_SOCKET_TIMEOUT__version__version_infomajorminorr  r)   r   rE   r   rG   r[   r    rl   rn   r~   r   r   r   r   r|  r{  rw   r  r  r  RawConfigParserr  r   r   rF  r  r  rE  r'   r'   r'   r(   <module>   s    @
 	


#
"
!     
(0