B
    
\7                 @   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e
ZedejZe eZedZed	Zerese Zed
 esedddd ZeseddddZyedd edD ZW n ek
r   ed Y nX yedd edD ZW n  ek
r:   ed Y nX G dd dZ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   s*   | ]"}t d d | 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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   s   t |ttfr"ddd |D }t |trPxdD ]}t| |t|| q2W d S t }|d= |d= |rt	|}	x<|	r|	
  ng D ]$\}}|d k	r|| d kr|||< qW x8| D ],\}}|dkr|d k	rt|}t| || qW | jst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valuer   zmajor component is required)
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   s(   t | j}| jdk	r$|d| 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   s>   d | }x*dD ]"}t| |}|s$P |d |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'))r-   r#   )r   r.   r*   r   r   r   r   __repr__g   s    


zVersion.__repr__c             C   s<   t | }| jdkr&| 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   sX   t | }| jdkr,| jt|8  _|j}n| jt|8  _|j}|dk rTt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   |  |dkS )Nr   )_Version__cmp)r   r4   r   r   r   __eq__   s    zVersion.__eq__c             C   s   |  |dk S )Nr   )r8   )r   r4   r   r   r   __lt__   s    zVersion.__lt__c             C   s   |  |dkS )Nr   )r8   )r   r4   r   r   r   __le__   s    zVersion.__le__c             C   s   |  |dkS )Nr   )r8   )r   r4   r   r   r   __gt__   s    zVersion.__gt__c             C   s   |  |dkS )Nr   )r8   )r   r4   r   r   r   __ge__   s    zVersion.__ge__c             C   sN   t |tst|}| jdks&|jdkr8| j|dddk S | j|dddk S d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
        Nr   )ignorer   r   )r   r   r   r8   )r   r4   r   r   r   
__lshift__   s
    
zVersion.__lshift__c             C   sN   t |tst|}| jdks&|jdkr8| j|dddkS | j|dddkS d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|}xxdD ]p}||kr&P t| |p2d}t||p@d}|dkrpddddd}||d}||d}||krzq||k||k  S W dS )N)r   r   r   r   r   r   r   )ZalphaZbeta	candidatefinal)r   r   r#   get)r   r4   r>   r*   Zvalue1Zvalue2Zrmapr   r   r   Z__cmp   s    

zVersion.__cmp)NNNNNN)N)__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| } | r&t| ddgkr0tt}nj| d dkr@dn| d | d dkrXdn| d   krttkrxfnt }nt fddtD }|rtdd |D }n|d	krt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   )r   r      )c   rK   c             3   s*   | ]"}|  kr k rn q|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   rL   r   r   r   r     s    Fc             s   s   | ]}t d | s|V  qdS )z/usr/bin/python%d.%dN)r   )r   rL   r   r   r   r     s    )r   r   parse_vranger    set	SUPPORTEDr   )vrangeZ	availableversionsr   )rM   rN   r   get_requested_versions   s    

rT   c             C   s   | dkrdS t | }|s&td|  | }t|ddkrdtdd |d d	D }||fS d }}|d
 r~|d }n|d }|d }|rtdd |d	D nd}|rtdd |d	D nd}|r|r||krt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	   -)NNzversion range is invalid: %sN   c             s   s   | ]}t |V  qd S )N)r
   )r   r   r   r   r   r   %  s    zparse_vrange.<locals>.<genexpr>rJ   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    )RANGE_REr&   r)   groupsr    countr   r   )r   r&   rX   rN   rM   r   r   r   rO     s&    

  rO   c             C   s   d }}t  }x~| dD ]p}| }td|}|rFd|d }qtd|}|rfd|d }qtd|}|r|d|d  qW t|dkr| }t	|t	|fS |s|rt
|d }|rt	|nd|rt	|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%.3srJ   z<<\s*([\d\.]+)z	^[\d\.]+$r   )rP   r   r   rer&   groupaddlenpopgetversorted)r   rN   rM   Z	hardcodeditemr&   verr   r   r   parse_pycentral_vrange8  s*    rc   c             C   s   | d | d   krdkr$n ndS | d | d krLd dd | d D S | d dkrtdd dd | d D  S | d dkrd d	d | d D d S d
d dd | d D d dd | d D f S d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   rJ   NrU   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!   )rR   r   r   r   
vrange_strc  s     rd   c             C   s   t | tr| S t | ttfs>t | d tr>ddd | D S g }x<| D ]4}t |trb|| qH|ddd |D  qHW |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   rP   r
   r!   append)r   r.   versionr   r   r   vrepr  s    


rg   c             C   s@   | sdS t | tr| dd S tdd | 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	   N   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   r_     s
    
r_   c             C   sl   g }g }x@t | D ]4}t|tr(t|}|tk r<|| q|| qW |t| |rh|rht|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']
    )	r`   r   r   r_   r   re   extendreversedrg   )rS   Z
return_strr.   Zold_versionsrf   r   r   r   	debsorted  s    
rk   )NN)N)&loggingrZ   osr   os.pathr   configparserr   typesr   ZRANGE_PATTERNcompilerW   VERBOSEr%   	getLoggerrG   logrF   Z
_supportedZ_defaultZ_configreadreplacer   r   r   	Exception	exceptionrQ   r   rT   rO   rc   rd   rg   r_   rk   r   r   r   r   <module>   sL   





 &
(,+