ó
^†êWc           @   s”  d  Z  d d l Z d d l Z d d l Z d d l Z d d l Z d d l Z d d l Z d d l	 Z	 y e j
 Z Wn e k
 r e j Z n Xd d l m Z d d l m Z 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 d d	 l m Z d d
 l m Z d d f Z  e j! d e j" ƒ j# Z$ d „  a% d e& f d „  ƒ  YZ' d e( f d „  ƒ  YZ) d e j* f d „  ƒ  YZ+ d S(   sD   
Operations on existing wheel files, including basic installation. 
iÿÿÿÿNi   (   t   reify(   t   urlsafe_b64encodet	   from_jsont   urlsafe_b64decodet   nativet   binaryt   HashingFile(   t
   signatures(   t   read_pkg_info_bytes(   t   open_for_csv(   t   get_supported(   t   get_install_pathsi    s‰   ^(?P<namever>(?P<name>.+?)(-(?P<ver>\d.+?))?)
    ((-(?P<build>\d.*?))?-(?P<pyver>.+?)-(?P<abi>.+?)-(?P<plat>.+?)
    \.whl|\.dist-info)$c         C   sB   y d d l  m a Wn! t k
 r7 d d l m a n Xt |  ƒ S(   s?   Use parse_version from pkg_resources or distutils as available.iÿÿÿÿ(   t   parse_version(   t   LooseVersion(   t   pkg_resourcesR   t   ImportErrort   distutils.versionR   (   t   version(    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyR   *   s
    t   BadWheelFilec           B   s   e  Z RS(    (   t   __name__t
   __module__(    (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyR   3   s   t	   WheelFilec           B   s[  e  Z d  Z d Z d Z d e e d „ Z d „  Z	 e
 d „  ƒ Z e
 d „  ƒ Z e
 d „  ƒ Z e
 d „  ƒ Z e
 d	 „  ƒ Z e Z e
 d
 „  ƒ Z e
 d „  ƒ Z e
 d „  ƒ Z d „  Z d „  Z e
 d „  ƒ Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z e d „  ƒ Z e d „  ƒ Z d „  Z  e d „  ƒ Z! e i  d „ Z" d d „ Z# RS(   sö   Parse wheel-specific attributes from a wheel (.whl) file and offer
    basic installation and verification support.
    
    WheelFile can be used to simply parse a wheel filename by avoiding the
    methods that require the actual file contents.t   WHEELt   RECORDc         C   s{   | |  _  | |  _ | |  _ | |  _ t j j | ƒ } t | ƒ |  _ | j	 d ƒ sd |  j d k rw t d | ƒ ‚ n  d S(   s  
        :param fp: A seekable file-like object or None to open(filename).
        :param append: Open archive in append mode.
        :param context: Function returning list of supported tags. Wheels
        must have the same context to be sortable.
        s   .whls   Bad filename '%s'N(   t   filenamet   fpt   appendt   contextt   ost   patht   basenamet   WHEEL_INFO_REt   parsed_filenamet   endswitht   NoneR   (   t   selfR   R   R   R   R   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   __init__A   s    				c         C   s   |  j  S(   N(   R   (   R#   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   __repr__U   s    c         C   s   d |  j  j d ƒ S(   Ns   %s.dist-infot   namever(   R    t   group(   R#   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   distinfo_nameX   s    c         C   s   d |  j  j d ƒ S(   Ns   %s.dataR&   (   R    R'   (   R#   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   datadir_name\   s    c         C   s   d |  j  |  j f S(   Ns   %s/%s(   R(   R   (   R#   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   record_name`   s    c         C   s   d |  j  |  j f S(   Ns   %s/%s(   R(   t
   WHEEL_INFO(   R#   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   wheelinfo_named   s    c         c   s{   |  j  j ƒ  } xe | d j d ƒ D]P } xG | d j d ƒ D]2 } x) | d j d ƒ D] } | | | f VqW Wq= Wq# Wd S(   sÎ  A wheel file is compatible with the Cartesian product of the
        period-delimited tags in its filename.
        To choose a wheel file among several candidates having the same
        distribution version 'ver', an installer ranks each triple of
        (pyver, abi, plat) that its Python installation can run, sorting
        the wheels by the best-ranked tag it supports and then by their
        arity which is just len(list(compatibility_tags)).
        t   pyvert   .t   abit   platN(   R    t	   groupdictt   split(   R#   t   tagsR-   R/   R0   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyR3   h   s
    
c         C   s   t  t |  j ƒ ƒ S(   s4   The number of compatibility tags the wheel declares.(   t   lent   listt   compatibility_tags(   R#   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   arityz   s    c         C   s   |  j  |  j ƒ  ƒ S(   so   
        Lowest index of any of this wheel's tags in self.context(), and the
        arity e.g. (0, 1)
        (   t   compatibility_rankR   (   R#   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   rank   s    c         C   s   |  j  d t k S(   Ni    (   R9   t   _big_number(   R#   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt
   compatible‡   s    c         C   sq   g  } x? |  j  D]4 } y | j | j | ƒ ƒ Wq t k
 rC q Xq Wt | ƒ rg t | ƒ |  j f St d f S(   sÑ   Rank the wheel against the supported tags. Smaller ranks are more
        compatible!

        :param supported: A list of compatibility tags that the current
            Python implemenation can run.
        i    (   R6   R   t   indext
   ValueErrorR4   t   minR7   R:   (   R#   t	   supportedt   preferencest   tag(    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyR8   Œ   s    c         C   s"   |  j  | k s t d ƒ ‚ |  j S(   Ns   context mismatch(   R   t   AssertionErrorR;   (   R#   t   x(    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   supports_current_pythonŸ   s    c         C   sD   |  j  j d ƒ t |  j  j d ƒ ƒ t d „  |  j Dƒ ƒ |  j f S(   Nt   namet   verc         s   s   |  ] } | Vq d  S(   N(    (   t   .0RC   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pys	   <genexpr>®   s    (   R    R'   R   t   tupleR9   R   (   R#   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt	   _sort_keyª   s    c         C   s   |  j  | j  k S(   N(   R   (   R#   t   other(    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   __eq__±   s    c         C   s   |  j  | j  k S(   N(   R   (   R#   RJ   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   __ne__´   s    c         C   sV  |  j  | j  k r- t d j |  | ƒ ƒ ‚ n  |  j | j k  S|  j j d ƒ } | j j d ƒ } | | k rw | | k  St |  j j d ƒ ƒ } t | j j d ƒ ƒ } | | k r½ | | k  S|  j  | j  k rê t d j |  | ƒ ƒ ‚ n  |  j } | j } | d  k r*| d  k r*| | k r*| | k S| d  k rF| d  k rFt	 S|  j
 | j
 k  S(   Ns   {0}.context != {1}.contextRE   RF   (   R   t	   TypeErrort   formatRI   R    R'   R   R9   R"   t   FalseR   (   R#   RJ   t   snt   ont   svt   ovt   sct   oc(    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   __lt__·   s(    

		$
c         C   s
   | |  k  S(   N(    (   R#   RJ   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   __gt__Ô   s    c         C   s   |  | k p |  | k  S(   N(    (   R#   RJ   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   __le__×   s    c         C   s   |  | k p | |  k  S(   N(    (   R#   RJ   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   __ge__Ú   s    c         C   sY   d } |  j  r d } n  t |  j r- |  j n |  j | ƒ } |  j  sU |  j | ƒ n  | S(   Nt   rt   a(   R   t   VerifyingZipFileR   R   t   verify(   R#   t   modet   vzf(    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   zipfileá   s    		$	c         C   s   t  |  j j |  j ƒ ƒ S(   s+   Parse wheel metadata (the .data/WHEEL file)(   R   R`   t   readR,   (   R#   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   parsed_wheel_infoë   s    c         C   sD   |  j  d } t t t | j d ƒ ƒ ƒ t k r@ t d ƒ ‚ n  d  S(   Ns   Wheel-VersionR.   s   Wheel version is too high(   Rb   RH   t   mapt   intR2   t   VERSION_TOO_HIGHR=   (   R#   R   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   check_versionð   s    $c         C   s   |  j  j d ƒ } t | ƒ S(   sl  
        Consult distutils to get the install paths for our dist.  A dict with
        ('purelib', 'platlib', 'headers', 'scripts', 'data').
        
        We use the name from our filename as the dist name, which means headers
        could be installed in the wrong place if the filesystem-escaped name
        is different than the Name.  Who cares? 
        RE   (   R    R'   R   (   R#   RE   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   install_pathsõ   s    
c      	      s  ‡  ‡ f d †  } ˆ j  d d k r4 | d ƒ } n | d ƒ } i  } xˆ j j ƒ  D]û } | j } | j d ƒ rz qV n  | j d ƒ r– | d } n  | j d ƒ \ } }	 }
 |	 r| ˆ j k r|
 j d ƒ \ } }	 }
 |	 sù t d	 j	 | ƒ ƒ ‚ n  | | ƒ } n d
 } | } | }
 t
 j j t
 j j | |
 ƒ ƒ } | | |
 | f | | <qV W| sÃxe | j ƒ  D]T \ } } | j } | \ } } }
 } t
 j j | ƒ rht d j	 | | ƒ ƒ ‚ qhqhWn  t j j t j ƒ  ƒ } g  } ˆ j d } x…| j ƒ  D]w\ } \ } } }
 } | j } ˆ j j | ƒ } | | k r@qûn  t
 j j | ƒ } t
 j j | ƒ stt
 j | ƒ n  t t | d ƒ ƒ } | d k rÚ| j ƒ  } | j d ƒ rÊd | t t
 j ƒ } n  | j | ƒ n  t j | | ƒ t
 j j  | | ƒ } | j! t
 j" d ƒ | j# | | j$ ƒ  | j% f ƒ | j& ƒ  | j& ƒ  | j' d ?} | rût
 j( | | j' d ?ƒ qûqûWt
 j j | ˆ j) ƒ } t* | d ƒ e } t+ j, | ƒ } x3 t- | ƒ D]% \ } } } | j. | | | f ƒ q¼W| j. ˆ j) d
 d
 f ƒ Wd QXd S(   s7   
        Install the wheel into site-packages.
        c            s   ˆ  j  |  ƒ p ˆ j |  S(   N(   t   getRg   (   t   key(   t	   overridesR#   (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   get_path  s    s   Root-Is-Purelibt   truet   purelibt   platlibt   /s   ./i   s   Invalid filename in wheel: {0}t    sA   Wheel file {0} would overwrite {1}. Use force if this is intendeds   /RECORDt   wbt   scriptss   #!pythons   #!i   s   w+N(/   Rb   R`   t   infolistR   R!   t
   startswitht	   partitionR)   R=   RN   R   R   t   normpatht   joint   itemst   existst   syst
   executablet   encodet   getfilesystemencodingR(   t   opent   dirnamet   isdirt   makedirsR   t   readlineR   t   linesept   writet   shutilt   copyfileobjt   relpatht   replacet   sepR   t   digestt   lengtht   closet   external_attrt   chmodR*   R	   t   csvt   writert   sortedt   writerow(   R#   t   forceRj   Rk   t   roott
   name_transt   infoRE   t   basedirR‰   R   Ri   t   targett   destt   vt   kt   exenamet   record_dataR*   t   sourcet   ddirt   destinationt   hashbangt   reldestt   attrst   record_fileR   RŠ   R‹   (    (   Rj   R#   s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   install  sx    	!	"%	

c         C   s,  d } | d k r |  j } n  t | _ d j |  j d f ƒ } d j |  j d f ƒ } d j |  j d f ƒ } | j | d ƒ | j | d ƒ | j | d ƒ | j | ƒ } t t	 j
 | ƒ j ƒ  ƒ } y t t | j | ƒ ƒ ƒ } Wn t k
 rû n X| r_t j | ƒ \ } }	 |	 d d t | ƒ k r_d }
 t |
 j |	 d t | ƒ ƒ ƒ ‚ q_n  t j d „  | j ƒ  Dƒ ƒ } x§ | D]Ÿ } | d	 } | d
 } | sÔ| | | f k r…t j j d | ƒ q…q…n  | d
 j d d
 ƒ \ } } | d k st d ƒ ‚ | j | t t | ƒ ƒ ƒ q…Wd S(   s	  Configure the VerifyingZipFile `zipfile` by verifying its signature 
        and setting expected hashes for every hash in RECORD.
        Caller must complete the verification process by completely reading 
        every file in the archive (e.g. with extractall).Ro   R   s
   RECORD.jwss
   RECORD.p7st   hashs   sha256=s8   RECORD.sig claimed RECORD hash {0} != computed hash {1}.c         s   s   |  ] } t  | ƒ Vq d  S(   N(   R   (   RG   RZ   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pys	   <genexpr>  s    i    i   s   %s has no hash!
t   =t   sha256s   Unsupported hash algorithmN(   R"   R`   t   Truet   strictRw   R(   t   set_expected_hashRa   R   t   hashlibR¨   RŠ   R   R   t   KeyErrorR   R]   R   RN   R   t   readert
   splitlinesRz   t   stderrR„   R2   RB   R   R   (   R#   R`   t   sigR*   t   sig_namet   smime_sig_namet   recordt   record_digestt   headerst   payloadt   msgR®   t   rowR   R¦   t   algot   data(    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyR]   q  sB    	

N($   R   R   t   __doc__R+   R   R"   RO   R
   R$   R%   t   propertyR(   R)   R*   R,   R3   R6   R7   R9   R;   R8   RD   RI   RK   RL   RV   RW   RX   RY   R    R`   Rb   Rf   Rg   R¥   R]   (    (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyR   7   s>   									
	oR\   c           B   sD   e  Z d  Z d e j e d „ Z d „  Z d d d „ Z	 d „  Z
 RS(   sµ   ZipFile that can assert that each of its extracted contents matches
    an expected sha256 hash. Note that each file must be completly read in 
    order for its hash to be checked.RZ   c         C   s>   t  j j |  | | | | ƒ t |  _ i  |  _ t j |  _ d  S(   N(	   R`   t   ZipFileR$   RO   Rª   t   _expected_hashesR¬   R¨   t   _hash_algorithm(   R#   t   fileR^   t   compressiont
   allowZip64(    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyR$   £  s    		c         C   s   | |  j  | <d S(   sn   
        :param name: name of zip entry
        :param hash: bytes of hash (or None for "don't care")
        N(   R¿   (   R#   RE   R¦   (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyR«   ¬  s    c            s,  t  j j |  | | | ƒ ‰ t | t  j ƒ r9 | j } n | } | |  j k rú |  j | d k rú |  j | ‰ y ˆ j ‰  Wn t	 k
 rœ t
 j d ƒ ˆ SX|  j ƒ  ‰ t ˆ d ƒ rÓ ‡  ‡ ‡ ‡ f d †  } n d ‡  ‡ ‡ ‡ f d † } | ˆ _ n. |  j r(| |  j k r(t d ˆ j ƒ ‚ n  ˆ S(   s#   Return file-like object for 'name'.sR   Need ZipExtFile._update_crc to implement file hash verification (in Python >= 2.7)t   _eofc            sL   ˆ  |  ƒ ˆ j  |  ƒ ˆ j rH ˆ j ƒ  ˆ k rH t d ˆ j ƒ ‚ n  d  S(   Ns   Bad hash for file %r(   t   updateRÄ   RŠ   R   RE   (   R»   (   t   _update_crc_origt   eft   expected_hasht   running_hash(    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   _update_crcÆ  s    
c            sO   ˆ  |  d | ƒˆ j  |  ƒ | rK ˆ j ƒ  ˆ k rK t d ˆ j ƒ ‚ n  d  S(   Nt   eofs   Bad hash for file %r(   RÅ   RŠ   R   RE   (   R»   RË   (   RÆ   RÇ   RÈ   RÉ   (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyRÊ   Ì  s    s   No expected hash for file %rN(   R`   R¾   R~   t
   isinstancet   ZipInfoR   R¿   R"   RÊ   t   AttributeErrort   warningst   warnRÀ   t   hasattrRª   R   RE   (   R#   t   name_or_infoR^   t   pwdRE   RÊ   (    (   RÆ   RÇ   RÈ   RÉ   s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyR~   ³  s(    c         C   sj   |  j  s t d ƒ ‚ n  |  j ƒ  j ƒ  } |  j | j =|  j  j | j t j	 ƒ |  j  j
 ƒ  t |  _ d S(   s   Truncate the last file off this zipfile.
        Assumes infolist() is in the same order as the files (true for
        ordinary zip files created by Python)s7   Attempt to pop from ZIP archive that was already closedN(   R   t   RuntimeErrorRs   t   popt
   NameToInfoR   t   seekt   header_offsetR   t   SEEK_SETt   truncateR©   t
   _didModify(   R#   t   last(    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyRÕ   Ö  s    	N(   R   R   R¼   R`   t
   ZIP_STOREDRO   R$   R«   R"   R~   RÕ   (    (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyR\   ž  s   	#(,   R¼   Rz   RÏ   t   os.pathR   t   reR`   R¬   R   R…   t   maxsizeR:   t	   NameErrort   maxintt	   decoratorR    t   utilR   R   R   R   R   R   Rp   R   t   pkginfoR   R	   t
   pep425tagsR
   t   pathsR   Re   t   compilet   VERBOSEt   matchR   R   R=   R   t   objectR   R¾   R\   (    (    (    s`   /private/var/folders/3n/6h2rwf155rn1m71wwyxn79n80000gn/T/pip-build-IcAT_k/wheel/wheel/install.pyt   <module>   s8   .		ÿ h