
NwV7                 @   s  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	 d Z
 e j e
  Z e j d e j  Z e  j e  Z e j d  Z e j d	  Z e s e re   Z e j d
  e s e j d d  d d  Z e se j d d  j d d  Z y& e d d   e j d  D  Z Wn e k
 r`e j d  Yn Xy& e d d   e j d  D  Z Wn e k
 re j d  Yn XGd d   d  Z d d d d  Z d d   Z  d d   Z! d d    Z" d! d"   Z# d# d$   Z$ d d% d&  Z% d S)'    N)environ)exists)ConfigParser)GeneratorTypez(-)?(\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+)?ZDEBPYTHON3_SUPPORTEDZDEBPYTHON3_DEFAULTz"/usr/share/python3/debian_defaultsDEFAULTzdefault-version   zsupported-versionspython c             c   s   |  ] } t  |  Vq d  S)N)int).0i r   '/usr/share/python3/debpython/version.py	<genexpr>5   s    r   .zcannot read debian_defaultsc             c   s7   |  ]- } t  d  d   | j   j d  D  Vq d S)c             s   s   |  ] } t  |  Vq d  S)N)r
   )r   jr   r   r   r   9   s    z<genexpr>.<genexpr>r   N)tuplestripsplit)r   r   r   r   r   r   9   s   ,c               @   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)Nr   c             s   s   |  ] } t  |  Vq d  S)N)str)r   r   r   r   r   r   C   s    z#Version.__init__.<locals>.<genexpr>majorminormicroreleaselevelserialselfvaluezmajor component is required)zmajorzminorzmicrozreleaselevelzserial)
isinstancer   listjoinr   setattrgetattrlocals
VERSION_REmatch	groupdictitemsr
   r   
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__W   s    zVersion.__str__c             C   s   t  t |    S)N)hashrepr)r   r   r   r   __hash__d   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__g   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__w   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   r4   r.   newr   r   r   __sub__   s    	zVersion.__sub__c             C   s   |  j  |  d k S)Nr   )_Version__cmp)r   r4   r   r   r   __eq__   s    zVersion.__eq__c             C   s   |  j  |  d k  S)Nr   )r8   )r   r4   r   r   r   __lt__   s    zVersion.__lt__c             C   s   |  j  |  d k S)Nr   )r8   )r   r4   r   r   r   __le__   s    zVersion.__le__c             C   s   |  j  |  d k S)Nr   )r8   )r   r4   r   r   r   __gt__   s    zVersion.__gt__c             C   s   |  j  |  d k S)Nr   )r8   )r   r4   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   r8   )r   r4   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
        Nr>   r   r   r   )r   r   r   r8   )r   r4   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   r4   r>   r*   Zvalue1Zvalue2Zrmapr   r   r   Z__cmp   s    zVersion.__cmp)__name__
__module____qualname__r,   r/   r2   r3   r5   r7   r9   r:   r;   r<   r=   r?   r@   r8   r   r   r   r   r   ?   s   r   c                s)  t  |  t  r t |   }  |  s: t |   d d g k rI t t  } n |  d d k r_ d
 n |  d  |  d d k r d n |  d      k r t  t k r  f n t    } n" t    f d d   t D  } | r t d d   | D  } n% | d k r%t d	 d   | D  } | S)aJ  Return a set of requested and supported Python versions.

    :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([(3, 0), None]))
    [(3, 2), (3, 3)]
    >>> sorted(get_requested_versions('')) == sorted(SUPPORTED)
    True
    >>> sorted(get_requested_versions([None, None])) == sorted(SUPPORTED)
    True
    >>> get_requested_versions([(5, 0), None]) == set()
    True
    Nr   rD   c   c             3   s1   |  ]' }  | k o    k  n r | Vq d  S)Nr   )r   v)maxvminvr   r   r      s    z)get_requested_versions.<locals>.<genexpr>c             s   s%   |  ] } t  d  |  r | Vq d S)z/usr/bin/python%d.%dN)r   )r   rN   r   r   r   r     s    Fc             s   s%   |  ] } t  d  |  s | Vq d S)z/usr/bin/python%d.%dN)r   )r   rN   r   r   r   r     s    )r   r   )rM   rM   )r   r   parse_vranger    set	SUPPORTEDr   )vrange	availableversionsr   )rO   rP   r   get_requested_versions   s      '"rW   c             C   sO  |  d k r d St  j |   } | s5 t d |    | j   } t |  j d  d k r t d d   | d j d	  D  } | | f Sd } } | d
 r | d } n | d } | d } | r t d d   | j d	  D  n d } | rt d d   | j d	  D  n d } | rE| rE| | k rEt d |    | | f S)a  Return minimum and maximum Python version from given range.

    >>> parse_vrange('3.0-')
    ((3, 0), None)
    >>> parse_vrange('3.1-3.3')
    ((3, 1), (3, 3))
    >>> parse_vrange('3.2-4.0')
    ((3, 2), (4, 0))
    >>> parse_vrange('-3.7')
    (None, (3, 7))
    >>> parse_vrange('3.2')
    ((3, 2), (3, 2))
    >>> parse_vrange('') == parse_vrange('-') == (None, None)
    True
    r	   -Nzversion range is invalid: %srA   c             s   s   |  ] } t  |  Vq d  S)N)r
   )r   r   r   r   r   r   %  s    zparse_vrange.<locals>.<genexpr>rD   r   r   c             s   s   |  ] } t  |  Vq d  S)N)r
   )r   r   r   r   r   r   /  s    c             s   s   |  ] } t  |  Vq d  S)N)r
   )r   r   r   r   r   r   0  s    )r	   rX   )NN)RANGE_REr&   r)   groupsr    countr   r   )r   r&   rZ   rP   rO   r   r   r   rQ     s&    &




..rQ   c             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)	a  Parse X-Python3-Version.

    >>> parse_pycentral_vrange('>= 3.1')
    ((3, 1), None)
    >>> parse_pycentral_vrange('<< 4.0')
    (None, (4, 0))
    >>> parse_pycentral_vrange('3.1')
    ((3, 1), (3, 1))
    >>> parse_pycentral_vrange('3.1, 3.2')
    ((3, 1), None)
    Nr   z>=\s*([\d\.]+)z%.3srD   z<<\s*([\d\.]+)z	^[\d\.]+$r   )rR   r   r   rer&   groupaddlenpopgetversorted)r   rP   rO   Z	hardcodeditemr&   Zverr   r   r   parse_pycentral_vrange8  s*    
	rd   c             C   s  |  d |  d k o d k n r( d S|  d |  d k rZ d j  d d   |  d D  S|  d d k r d d j  d d   |  d D  S|  d d k r d j  d	 d   |  d D  d Sd
 d j  d d   |  d D  d j  d d   |  d D  f Sd S)aM  Return version range string from given range.

    >>> vrange_str(((3, 4), None))
    '3.4-'
    >>> vrange_str(((3, 4), (3, 6)))
    '3.4-3.6'
    >>> vrange_str(((3, 4), (4, 0)))
    '3.4-4.0'
    >>> vrange_str((None, (3, 7)))
    '-3.7'
    >>> vrange_str(((3, 5), (3, 5)))
    '3.5'
    >>> vrange_str((None, None))
    '-'
    r   rD   NrX   r   c             s   s   |  ] } t  |  Vq d  S)N)r   )r   r   r   r   r   r   v  s    zvrange_str.<locals>.<genexpr>c             s   s   |  ] } t  |  Vq d  S)N)r   )r   r   r   r   r   r   x  s    c             s   s   |  ] } t  |  Vq d  S)N)r   )r   r   r   r   r   r   z  s    z%s-%sc             s   s   |  ] } t  |  Vq d  S)N)r   )r   r   r   r   r   r   |  s    c             s   s   |  ] } t  |  Vq d  S)N)r   )r   r   r   r   r   r   }  s    )r!   )rT   r   r   r   
vrange_strc  s    $"" re   c             C   s   t  |  t  r |  St  |  t t f  rV t  |  d t  rV d j d d   |  D  Sg  } xP |  D]H } t  | t  r | j |  qc | j d j d d   | D   qc W| S)z
    >>> vrepr(([3, 4], [3, 2]))
    ['3.4', '3.2']
    >>> vrepr(('2.6', '3.1'))
    ['2.6', '3.1']
    >>> vrepr('3.2')
    '3.2'
    >>> vrepr((3, 2))
    '3.2'
    r   r   c             s   s   |  ] } t  |  Vq d  S)N)r   )r   r   r   r   r   r     s    zvrepr.<locals>.<genexpr>c             s   s   |  ] } t  |  Vq d  S)N)r   )r   r   r   r   r   r     s    )r   r   r   rR   r
   r!   append)r   r.   versionr   r   r   vrepr  s    )'rh   c             C   sT   |  s
 d St  |  t  r' |  d d  St d d   |  j d d  D  d d  S)zReturn pair of integers that represent version.

    >>> getver('3.2')
    (3, 2)
    >>> getver('3.1.4')
    (3, 1)
    >>> getver((3, 3, 1))
    (3, 3)
    >>> getver(None)
    ''
    r	   NrB   c             s   s   |  ] } t  |  Vq d  S)N)r
   )r   r   r   r   r   r     s    zgetver.<locals>.<genexpr>r   )r   r   r   )r   r   r   r   ra     s
    ra   c             C   s   g  } g  } xX t  |   D]J } t | t  r: t |  } | t k  rV | j |  q | j |  q W| j t |   | r | r t |  S| S)a  Return sorted list of versions starting with default Python
    version (if available) then list of suppored versions greater than default
    one followed by reversed list of older versions.

    List of versions sorted this way can be used in Depends field.

    :param vrepr: return string represenatations of versions, by default the
        same format is used as in :param:`versions`

    >>> debsorted([(2, 6), (3, 1), (3, 2), (3, 3), (2, 7)])[0] == DEFAULT
    True
    >>> debsorted(('2.4', '3.2', '2.6', '2.7'))[-1]
    (2, 4)
    >>> debsorted(set([(2, 1), (2, 2)]))
    [(2, 2), (2, 1)]
    >>> debsorted([(2, 1), (2, 2)], return_str=True)
    ['2.2', '2.1']
    )	rb   r   r   ra   r   rf   extendreversedrh   )rV   Z
return_strr.   Zold_versionsrg   r   r   r   	debsorted  s    
rk   )&loggingr\   osr   os.pathr   configparserr   typesr   ZRANGE_PATTERNcompilerY   VERBOSEr%   	getLoggerrJ   logrI   Z
_supportedZ_defaultZ_configreadreplacer   r   r   	Exception	exceptionrS   r   rW   rQ   rd   re   rh   ra   rk   r   r   r   r   <module>   sJ   	&(,+