
U]9                 @   s   d  d l  Z  d  d l Z d  d l m Z d  d l m Z d Z e j e  Z e j d e j	  Z
 e  j d  Z d a Gd d   d  Z Gd	 d
   d
  Z d d   Z d d   Z d d d d  Z d d d  Z d S)    N)exists)	_defaultsz(-)?(\d\.\d+)(?:(-)(\d\.\d+)?)?z
    (?P<major>\d+)\.?
    (?P<minor>\d+)?\.?
    (?P<micro>\d+)?[.\s]?
    (?P<releaselevel>alpha|beta|candidate|final)?[.\s]?
    (?P<serial>\d+)?dhpythonc               @   s   e  Z d  Z d d d d d d d d  Z d d   Z d d   Z d d	   Z d
 d   Z d d   Z d d   Z	 d d   Z
 d d   Z d d   Z d d   Z d d   Z d d   Z d d d  Z d S)VersionNc       
      C   sY  t  | t t f  r1 d j d d   | D  } t  | t  rn x' d D] } t |  | t | |   qG Wd  St   } | d	 =| d
 =| r t j	 |  }	 xR |	 r |	 j
   j   n g  D]2 \ } } | d  k	 r | | d  k r | | | <q WxN | j   D]@ \ } } | d k r,| d  k	 r,t |  } t |  | |  q W|  j sUt d   d  S)N.c             s   s   |  ] } t  |  Vq d  S)N)str).0i r
   (/usr/share/dh-python/dhpython/version.py	<genexpr>,   s    z#Version.__init__.<locals>.<genexpr>majorminormicroreleaselevelserialselfvaluezmajor component is required)zmajorzminorzmicrozreleaselevelzserial)
isinstancetuplelistjoinr   setattrgetattrlocals
VERSION_REmatch	groupdictitemsintr   
ValueError)
r   r   r   r   r   r   r   namecompr   r
   r
   r   __init__)   s(    	+	zVersion.__init__c             C   s8   t  |  j  } |  j d k	 r4 | d j |  j  7} | S)zReturn major.minor or major string.

        >>> str(Version(major=3, minor=2, micro=1, releaselevel='final', serial=4))
        '3.2'
        >>> str(Version(major=2))
        '2'
        Nz.{})r   r   r   format)r   resultr
   r
   r   __str__@   s    zVersion.__str__c             C   s   t  t |    S)N)hashrepr)r   r
   r
   r   __hash__M   s    zVersion.__hash__c             C   sQ   d j  |   } x7 d D]/ } t |  |  } | s2 P| d j  |  7} q W| d S)zReturn full version string.

        >>> repr(Version(major=3, minor=2, micro=1, releaselevel='final', serial=4))
        "Version('3.2.1.final.4')"
        >>> repr(Version(major=2))
        "Version('2')"
        zVersion('{}r   r   r   z.{}z'))zmicrozreleaselevelzserial)r$   r   )r   r%   r!   r   r
   r
   r   __repr__P   s    zVersion.__repr__c             C   sL   t  |   } |  j d k r3 | j t |  7_ n | j t |  7_ | S)zReturn next version.

        >>> Version('3.1') + 1
        Version('3.2')
        >>> Version('2') + '1'
        Version('3')
        N)r   r   r   r   )r   otherr%   r
   r
   r   __add__`   s
    zVersion.__add__c             C   sv   t  |   } |  j d k r< | j t |  8_ | j } n | j t |  8_ | j } | d k  rr t d   | S)zReturn previous version.

        >>> Version('3.1') - 1
        Version('3.0')
        >>> Version('3') - '1'
        Version('2')
        Nr   zcannot decrease version further)r   r   r   r   r    )r   r+   r%   newr
   r
   r   __sub__o   s    	zVersion.__sub__c             C   s<   y t  |  } Wn t k
 r( d SYn X|  j |  d k S)NFr   )r   	Exception_Version__cmp)r   r+   r
   r
   r   __eq__   s
    	zVersion.__eq__c             C   s   |  j  |  d k  S)Nr   )r0   )r   r+   r
   r
   r   __lt__   s    zVersion.__lt__c             C   s   |  j  |  d k S)Nr   )r0   )r   r+   r
   r
   r   __le__   s    zVersion.__le__c             C   s   |  j  |  d k S)Nr   )r0   )r   r+   r
   r
   r   __gt__   s    zVersion.__gt__c             C   s   |  j  |  d k S)Nr   )r0   )r   r+   r
   r
   r   __ge__   s    zVersion.__ge__c             C   so   t  | t  s t |  } |  j d k s9 | j d k rR |  j | d d d k  S|  j | d d d k  Sd S)ak  Compare major.minor or major only (if minor is not set).

        >>> Version('2.6') << Version('2.7')
        True
        >>> Version('2.6') << Version('2.6.6')
        False
        >>> Version('3') << Version('2')
        False
        >>> Version('3.1') << Version('2')
        False
        >>> Version('2') << Version('3.2.1.alpha.3')
        True
        Nignorer   r   r   )r   r   r   r0   )r   r+   r
   r
   r   
__lshift__   s
    zVersion.__lshift__c             C   so   t  | t  s t |  } |  j d k s9 | j d k rR |  j | d d d k S|  j | d d d k Sd S)ao  Compare major.minor or major only (if minor is not set).

        >>> Version('2.6') >> Version('2.7')
        False
        >>> Version('2.6.7') >> Version('2.6.6')
        False
        >>> Version('3') >> Version('2')
        True
        >>> Version('3.1') >> Version('2')
        True
        >>> Version('2.1') >> Version('3.2.1.alpha.3')
        False
        Nr6   r   r   r   )r   r   r   r0   )r   r+   r
   r
   r   
__rshift__   s
    zVersion.__rshift__c          	   C   s   t  | t  s t |  } x d D] } | | k r5 Pt |  |  pG d } t | |  p\ d } | d k r d d d	 d d d d d i } | j | d  } | j | d  } | | k r q" | | k | | k  SWd S)Nr   r   r   r   r   r   Zalpha   Zbeta   	candidate   final)zmajorzminorzmicrozreleaselevelzserial)r   r   r   get)r   r+   r6   r!   Zvalue1Zvalue2Zrmapr
   r
   r   Z__cmp   s    zVersion.__cmp)__name__
__module____qualname__r#   r&   r)   r*   r,   r.   r1   r2   r3   r4   r5   r7   r8   r0   r
   r
   r
   r   r   (   s   r   c               @   sm   e  Z d  Z d d d d d  Z d d   Z d d   Z d d	   Z e d
 d    Z e d d    Z	 d S)VersionRangeNc             C   s   | r t  |  |  _ n	 d  |  _ | r9 t  |  |  _ n	 d  |  _ | r |  j |  \ } } | r{ |  j d  k r{ | |  _ | r |  j d  k r | |  _ d  S)N)r   minvermaxverparse)r   r   rF   rG   r
   r
   r   r#      s    			zVersionRange.__init__c             C   s&   |  j  d  k	 s |  j d  k	 r" d Sd S)NTF)rF   rG   )r   r
   r
   r   __bool__   s    zVersionRange.__bool__c             C   s   |  j  d k o |  j k n r& d S|  j  |  j k rE t |  j   S|  j  d k rd d j |  j  S|  j d k r d j |  j   Sd j |  j  |  j  Sd S)a  Return version range string from given range.

        >>> str(VersionRange(minver='3.4'))
        '3.4-'
        >>> str(VersionRange(minver='3.4', maxver='3.6'))
        '3.4-3.6'
        >>> str(VersionRange(minver='3.4', maxver='4.0'))
        '3.4-4.0'
        >>> str(VersionRange(maxver='3.7'))
        '-3.7'
        >>> str(VersionRange(minver='3.5', maxver='3.5'))
        '3.5'
        >>> str(VersionRange())
        '-'
        N-z-{}z{}-z{}-{})rF   rG   r   r$   )r   r
   r
   r   r&      s    "zVersionRange.__str__c             C   sj   d } |  j  d k	 r+ | d j |  j   7} |  j d k	 rP | d j |  j  7} | j d d  } | d S)zReturn version range string.

        >>> repr(VersionRange('5.0-'))
        "VersionRange(minver='5.0')"
        >>> repr(VersionRange('3.0-3.5'))
        "VersionRange(minver='3.0', maxver='3.5')"
        zVersionRange(Nzminver='{}'z, maxver='{}'z(, ())rF   r$   rG   replace)r   r%   r
   r
   r   r*     s    zVersionRange.__repr__c             C   s>  |  d k r d	 St  j |   } | sf y t j |   \ } } Wqt k
 rb t d |    YqXn | j   } t |  j d  d k r t	 | d  } | | f Sd } } | d r | d } n | d } | d } | r t	 |  n d } | rt	 |  n d } | r4| r4| | k r4t d |    | | f S)
aY  Return minimum and maximum Python version from given range.

        >>> VersionRange.parse('3.0-')
        (Version('3.0'), None)
        >>> VersionRange.parse('3.1-3.3')
        (Version('3.1'), Version('3.3'))
        >>> VersionRange.parse('3.2-4.0')
        (Version('3.2'), Version('4.0'))
        >>> VersionRange.parse('-3.7')
        (None, Version('3.7'))
        >>> VersionRange.parse('3.2')
        (Version('3.2'), Version('3.2'))
        >>> VersionRange.parse('') == VersionRange.parse('-')
        True
        >>> VersionRange.parse('>= 4.0')
        (Version('4.0'), None)
         rJ   Nzversion range is invalid: %sr9   r<   r   )rN   rJ   )NN)
RANGE_REr   rE   _parse_pycentralr/   r    groupsr   countr   )r   r   minvmaxvrQ   r
   r
   r   rH     s,    




zVersionRange.parsec             C   sF  d } } t    } x |  j d  D] } | j   } t j d |  } | rc d | j d  } q# t j d |  } | r d | j d  } q# t j d |  } | r# | j d | j d   q# Wt |  d k r | j   } t	 |  t	 |  f S| r| rt
 |  d } | r*t	 |  n d | r?t	 |  n d f S)	aw  Parse X-Python3-Version.

        >>> VersionRange._parse_pycentral('>= 3.1')
        (Version('3.1'), None)
        >>> VersionRange._parse_pycentral('<< 4.0')
        (None, Version('4.0'))
        >>> VersionRange._parse_pycentral('3.1')
        (Version('3.1'), Version('3.1'))
        >>> VersionRange._parse_pycentral('3.1, 3.2')
        (Version('3.1'), None)
        N,z>=\s*([\d\.]+)z%.3sr<   z<<\s*([\d\.]+)z	^[\d\.]+$r   )setsplitstriprer   groupaddlenpopr   sorted)r   rS   rT   Z	hardcodeditemr   verr
   r
   r   rP   E  s*    
	zVersionRange._parse_pycentral)
rB   rC   rD   r#   rI   r&   r*   staticmethodrH   rP   r
   r
   r
   r   rE      s   2rE   c             C   sG   |  t  j k r t d |    t  j |  } t d | d d | d  S)z<Return default interpreter version for given implementation.z,interpreter implementation not supported: %rr   r   r   r<   )r   ZDEFAULTr    r   )implr`   r
   r
   r   defaultp  s    rc   c             C   s=   |  t  j k r t d |    t  j |  } d d   | D S)zGReturn list of supported interpreter versions for given implementation.z,interpreter implementation not supported: %rc             S   s-   g  |  ]# } t  d  | d d | d   q S)r   r   r   r<   )r   )r   vr
   r
   r   
<listcomp>}  s   	 zsupported.<locals>.<listcomp>)r   Z	SUPPORTEDr    )rb   versionsr
   r
   r   	supportedx  s    rg   c                s  t  | t  r t |  } | s6 t t |    } n | j d k rZ t d d d d  n | j  | j d k r t d d d d  n | j    k r t  t |   k r  g n t    } n( t   f d d   t |   D  } | d k	 rt	 d k rd d l
 m	 a	 | rPt	 d	 |     t   f d
 d   | D  } n: | d k rt	 d	 |     t   f d d   | D  } | S)aO  Return a set of requested and supported Python versions.

    :param impl: interpreter implementation
    :param available: if set to `True`, return installed versions only,
        if set to `False`, return requested versions that are not installed.
        By default returns all requested versions.
    :type available: bool

    >>> sorted(get_requested_versions('cpython3', '')) == sorted(supported('cpython3'))
    True
    >>> sorted(get_requested_versions('cpython3', '-')) == sorted(supported('cpython3'))
    True
    >>> get_requested_versions('cpython3', '>= 5.0')
    set()
    Nr   r   r   c   c             3   s1   |  ]' }  | k o    k  n r | Vq d  S)Nr
   )r   rd   )rT   rS   r
   r   r     s    z)get_requested_versions.<locals>.<genexpr>)Interpreterrb   c             3   s*   |  ]  } t    j |   r | Vq d  S)N)r   binary)r   rd   )interpreterr
   r   r     s    Fc             3   s*   |  ]  } t    j |   s | Vq d  S)N)r   rj   )r   rd   )rk   r
   r   r     s    )r   r   rE   rV   rg   rF   r   rG   r   ri   Zdhpython.interpreter)rb   ZvrangeZ	availablerf   r
   )rk   rT   rS   r   get_requested_versions  s&    ---("rl   Zcpython3c             C   s\   t  |  } t d d   |  D  } y | j |  Wn t k
 rJ Yn X| j |  | S)aO  Return sorted list of versions in a build friendly order.

    i.e. default version, if among versions, is sorted last.

    >>> build_sorted([(2, 6), (3, 4), default('cpython3'), (3, 6), (2, 7)])[-1] == default('cpython3')
    True
    >>> build_sorted(('3.2', (3, 0), '3.1'))
    [Version('3.0'), Version('3.1'), Version('3.2')]
    c             s   s   |  ] } t  |  Vq d  S)N)r   )r   rd   r
   r
   r   r     s    zbuild_sorted.<locals>.<genexpr>)rc   r^   remover    append)rf   rb   Zdefault_verr%   r
   r
   r   build_sorted  s    
ro   )ZloggingrY   os.pathr   r   r   ZRANGE_PATTERNcompilerO   VERBOSEr   Z	getLoggerlogri   r   rE   rc   rg   rl   ro   r
   r
   r
   r   <module>   s   .