B
    =)H[s6  ã               @   s’   d Z ddlZddlmZ ddlmZ ddlmZmZm	Z	m
Z
mZ ddlmZ ddlmZ ddlmZmZ dd	lmZ e e¡ZG d
d„ deƒZdS )ay  Dependency 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)ÚBestVersionAlreadyInstalledÚDistributionNotFoundÚ	HashErrorÚ
HashErrorsÚUnsupportedPythonVersion)ÚInstallRequirement)Ú
indent_log)Údist_in_usersiteÚ
ensure_dir)Úcheck_dist_requires_pythonc                   sb   e Zd ZdZdddhZ‡ fdd„Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Z‡  ZS )ÚResolverz–Resolves which packages need to be installed/uninstalled to perform     the requested operation without breaking the requirements of any package.
    Úeagerzonly-if-neededzto-satisfy-onlyc                sr   t t| ƒ ¡  || jkst‚|| _|| _|| _|| _d | _	|| _
|	| _|
| _|| _|| _|| _|| _ttƒ| _d S )N)Úsuperr   Ú__init__Ú_allowed_strategiesÚAssertionErrorÚpreparerÚfinderÚsessionÚwheel_cacheÚrequire_hashesÚupgrade_strategyÚforce_reinstallÚisolatedÚignore_dependenciesÚignore_installedÚignore_requires_pythonÚuse_user_siter   ÚlistÚ_discovered_dependencies)Úselfr   r   r   r   r   r   r   r   r   r   r   )Ú	__class__© úVC:\Users\HIRONO~1\AppData\Local\Temp\pip-install-qz7kpjmn\pip\pip\_internal\resolve.pyr   %   s    zResolver.__init__c             C   sÎ   | j jrt| j jƒ |jt|j ¡ ƒ }|jp>tdd„ |D ƒƒ| _| j	 
¡ }|rZt |¡ g }tƒ }x\t||ƒD ]N}y| |  ||¡¡ W qp tk
r¼ } z||_| |¡ W dd}~X Y qpX qpW |rÊ|‚dS )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.
        c             s   s   | ]}|j V  qd S )N)Úhas_hash_options)Ú.0Úreqr$   r$   r%   ú	<genexpr>V   s    z#Resolver.resolve.<locals>.<genexpr>N)r   Úwheel_download_dirr   Úunnamed_requirementsr    ÚrequirementsÚvaluesr   Úanyr   Úget_formatted_locationsÚloggerÚinfor   r   ÚextendÚ_resolve_oner   r(   Úappend)r"   Úrequirement_setÚ	root_reqsÚ	locationsÚdiscovered_reqsÚhash_errorsr(   Úexcr$   r$   r%   Úresolve?   s(    

 zResolver.resolvec             C   s4   | j dkrdS | j dkrdS | j dks*t‚|jS d S )Nzto-satisfy-onlyFr   Tzonly-if-needed)r   r   Ú	is_direct)r"   r(   r$   r$   r%   Ú_is_upgrade_allowedp   s    

zResolver._is_upgrade_allowedc             C   s"   | j rt|jƒr|j|_d|_dS )z4
        Set a requirement to be installed.
        N)r   r   Úsatisfied_byÚconflicts_with)r"   r(   r$   r$   r%   Ú_set_req_to_reinstally   s    zResolver._set_req_to_reinstallc             C   s    | j r
dS | | j¡ |js dS | jr4|  |¡ dS |  |¡sP| jdkrLdS dS |js’y| j	j
|dd� W n& tk
r~   dS  tk
r�   Y nX |  |¡ dS )a  Check 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.
        Nzonly-if-neededz%not upgraded as not directly requiredzalready satisfiedT)Úupgradezalready up-to-date)r   Úcheck_if_existsr   r>   r   r@   r=   r   Úlinkr   Úfind_requirementr   r   )r"   Úreq_to_installr$   r$   r%   Ú_check_skip_installed„   s*    



zResolver._check_skip_installedc             C   sÞ   | j dk	stdƒ‚|jr0| j || j | j| j¡S |jdks>t‚|  |¡}|jr`| j 	|| j |¡S |  
|¡}| j || j| j|| j ¡}| js–| | j¡ |jrÚ| jdkp¼| jp¼| jp¼|jjdk}|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()zto-satisfy-onlyÚfilez<Requirement already satisfied (use --upgrade to upgrade): %s)r   r   Úeditabler   Úprepare_editable_requirementr   r   r>   rF   Úprepare_installed_requirementr=   Úprepare_linked_requirementr   r   rB   r   r   rC   Úschemer@   r0   r1   )r"   r(   Úskip_reasonÚupgrade_allowedÚabstract_distÚshould_modifyr$   r$   r%   Ú_get_abstract_dist_for¸   s6    


zResolver._get_abstract_dist_forc          
      s|  ˆj sˆjrg S dˆ_ˆj ˆ¡ ˆ ˆ¡}| ˆj¡}yt|ƒ W n< tk
r€ } zˆj	rnt
 |jd ¡ n‚ W dd}~X Y nX g ‰ ‡ ‡‡‡fdd„}tƒ �Ô ˆ ˆj¡sÀdˆ_ˆjˆdd� ˆj�sRˆjrât
 dd ˆj¡¡ ttˆjƒt|jƒ ƒ}x|D ]}t
 d	||¡ �q W tt|jƒtˆjƒ@ ƒ}	x | |	¡D ]}
||
|	d
� �q<W ˆj�snˆj�snˆj ˆ¡ W dQ R X ˆ S )zxPrepare a single requirements file.

        :return: A list of additional InstallRequirements to also install.
        Tr   Nc                sZ   t jt| ƒˆˆjˆjd�}ˆj}ˆj|||d�\}}|rL|rLˆj|  |¡ ˆ  	|¡ d S )N)r   r   )Úparent_req_nameÚextras_requested)
r	   Úfrom_reqÚstrr   r   ÚnameÚadd_requirementr!   r4   r2   )ÚsubreqrS   Úsub_install_reqrR   Úto_scan_againÚadd_to_parent)Ú	more_reqsrE   r5   r"   r$   r%   Úadd_req  s    

z&Resolver._resolve_one.<locals>.add_req)rR   z!Installing extra requirements: %rú,z"%s does not provide the extra '%s')rS   )Ú
constraintÚpreparedÚreqs_to_cleanupr4   rQ   Údistr   r   r   r   r0   ÚwarningÚargsr
   Úhas_requirementrV   r<   rW   r   ÚextrasÚdebugÚjoinÚsortedÚsetÚrequiresrH   r>   Úsuccessfully_downloaded)r"   r5   rE   rO   rb   Úerrr]   Úmissing_requestedÚmissingÚavailable_requestedrX   r$   )r\   rE   r5   r"   r%   r3   ñ   sJ    


zResolver._resolve_onec                s<   g ‰ t ƒ ‰‡ ‡‡‡fdd„‰x|j ¡ D ]}ˆ|ƒ q(W ˆ 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.
        c                sR   | j s| ˆkrd S | jrd S ˆ | ¡ xˆj| j D ]}ˆ|ƒ q4W ˆ  | ¡ d S )N)r>   r_   Úaddr!   rV   r4   )r(   Údep)ÚorderÚordered_reqsÚscheduler"   r$   r%   ru   V  s    
z1Resolver.get_installation_order.<locals>.schedule)rj   r,   r-   )r"   Úreq_setÚinstall_reqr$   )rs   rt   ru   r"   r%   Úget_installation_orderI  s    

zResolver.get_installation_order)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r;   r=   r@   rF   rQ   r3   rx   Ú__classcell__r$   r$   )r#   r%   r      s   
1	49Xr   )r|   ÚloggingÚcollectionsr   Ú	itertoolsr   Úpip._internal.exceptionsr   r   r   r   r   Zpip._internal.req.req_installr	   Úpip._internal.utils.loggingr
   Úpip._internal.utils.miscr   r   Úpip._internal.utils.packagingr   Ú	getLoggerry   r0   Úobjectr   r$   r$   r$   r%   Ú<module>   s   
