
}_                 @   s  d  d l  m Z d  d l m Z d  d l m Z d  d l Z d  d l Z d  d l m	 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 m Z m Z m Z m Z m Z m Z m Z m Z m Z d  d
 l m Z d  d l  m! Z! m" Z" m# Z# m$ Z$ d  d l% m& Z& d  d l' m( Z( d  d l) m* Z* d  d l+ m, Z, d  d l- m. Z. e j/ e0  Z1 Gd d   d e2  Z3 Gd d   d e2  Z4 d d   Z5 Gd d   d e4  Z6 Gd d   d e4  Z7 Gd d   d e4  Z8 Gd d   d e2  Z9 d S)    )absolute_import)defaultdict)chainN)pkg_resources)requests)
expanduser)is_file_url
is_dir_url
is_vcs_urlurl_to_path
unpack_url)
InstallationErrorBestVersionAlreadyInstalledDistributionNotFoundPreviousBuildDirError	HashError
HashErrorsHashUnpinnedDirectoryUrlHashUnsupportedVcsHashUnsupportedUnsupportedPythonVersion)InstallRequirement)display_pathdist_in_usersite
ensure_dirnormalize_path)MissingHashes)
indent_log)check_dist_requires_python)vcs)Wheelc               @   sd   e  Z d  Z d d   Z d d   Z d d   Z d d   Z d	 d
   Z d d   Z d d   Z	 d S)Requirementsc             C   s   g  |  _  i  |  _ d  S)N)_keys_dict)self r%   ./tmp/pip-build-3_sjtvrs/pip/pip/req/req_set.py__init__!   s    	zRequirements.__init__c             C   s   |  j  S)N)r"   )r$   r%   r%   r&   keys%   s    zRequirements.keysc                s     f d d     j  D S)Nc                s   g  |  ] }   j  |  q Sr%   )r#   ).0key)r$   r%   r&   
<listcomp>)   s   	 z'Requirements.values.<locals>.<listcomp>)r"   )r$   r%   )r$   r&   values(   s    zRequirements.valuesc             C   s   | |  j  k S)N)r"   )r$   itemr%   r%   r&   __contains__+   s    zRequirements.__contains__c             C   s0   | |  j  k r |  j  j |  | |  j | <d  S)N)r"   appendr#   )r$   r*   valuer%   r%   r&   __setitem__.   s    zRequirements.__setitem__c             C   s   |  j  | S)N)r#   )r$   r*   r%   r%   r&   __getitem__3   s    zRequirements.__getitem__c                s0     f d d     j    D } d d j |  S)Nc                s0   g  |  ]& } d  t  |  t    |  f  q S)z%s: %s)repr)r)   k)r$   r%   r&   r+   7   s   	 z)Requirements.__repr__.<locals>.<listcomp>zRequirements({%s})z, )r(   join)r$   r,   r%   )r$   r&   __repr__6   s    zRequirements.__repr__N)
__name__
__module____qualname__r'   r(   r,   r.   r1   r2   r6   r%   r%   r%   r&   r!      s   r!   c               @   s:   e  Z d  Z d Z d d   Z d d   Z d d   Z d S)	DistAbstractionat  Abstracts out the wheel vs non-wheel prepare_files logic.

    The requirements for anything installable are as follows:
     - we must be able to determine the requirement name
       (or we can't correctly handle the non-upgrade case).
     - we must be able to generate a list of run-time dependencies
       without installing any additional packages (or we would
       have to either burn time by doing temporary isolated installs
       or alternatively violate pips 'don't start installing unless
       all requirements are available' rule - neither of which are
       desirable).
     - for packages with setup requirements, we must also be able
       to determine their requirements without installing additional
       packages (for the same reason as run-time dependencies)
     - we must be able to create a Distribution object exposing the
       above metadata.
    c             C   s   | |  _  d  S)N)req_to_install)r$   r;   r%   r%   r&   r'   N   s    zDistAbstraction.__init__c             C   s   t  |  j   d S)z Return a setuptools Dist object.N)NotImplementedErrordist)r$   finderr%   r%   r&   r=   Q   s    zDistAbstraction.distc             C   s   t  |  j   d S)z3Ensure that we can get a Dist for this requirement.N)r<   r=   )r$   r%   r%   r&   prep_for_distU   s    zDistAbstraction.prep_for_distN)r7   r8   r9   __doc__r'   r=   r?   r%   r%   r%   r&   r:   ;   s   r:   c             C   s@   |  j  r t |   S|  j r2 |  j j r2 t |   St |   Sd S)zFactory to make an abstract dist object.

    Preconditions: Either an editable req with a source_dir, or satisfied_by or
    a wheel link, or a non-editable req with a source_dir.

    :return: A concrete DistAbstraction.
    N)editableIsSDistlinkis_wheelIsWheel)r;   r%   r%   r&   make_abstract_distZ   s
    	

rF   c               @   s(   e  Z d  Z d d   Z d d   Z d S)rE   c             C   s   t  t j |  j j   d S)Nr   )listr   find_distributionsr;   
source_dir)r$   r>   r%   r%   r&   r=   l   s    	zIsWheel.distc             C   s   d  S)Nr%   )r$   r%   r%   r&   r?   p   s    zIsWheel.prep_for_distN)r7   r8   r9   r=   r?   r%   r%   r%   r&   rE   j   s   rE   c               @   s(   e  Z d  Z d d   Z d d   Z d S)rB   c             C   s8   |  j  j   } | j d  r4 | j | j d   | S)Nzdependency_links.txt)r;   get_disthas_metadataadd_dependency_linksget_metadata_lines)r$   r>   r=   r%   r%   r&   r=   w   s
    zIsSDist.distc             C   s   |  j  j   |  j  j   d  S)N)r;   run_egg_infoassert_source_matches_version)r$   r%   r%   r&   r?      s    zIsSDist.prep_for_distN)r7   r8   r9   r=   r?   r%   r%   r%   r&   rB   u   s   	rB   c               @   s(   e  Z d  Z d d   Z d d   Z d S)	Installedc             C   s
   |  j  j S)N)r;   satisfied_by)r$   r>   r%   r%   r&   r=      s    zInstalled.distc             C   s   d  S)Nr%   )r$   r%   r%   r&   r?      s    zInstalled.prep_for_distN)r7   r8   r9   r=   r?   r%   r%   r%   r&   rP      s   rP   c               @   s  e  Z d  Z d d d d d d d d d d d d d d d d d  Z d d   Z d d	   Z d d d
 d  Z d d   Z e d d    Z	 e d d    Z
 d d   Z d d d  Z d d   Z d d   Z d d   Z d d d d  Z d d   Z d  d!   Z f  d" d#  Z d S)$RequirementSetFNTc             C   s  | d k r t  d   | |  _ | |  _ | |  _ | |  _ | |  _ | |  _ |
 |  _ t   |  _	 i  |  _
 g  |  _ |	 |  _ | |  _ g  |  _ g  |  _ g  |  _ | |  _ | |  _ | |  _ | |  _ | |  _ | |  _ | r t |  } | |  _ | |  _ | |  _ t t  |  _ d S)a3  Create a RequirementSet.

        :param wheel_download_dir: Where still-packed .whl files should be
            written to. If None they are written to the download_dir parameter.
            Separate to download_dir to permit only keeping wheel archives for
            pip wheel.
        :param download_dir: Where still packed archives should be written to.
            If None they are not saved, and are deleted immediately after
            unpacking.
        :param wheel_cache: The pip wheel cache, for passing to
            InstallRequirement.
        Nz?RequirementSet() missing 1 required keyword argument: 'session')	TypeError	build_dirsrc_dirdownload_dirupgradeupgrade_strategyignore_installedforce_reinstallr!   requirementsrequirement_aliasesunnamed_requirementsignore_dependenciesignore_requires_pythonsuccessfully_downloadedsuccessfully_installedreqs_to_cleanupas_egguse_user_site
target_dirsession	pycompileisolatedr   wheel_download_dir_wheel_cacherequire_hashesr   rG   _dependencies)r$   rT   rU   rV   rW   rX   rY   rc   re   r^   rZ   rd   rf   rg   rh   ri   wheel_cacherk   r_   r%   r%   r&   r'      s<    																								zRequirementSet.__init__c             C   sL   d d   |  j  j   D } | j d d d    d j d d   | D  S)Nc             S   s   g  |  ] } | j  s |  q Sr%   )
comes_from)r)   reqr%   r%   r&   r+      s   	 z*RequirementSet.__str__.<locals>.<listcomp>r*   c             S   s   |  j  j   S)N)namelower)ro   r%   r%   r&   <lambda>   s    z(RequirementSet.__str__.<locals>.<lambda> c             S   s   g  |  ] } t  | j   q Sr%   )strro   )r)   ro   r%   r%   r&   r+      s   	 )r[   r,   sortr5   )r$   reqsr%   r%   r&   __str__   s    zRequirementSet.__str__c             C   sk   d d   |  j  j   D } | j d d d    d j d d   | D  } d |  j j t |  | f S)	Nc             S   s   g  |  ] } |  q Sr%   r%   )r)   ro   r%   r%   r&   r+      s   	 z+RequirementSet.__repr__.<locals>.<listcomp>r*   c             S   s   |  j  j   S)N)rp   rq   )ro   r%   r%   r&   rr      s    z)RequirementSet.__repr__.<locals>.<lambda>z, c             S   s   g  |  ] } t  | j   q Sr%   )rt   ro   )r)   ro   r%   r%   r&   r+      s   	 z"<%s object; %d requirement(s): %s>)r[   r,   ru   r5   	__class__r7   len)r$   rv   reqs_strr%   r%   r&   r6      s
    zRequirementSet.__repr__c       	      C   s  | j  } | j |  s5 t j d | j  | j  g  S| j r{ | j j r{ t | j j  } | j	   s{ t
 d | j   |  j | _ |  j | _ |  j | _ |  j | _ | d k | _ | s |  j j |  | g Sy |  j |  } Wn t k
 rd } Yn X| d k re| re| j re| j | j k re| j j | j j k ret
 d | | | f   | s| |  j | <| j   | k r| |  j | j   <| g } n g  } | j re| j re| j r| j o| j j | j j k r|  j j |  t
 d |   d | _ t t t | j  j  t | j     | _ t j! d | | j  | g } | } | r|  j |  } |  j" | j |  | Sd S)a'  Add install_req as a requirement to install.

        :param parent_req_name: The name of the requirement that needed this
            added. The name is used because when multiple unnamed requirements
            resolve to the same name, we could otherwise end up with dependency
            links that point outside the Requirements set. parent_req must
            already be added. Note that None implies that this is a user
            supplied requirement, vs an inferred one.
        :param extras_requested: an iterable of extras used to evaluate the
            environement markers.
        :return: Additional requirements to scan. That is either [] if
            the requirement is not applicable, or [install_req] if the
            requirement is applicable and has just been added.
        z6Ignoring %s: markers '%s' don't match your environmentz-%s is not a supported wheel on this platform.Nz5Double requirement given: %s (already in %s, name=%r)zhCould not satisfy constraints for '%s': installation from path or url cannot be constrained to a versionFzSetting %s extras to: %s)#rp   match_markersloggerwarningmarkersrC   rD   r    filename	supportedr   rc   rd   re   rg   	is_directr]   r/   get_requirementKeyError
constraintextrasro   	specifierr[   rq   r\   pathrb   tuplesortedsetuniondebugrl   )	r$   install_reqparent_req_nameextras_requestedrp   wheelexisting_reqresult
parent_reqr%   r%   r&   add_requirement   sp    		


			zRequirementSet.add_requirementc             C   s[   | j    } | |  j k r, |  j | j sS | |  j k rW |  j |  j | j rW d Sd S)NTF)rq   r[   r   r\   )r$   project_namerp   r%   r%   r&   has_requirement3  s    zRequirementSet.has_requirementc             C   s)   t  d d   |  j j   D  p( |  j S)Nc             s   s   |  ] } | j  s | Vq d  S)N)r   )r)   ro   r%   r%   r&   	<genexpr>>  s    z2RequirementSet.has_requirements.<locals>.<genexpr>)rG   r[   r,   r]   )r$   r%   r%   r&   has_requirements<  s    "zRequirementSet.has_requirementsc             C   s^   |  j  rZ t |  j   |  _  t j j |  j   r4 d St j d  t d t |  j     d S)NTz!Could not find download directoryz0Could not find or access download directory '%s'F)	rV   r   osr   existsr|   criticalr   r   )r$   r%   r%   r&   is_downloadA  s    	zRequirementSet.is_downloadc             C   sl   xU | | j    f D]A } | |  j k r3 |  j | S| |  j k r |  j |  j | Sq Wt d |   d  S)NzNo project with the name %r)rq   r[   r\   r   )r$   r   rp   r%   r%   r&   r   N  s    zRequirementSet.get_requirementc             C   sD   x= |  j  j   D], } | j r" q | j d |  | j   q Wd  S)Nauto_confirm)r[   r,   r   	uninstallcommit_uninstall)r$   r   ro   r%   r%   r&   r   V  s
    	zRequirementSet.uninstallc             C   s  |  j  r t |  j   |  j |  j j   } |  j pK t d d   | D  } | ri |  j ri t d   g  } t	   } x t
 | |  D]p } y, | j |  j | | d | d |  j  Wq t k
 r } z | | _ | j |  WYd d } ~ Xq Xq W| r|  d S)zY
        Prepare process. Create temp directories, download and/or unpack files.
        c             s   s   |  ] } | j  Vq d  S)N)has_hash_options)r)   ro   r%   r%   r&   r   i  s    z/RequirementSet.prepare_files.<locals>.<genexpr>z--egg is not allowed with --require-hashes mode, since it delegates dependency resolution to setuptools and could thus result in installation of unhashed packages.rk   r^   N)ri   r   r]   r[   r,   rk   anyrc   r   r   r   extend_prepare_filer^   r   ro   r/   )r$   r>   	root_reqsrk   discovered_reqshash_errorsro   excr%   r%   r&   prepare_files]  s,    					$zRequirementSet.prepare_filesc             C   s.   |  j  o- |  j d k p- |  j d k o- | j S)Neagerzonly-if-needed)rW   rX   r   )r$   ro   r%   r%   r&   _is_upgrade_allowed  s    	z"RequirementSet._is_upgrade_allowedc             C   s   | j    | j r |  j |  } d } | r |  j p= | j s y | j | |  Wn) t k
 rn d } Yn t k
 r Yn X| s |  j o t	 | j  s | j | _
 d | _ | r d } n |  j d k r d } n d } | Sd Sd 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.
        FTNzalready up-to-datezonly-if-neededz%not upgraded as not directly requiredzalready satisfied)check_if_existsrQ   r   rZ   rC   find_requirementr   r   rd   r   conflicts_withrX   )r$   r;   r>   upgrade_allowedbest_installedskip_reasonr%   r%   r&   _check_skip_installed  s2    
	
				z$RequirementSet._check_skip_installedc          (      s   j  s  j r g  Sd  _  j r; t j d   n  j d k sP t   j sk  j  |  }  j r | d k	 s t d  j f   t j d |   nV  j	 r  j	 j
 d k r t  j	 j  } t j d t |   n t j d   t    j r| r+t d	     j  j   j  j  t   } | j    j r{ j  j   j   n j r| rt j d
  t   } n j  j  t j j t j j  j  d   r t! d   j  f    j" |  j#   |   j	 s+t   j	 } | rt$ |  rRt%    n! t& |  rst' |  rst(     j) r j* rt+     j, d |  }	 | r|	 rt-   }	 yz  j }
 d }  j	 j. r j/ r j/ }
  j	 j. r
|
 rd } n d } t0  j	  j  |
 | d  j1 d |	 WnW t2 j3 k
 r} z4 t j4 d  |  t d  |  j	 f   WYd d } ~ Xn Xt   } | j    j r j	 j
 t5 j6 k r j  j   j s j    j r@ j7 s j r0 j8 ot9  j  s$ j  _: d  _ n t j d   | j; |  } y t< |  WnR t= k
 r} z2  j> rt j? | j@ d  n  jA     WYd d } ~ Xn Xg        f d d   }  jB  jC  s jD  d  | s jE rt j d d j  jE   tF tG  jE  tG | jE   } x! | D] } t j? d | |  qFWtF tG | jE  tG  jE  @ } x' | jH |  D] } | | d | qW jI jJ    j r j r jK jJ   Wd QRX  S)zxPrepare a single requirements file.

        :return: A list of additional InstallRequirements to also install.
        TzObtaining %sNzP_check_skip_installed returned None but req_to_install.satisfied_by is set to %rzRequirement %s: %sfilezProcessing %szCollecting %szoThe editable requirement %s cannot be installed when requiring hashes, because there is no single file to hash.zSince it is already installed, we are trusting this package without checking its hash. To ensure a completely repeatable environment, install into an empty virtualenv.zsetup.pyzpip can't proceed with requirements '%s' due to a pre-existing build directory (%s). This is likely due to a previous installation that failed. pip is being responsible and not assuming it can delete this. Please delete it and try again.trust_internetFrf   hashesz4Could not install requirement %s because of error %szDCould not install requirement %s because of HTTP error %s for URL %sz<Requirement already satisfied (use --upgrade to upgrade): %sr   c                sM   t  t |    d  j d  j }   j  j |  j d |  d  S)Nrh   rm   r   )r   rt   rh   rj   r   r   rp   )subreqr   sub_install_req)	more_reqsr;   r$   r%   r&   add_req  s    		z-RequirementSet._prepare_file.<locals>.add_reqz!Installing extra requirements: %r,z"%s does not provide the extra '%s'r   )Lr   preparedrA   r|   inforQ   AssertionErrorrY   r   rC   schemer   urlr   r   r   ensure_has_source_dirrU   update_editabler   rF   r?   archiverV   r   r   rP   rT   r   r   r   r5   rI   r   populate_linkr   r
   r   r   r	   r   original_link	is_pinnedr   r   r   rD   ri   r   rf   r   	HTTPErrorr   r   all_schemesrW   rd   r   r   r=   r   r   r_   r}   argsremove_temporary_sourcer   rp   r   r   r   r   requiresrb   r/   r`   )r$   r>   r;   rk   r^   r   r   abstract_distrC   r   rV   autodelete_unpackedr   r=   er   missing_requestedmissingavailable_requestedr   r%   )r   r;   r$   r&   r     s
   				
	
	

						

		
						)
		
			
	zRequirementSet._prepare_filec          	   C   s@   t  j d  t   # x |  j D] } | j   q! WWd QRXd S)zClean up files, remove builds.zCleaning up...N)r|   r   r   rb   r   )r$   ro   r%   r%   r&   cleanup_files  s    
zRequirementSet.cleanup_filesc                sR   g    t          f d d    x!  j j   D] }  |  q: W  S)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.
        c                sf   |  j  s |   k r d  S|  j r& d  S j |   x  j |  D] }  |  qA W  j |   d  S)N)rQ   r   addrl   r/   )ro   dep)orderordered_reqsscheduler$   r%   r&   r     s    	z,RequirementSet._to_install.<locals>.schedule)r   r[   r,   )r$   r   r%   )r   r   r   r$   r&   _to_install  s    
		zRequirementSet._to_installc             O   s  |  j    } | r8 t j d d j d d   | D   t    x | D] } | j r t j d | j  t    | j d d  Wd QRXy | j | | | |  Wn( | j r | j r | j	     Yn X| j r | j r | j
   | j   qI WWd QRX| |  _ d S)	zl
        Install everything in this set (after having downloaded and unpacked
        the packages)
        z!Installing collected packages: %sz, c             S   s   g  |  ] } | j   q Sr%   )rp   )r)   ro   r%   r%   r&   r+     s   	 z*RequirementSet.install.<locals>.<listcomp>zFound existing installation: %sr   TN)r   r|   r   r5   r   r   r   installinstall_succeededrollback_uninstallr   r   ra   )r$   install_optionsglobal_optionsr   kwargs
to_installrequirementr%   r%   r&   r     s:    
	

	

		
zRequirementSet.install)r7   r8   r9   r'   rw   r6   r   r   propertyr   r   r   r   r   r   r   r   r   r   r   r%   r%   r%   r&   rR      s2   			4[	'C rR   ):
__future__r   collectionsr   	itertoolsr   loggingr   pip._vendorr   r   
pip.compatr   pip.downloadr   r	   r
   r   r   pip.exceptionsr   r   r   r   r   r   r   r   r   r   Zpip.req.req_installr   	pip.utilsr   r   r   r   pip.utils.hashesr   pip.utils.loggingr   pip.utils.packagingr   pip.vcsr   	pip.wheelr    	getLoggerr7   r|   objectr!   r:   rF   rE   rB   rP   rR   r%   r%   r%   r&   <module>   s0   (F"	