3
Ĥ[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je
ZejdejZe jeZejdZejd	Ze se re Zejd
 esejdddd ZesejddjddZyedd ejdD ZW n  ek
r   ejd Y nX yedd ejdD ZW n  ek
r@   ej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 |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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jdd |D }t |trPxdD ]}t| |t|| q2W d S t }|d	= |d
= |rtj	|}	x<|	r|	j
 j ng D ]$\}}|d k	r|| d kr|||< qW x8|j 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valuezmajor component is required)r   r   r   r   r   )
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| 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j | }x*dD ]"}t| |}|s$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'))r   r   r   )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   | 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   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
}|j|d}|j|d}||krzq||k||k  S W dS )Nr   r   r   r   r   r            )ZalphaZbeta	candidatefinal)r   r   r   r   r   )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| } |  s(t| ddgkr2tt}nj| d dkrBd
n| d | d dkrZdn| d   krttkrz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   rC   c   c             3   s*   | ]"}|  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   s   | dkrdS t j| }|s&td|  |j }t|jddkrdtdd |d jd	D }||fS d }}|d
 r~|d }n|d }|d }|rtdd |jd	D nd}|rtdd |j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	   -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>rC   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   s   d }}t  }x~| jdD ]p}|j }tjd|}|rFd|jd }qtjd|}|rfd|jd }qtjd|}|r|jd|jd  qW t|dkr|j }t	|t	|fS | r|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%.3srC   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rLdj dd | d D S | d dkrtddj dd | d D  S | d dkrdj d	d | d D d S d
dj dd | d D dj 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   rC   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| S t | ttf r@t | d tr@djdd | D S g }x<| D ]4}t |trd|j| qJ|jdjdd |D  qJW |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   s@   | sdS t | tr| dd S t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   sl   g }g }x@t | D ]4}t|tr(t|}|tk r<|j| q|j| qW |j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']
    )	rb   r   r   ra   r   rf   extendreversedrh   )rV   Z
return_strr.   Zold_versionsrg   r   r   r   	debsorted  s    
rk   )NN)N)&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>   sL   





 &
(,+