U
    zk^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k
r   ed Y nX z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 r   r   )r   jr   r   r   r   9   s     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 k	r|| d kr|||< q| D ],\}}|dkr|d k	rt|}t| || q| jstdd S )	Nr   c                 s   s   | ]}t |V  qd S r   strr   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'
        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"   r3   z'))r4   r)   )r#   r5   r0   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#   otherr5   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#   r;   r5   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?   r@   rB   r   r   r   __lt__   s    zVersion.__lt__c                 C   s   |  |dkS r?   r@   rB   r   r   r   __le__   s    zVersion.__le__c                 C   s   |  |dkS r?   r@   rB   r   r   r   __gt__   s    zVersion.__gt__c                 C   s   |  |dkS r?   r@   rB   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   rA   rB   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   rH   r   r    rJ   rB   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;   rI   r0   Zvalue1Zvalue2Zrmapr   r   r   Z__cmp   s    
zVersion.__cmp)NNNNNN)N)__name__
__module____qualname__r2   r6   r9   r:   r<   r>   rC   rD   rE   rF   rG   rK   rL   rA   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   rW   c                 3   s*   | ]"}|  kr k rn q|V  qd S r   r   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.%dNr   rX   r   r   r   r     s    Fc                 s   s   | ]}t d | s|V  qdS r]   r   rX   r   r   r   r     s    )r%   r   parse_vranger&   set	SUPPORTEDr   )vrangeZ	availableversionsr   rZ   r   get_requested_versions   s    

rc   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 r   r   r   r   r   r   r   %  s     zparse_vrange.<locals>.<genexpr>rV   r   r   c                 s   s   | ]}t |V  qd S r   r   r   r   r   r   r   /  s     c                 s   s   | ]}t |V  qd S r   r   r   r   r   r   r   0  s     )RANGE_REr,   r/   groupsr&   countr   r   )r$   r,   rg   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%.3srV   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*    rq   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   rV   Nrd   r   c                 s   s   | ]}t |V  qd S r   r   r   r   r   r   r   v  s     zvrange_str.<locals>.<genexpr>c                 s   s   | ]}t |V  qd S r   r   r   r   r   r   r   x  s     c                 s   s   | ]}t |V  qd S r   r   r   r   r   r   r   z  s     z%s-%sc                 s   s   | ]}t |V  qd S r   r   r   r   r   r   r   |  s     c                 s   s   | ]}t |V  qd S r   r   r   r   r   r   r   }  s     )r'   )ra   r   r   r   
vrange_strc  s     rr   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     s     zvrepr.<locals>.<genexpr>c                 s   s   | ]}t |V  qd S r   r   r   r   r   r   r     s     )r%   r   r   r_   r   r'   append)r$   r5   versionr   r   r   vrepr  s    

ru   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     s     zgetver.<locals>.<genexpr>r   )r%   r   r   )r$   r   r   r   rn     s
    
rn   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']
    )	ro   r%   r   rn   r   rs   extendreversedru   )rb   Z
return_strr5   Zold_versionsrt   r   r   r   	debsorted  s    
ry   )NN)N)&Zloggingri   osr   os.pathr   Zconfigparserr   typesr   ZRANGE_PATTERNcompilerf   VERBOSEr+   Z	getLoggerrS   logrR   Z
_supportedZ_defaultZ_configreadreplacer   r   r   	ExceptionZ	exceptionr`   r   rc   r^   rq   rr   ru   rn   ry   r   r   r   r   <module>   sT   




  &
(,+