3 (\;@sdZddlZddlmZddlmZddlmZmZm Z m Z m Z ddl m Z ddlmZddlmZmZdd lmZdd lmZerdd lmZmZmZmZdd lmZdd lmZddl m!Z!ddl"m#Z#ddl$m%Z%m&Z&ddl'm(Z(ej)e*Z+Gddde,Z-dS)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)BestVersionAlreadyInstalledDistributionNotFound HashError HashErrorsUnsupportedPythonVersion)install_req_from_req_string) indent_log)dist_in_usersite ensure_dir)check_dist_requires_python)MYPY_CHECK_RUNNING)Optional DefaultDictListSet) PipSession)InstallRequirement) PackageFinder)RequirementSet)DistAbstractionRequirementPreparer) WheelCachecsdeZdZdZdddhZdfdd Zdd Zd d Zd d ZddZ ddZ ddZ ddZ Z S)ResolverzResolves which packages need to be installed/uninstalled to perform the requested operation without breaking the requirements of any package. eagerzonly-if-neededzto-satisfy-onlyNc sxtt|j| |jkst||_||_||_||_d|_ | |_ | |_ | |_ ||_ ||_||_||_| |_tt|_dS)N)superr__init___allowed_strategiesAssertionErrorpreparerfindersession wheel_cacherequire_hashesupgrade_strategyforce_reinstallisolatedignore_dependenciesignore_installedignore_requires_python use_user_site use_pep517rlist_discovered_dependencies) selfr r"r!r#r+r(r)r*r&r'r%r,) __class__h/private/var/folders/pf/wv4htv3x0qs2c2mp0dnn0kchsvlck3/T/pip-build-k1a8l1r5/pip/pip/_internal/resolve.pyr0s zResolver.__init__cCs|jjrt|jj|jt|jj}|jp>tdd|D|_|j j }|rZt j |g}t }x\t||D]N}y|j|j||Wqptk r}z||_|j|WYdd}~XqpXqpW|r|dS)aResolve 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)has_hash_options).0reqr1r1r2 rsz#Resolver.resolve..N)r wheel_download_dirr unnamed_requirementsr- requirementsvaluesr$anyr!Zget_formatted_locationsloggerinforrextend _resolve_onerr5append)r/requirement_set root_reqs locationsdiscovered_reqs hash_errorsr5excr1r1r2resolveZs(     zResolver.resolvecCs4|jdkrdS|jdkrdS|jdks*t|jSdS)Nzto-satisfy-onlyFrTzonly-if-needed)r%r is_direct)r/r5r1r1r2_is_upgrade_alloweds   zResolver._is_upgrade_allowedcCs$|j st|jr|j|_d|_dS)z4 Set a requirement to be installed. N)r+r satisfied_byconflicts_with)r/r5r1r1r2_set_req_to_reinstallszResolver._set_req_to_reinstallc Cs|jr dS|j|j|js dS|jr4|j|dS|j|sP|jdkrLdSdS|jsy|j j |ddWn&t k r~dSt k rYnX|j|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. Nzonly-if-neededz#already satisfied, skipping upgradezalready satisfiedT)upgradezalready up-to-date) r)check_if_existsr+rJr&rLrIr%linkr!find_requirementrr)r/req_to_installr1r1r2_check_skip_installeds*     zResolver._check_skip_installedcCs|jdk std|jr0|jj||j|j|jS|jdks>t|j|}|jr`|jj ||j|S|j |}|jj ||j |j||j}|j s|j|j|jr|jdkp|jp|j p|jjdk}|r|j|n tjd||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()zto-satisfy-onlyfilez)subreqr[sub_install_reqrZZ to_scan_againZ add_to_parent) more_reqsrQrAr/r1r2add_req4s   z&Resolver._resolve_one..add_req)rZz!Installing extra requirements: %r,z"%s does not provide the extra '%s')r[) constraintpreparedreqs_to_cleanupr@rYdistr rr*r<warningargsr has_requirementr]rHr^r(extrasdebugjoinsortedsetrequiresrTrJsuccessfully_downloaded) r/rArQrXrgerrrbmissing_requestedmissingavailable_requestedr_r1)rarQrAr/r2r?sJ       zResolver._resolve_onecs<gtfddx|jjD] }|q(WS)zCreate 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. csR|js|krdS|jrdSj|xj|jD] }|q4Wj|dS)N)rJrdaddr.r]r@)r5dep)order ordered_reqsscheduler/r1r2rz}s  z1Resolver.get_installation_order..schedule)ror9r:)r/req_set install_reqr1)rxryrzr/r2get_installation_orderos   zResolver.get_installation_order)N)__name__ __module__ __qualname____doc__rrrGrIrLrRrYr?r} __classcell__r1r1)r0r2r)s 2  5:^r).rlogging collectionsr itertoolsrZpip._internal.exceptionsrrrrrZpip._internal.req.constructorsr Zpip._internal.utils.loggingr Zpip._internal.utils.miscr r Zpip._internal.utils.packagingr Zpip._internal.utils.typingrZtypingrrrrZpip._internal.downloadrZpip._internal.req.req_installrZpip._internal.indexrZpip._internal.req.req_setrZ pip._internal.operations.preparerrZpip._internal.cacher getLoggerr~r<objectrr1r1r1r2 s&