B
    ¨j\Ð“  ã               @   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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 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"m#Z#m$Z$m%Z% ddl&m'Z'm(Z(m)Z)m*Z* ddl+m,Z, ddl-m.Z. ddl/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6 ddl7m8Z8 ddl9m:Z:m;Z;m<Z<m=Z=m>Z> ddl?m@Z@ ddlAmBZB ddlCmDZD eBr0ddlmEZE ddlFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZP ddlmQZQ ddlRmSZS ddlTmUZU ddl!mVZV eGeWeWeHeW f ZXeGeIdf ZYeGeZeQeYeHeZ f Z[d d!gZ\d"d#d$d%d&d'gZ]e ^e_¡Z`d(d)„ Zad*d+„ ZbG d,d-„ d-ecƒZdd.d/„ ZeG d0d1„ d1ecƒZfd2d3„ Zgd4d5„ ZhdJd6d7„ZidKd8d9„ZjG d:d!„ d!ekƒZld;d<„ Zmd=d>„ Znd?d@„ ZodAdB„ Zpe	 qdCe	jr¡ZsdDdE„ ZtG dFdG„ dGekƒZuedHdIƒZvdS )Lz!Routines related to PyPI, indexesé    )Úabsolute_importN)Ú
namedtuple)Úhtml5libÚrequestsÚsix)Úunescape)Ú
specifiers)Úcanonicalize_name)Úparse)Ú
RetryErrorÚSSLError)Úrequest)ÚHAS_TLSÚis_urlÚpath_to_urlÚurl_to_path)ÚBestVersionAlreadyInstalledÚDistributionNotFoundÚInvalidWheelFilenameÚUnsupportedWheel)ÚInstallationCandidate)ÚFormatControl)ÚPyPI)ÚLink)Úget_supported)Ú	ipaddress)Ú
indent_log)ÚARCHIVE_EXTENSIONSÚSUPPORTED_EXTENSIONSÚWHEEL_EXTENSIONÚnormalize_pathÚredact_password_from_url)Úcheck_requires_python)ÚMYPY_CHECK_RUNNING)ÚWheel)ÚLogger)
ÚTupleÚOptionalÚAnyÚListÚUnionÚCallableÚSetÚSequenceÚIterableÚMutableMapping)Ú_BaseVersion)ÚResponse)ÚInstallRequirement)Ú
PipSession.r   ÚPackageFinder)ÚhttpsÚ*r6   )r6   Z	localhostr6   )r6   z127.0.0.0/8r6   )r6   z::1/128r6   )Úfiler6   N)Zsshr6   r6   c             C   sB   ddl m} x0|jD ]&}|  ¡  |¡r| t|ƒ dkr|S qW dS )zgLook for VCS schemes in the URL.

    Returns the matched VCS scheme, or None if there's no match.
    r   )Ú
VcsSupportz+:N)Zpip._internal.vcsr8   ZschemesÚlowerÚ
startswithÚlen)Úurlr8   Úscheme© r>   ú2lib/python3.7/site-packages/pip/_internal/index.pyÚ_match_vcs_schemeM   s
    r@   c             C   s*   t | ƒj}xtD ]}| |¡rdS qW dS )z2Return whether the URL looks like an archive.
    TF)r   Úfilenamer   Úendswith)r<   rA   Zbad_extr>   r>   r?   Ú_is_url_like_archiveZ   s
    


rC   c                   s   e Zd Z‡ fdd„Z‡  ZS )Ú_NotHTMLc                s"   t t| ƒ ||¡ || _|| _d S )N)ÚsuperrD   Ú__init__Úcontent_typeÚrequest_desc)ÚselfrG   rH   )Ú	__class__r>   r?   rF   f   s    z_NotHTML.__init__)Ú__name__Ú
__module__Ú__qualname__rF   Ú__classcell__r>   r>   )rJ   r?   rD   e   s   rD   c             C   s.   | j  dd¡}| ¡  d¡s*t|| jjƒ‚dS )z…Check the Content-Type header to ensure the response contains HTML.

    Raises `_NotHTML` if the content type is not text/html.
    zContent-TypeÚ z	text/htmlN)ÚheadersÚgetr9   r:   rD   r   Úmethod)ZresponserG   r>   r>   r?   Ú_ensure_html_headerm   s    rS   c               @   s   e Zd ZdS )Ú_NotHTTPN)rK   rL   rM   r>   r>   r>   r?   rT   x   s   rT   c             C   sD   t  | ¡\}}}}}|dkr"tƒ ‚|j| dd}| ¡  t|ƒ dS )zÊSend a HEAD request to the URL, and ensure the response contains HTML.

    Raises `_NotHTTP` if the URL is not available for a HEAD request, or
    `_NotHTML` if the content type is not text/html.
    >   r5   ÚhttpT)Zallow_redirectsN)Úurllib_parseZurlsplitrT   ÚheadÚraise_for_statusrS   )r<   Úsessionr=   ZnetlocÚpathZqueryZfragmentÚrespr>   r>   r?   Ú_ensure_html_response|   s    r\   c             C   sH   t | ƒrt| |d t d| ¡ |j| dddœd}| ¡  t|ƒ |S )a  Access an HTML page 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, to avoid downloading a large file.
       Raise `_NotHTTP` if the content type cannot be determined, or
       `_NotHTML` if it is not HTML.
    2. Actually perform the request. Raise HTTP exceptions on network failures.
    3. Check the Content-Type header to make sure we got HTML, and raise
       `_NotHTML` otherwise.
    )rY   zGetting page %sz	text/htmlz	max-age=0)ZAcceptzCache-Control)rP   )rC   r\   ÚloggerÚdebugrQ   rX   rS   )r<   rY   r[   r>   r>   r?   Ú_get_html_response   s    r_   c             C   s   |d krt j}|d| |ƒ d S )Nz%Could not fetch URL %s: %s - skipping)r]   r^   )ÚlinkÚreasonÚmethr>   r>   r?   Ú_handle_get_page_failÀ   s    rc   c       
   
   C   s  |d krt dƒ‚| j dd¡d }t|ƒ}|r@t d|| ¡ d S t |¡\}}}}}}|dkrštj	 
t |¡¡rš| d¡s‚|d7 }t |d¡}t d	|¡ yt||d
}W nV tk
rÜ } zt d| ¡ W d d }~X Y n: tk
r } zt d| |j|j¡ W d d }~X Y n tjk
rB } zt| |ƒ W d d }~X Y nÔ tk
rn } zt| |ƒ W d d }~X Y n¨ tk
r° } z$d}	|	t|ƒ7 }	t| |	tjd W d d }~X Y nf tjk
râ } zt| d| ƒ W d d }~X Y n4 tjk
r   t| dƒ Y nX t|j|j|jƒS d S )Nz?_get_html_page() missing 1 required keyword argument: 'session'ú#é   r   zCannot look at %s URL %sr7   ú/z
index.htmlz# file: URL is directory, getting %s)rY   zQSkipping page %s because it looks like an archive, and cannot be checked by HEAD.z<Skipping page %s because the %s request got Content-Type: %sz4There was a problem confirming the ssl certificate: )rb   zconnection error: %sz	timed out) Ú	TypeErrorr<   Úsplitr@   r]   r^   rV   ÚurlparseÚosrZ   ÚisdirÚurllib_requestZurl2pathnamerB   Úurljoinr_   rT   rD   rH   rG   r   Z	HTTPErrorrc   r   r   ÚstrÚinfoÚConnectionErrorZTimeoutÚHTMLPageÚcontentrP   )
r`   rY   r<   Z
vcs_schemer=   Ú_rZ   r[   Úexcra   r>   r>   r?   Ú_get_html_pageË   sL    
  ru   c            	   @   sŠ   e Zd ZdZddd„Zdd„ Zed dd	„ƒZd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Ze d¡Zdd„ Zdd„ Zdd„ Zdd„ ZdS )!r4   z This finds packages.

    This is meant to match easy_install's technique for looking for
    packages, by reading pages and looking for appropriate links.
    FNc             C   sò   |dkrt dƒ‚g | _x:|D ]2}| d¡rBt|ƒ}tj |¡rB|}| j |¡ qW || _t	ƒ | _
|pptt	ƒ t	ƒ ƒ| _dd„ |r‚|ng D ƒ| _|| _|| _t|||	|
d| _|| _tsîx8t | j| j¡D ]$}t |¡}|jdkrÆt d¡ P qÆW dS )	a¯  Create a PackageFinder.

        :param format_control: A FormatControl object or None. Used to control
            the selection of source packages / binary packages when consulting
            the index and links.
        :param platform: A string or None. If None, searches for packages
            that are supported by the current system. Otherwise, will find
            packages that can be built on the platform passed in. These
            packages will only be downloaded for distribution: they will
            not be built locally.
        :param versions: A list of strings or None. This is passed directly
            to pep425tags.py in the get_supported() method.
        :param abi: A string or None. This is passed directly
            to pep425tags.py in the get_supported() method.
        :param implementation: A string or None. This is passed directly
            to pep425tags.py in the get_supported() method.
        Nz>PackageFinder() missing 1 required keyword argument: 'session'ú~c             S   s   g | ]}d |d f‘qS )r6   r>   )Ú.0Zhostr>   r>   r?   ú
<listcomp>D  s   z*PackageFinder.__init__.<locals>.<listcomp>)ÚversionsÚplatformÚabiÚimplr5   zipip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.)rg   Ú
find_linksr:   r    rj   rZ   ÚexistsÚappendÚ
index_urlsÚsetÚlogged_linksr   Úformat_controlÚsecure_originsÚallow_all_prereleasesrY   r   Ú
valid_tagsÚprefer_binaryr   Ú	itertoolsÚchainrV   ri   r=   r]   Úwarning)rI   r}   r€   r…   Ztrusted_hostsrY   rƒ   rz   ry   r{   Úimplementationr‡   r`   Znew_linkÚparsedr>   r>   r?   rF     s<     	




zPackageFinder.__init__c             C   sb   g }| j r:| j tjgkr:| d d dd„ | j D ƒ¡¡¡ | jrX| d d | j¡¡¡ d |¡S )NzLooking in indexes: {}z, c             s   s   | ]}t |ƒV  qd S )N)r!   )rw   r<   r>   r>   r?   ú	<genexpr>l  s    z8PackageFinder.get_formatted_locations.<locals>.<genexpr>zLooking in links: {}Ú
)r€   r   Z
simple_urlr   ÚformatÚjoinr}   )rI   Úlinesr>   r>   r?   Úget_formatted_locationsf  s    z%PackageFinder.get_formatted_locationsc                s  g ‰ g ‰‡ ‡fdd„}xæ| D ]Þ}t j |¡}| d¡}|s>|rÚ|rH|}nt|ƒ}t j |¡r¶|r”t j |¡}xFt  |¡D ]}|t j ||¡ƒ qxW qØ|r¤ˆ 	|¡ qØt
 d |¡¡ qút j |¡rÌ||ƒ qút
 d|¡ qt|ƒrîˆ 	|¡ qt
 d|¡ qW ˆ ˆfS )zt
        Sort locations into "files" (archives) and "urls", and return
        a pair of lists (files,urls)
        c                s8   t | ƒ}tj|ddd dkr*ˆ |¡ n
ˆ  |¡ d S )NF)Ústrictr   z	text/html)r   Ú	mimetypesZ
guess_typer   )rZ   r<   )ÚfilesÚurlsr>   r?   Ú	sort_path  s    z0PackageFinder._sort_locations.<locals>.sort_pathzfile:z)Path '{0}' is ignored: it is a directory.z:Url '%s' is ignored: it is neither a file nor a directory.zQUrl '%s' is ignored. It is either a non-existing path or lacks a specific scheme.)rj   rZ   r~   r:   r   rk   ÚrealpathÚlistdirr   r   r]   rŠ   r   Úisfiler   )Ú	locationsÚ
expand_dirr—   r<   Zis_local_pathZis_file_urlrZ   Úitemr>   )r•   r–   r?   Ú_sort_locationst  s>    




zPackageFinder._sort_locationsc       	      C   s¤   t | jƒ}tƒ }d}|jjrt|jjƒ}| | j¡sBtd|j ƒ‚| j	rLd}| 
| j¡ }|jdk	r–t d|j¡}| ¡ }t|d ƒ|d f}n| }||j||fS )a§  
        Function used to generate link sort key for link tuples.
        The greater the return value, the more preferred it is.
        If not finding wheels, then sorted by version only.
        If finding wheels, then the sort order is by version, then:
          1. existing installs
          2. wheels ordered via Wheel.support_index_min(self.valid_tags)
          3. source archives
        If prefer_binary was set, then all wheels are sorted above sources.
        Note: it was considered to embed this logic into the Link
              comparison operators, but then different sdist links
              with the same version, would have to be considered equal
        r   zB%s is not a supported wheel for this platform. It can't be sorted.re   Nz^(\d+)(.*)$)r;   r†   ÚtupleÚlocationZis_wheelr$   rA   Ú	supportedr   r‡   Zsupport_index_minÚ	build_tagÚreÚmatchÚgroupsÚintÚversion)	rI   Ú	candidateZsupport_numr¢   Zbinary_preferenceÚwheelZprir¤   Zbuild_tag_groupsr>   r>   r?   Ú_candidate_sort_key®  s$    


z!PackageFinder._candidate_sort_keyc       	   	   C   sl  t  t|ƒ¡}|j|j|jf}|d  dd¡d }x t| j D ]}||d kr`|d dkr`q@yht	 
t|d tjƒs‚|d d krŠ|d n|d  d¡¡}t	 t|d tjƒr¶|d n|d  d¡¡}W nJ tk
r   |d r|d  ¡ |d  ¡ kr|d dkrw@Y nX ||kr q@|d |d krP|d dkrP|d d k	rPq@dS W | d	|j|j¡ d
S )Nr   ú+re   éÿÿÿÿr6   Úutf8é   TzõThe repository located at %s is not a trusted or secure host and is being ignored. If this repository is available via HTTPS we recommend you use HTTPS instead, otherwise you may silence this warning and allow it anyway with '--trusted-host %s'.F)rV   ri   rn   r=   ZhostnameZportÚrsplitÚSECURE_ORIGINSr„   r   Z
ip_addressÚ
isinstancer   Z	text_typeÚdecodeZ
ip_networkÚ
ValueErrorr9   rŠ   )	rI   r]   r    rŒ   ÚoriginZprotocolZsecure_originZaddrZnetworkr>   r>   r?   Ú_validate_secure_originÓ  s>    

z%PackageFinder._validate_secure_originc                s    ‡fdd„‰ ‡ fdd„| j D ƒS )z²Returns the locations found via self.index_urls

        Checks the url_name on the main (first in the list) index and
        use this url_name to produce all locations
        c                s,   t  | t tˆ ƒ¡¡}| d¡s(|d }|S )Nrf   )Ú	posixpathr   rV   Zquoter	   rB   )r<   Zloc)Úproject_namer>   r?   Úmkurl_pypi_url%  s    
z?PackageFinder._get_index_urls_locations.<locals>.mkurl_pypi_urlc                s   g | ]}ˆ |ƒ‘qS r>   r>   )rw   r<   )r¸   r>   r?   rx   2  s    z;PackageFinder._get_index_urls_locations.<locals>.<listcomp>)r€   )rI   r·   r>   )r¸   r·   r?   Ú_get_index_urls_locations  s    z'PackageFinder._get_index_urls_locationsc          
      sj  ˆ   |¡}ˆ  |¡\}}ˆ jˆ jdd\}}dd„ t ||¡D ƒ}‡ fdd„t dd„ |D ƒdd„ |D ƒ¡D ƒ}t d	t|ƒ|¡ x|D ]}	t d
|	¡ qˆW t|ƒ}
ˆ j	 
|
¡}t||
|ƒ}ˆ  dd„ ˆ jD ƒ|¡}g }xJˆ  ||¡D ]:}t d|j¡ tƒ  | ˆ  | ¡ |¡¡ W dQ R X qæW ˆ  ||¡}|r^|jdd t dd dd„ |D ƒ¡¡ || | S )a  Find all available InstallationCandidate for project_name

        This checks index_urls and find_links.
        All versions found are returned as an InstallationCandidate list.

        See _link_package_versions for details on which files are accepted
        T)rœ   c             s   s   | ]}t |ƒV  qd S )N)r   )rw   r<   r>   r>   r?   r   C  s    z4PackageFinder.find_all_candidates.<locals>.<genexpr>c                s   g | ]}ˆ   t|¡r|‘qS r>   )rµ   r]   )rw   r`   )rI   r>   r?   rx   K  s    z5PackageFinder.find_all_candidates.<locals>.<listcomp>c             s   s   | ]}t |ƒV  qd S )N)r   )rw   r<   r>   r>   r?   r   L  s    c             s   s   | ]}t |ƒV  qd S )N)r   )rw   r<   r>   r>   r?   r   M  s    z,%d location(s) to search for versions of %s:z* %sc             s   s   | ]}t |d ƒV  qdS )z-fN)r   )rw   r<   r>   r>   r?   r   ]  s    zAnalyzing links from page %sN)ÚreversezLocal files found: %sz, c             S   s   g | ]}t |jjƒ‘qS r>   )r   r    r<   )rw   r¨   r>   r>   r?   rx   o  s   )r¹   rž   r}   rˆ   r‰   r]   r^   r;   r	   rƒ   Zget_allowed_formatsÚSearchÚ_package_versionsÚ
_get_pagesr<   r   ÚextendÚ
iter_linksÚsortr   )rI   r·   Zindex_locationsZindex_file_locZindex_url_locZfl_file_locZ
fl_url_locZfile_locationsZurl_locationsr    Úcanonical_nameÚformatsÚsearchZfind_links_versionsZpage_versionsÚpageZfile_versionsr>   )rI   r?   Úfind_all_candidates4  sD    	


 z!PackageFinder.find_all_candidatesc          
      sb  |   |j¡}t|jjdd„ |D ƒ| jr,| jnddƒ‰ ‡ fdd„|D ƒ}|r\t|| jd}nd}|jdk	rxt	|jj
ƒ}nd}|dkr¾|dkr¾t d|d td	d
„ |D ƒt	d¡¡ td| ƒ‚d}|rÜ|dksØ|j
|krÜd}|s|dk	r|rþt d|¡ nt d||j
¡ dS |r>t d|d tˆ t	d¡p6d¡ t‚t d|j
d tˆ t	d¡¡ |jS )zÙTry to find a Link matching req

        Expects req, an InstallRequirement and upgrade, a boolean
        Returns a Link if found,
        Raises DistributionNotFound or BestVersionAlreadyInstalled otherwise
        c             S   s   g | ]}t |jƒ‘qS r>   )rn   r§   )rw   Úcr>   r>   r?   rx   ‹  s    z2PackageFinder.find_requirement.<locals>.<listcomp>N)Zprereleasesc                s   g | ]}t |jƒˆ kr|‘qS r>   )rn   r§   )rw   rÆ   )Úcompatible_versionsr>   r?   rx   ”  s    )ÚkeyzNCould not find a version that satisfies the requirement %s (from versions: %s)z, c             S   s   h | ]}t |jƒ’qS r>   )rn   r§   )rw   rÆ   r>   r>   r?   ú	<setcomp>©  s    z1PackageFinder.find_requirement.<locals>.<setcomp>z%No matching distribution found for %sFTzLExisting installed version (%s) is most up-to-date and satisfies requirementzUExisting installed version (%s) satisfies requirement (most up-to-date version is %s)z=Installed version (%s) is most up-to-date (past versions: %s)Znonez)Using version %s (newest of versions: %s))rÅ   Únamer   Z	specifierÚfilterr…   Úmaxrª   Zsatisfied_byÚparse_versionr§   r]   Zcriticalr   Úsortedr   r^   r   r    )rI   ZreqZupgradeZall_candidatesZapplicable_candidatesZbest_candidateZinstalled_versionZbest_installedr>   )rÇ   r?   Úfind_requirementw  sd    


zPackageFinder.find_requirementc             c   sJ   t ƒ }x>|D ]6}||krq| |¡ t|| jd}|dkr<q|V  qW dS )zp
        Yields (page, page_url) from the given locations, skipping
        locations that have errors.
        )rY   N)r   Úaddru   rY   )rI   r›   r·   Úseenr    rÄ   r>   r>   r?   r½   Û  s    

zPackageFinder._get_pagesz-py([123]\.?[0-9]?)$c             C   sT   g g  }}t ƒ }x:|D ]2}||kr| |¡ |jr>| |¡ q| |¡ qW || S )z
        Returns elements of links in order, non-egg links first, egg links
        second, while eliminating duplicates
        )r   rÐ   Úegg_fragmentr   )rI   ÚlinksZeggsZno_eggsrÑ   r`   r>   r>   r?   Ú_sort_linksï  s    


zPackageFinder._sort_linksc             C   s:   g }x0|   |¡D ]"}|  ||¡}|d k	r| |¡ qW |S )N)rÔ   Ú_link_package_versionsr   )rI   rÓ   rÃ   Úresultr`   Úvr>   r>   r?   r¼      s    zPackageFinder._package_versionsc             C   s(   || j kr$t d||¡ | j  |¡ d S )NzSkipping link %s; %s)r‚   r]   r^   rÐ   )rI   r`   ra   r>   r>   r?   Ú_log_skipped_link  s    
zPackageFinder._log_skipped_linkc       
      C   sD  d}|j r|j }|j}n| ¡ \}}|s:|  |d¡ dS |tkrV|  |d| ¡ dS d|jkr~|tkr~|  |d|j ¡ dS d|jkr |dkr |  |d¡ dS |tkr&yt	|j
ƒ}W n  tk
rØ   |  |d	¡ dS X t|jƒ|jkr|  |d
|j ¡ dS | | j¡s |  |d¡ dS |j}d|jkrR|tkrR|  |d|j ¡ dS |sdt||jƒ}|s€|  |d|j ¡ dS | j |¡}|rÐ|d| ¡ … }| d¡}|tjdd… krÐ|  |d¡ dS yt|jƒ}	W n. tjk
r   t d|j
|j¡ d}	Y nX |	s(t d||j¡ dS t d||¡ t|j||ƒS )z'Return an InstallationCandidate or NoneNz
not a filezunsupported archive format: %sZbinaryzNo binaries permitted for %sZmacosx10z.zipzmacosx10 onezinvalid wheel filenamezwrong project name (not %s)z%it is not compatible with this PythonÚsourcezNo sources permitted for %szMissing project version for %sre   é   zPython version is incorrectz3Package %s has an invalid Requires-Python entry: %sTzaThe package %s is incompatible with the python version in use. Acceptable python versions are: %szFound link %s, version: %s)rÒ   ÚextÚsplitextrØ   r   rÂ   r   ZsuppliedrZ   r$   rA   r   r	   rÊ   Z	canonicalr¡   r†   r§   Ú_egg_info_matchesÚ_py_version_rerÃ   ÚstartÚgroupÚsysr"   Úrequires_pythonr   ZInvalidSpecifierr]   r^   r   )
rI   r`   rÃ   r§   Úegg_inforÛ   r©   r¤   Z
py_versionZsupport_this_pythonr>   r>   r?   rÕ     s€    




z$PackageFinder._link_package_versions)	FNNNNNNNF)F)rK   rL   rM   Ú__doc__rF   r’   Ústaticmethodrž   rª   rµ   r¹   rÅ   rÏ   r½   r£   ÚcompilerÞ   rÔ   r¼   rØ   rÕ   r>   r>   r>   r?   r4     s0           
R9%JCd
c             C   sL   x6t | ƒD ]*\}}|dkrq
t| d|… ƒ|kr
|S q
W td | |¡ƒ‚dS )aÞ  Find the separator's index based on the package's canonical name.

    `egg_info` must be an egg info string for the given package, and
    `canonical_name` must be the package's canonical name.

    This function is needed since the canonicalized name does not necessarily
    have the same length as the egg info's name part. An example::

    >>> egg_info = 'foo__bar-1.0'
    >>> canonical_name = 'foo-bar'
    >>> _find_name_version_sep(egg_info, canonical_name)
    8
    ú-Nz{} does not match {})Ú	enumerater	   r³   r   )rã   rÁ   ÚirÆ   r>   r>   r?   Ú_find_name_version_sepe  s    rê   c             C   s@   yt | |ƒd }W n tk
r&   dS X | |d… }|s<dS |S )z½Pull the version part out of a string.

    :param egg_info: The string to parse. E.g. foo-2.1
    :param canonical_name: The canonicalized name of the package this
        belongs to.
    re   N)rê   r³   )rã   rÁ   Zversion_startr§   r>   r>   r?   rÝ     s    rÝ   c             C   s.   x(|   d¡D ]}| d¡}|dk	r|S qW |S )aö  Determine the HTML document's base URL.

    This looks for a ``<base>`` tag in the HTML document. If present, its href
    attribute denotes the base URL of anchor tags in the document. If there is
    no such tag (or if it does not have a valid href attribute), the HTML
    file's URL is used as the base URL.

    :param document: An HTML document representation. The current
        implementation expects the result of ``html5lib.parse()``.
    :param page_url: The URL of the HTML document.
    z.//baseÚhrefN)ÚfindallrQ   )ÚdocumentZpage_urlÚbaserë   r>   r>   r?   Ú_determine_base_url‘  s
    
rï   c             C   s2   | r.d| kr.t  | d ¡\}}d|kr.|d S dS )zBDetermine if we have any encoding information in our headers.
    zContent-TypeÚcharsetN)ÚcgiZparse_header)rP   rG   Zparamsr>   r>   r?   Ú_get_encoding_from_headers¤  s
    rò   z[^a-z0-9$&+,/:;=?@.#%_\\|-]c             C   s   t  dd„ | ¡S )z Makes sure a link is fully encoded.  That is, if a ' ' shows up in
    the link, it will be rewritten to %20 (while not over-quoting
    % or other characters).c             S   s   dt |  d¡ƒ S )Nz%%%2xr   )Úordrà   )r¤   r>   r>   r?   Ú<lambda>¶  s    z_clean_link.<locals>.<lambda>)Ú_CLEAN_LINK_REÚsub)r<   r>   r>   r?   Ú_clean_link±  s    r÷   c               @   s*   e Zd ZdZd	dd„Zdd„ Zdd„ ZdS )
rq   z'Represents one page, along with its URLNc             C   s   || _ || _|| _d S )N)rr   r<   rP   )rI   rr   r<   rP   r>   r>   r?   rF   ¼  s    zHTMLPage.__init__c             C   s
   t | jƒS )N)r!   r<   )rI   r>   r>   r?   Ú__str__Â  s    zHTMLPage.__str__c             c   sŒ   t j| jt| jƒdd}t|| jƒ}xb| d¡D ]T}| d¡r0| d¡}t	t
 ||¡ƒ}| d¡}|rnt|ƒnd}t|| j|dV  q0W dS )zYields all links in the pageF)Ztransport_encodingZnamespaceHTMLElementsz.//arë   zdata-requires-pythonN)râ   )r   r
   rr   rò   rP   rï   r<   rì   rQ   r÷   rV   rm   r   r   )rI   rí   Zbase_urlZanchorrë   r<   Z	pyrequirer>   r>   r?   r¿   Å  s    


zHTMLPage.iter_links)N)rK   rL   rM   rä   rF   rø   r¿   r>   r>   r>   r?   rq   ¹  s   
rq   r»   zsupplied canonical formats)N)N)wrä   Z
__future__r   rñ   rˆ   Zloggingr”   rj   r¶   r£   rá   Úcollectionsr   Zpip._vendorr   r   r   Zpip._vendor.distlib.compatr   Zpip._vendor.packagingr   Zpip._vendor.packaging.utilsr	   Zpip._vendor.packaging.versionr
   rÍ   Zpip._vendor.requests.exceptionsr   r   Zpip._vendor.six.moves.urllibrV   r   rl   Zpip._internal.downloadr   r   r   r   Zpip._internal.exceptionsr   r   r   r   Zpip._internal.models.candidater   Z#pip._internal.models.format_controlr   Zpip._internal.models.indexr   Zpip._internal.models.linkr   Zpip._internal.pep425tagsr   Zpip._internal.utils.compatr   Zpip._internal.utils.loggingr   Zpip._internal.utils.miscr   r   r   r    r!   Zpip._internal.utils.packagingr"   Zpip._internal.utils.typingr#   Zpip._internal.wheelr$   r%   Útypingr&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   Zpip._vendor.requestsr1   Zpip._internal.reqr2   r3   rn   ZSecureOriginZBuildTagr¦   ZCandidateSortingKeyÚ__all__r°   Z	getLoggerrK   r]   r@   rC   Ú	ExceptionrD   rS   rT   r\   r_   rc   ru   Úobjectr4   rê   rÝ   rï   rò   ræ   ÚIrõ   r÷   rq   r»   r>   r>   r>   r?   Ú<module>   s   0
6

6    h

