3 ”Re@Wã@s dZddlZddlZddlZddlZddlZddlZddlZddlm Z ddl m Z m Z ddl mZddlmZmZddlmZddlmZdd lmZdd lmZdd lmZdd lmZdd lm Z ddl!m"Z"ddl#m$Z$m%Z%ddl&m'Z'ddl(m)Z)m*Z*ddl+m,Z,m-Z-e'�r€ddl.m/Z/ddl0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8ddl9Z:ddl;mZ>e:j?j@jAZBe4eCeCfZDejEeFƒZGdd„ZHdd„ZIGdd„deJƒZKdd„ZLGdd „d eJƒZMd!d"„ZNd#d$„ZOd%d&„ZPd'd(„ZQd)d*„ZRd+d,„ZSejTd-ejUƒZVd.d/„ZWd0d1„ZXd2d3„ZYGd4d5„d5eZƒZ[d6d7„Z\e\d8d9„ƒZ]Gd:d;„d;eZƒZ^dLdrArB)Ú urllib_parseÚurlsplitr@Úheadr r?)r&Úsessionr'ÚnetlocÚpathÚqueryÚfragmentÚrespr(r(r)Ú_ensure_html_responsefs rMcCsLt|ƒrt||d�tjdt|ƒƒ|j|dddœd�}t|ƒt|ƒ|S)aAccess 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. )rGzGetting page %sz text/htmlz max-age=0)ÚAcceptz Cache-Control)r;)r.rMÚloggerÚdebugrr<r r?)r&rGrLr(r(r)Ú_get_html_responsews  rQcCs2|r.d|kr.tj|dƒ\}}d|kr.|dSdS)zBDetermine if we have any encoding information in our headers. z Content-TypeÚcharsetN)ÚcgiÚ parse_header)r;r2Úparamsr(r(r)Ú_get_encoding_from_headersªs  rVcCs.x(|jdƒD]}|jdƒ}|dk r |Sq W|S)aöDetermine the HTML document's base URL. This looks for a ```` 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)Úfindallr<)ÚdocumentÚpage_urlÚbaserWr(r(r)Ú_determine_base_urlµs  r\cCstjtj|ƒƒS)zP Clean a "part" of a URL path (i.e. after splitting on "@" characters). )rDÚquoteÚunquote)Úpartr(r(r)Ú_clean_url_path_partÉsr`cCstjtj|ƒƒS)z• Clean the first part of a URL path that corresponds to a local filesystem path (i.e. the first part after splitting on "@" characters). )Úurllib_requestÚ pathname2urlÚ url2pathname)r_r(r(r)Ú_clean_file_url_pathÒs rdz(@|%2F)cCsb|r t}nt}tj|ƒ}g}x:ttj|dgƒƒD]$\}}|j||ƒƒ|j|jƒƒq0Wdj |ƒS)z* Clean the path portion of a URL. r:) rdr`Ú_reserved_chars_reÚsplitrÚ itertoolsÚchainÚappendÚupperÚjoin)rIÚ is_local_pathÚ clean_funcÚpartsÚ cleaned_partsÚto_cleanÚreservedr(r(r)Ú_clean_url_pathäs rrcCs2tj|ƒ}|j }t|j|d�}tj|j|d�ƒS)z§ Make sure a link is fully quoted. For example, if ' ' occurs in the URL, it will be replaced with "%20", and without double-quoting other characters. )rl)rI)rDÚurlparserHrrrIÚ urlunparseÚ_replace)r&ÚresultrlrIr(r(r)Ú _clean_linkûs rwcCsf|jdƒ}|sdSttj||ƒƒ}|jdƒ}|r8t|ƒnd}|jdƒ}|rRt|ƒ}t||||d�}|S)zJ Convert an anchor element in a simple repository page to a Link. rWNzdata-requires-pythonz data-yanked)Ú comes_fromÚrequires_pythonÚ yanked_reason)r<rwrDÚurljoinrr )ÚanchorrZÚbase_urlrWr&Ú pyrequirerzÚlinkr(r(r)Ú_create_link_from_element s   r€c@s$eZdZdd„Zdd„Zdd„ZdS)ÚCacheablePageContentcCs|js t‚||_dS)N)Úcache_link_parsingÚAssertionErrorÚpage)r4r„r(r(r)r1,s zCacheablePageContent.__init__cCst|t|ƒƒo|jj|jjkS)N)Ú isinstanceÚtyper„r&)r4Úotherr(r(r)Ú__eq__1szCacheablePageContent.__eq__cCs t|jjƒS)N)Úhashr„r&)r4r(r(r)Ú__hash__6szCacheablePageContent.__hash__N)r6r7r8r1rˆrŠr(r(r(r)r�+sr�cs2tdd�‡fdd„ƒ‰tjˆƒ‡‡fdd„ƒ}|S)zÒ Given a function that parses an Iterable[Link] from an HTMLPage, cache the function's result (keyed by CacheablePageContent), unless the HTMLPage `page` has `page.cache_link_parsing == False`. N)Úmaxsizecstˆ|jƒƒS)N)Úlistr„)Úcacheable_page)Úfnr(r)ÚwrapperEsz'with_cached_html_pages..wrappercs|jrˆt|ƒƒStˆ|ƒƒS)N)r‚r�rŒ)r„)rŽr�r(r)Úwrapper_wrapperJs z/with_cached_html_pages..wrapper_wrapper)rÚ functoolsÚwraps)rŽr�r()rŽr�r)Úwith_cached_html_pages;s r“ccsZtj|j|jdd�}|j}t||ƒ}x0|jdƒD]"}t|||d�}|dkrLq0|Vq0WdS)zP Parse an HTML document, and yield its anchor elements as Link objects. F)Útransport_encodingÚnamespaceHTMLElementsz.//a)rZr}N)rrÚcontentÚencodingr&r\rXr€)r„rYr&r}r|rr(r(r)Ú parse_linksTs r˜c@s"eZdZdZddd„Zdd„ZdS) ÚHTMLPagez'Represents one page, along with its URLTcCs||_||_||_||_dS)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‚)r4r–r—r&r‚r(r(r)r1pszHTMLPage.__init__cCs t|jƒS)N)rr&)r4r(r(r)Ú__str__„szHTMLPage.__str__N)T)r6r7r8Ú__doc__r1ršr(r(r(r)r™ms r™cCs|dkrtj}|d||ƒdS)Nz%Could not fetch URL %s: %s - skipping)rOrP)rÚreasonÚmethr(r(r)Ú_handle_get_page_fail‰sržTcCst|jƒ}t|j||j|d�S)N)r—r&r‚)rVr;r™r–r&)r>r‚r—r(r(r)Ú_make_html_page”s  rŸc Cs|dkrtdƒ‚|jjddƒd}t|ƒ}|r@tjd||ƒdStj|ƒ\}}}}}}|dkrštj j t j |ƒƒrš|j dƒs‚|d7}tj|dƒ}tjd |ƒyt||d �}W�nFtk rÎtjd |ƒY�n4tk �r}ztjd ||j|jƒWYdd}~Xnþtk �r0}zt||ƒWYdd}~XnÒtk �r\}zt||ƒWYdd}~Xn¦tk �rž}z&d } | t|ƒ7} t|| tjd�WYdd}~Xndtjk �rÒ}zt|dj|ƒƒWYdd}~Xn0tjk �ròt|dƒYnXt||j d�SdS)Nz?_get_html_page() missing 1 required keyword argument: 'session'ú#érzICannot look at %s URL %s because it does not support lookup as web pages.Úfileú/z index.htmlz# file: URL is directory, getting %s)rGz`Skipping page %s because it looks like an archive, and cannot be checked by a HTTP HEAD request.ziSkipping page %s because the %s request got Content-Type: %s.The only supported Content-Type is text/htmlz4There was a problem confirming the ssl certificate: )r�zconnection error: {}z timed out)r‚)!Ú TypeErrorr&rfr*rOÚwarningrDrsÚosrIÚisdirrarcr,r{rPrQr@r/r3r2r ržrrÚstrÚinforÚConnectionErrorÚformatÚTimeoutrŸr‚) rrGr&Ú vcs_schemer'Ú_rIrLÚexcrœr(r(r)Ú_get_html_pagežsP        r°cCsttj|ƒƒS)zQ Return a list of links, with duplicates removed and ordering preserved. )rŒrÚfromkeys)Úlinksr(r(r)Ú_remove_duplicate_links×sr³Fcsg‰g‰‡‡fdd„}xâ|D]Ú}tjj|ƒ}|jdƒ}|s>|rÖ|rH|}nt|ƒ}tjj|ƒr²|r”tjj|ƒ}xBtj|ƒD]}|tjj||ƒƒqxWqÔ|r¤ˆj |ƒqÔt j d|ƒqötjj |ƒrÈ||ƒqöt j d|ƒqt |ƒrêˆj |ƒqt j d|ƒqWˆˆfS)z� Divide a list of locations into two groups: "files" (archives) and "urls." :return: A pair of lists (files, urls). cs8t|ƒ}tj|dd�ddkr*ˆj|ƒn ˆj|ƒdS)NF)Ústrictrz text/html)rÚ mimetypesÚ guess_typeri)rIr&)ÚfilesÚurlsr(r)Ú sort_pathës z"group_locations..sort_pathzfile:z(Path '%s' 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.)r¦rIÚexistsr$rr§ÚrealpathÚlistdirrkrirOr¥Úisfiler)Ú locationsÚ expand_dirr¹r&rlÚ is_file_urlrIÚitemr()r·r¸r)Úgroup_locationsàs<           rÂc@seZdZdZdd„ZdS)ÚCollectedLinksaä Encapsulates the return value of a call to LinkCollector.collect_links(). The return value includes both URLs to project pages containing package links, as well as individual package Link objects collected from other sources. This info is stored separately as: (1) links from the configured file locations, (2) links from the configured find_links, and (3) urls to HTML project pages, as described by the PEP 503 simple repository API. cCs||_||_||_dS)zä :param files: Links from file locations. :param find_links: Links from find_links. :param project_urls: URLs to HTML project pages, as described by the PEP 503 simple repository API. N)r·Ú find_linksÚ project_urls)r4r·rÄrÅr(r(r)r1,s zCollectedLinks.__init__N)r6r7r8r›r1r(r(r(r)rÃsrÃc@sBeZdZdZdd„Zeddd„ƒZedd„ƒZd d „Z 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_links() method. cCs||_||_dS)N)Ú search_scoperG)r4rGrÇr(r(r)r1GszLinkCollector.__init__FcCsb|jg|j}|jr:| r:tjddjdd„|Dƒƒƒg}|jpBg}tj||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. zIgnoring indexes: %sú,css|]}t|ƒVqdS)N)r)Ú.0r&r(r(r)ú \sz'LinkCollector.create..)rÄÚ index_urls)rGrÇ) Ú index_urlÚextra_index_urlsÚno_indexrOrPrkrÄr ÚcreaterÆ)ÚclsrGÚoptionsÚsuppress_no_indexrËrÄrÇÚlink_collectorr(r(r)rÏPs    zLinkCollector.createcCs|jjS)N)rÇrÄ)r4r(r(r)rÄkszLinkCollector.find_linkscCst||jd�S)z> Fetch an HTML page containing package links. )rG)r°rG)r4Úlocationr(r(r)Ú fetch_pagepszLinkCollector.fetch_pagec s؈j}|j|ƒ}t|ƒ\}}tˆjdd�\}}dd„tj||ƒDƒ}dd„ˆjDƒ} ‡fdd„tjdd„|Dƒd d„|DƒƒDƒ} t| ƒ} d jt| ƒ|ƒg} x| D]} | j d j| ƒƒq¢Wt j d j | ƒƒt || | d �S)zŽFind all available links for the given project name. :return: All the Link objects (unfiltered), as a CollectedLinks object. T)r¿cSsg|] }t|ƒ‘qSr()r )rÉr&r(r(r)ú …sz/LinkCollector.collect_links..cSsg|]}t|dƒ‘qS)z-f)r )rÉr&r(r(r)rÖ‰scsg|]}ˆjj|ƒr|‘qSr()rGÚis_secure_origin)rÉr)r4r(r)rÖ�scss|]}t|dd�VqdS)F)r‚N)r )rÉr&r(r(r)rÊ’sz.LinkCollector.collect_links..css|]}t|ƒVqdS)N)r )rÉr&r(r(r)rÊ“sz,{} location(s) to search for versions of {}:z* {}Ú )r·rÄrÅ)rÇÚget_index_urls_locationsrÂrÄrgrhr³r«r%rirOrPrkrÃ) r4Ú project_namerÇÚindex_locationsÚindex_file_locÚ index_url_locÚ fl_file_locÚ fl_url_locÚ file_linksÚfind_link_linksÚ url_locationsÚlinesrr()r4r)Ú collect_linksws(    zLinkCollector.collect_linksN)F) r6r7r8r›r1Ú classmethodrÏÚpropertyrÄrÕrär(r(r(r)rÆ>s   rÆ)N)T)N)F)fr›rSr‘rgÚloggingrµr¦ÚreÚ collectionsrÚ pip._vendorrrÚpip._vendor.distlib.compatrZpip._vendor.requests.exceptionsrrZpip._vendor.six.moves.urllibrrDr raÚpip._internal.exceptionsr Úpip._internal.models.linkr Ú!pip._internal.models.search_scoper Úpip._internal.network.utilsr Úpip._internal.utils.compatrÚpip._internal.utils.filetypesrÚpip._internal.utils.miscrrÚpip._internal.utils.typingrÚpip._internal.utils.urlsrrÚpip._internal.vcsrrÚoptparserÚtypingrrrrrrrrÚxml.etree.ElementTreeÚxmlZpip._vendor.requestsr Úpip._internal.network.sessionr!ÚetreeÚ ElementTreeÚElementZ HTMLElementr¨ZResponseHeadersÚ getLoggerr6rOr*r.Ú Exceptionr/r?r@rMrQrVr\r`rdÚcompileÚ IGNORECASErerrrwr€Úobjectr�r“r˜r™ržrŸr°r³rÂrÃrÆr(r(r(r)Úst            (         3      9 ;#