Re@W@sdZddlZddlZddlZddlZddlZddlZddlZddlm 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'rddl.m/Z/ddl0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8ddl9Z:ddl;m<Z<ddl=m>Z>e:j?j@jAZBe4eCeCfZDejEeFZGddZHddZIGdddeJZKddZLGdd d eJZMd!d"ZNd#d$ZOd%d&ZPd'd(ZQd)d*ZRd+d,ZSejTd-ejUZVd.d/ZWd0d1ZXd2d3ZYGd4d5d5eZZ[d6d7Z\e\d8d9Z]Gd:d;d;eZZ^dd<d=Z_d>d?d@Z`ddAdBZadCdDZbdEdFdGZcGdHdIdIeZZdGdJdKdKeZZedS)LzM The main purpose of this module is to expose LinkCollector.collect_links(). N) OrderedDict)html5librequests)unescape) RetryErrorSSLError)parse)request)NetworkConnectionError)Link) SearchScope)raise_for_status) lru_cache)ARCHIVE_EXTENSIONS)pairwiseredact_auth_from_url)MYPY_CHECK_RUNNING) path_to_url url_to_path)is_urlvcs)Values)CallableIterableListMutableMappingOptionalSequenceTupleUnion)Response) PipSessioncCsGx@tjD]5}|jj|r |t|dkr |Sq WdS)zgLook for VCS schemes in the URL. Returns the matched VCS scheme, or None if there's no match. z+:N)rschemeslower startswithlen)urlschemer(/builddir/build/BUILDROOT/alt-python35-pip-20.2.4-5.el8.x86_64/opt/alt/python35/lib/python3.5/site-packages/pip/_internal/index/collector.py_match_vcs_scheme8s+r*cCs7t|j}x!tD]}|j|rdSqWdS)z2Return whether the URL looks like an archive. TF)r filenamerendswith)r&r+bad_extr(r(r)_is_url_like_archiveDs  r.cs"eZdZfddZS)_NotHTMLcs/tt|j||||_||_dS)N)superr/__init__ content_type request_desc)selfr2r3) __class__r(r)r1Ps z_NotHTML.__init__)__name__ __module__ __qualname__r1r(r()r5r)r/Os r/cCsC|jjdd}|jjds?t||jjdS)zCheck the Content-Type header to ensure the response contains HTML. Raises `_NotHTML` if the content type is not text/html. z Content-Typez text/htmlN)headersgetr#r$r/r method)responser2r(r(r)_ensure_html_headerWsr>c@seZdZdS)_NotHTTPN)r6r7r8r(r(r(r)r?bs r?cCs`tj|\}}}}}|dkr3t|j|dd}t|t|dS)zSend 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. httphttpsallow_redirectsTN>r@rA) urllib_parseurlsplitr?headr r>)r&sessionr'netlocpathqueryfragmentrespr(r(r)_ensure_html_responsefs    rLcCskt|rt|d|tjdt||j|dddddi}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. rFzGetting page %sr:Acceptz text/htmlz Cache-Controlz max-age=0)r.rLloggerdebugrr;r r>)r&rFrKr(r(r)_get_html_responsews   rPcCsC|r?d|kr?tj|d\}}d|kr?|dSdS)zBDetermine if we have any encoding information in our headers. z Content-TypecharsetN)cgi parse_header)r:r2paramsr(r(r)_get_encoding_from_headerss  rUcCs=x6|jdD]%}|jd}|dk r|SqW|S)aDetermine 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.//basehrefN)findallr;)documentpage_urlbaserVr(r(r)_determine_base_urls  r[cCstjtj|S)zP Clean a "part" of a URL path (i.e. after splitting on "@" characters). )rCquoteunquote)partr(r(r)_clean_url_path_partsr_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_paths rcz(@|%2F)cCs|rt}nt}tj|}g}xOttj|dgD]2\}}|j|||j|jqFWdj |S)z* Clean the path portion of a URL. r9) rcr__reserved_chars_resplitr itertoolschainappendupperjoin)rH is_local_path clean_funcparts cleaned_partsto_cleanreservedr(r(r)_clean_url_paths (rqcCsGtj|}|j }t|jd|}tj|jd|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. rkrH)rCurlparserGrqrH urlunparse_replace)r&resultrkrHr(r(r) _clean_links  rvcCs|jd}|sdSttj||}|jd}|rRt|nd}|jd}|ryt|}t|d|d|d|}|S)zJ Convert an anchor element in a simple repository page to a Link. rVNzdata-requires-pythonz data-yanked comes_fromrequires_python yanked_reason)r;rvrCurljoinrr )anchorrYbase_urlrVr& pyrequirerylinkr(r(r)_create_link_from_element s   rc@s4eZdZddZddZddZdS)CacheablePageContentcCs|jst||_dS)N)cache_link_parsingAssertionErrorpage)r4rr(r(r)r1,szCacheablePageContent.__init__cCs+t|t|o*|jj|jjkS)N) isinstancetyperr&)r4otherr(r(r)__eq__1szCacheablePageContent.__eq__cCst|jjS)N)hashrr&)r4r(r(r)__hash__6szCacheablePageContent.__hash__N)r6r7r8r1rrr(r(r(r)r+s   rcsItddfddtjfdd}|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`. maxsizeNcst|jS)N)listr)cacheable_page)fnr(r)wrapperEsz'with_cached_html_pages..wrappercs)|jrt|St|S)N)rrr)r)rrr(r)wrapper_wrapperJs z/with_cached_html_pages..wrapper_wrapper)r functoolswraps)rrr()rrr)with_cached_html_pages;s !$rccstj|jd|jdd}|j}t||}xC|jdD]2}t|d|d|}|dkrvqI|VqIWdS)zP Parse an HTML document, and yield its anchor elements as Link objects. transport_encodingnamespaceHTMLElementsFz.//arYr|N)rrcontentencodingr&r[rWr)rrXr&r|r{r~r(r(r) parse_linksTs      rc@s1eZdZdZdddZddZdS)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)rrr&r)r4rrr&rr(r(r)r1ps   zHTMLPage.__init__cCs t|jS)N)rr&)r4r(r(r)__str__szHTMLPage.__str__N)r6r7r8__doc__r1rr(r(r(r)rms rcCs)|dkrtj}|d||dS)Nz%Could not fetch URL %s: %s - skipping)rNrO)r~reasonmethr(r(r)_handle_get_page_fails  rTcCs1t|j}t|jd|d|jd|S)Nrr&r)rUr:rrr&)r=rrr(r(r)_make_html_pages   rc Cs|dkrtd|jjddd}t|}|rZtjd||dStj|\}}}}}}|dkrtj j t j |r|j ds|d7}tj|d}tjd |yt|d |}Wnrtk rtjd |Yndtk rW}z!tjd ||j|jWYdd}~Xn$tk r}zt||WYdd}~Xntk r}zt||WYdd}~Xntk r }z1d } | t|7} t|| dtjWYdd}~Xnrtjk rF}zt|dj|WYdd}~Xn5tjk rgt|dYnXt|d|j 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 %srFz`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: rzconnection error: {}z timed outr)! TypeErrorr&rer*rNwarningrCrrosrHisdirr`rbr,rzrOrPr?r/r3r2r rrrstrinforConnectionErrorformatTimeoutrr) r~rFr& vcs_schemer'_rHrKexcrr(r(r)_get_html_pagesP     !'   %((  rcCsttj|S)zQ Return a list of links, with duplicates removed and ordering preserved. )rrfromkeys)linksr(r(r)_remove_duplicate_linkssrFcskggfdd}x=|D]5}tjj|}|jd}|s[|r1|rj|}n t|}tjj|r|rtjj|}xYtj|D]}|tjj||qWq.|rj |q.t j d|q]tjj |r||q]t j d|q(t |rMj |q(t j d|q(WfS)z Divide a list of locations into two groups: "files" (archives) and "urls." :return: A pair of lists (files, urls). csLt|}tj|ddddkr;j|n j|dS)NstrictFrz text/html)r mimetypes guess_typerh)rHr&)filesurlsr(r) sort_paths 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.)rrHexistsr$rrrealpathlistdirrjrhrNrisfiler) locations expand_dirrr&rk is_file_urlrHitemr()rrr)group_locationss<          rc@s"eZdZdZddZdS)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)r4rrrr(r(r)r1,s  zCollectedLinks.__init__N)r6r7r8rr1r(r(r(r)rs rc@saeZdZdZddZedddZeddZd 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_scoperF)r4rFrr(r(r)r1Gs zLinkCollector.__init__FcCs|jg|j}|jrO| rOtjddjdd|Dg}|jp[g}tjd|d|}t d|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_urlsrFr) index_urlextra_index_urlsno_indexrNrOrjrr creater)clsrFoptionssuppress_no_indexrrrlink_collectorr(r(r)rPs zLinkCollector.createcCs |jjS)N)rr)r4r(r(r)rkszLinkCollector.find_linkscCst|d|jS)z> Fetch an HTML page containing package links. rF)rrF)r4locationr(r(r) fetch_pagepszLinkCollector.fetch_pagec s6j}|j|}t|\}}tjdd\}}ddtj||D}ddjD} fddtjdd|Dd d|DD} t| } d jt| |g} x$| D]} | j d j| qWt j d j | t d |d| d| S)zFind all available links for the given project name. :return: All the Link objects (unfiltered), as a CollectedLinks object. rTcSsg|]}t|qSr()r )rr&r(r(r) s z/LinkCollector.collect_links..cSsg|]}t|dqS)z-f)r )rr&r(r(r)rs cs(g|]}jj|r|qSr()rFis_secure_origin)rr~)r4r(r)rs css!|]}t|ddVqdS)rFN)r )rr&r(r(r)rsz.LinkCollector.collect_links..css|]}t|VqdS)N)r )rr&r(r(r)rsz,{} location(s) to search for versions of {}:z* {} rrr)rget_index_urls_locationsrrrfrgrrr%rhrNrOrjr) r4 project_namerindex_locationsindex_file_loc index_url_loc fl_file_loc fl_url_loc file_linksfind_link_links url_locationslinesr~r()r4r) collect_linksws(   zLinkCollector.collect_linksN) r6r7r8rr1 classmethodrpropertyrrrr(r(r(r)r>s   r)frrRrrfloggingrrre collectionsr pip._vendorrrpip._vendor.distlib.compatrZpip._vendor.requests.exceptionsrrZpip._vendor.six.moves.urllibrrCr r`pip._internal.exceptionsr pip._internal.models.linkr !pip._internal.models.search_scoper pip._internal.network.utilsr pip._internal.utils.compatrpip._internal.utils.filetypesrpip._internal.utils.miscrrpip._internal.utils.typingrpip._internal.utils.urlsrrpip._internal.vcsrroptparsertypingrrrrrrrrxml.etree.ElementTreexmlZpip._vendor.requestsr pip._internal.network.sessionr!etree ElementTreeElementZ HTMLElementrZResponseHeaders getLoggerr6rNr*r. Exceptionr/r>r?rLrPrUr[r_rccompile IGNORECASErdrqrvrobjectrrrrrrrrrrrr(r(r(r)st       :     3       9 ;#