a
    j`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zedd edD ZW n ey   ed Y n0 zedd edD ZW n ey6   ed Y n0 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       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 r   r   )r   jr   r   r   r   9   r   z<genexpr>.<genexpr>r   N)tuplestripsplitr   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rLdD ]}t| |t|| q0d S t }|d= |d= |rt	|}	|	r||	
  ng D ]$\}}|d ur|| d u r|||< q| D ],\}}|dkr|d urt|}t| || q| jstdd S )	Nr   c                 s   s   | ]}t |V  qd S r   strr   r   r   r   r   C   r   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u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'
        N.{})r   r   r    format)r$   resultr   r   r   __str__W   s    

zVersion.__str__c                 C   s   t t| S r   )hashrepr)r$   r   r   r   __hash__d   s    zVersion.__hash__c                 C   s<   d | }dD ]$}t| |}|s$ q4|d |7 }q|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#   r4   z'))r5   r*   )r$   r6   r1   r%   r   r   r   __repr__g   s    

zVersion.__repr__c                 C   s<   t | }| jdu 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$   otherr6   r   r   r   __add__w   s
    
zVersion.__add__c                 C   sX   t | }| jdu 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   r0   )r$   r<   r6   newr   r   r   __sub__   s    
zVersion.__sub__c                 C   s   |  |dkS Nr   _Version__cmpr$   r<   r   r   r   __eq__   s    zVersion.__eq__c                 C   s   |  |dk S r@   rA   rC   r   r   r   __lt__   s    zVersion.__lt__c                 C   s   |  |dkS r@   rA   rC   r   r   r   __le__   s    zVersion.__le__c                 C   s   |  |dkS r@   rA   rC   r   r   r   __gt__   s    zVersion.__gt__c                 C   s   |  |dkS r@   rA   rC   r   r   r   __ge__   s    zVersion.__ge__c                 C   sN   t |tst|}| jdu s&|jdu 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    rB   rC   r   r   r   
__lshift__   s
    
zVersion.__lshift__c                 C   sN   t |tst|}| jdu s&|jdu 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    rI   r   r!   rK   rC   r   r   r   
__rshift__   s
    
zVersion.__rshift__c                 C   s   t |tst|}dD ]v}||kr& qt| |p2d}t||p@d}|dkrpddddd}||d}||d}||krzq||k||k    S dS )Nr   r   r"   )ZalphaZbeta	candidatefinal)r&   r   r*   get)r$   r<   rJ   r1   Zvalue1Zvalue2Zrmapr   r   r   Z__cmp   s    
zVersion.__cmp)NNNNNN)N)__name__
__module____qualname__r3   r7   r:   r;   r=   r?   rD   rE   rF   rG   rH   rL   rM   rB   r   r   r   r   r   ?   s      
r   c                    s   t | trt| } | r&t| ddgkr0tt}nj| d du r@dn| d | d du rXdn| d   krttv rxfnt }nt fddtD }|rtdd |D }n|d	u 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   rX   c                 3   s*   | ]"}|  kr k rn q|V  qd S r   r   r   vmaxvminvr   r   r      r   z)get_requested_versions.<locals>.<genexpr>c                 s   s   | ]}t d | r|V  qdS z/usr/bin/python%d.%dNr   rY   r   r   r   r     s   Fc                 s   s   | ]}t d | s|V  qdS r^   r   rY   r   r   r   r     s   )r&   r   parse_vranger'   set	SUPPORTEDr   )vrangeZ	availableversionsr   r[   r   get_requested_versions   s    

rd   c                 C   s   | dv 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 r   r   r   r   r   r   r   %  r   zparse_vrange.<locals>.<genexpr>rW   r   r   c                 s   s   | ]}t |V  qd S r   r   r   r   r   r   r   /  r   c                 s   s   | ]}t |V  qd S r   r   r   r   r   r   r   0  r   )RANGE_REr-   r0   groupsr'   countr   r   )r%   r-   rh   r]   r\   r   r   r   r_     s&    

  r_   c                 C   s   d }}t  }| dD ]p}| }td|}|rDd|d }qtd|}|rdd|d }qtd|}|r|d|d  q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%.3srW   z<<\s*([\d\.]+)z	^[\d\.]+$r   )r`   r   r   rer-   groupaddlenpopgetversorted)r%   r]   r\   Z	hardcodeditemr-   Zverr   r   r   parse_pycentral_vrange8  s*    rr   c                 C   s   | d | d   u rdu r$n ndS | d | d krLd dd | d D S | d du rtdd dd | d D  S | d du 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   rW   Nre   r   c                 s   s   | ]}t |V  qd S r   r   r   r   r   r   r   v  r   zvrange_str.<locals>.<genexpr>c                 s   s   | ]}t |V  qd S r   r   r   r   r   r   r   x  r   c                 s   s   | ]}t |V  qd S r   r   r   r   r   r   r   z  r   z%s-%sc                 s   s   | ]}t |V  qd S r   r   r   r   r   r   r   |  r   c                 s   s   | ]}t |V  qd S r   r   r   r   r   r   r   }  r   )r(   )rb   r   r   r   
vrange_strc  s     rs   c                 C   s   t | tr| S t | ttfs>t | d tr>ddd | D S g }| D ]4}t |tr`|| qF|ddd |D  qF|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 r   r   r   r   r   r   r     r   zvrepr.<locals>.<genexpr>c                 s   s   | ]}t |V  qd S r   r   r   r   r   r   r     r   )r&   r   r   r`   r   r(   append)r%   r6   versionr   r   r   vrepr  s    

rv   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 r   r   r   r   r   r   r     r   zgetver.<locals>.<genexpr>r   )r&   r   r   )r%   r   r   r   ro     s
    
ro   c                 C   sh   g }g }t | D ]4}t|tr&t|}|tk r:|| q|| q|t| |rd|rdt|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']
    )	rp   r&   r   ro   r   rt   extendreversedrv   )rc   Z
return_strr6   Zold_versionsru   r   r   r   	debsorted  s    
rz   )NN)N)&Zloggingrj   osr   os.pathr   Zconfigparserr   typesr   ZRANGE_PATTERNcompilerg   VERBOSEr,   Z	getLoggerrT   logrS   Z
_supportedZ_defaultZ_configreadreplacer   r   r   	ExceptionZ	exceptionra   r   rd   r_   rr   rs   rv   ro   rz   r   r   r   r   <module>   sR   




 &
(,+