7Rebc@sddlZddlmZddlZddlZddlZddlZddlZyddlZWne k rddl ZYnXddl Z ddl m Z ddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZddlmZm Z m!Z!ddl"m#Z#ddl$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,dd l-m.Z.m/Z/dd l0m1Z1m2Z2ej3e4Z5ej6d Z7ej6d ej8Z9ej6d Z:dZ;e<ddZ=GdddeZ>Gddde?Z@Gddde@ZAGddde@ZBGddde?ZCGddde@ZDGddde@ZEGdd d e@ZFGd!d"d"e@ZGGd#d$d$e@ZHeHeFeDd%d&d'd(d)ZIeIjJZJej6d*ZKGd+d,d,e?ZLdS(-iN(uBytesIOi(uDistlibException(uurljoinuurlparseu urlunparseu url2pathnameu pathname2urluqueueuquoteuunescapeu string_typesu build_openeruHTTPRedirectHandleruRequestu HTTPErroruURLError(u DistributionuDistributionPathu make_dist(uMetadata(ucached_propertyuparse_credentialsu ensure_slashusplit_filenameuget_project_datauparse_requirementuparse_name_and_versionu ServerProxy(u get_schemeuUnsupportedVersionError(uWheelu is_compatibleu^(\w+)=([a-f0-9]+)u;\s*charset\s*=\s*(.*)\s*$utext/html|application/x(ht)?mluhttp://python.org/pypicCs1|dkrt}nt|dd}|jS(u Return all distribution names known by an index. :param url: The URL of the index. :return: A list of all known distribution names. utimeoutg@N(uNoneu DEFAULT_INDEXu ServerProxyu list_packages(uurluclient((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyuget_all_distribution_names)s  uget_all_distribution_namescBs4|EeZdZdZddZeZZZdS(uRedirectHandleruE A class to work around a bug in some Python 3.2.x releases. c Csd}x(dD] }||kr ||}Pq q W|dkrAdSt|}|jdkrt|j|}t|dr|j||q|||.same_projectuegg=u %s: version hint in fragment: %riu/Nu.whlunameuversionufilenameuuurlu, cSs/g|]%}djt|ddqS(u.iN(ujoinulist(u.0uv((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyu s u8Locator.convert_url_to_download_info..upython-versionuinvalid path for wheel: %su No match for project/version: %su %s_digest(NNiiT(uNoneuurlparseuloweru startswithuloggerudebugu HASHER_HASHumatchugroupsuendswithuWheelu is_compatibleu wheel_tagsuTrueunameuversionufilenameu urlunparseujoinupyveru Exceptionuwarningudownloadable_extensionsu posixpathubasenameulenusplit_filename(uselfuurlu project_nameu same_projecturesultuschemeunetlocupathuparamsuqueryufragumualgoudigestuorigpathuwheeluincludeueufilenameuextutunameuversionupyver((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyuconvert_url_to_download_infosj           '&   u$Locator.convert_url_to_download_infocCsEd}x8dD]0}d|}||kr |||f}Pq q W|S(u Get a digest from a dictionary by looking at keys of the form 'algo_digest'. Returns a 2-tuple (algo, digest) if found, else None. Currently looks only for SHA256, then MD5. usha256umd5u %s_digestN(usha256umd5(uNone(uselfuinfouresultualgoukey((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyu _get_digests   uLocator._get_digestcCs|jd}|jd}||kr@||}|j}n!t||d|j}|j}|j||_|j|dkr|j|j|d|_n||_|||= 1.0, < 2.0, != 1.3)' :param prereleases: If ``True``, allow pre-release versions to be located. Otherwise, pre-release versions are not returned. :return: A :class:`Distribution` instance, or ``None`` if no such distribution could be located. uNot a valid requirement: %rumatcher: %s (%s)u%s did not match %ru%skipping pre-release version %s of %suerror matching %s with %riukeyusorted list: %sNi(uNoneuparse_requirementuDistlibExceptionu get_schemeuschemeumatcheru requirementuloggerudebugutypeu__name__u get_projectunameu version_classumatchu is_prereleaseuappendu Exceptionuwarningulenusortedukeyuextras( uselfu requirementu prereleasesuresulturuschemeumatcheruversionsuslistuvclsuk((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyulocate7s>         uLocator.locateN(u.tar.gzu.tar.bz2u.taru.zipu.tgzu.tbz(u.eggu.exeu.whl(u.pdf(u.whlF(u__name__u __module__u __qualname__u__doc__usource_extensionsubinary_extensionsuexcluded_extensionsuNoneu wheel_tagsudownloadable_extensionsu__init__u clear_cacheu _get_schemeu _set_schemeupropertyuschemeu _get_projectuget_distribution_namesu get_projectu score_urlu prefer_urlusplit_filenameuconvert_url_to_download_infou _get_digestu_update_version_datauFalseulocate(u __locals__((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyuLocatorSs*         M  uLocatorcsD|EeZdZdZfddZddZddZS(uPyPIRPCLocatoru This locator uses XML-RPC to locate distributions. It therefore cannot be used with simple mirrors (that only mirror file content). c s8tt|j|||_t|dd|_dS(u Initialise an instance. :param url: The URL to use for XML-RPC. :param kwargs: Passed to the superclass constructor. utimeoutg@N(usuperuPyPIRPCLocatoru__init__ubase_urlu ServerProxyuclient(uselfuurlukwargs(u __class__(u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyu__init__ms uPyPIRPCLocator.__init__cCst|jjS(uJ Return all the distribution names known to this locator. (usetuclientu list_packages(uself((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyuget_distribution_namesxsu%PyPIRPCLocator.get_distribution_namesc Csi}|jj|d }x|D]}|jj||}|jj||}td|j}|d|_|d|_|j d|_ |j dg|_ |j d|_ t |}|r"|d} | d|_|j| |_||_|||[^"]*)"|'(?P[^']*)'|(?P[^>\s ]*))\s+)? href\s*=\s*(?:"(?P[^"]*)"|'(?P[^']*)'|(?P[^>\s ]*)) (\s+rel\s*=\s*(?:"(?P[^"]*)"|'(?P[^']*)'|(?P[^>\s ]*)))? u!]+)cCsM||_||_|_|jj|j}|rI|jd|_ndS(uk Initialise an instance with the Unicode page contents and the URL they came from. iN(udataubase_urluurlu_baseusearchugroup(uselfudatauurlum((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyu__init__s  u Page.__init__u[^a-z0-9$&+,/:;=?@.#%_\\|-]c Cs dd}t}x|jj|jD]}|jd}|dpy|dpy|dpy|dpy|dpy|d }|d p|d p|d }t|j|}t|}|jj d d|}|j ||fq+Wt |ddddd}|S(u Return the URLs of all the links on a page together with information about their "rel" attribute, for determining which ones to treat as downloads and which ones to queue for further scraping. cSs@t|\}}}}}}t||t||||fS(uTidy up an URL.(uurlparseu urlunparseuquote(uurluschemeunetlocupathuparamsuqueryufrag((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyucleansuPage.links..cleanuurel1urel2urel3urel4urel5urel6uurl1uurl2uurl3cSsdt|jdS(Nu%%%2xi(uordugroup(um((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyusuPage.links..ukeycSs|dS(Ni((ut((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyusureverseT( usetu_hrefufinditerudatau groupdictuurljoinubase_urluunescapeu _clean_reusubuaddusorteduTrue(uselfucleanuresultumatchudureluurl((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyulinkss   u Page.linksN(u__name__u __module__u __qualname__u__doc__ureucompileuIuSuXu_hrefu_baseu__init__u _clean_reucached_propertyulinks(u __locals__((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyuPages uPagecs|EeZdZdZiejd6ddd6ddd6Zddfd d Zd d Z d dZ ddZ e j de jZddZddZddZddZddZe j dZddZS( uSimpleScrapingLocatoru A locator which scrapes HTML pages to locate downloads for a distribution. This runs multiple threads to do the I/O; performance is at least as good as pip's PackageFinder, which works in an analogous fashion. udeflatecCstjdttjS(Nufileobj(ugzipuGzipFileuBytesIOuduread(ub((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyusuSimpleScrapingLocator.ugzipcCs|S(N((ub((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyusunonei c stt|j|t||_||_i|_t|_t j |_ t|_ d|_||_tj|_tj|_dS(u Initialise an instance. :param url: The root URL to use for scraping. :param timeout: The timeout, in seconds, to be applied to requests. This defaults to ``None`` (no timeout specified). :param num_workers: The number of worker threads you want to do I/O, This defaults to 10. :param kwargs: Passed to the superclass. NF(usuperuSimpleScrapingLocatoru__init__u ensure_slashubase_urlutimeoutu _page_cacheusetu_seenuqueueuQueueu _to_fetchu _bad_hostsuFalseuskip_externalsu num_workersu threadinguRLocku_locku_gplock(uselfuurlutimeoutu num_workersukwargs(u __class__(u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyu__init__s       uSimpleScrapingLocator.__init__cCscg|_xSt|jD]B}tjd|j}|jd|j|jj |qWdS(u Threads are created only when get_project is called, and terminate before it returns. They are there primarily to parallelise I/O (i.e. fetching web pages). utargetNT( u_threadsurangeu num_workersu threadinguThreadu_fetchu setDaemonuTrueustartuappend(uselfuiut((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyu_prepare_threadss    u&SimpleScrapingLocator._prepare_threadscCsOx!|jD]}|jjdq Wx|jD]}|jq.Wg|_dS(uu Tell all the threads to terminate (by sending a sentinel value) and wait for them to do so. N(u_threadsu _to_fetchuputuNoneujoin(uselfut((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyu _wait_threads,s u#SimpleScrapingLocator._wait_threadscCsi}|j||_||_t|jdt|}|jj|jj|j z1t j d||j j ||j jWd|jX|`WdQX|S(Nu%s/u Queueing %s(u_gplockuresultu project_nameuurljoinubase_urluquoteu_seenuclearu _page_cacheu_prepare_threadsuloggerudebugu _to_fetchuputujoinu _wait_threads(uselfunameuresultuurl((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyu _get_project9s        u"SimpleScrapingLocator._get_projectu<\b(linux-(i\d86|x86_64|arm\w+)|win(32|-amd64)|macosx-?\d+)\bcCs|jj|S(uD Does an URL refer to a platform-specific download? (uplatform_dependentusearch(uselfuurl((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyu_is_platform_dependentNsu,SimpleScrapingLocator._is_platform_dependentc Csp|j|rd}n|j||j}tjd|||rl|j|j|j|WdQXn|S(u% See if an URL is a suitable download for a project. If it is, register information in the result dictionary (for _get_project) about the specific version it's for. Note that the return value isn't actually used other than as a boolean value. uprocess_download: %s -> %sN( u_is_platform_dependentuNoneuconvert_url_to_download_infou project_nameuloggerudebugu_locku_update_version_datauresult(uselfuurluinfo((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyu_process_downloadTs   u'SimpleScrapingLocator._process_downloadc Cst|\}}}}}}|j|j|j|jrGd }n|jrl|j|j rld }n|j|jsd }ny|d krd }nd|d krd }nO|j |rd }n7|j ddd} | j d krd }nd}t jd |||||S(u Determine whether a link URL from a referring page and with a particular "rel" attribute should be queued for scraping. uhomepageudownloaduhttpuhttpsuftpu:iiu localhostu#should_queue: %s (%s) from %s -> %sF(uhomepageudownload(uhttpuhttpsuftpT(uurlparseuendswithusource_extensionsubinary_extensionsuexcluded_extensionsuFalseuskip_externalsu startswithubase_urlu_is_platform_dependentusplituloweruTrueuloggerudebug( uselfulinkureferrerureluschemeunetlocupathu_uresultuhost((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyu _should_queuehs*           u#SimpleScrapingLocator._should_queuec Csx|jj}z|r|j|}|dkr<wnx|jD]y\}}||jkrF|jj||j| r|j|||rt j d|||jj |qqFqFWnWd|jj X|sPqqdS(u Get a URL to fetch from the work queue, get the HTML page, examine its links for download candidates and candidates for further scraping. This is a handy method to run in a thread. uQueueing %s from %sN( u _to_fetchugetuget_pageuNoneulinksu_seenuaddu_process_downloadu _should_queueuloggerudebuguputu task_done(uselfuurlupageulinkurel((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyu_fetchs" !uSimpleScrapingLocator._fetchcCst|\}}}}}}|dkrZtjjt|rZtt|d}n||jkr|j|}tj d||n|j ddd}d}||j krtj d||nAt |did d 6}zy8tj d ||jj|d |j} tj d || j} | jdd} tj| r | j} | j} | jd}|r|j|}|| } nd}tj| }|r|jd}ny| j|} Wn!tk r| jd} YnXt| | }||j| ]*>([^<]+)[\w-]+)\s*\(\s*(==\s*)?(?P[^)]+)\)$cBsw|EeZdZdZdddZddZddZdd Zd d Z d d Z ddddZ dS(uDependencyFinderu0 Locate dependencies for distributions. cCs(|p t|_t|jj|_dS(uf Initialise an instance, using the specified locator to locate distributions. N(udefault_locatorulocatoru get_schemeuscheme(uselfulocator((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyu__init__suDependencyFinder.__init__cCstjd||j}||j|<||j||jf= 1.0) while C requires (B >= 1.1). For successful replacement, ``provider`` must meet all the requirements which ``other`` fulfills. :param provider: The provider we are trying to replace with. :param other: The provider we're trying to replace. :param problems: If False is returned, this will contain what problems prevented replacement. This is currently a tuple of the literal string 'cantreplace', ``provider``, ``other`` and the set of requirements that ``provider`` couldn't fulfill. :return: True if we can replace ``other`` with ``provider``, else False. u cantreplaceFT( ureqtsusetu get_matcherumatchuversionuadduFalseuremove_distributionu setdefaultuadd_distributionuTrue( uselfuprovideruotheruproblemsurlistu unmatchedusumatcheruresult((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyutry_to_replaces        # uDependencyFinder.try_to_replacec Csi|_i|_i|_i|_t|p0g}d|krk|jd|tdddgO}nt|tr|}}tj d|nK|j j |d|}}|dkrt d|ntj d|d|_t}t|g}t|g}x|r|j}|j} | |jkrO|j|n/|j| } | |kr~|j|| |n|j|jB} |j} t} ||krxAdD]6}d |}||kr| t|d |O} qqWn| | B| B}x|D]}|j|}|s+tj d||j j |d|}|dkrv| rv|j j |dd}n|dkrtj d||jd|fq+|j|j}}||f|jkr|j|n|j||| kr+||kr+|j|tj d|jq+nxw|D]o}|j} | |jkrr|jj|tj|q2|j| } | |kr2|j|| |q2q2WqWqWt|jj}x<|D]4}||k|_|jrtj d|jqqWtj d|||fS(u Find a distribution and all distributions it depends on. :param requirement: The requirement specifying the distribution to find, or a Distribution instance. :param meta_extras: A list of meta extras such as :test:, :build: and so on. :param prereleases: If ``True``, allow pre-release versions to be returned - otherwise, don't return prereleases unless they're all that's available. Return a set of :class:`Distribution` instances and a set of problems. The distributions returned should be such that they have the :attr:`required` attribute set to ``True`` if they were from the ``requirement`` passed to ``find()``, and they have the :attr:`build_time_dependency` attribute set to ``True`` unless they are post-installation dependencies of the ``requirement``. The problems should be a tuple consisting of the string ``'unsatisfied'`` and the requirement which couldn't be satisfied by any distribution known to the locator. u:*:u:test:u:build:u:dev:upassed %s as requirementu prereleasesuUnable to locate %ru located %sutestubuildudevu:%s:u %s_requiresuNo providers found for %ruCannot satisfy %ru unsatisfieduAdding %s to install_distsu#%s is a build-time dependency only.ufind done for %sNT(utestubuildudev(uprovidedudistsu dists_by_nameureqtsuseturemoveu isinstanceu DistributionuloggerudebugulocatorulocateuNoneuDistlibExceptionuTrueu requestedupopukeyuadd_distributionutry_to_replaceu run_requiresu meta_requiresubuild_requiresugetattrufind_providersuadduversionuname_and_versionu setdefaultuvaluesubuild_time_dependency(uselfu requirementu meta_extrasu prereleasesudistuodistuproblemsutodou install_distsunameuotheruireqtsusreqtsuereqtsukeyueu all_reqtsuru providersuproviderunuvupudists((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyufind>s                      !       "  "   uDependencyFinder.findNF( u__name__u __module__u __qualname__u__doc__uNoneu__init__uadd_distributionuremove_distributionu get_matcherufind_providersutry_to_replaceuFalseufind(u __locals__((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyuDependencyFinders     'uDependencyFinder(MugzipuiouBytesIOujsonulogginguosu posixpathureu threadingu ImportErrorudummy_threadinguzlibuuDistlibExceptionucompatuurljoinuurlparseu urlunparseu url2pathnameu pathname2urluqueueuquoteuunescapeu string_typesu build_openeruHTTPRedirectHandleruBaseRedirectHandleruRequestu HTTPErroruURLErrorudatabaseu DistributionuDistributionPathu make_distumetadatauMetadatauutilucached_propertyuparse_credentialsu ensure_slashusplit_filenameuget_project_datauparse_requirementuparse_name_and_versionu ServerProxyuversionu get_schemeuUnsupportedVersionErroruwheeluWheelu is_compatibleu getLoggeru__name__uloggerucompileu HASHER_HASHuIuCHARSETuHTML_CONTENT_TYPEu DEFAULT_INDEXuNoneuget_all_distribution_namesuRedirectHandleruobjectuLocatoruPyPIRPCLocatoruPyPIJSONLocatoruPageuSimpleScrapingLocatoruDirectoryLocatoru JSONLocatoruDistPathLocatoruAggregatingLocatorudefault_locatorulocateuNAME_VERSION_REuDependencyFinder(((u5/tmp/pip-zej_zi-build/pip/_vendor/distlib/locators.pyusV        ^: +*:A%N