U ÀÒ.eRCã@sFdZddlZddlZddlmZddlmZddlmZddl m Z m Z m Z m Z mZddlmZddlmZmZmZmZdd lmZmZdd lmZe�rdd lmZmZmZmZm Z m!Z!dd l"m#Z#dd l$m%Z%ddl&m'Z'ddl(m)Z)ddl*m+Z+ddl,m-Z-ddl.m/Z/ee0e-ge-fZ1e 2e3¡Z4ddd„Z5Gdd„de6ƒZ7dS)ayDependency Resolution The dependency resolution in pip is performed as follows: for top-level requirements: a. only one spec allowed per project, regardless of conflicts or not. otherwise a "double requirement" exception is raised b. they override sub-dependency requirements. for sub-dependencies a. "first found, wins" (where the order is breadth first) éN)Ú defaultdict)Úchain)Ú specifiers)ÚBestVersionAlreadyInstalledÚDistributionNotFoundÚ HashErrorÚ HashErrorsÚUnsupportedPythonVersion)Ú indent_log)Údist_in_install_pathÚdist_in_usersiteÚ ensure_dirÚnormalize_version_info)Úcheck_requires_pythonÚget_requires_python)ÚMYPY_CHECK_RUNNING)ÚCallableÚ DefaultDictÚListÚOptionalÚSetÚTuple)Ú pkg_resources)ÚAbstractDistribution)Ú PipSession)Ú PackageFinder)ÚRequirementPreparer)ÚInstallRequirement)ÚRequirementSetFc Csžt|ƒ}zt||d�}Wn:tjk rR}zt d|j|¡WY¢dSd}~XYnX|r\dSd tt |ƒ¡}|r†t  d|j||¡dSt d  |j||¡ƒ‚dS)aÇ Check whether the given Python version is compatible with a distribution's "Requires-Python" value. :param version_info: A 3-tuple of ints representing the Python major-minor-micro version to check. :param ignore_requires_python: Whether to ignore the "Requires-Python" value if the given Python version isn't compatible. :raises UnsupportedPythonVersion: When the given Python version isn't compatible. )Ú version_infoz-Package %r has an invalid Requires-Python: %sNÚ.zBIgnoring failed Requires-Python check for package %r: %s not in %rz8Package {!r} requires a different Python: {} not in {!r}) rrrZInvalidSpecifierÚloggerÚwarningZ project_nameÚjoinÚmapÚstrÚdebugr Úformat)ÚdistrÚignore_requires_pythonZrequires_pythonZ is_compatibleÚexcÚversion©r,ú@/usr/lib/python3.8/site-packages/pip/_internal/legacy_resolve.pyÚ_check_dist_requires_python>s>ÿ þýÿÿr.csdeZdZdZdddhZd‡fdd„ Zdd „Zd d „Zd d „Zdd„Z dd„Z dd„Z dd„Z ‡Z S)ÚResolverz–Resolves which packages need to be installed/uninstalled to perform the requested operation without breaking the requirements of any package. Úeagerúonly-if-neededúto-satisfy-onlyNc s’tt|ƒ ¡| |jkst‚| dkr4tjdd…} nt| ƒ} | |_||_ ||_ ||_ d|_ | |_ | |_||_||_||_||_||_ttƒ|_dS)Né)Úsuperr/Ú__init__Ú_allowed_strategiesÚAssertionErrorÚsysrrÚ_py_version_infoÚpreparerÚfinderÚsessionÚrequire_hashesÚupgrade_strategyÚforce_reinstallÚignore_dependenciesÚignore_installedr)Ú use_user_siteÚ_make_install_reqrÚlistÚ_discovered_dependencies) Úselfr:r<r;Zmake_install_reqrBr@rAr)r?r>Zpy_version_info©Ú __class__r,r-r5us&ÿzResolver.__init__c CsÐ|jjrt|jjƒ|jt|j ¡ƒ}|jp>tdd„|Dƒƒ|_|j j }|  ¡}|r`t   |¡g}tƒ}t||ƒD]N}z| | ||¡¡Wqttk rÀ}z||_| |¡W5d}~XYqtXqt|rÌ|‚dS)a±Resolve what operations need to be done As a side-effect of this method, the packages (and their dependencies) are downloaded, unpacked and prepared for installation. This preparation is done by ``pip.operations.prepare``. Once PyPI has static dependency metadata available, it would be possible to move the preparation to become a step separated from dependency resolution. css|] }|jVqdS©N)Zhas_hash_options)Ú.0Úreqr,r,r-Ú ¸sz#Resolver.resolve..N)r:Zwheel_download_dirr Zunnamed_requirementsrDÚ requirementsÚvaluesr=Úanyr;Ú search_scopeZget_formatted_locationsr!ÚinforrÚextendÚ _resolve_onerrKÚappend) rFÚrequirement_setZ root_reqsrPZ locationsZdiscovered_reqsZ hash_errorsrKr*r,r,r-Úresolve s2   ÿÿþ  ÿzResolver.resolvecCs4|jdkrdS|jdkrdS|jdks*t‚|jSdS)Nr2Fr0Tr1)r>r7Ú is_direct©rFrKr,r,r-Ú_is_upgrade_allowedÓs   zResolver._is_upgrade_allowedcCs,|jrt|jƒr"t|jƒr"|j|_d|_dS)z4 Set a requirement to be installed. N)rBr Ú satisfied_byr Zconflicts_withrXr,r,r-Ú_set_req_to_reinstallÝsÿþzResolver._set_req_to_reinstallcCs¢|jr dS| |j¡|js dS|jr4| |¡dS| |¡sP|jdkrLdSdS|js”z|j j |dd�Wn(t k r€YdSt k r’YnX| |¡dS)aCheck if req_to_install should be skipped. This will check if the req is installed, and whether we should upgrade or reinstall it, taking into account all the relevant user options. After calling this req_to_install will only have satisfied_by set to None if the req_to_install is to be upgraded/reinstalled etc. Any other value will be a dist recording the current thing installed that satisfies the requirement. Note that for vcs urls and the like we can't assess skipping in this routine - we simply identify that we need to pull the thing down, then later on it is pulled down and introspected to assess upgrade/ reinstalls etc. :return: A text reason for why it was skipped, or None. Nr1z#already satisfied, skipping upgradezalready satisfiedT)Zupgradezalready up-to-date) rAÚcheck_if_existsrBrZr?r[rYr>Úlinkr;Zfind_requirementrr)rFÚreq_to_installr,r,r-Ú_check_skip_installedês*     zResolver._check_skip_installedcCsî|jdk stdƒ‚|jr0|j ||j|j|j¡S|jdks>t‚| |¡}|jr`|j  ||j|¡S|  |¡}|  |j||j¡|j  ||j |j|j¡}|js¦| |j¡|jrê|jdkpÌ|jpÌ|jpÌ|jjdk}|rÞ| |¡n t d|¡|S)zzTakes a InstallRequirement and returns a single AbstractDist representing a prepared variant of the same. Nz9require_hashes should have been set in Resolver.resolve()r2Úfilezr?r]Zschemer[r!rQ)rFrKZ skip_reasonZupgrade_allowedÚ abstract_distZ should_modifyr,r,r-Ú_get_abstract_dist_forsV ÿÿ ÿ ÿ   ÿþ ü þzResolver._get_abstract_dist_forc s4ˆjs ˆjrgSdˆ_ˆj ˆ¡ˆ ˆ¡}| ¡}t|ˆjˆjd�g‰‡‡‡‡fdd„}t ƒ�Ȉ  ˆj ¡s„dˆ_ ˆj ˆdd�ˆj�s ˆjr¦t dd ˆj¡¡ttˆjƒt|jƒƒ}|D]}t d ||¡qÂtt|jƒtˆjƒ@ƒ}| |¡D]} || |d �qøˆj�s&ˆj�s&ˆj ˆ¡W5QRXˆS) zxPrepare a single requirements file. :return: A list of additional InstallRequirements to also install. T)rr)csPˆ t|ƒˆ¡}ˆj}ˆj|||d�\}}|rB|rBˆj| |¡ˆ |¡dS)N)Úparent_req_nameÚextras_requested)rCr%ÚnameÚadd_requirementrErTrR)ÚsubreqreZsub_install_reqrdZ to_scan_againZ add_to_parent©Z more_reqsr^rUrFr,r-Úadd_req}sþý  ÿz&Resolver._resolve_one..add_reqN)rdz!Installing extra requirements: %rú,z"%s does not provide the extra '%s')re)Ú constraintZpreparedZreqs_to_cleanuprTrcZget_pkg_resources_distributionr.r9r)r Zhas_requirementrfrWrgr@Zextrasr!r&r#ÚsortedÚsetr"ZrequiresrarZZsuccessfully_downloaded) rFrUr^rbr(rjZmissing_requestedZmissingZavailable_requestedrhr,rir-rS[sV   þ ÿ þÿþÿzResolver._resolve_onecs8g‰tƒ‰‡‡‡‡fdd„‰|j ¡D] }ˆ|ƒq&ˆS)zäCreate the installation order. The installation order is topological - requirements are installed before the requiring thing. We break cycles at an arbitrary point, and make no other guarantees. csN|js|ˆkrdS|jrdSˆ |¡ˆj|jD] }ˆ|ƒq2ˆ |¡dSrI)rZrlÚaddrErfrT)rKZdep©ÚorderZ ordered_reqsÚschedulerFr,r-rrÃs  z1Resolver.get_installation_order..schedule)rnrMrN)rFZreq_setZ install_reqr,rpr-Úget_installation_orderµs   zResolver.get_installation_order)N)Ú__name__Ú __module__Ú __qualname__Ú__doc__r6r5rVrYr[r_rcrSrsÚ __classcell__r,r,rGr-r/ns ô+3  5<Zr/)F)8rwZloggingr8Ú collectionsrÚ itertoolsrZpip._vendor.packagingrZpip._internal.exceptionsrrrrr Zpip._internal.utils.loggingr Zpip._internal.utils.miscr r r rZpip._internal.utils.packagingrrZpip._internal.utils.typingrÚtypingrrrrrrZ pip._vendorrZpip._internal.distributionsrZpip._internal.network.sessionrZpip._internal.indexrZ pip._internal.operations.preparerZpip._internal.req.req_installrZpip._internal.req.req_setrr%ZInstallRequirementProviderZ getLoggerrtr!r.Úobjectr/r,r,r,r-Ús4              ÿ ý 0