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r‚esÂeƒ Ze d
¡ esªe dd¡dd… ZesÂe 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= |r¦t 	|¡}	|	r||	 
¡  ¡ ng D ]$\}}|d k	r€|| d kr€|||< q€| ¡ D ],\}}|dkrÎ|d k	rÎt|ƒ}t| ||ƒ q®| jsêt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 )z½Return 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 )z×Return 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 )zˆReturn 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 )zŒReturn 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& qŽt| |ƒ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r‚tˆtkrxˆ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   )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 }|rªtdd„ | d	¡D ƒƒnd}|rÊtdd„ | d	¡D ƒƒnd}|rê|rê||krê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
   ú-)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Â|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%.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rœd  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 )zºReturn 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   
û



 ÿÿ &
(,+