o
    å¹´f±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rAesaeƒ Ze d
¡ esUe dd¡dd… Zesae dd¡ dd¡Zzedd„ e d¡D ƒƒZW n ey}   e d¡ Y nw zedd„ e d¡D ƒƒZW n eyš   e d¡ Y nw 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+)?ÚDEBPYTHON3_SUPPORTEDÚDEBPYTHON3_DEFAULTz"/usr/share/python3/debian_defaultsÚDEFAULTzdefault-versioné   zsupported-versionsÚpythonÚ c                 c   ó   � | ]}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   r   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ƒr&dD ]}t| |t||ƒƒ qd S tƒ }|d= |d= |rSt 	|¡}	|	r>|	 
¡  ¡ ng D ]\}}|d urR|| d u rR|||< q@| ¡ D ]\}}|dkrg|d urgt|ƒ}t| ||ƒ qW| jsutdƒ‚d S )	Nr   c                 s   r   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Úcompr0   r   r   r   Ú__init__@   s,   

€ÿzVersion.__init__c                 C   s(   t | jƒ}| jdu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   sB   d  | ¡}dD ]}t| |ƒ}|s |d S |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&   r7   z'))r8   r-   )r'   r9   r4   r(   r   r   r   Ú__repr__g   s   

ÿzVersion.__repr__c                 C   s>   t | ƒ}| jdu r| jt|ƒ7  _|S | 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'   Úotherr9   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 r*t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   r3   )r'   r?   r9   Únewr   r   r   Ú__sub__†   s   
zVersion.__sub__c                 C   s   |   |¡dkS ©Nr   ©Ú_Version__cmp©r'   r?   r   r   r   Ú__eq__™   ó   zVersion.__eq__c                 C   s   |   |¡dk S rC   rD   rF   r   r   r   Ú__lt__œ   rH   zVersion.__lt__c                 C   s   |   |¡dkS rC   rD   rF   r   r   r   Ú__le__Ÿ   rH   zVersion.__le__c                 C   s   |   |¡dkS rC   rD   rF   r   r   r   Ú__gt__¢   rH   zVersion.__gt__c                 C   s   |   |¡dkS rC   rD   rF   r   r   r   Ú__ge__¥   rH   zVersion.__ge__c                 C   sJ   t |tƒs	t|ƒ}| jdu s|jdu r| j|dd�dk S | j|dd�dk 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#   rE   rF   r   r   r   Ú
__lshift__¨   ó
   
zVersion.__lshift__c                 C   sJ   t |tƒs	t|ƒ}| jdu s|jdu r| j|dd�dkS | j|dd�dk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#   rM   r   r$   rO   rF   r   r   r   Ú
__rshift__½   rQ   zVersion.__rshift__c                 C   s”   t |tƒs	t|ƒ}dD ]<}||kr dS t| |ƒpd}t||ƒp!d}|dkr9dddddœ}| |d¡}| |d¡}||kr>q||k||k    S dS )Nr!   r   r%   éýÿÿÿéþÿÿÿéÿÿÿÿ)ÚalphaÚbetaÚ	candidateÚfinal)r)   r   r-   Úget)r'   r?   rN   r4   Úvalue1Úvalue2Úrmapr   r   r   Ú__cmpÒ   s    

÷zVersion.__cmp)NNNNNNr   )Ú__name__Ú
__module__Ú__qualname__r6   r:   r=   r>   r@   rB   rG   rI   rJ   rK   rL   rP   rR   rE   r   r   r   r   r   ?   s"    
ÿr   c                    sÒ   t | tƒr	t| ƒ} | rt| ƒddgkrttƒ}n5| d du r dn| d ‰| d du r,dn| d ‰ ˆˆ krAtˆtv r<ˆfntƒ ƒ}nt‡ ‡fdd„tD ƒƒ}|rZtdd„ |D ƒƒ}|S |d	u rgt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   rc   c                 3   s,   � | ]}ˆ|  krˆ k rn n|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   rd   r   r   r   r     ó   € 
ÿFc                 s   s    � | ]}t d | ƒs|V  qdS ri   r   rd   r   r   r   r     rj   )r)   r    Úparse_vranger*   ÚsetÚ	SUPPORTEDr   )ÚvrangeÚ	availableÚversionsr   rf   r   Úget_requested_versionsä   s   

ürq   c                 C   sò   | dv rdS t  | ¡}|std|  ƒ‚| ¡ }t|ƒ d¡dkr2tdd„ |d  d	¡D ƒƒ}||fS d }}|d
 r?|d }n|d }|d }|rUtdd„ | d	¡D ƒƒnd}|retdd„ | d	¡D ƒƒnd}|ru|ru||krut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   r   r   r   r   r   r   r   r   %  r   zparse_vrange.<locals>.<genexpr>rb   r   r   c                 s   r   r   r   r   r   r   r   r   /  r   c                 s   r   r   r   r   r   r   r   r   0  r   )ÚRANGE_REr0   r3   Úgroupsr*   Úcountr   r   )r(   r0   rv   rh   rg   r   r   r   rk     s&   

  rk   c                 C   sä   d }}t ƒ }|  d¡D ]8}| ¡ }t d|¡}|r"d| d¡ }qt d|¡}|r2d| d¡ }qt d|¡}|rD| d| d¡ ¡ qt|ƒdkrW| ¡ }t	|ƒt	|ƒfS |sa|rat
|ƒd }|rgt	|ƒnd|rot	|ƒfS 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%.3srb   z<<\s*([\d\.]+)z	^[\d\.]+$r   )rl   r   r   Úrer0   ÚgroupÚaddÚlenÚpopÚgetverÚsorted)r(   rh   rg   Ú	hardcodedÚitemr0   Úverr   r   r   Úparse_pycentral_vrange8  s,   €"r‚   c                 C   sÌ   | d | d   u rdu rdS  | d | d kr$d  dd„ | d D ƒ¡S | d du r8dd  dd„ | d D ƒ¡ S | d du rLd  d	d„ | d D ƒ¡d S d
d  dd„ | d D ƒ¡d  dd„ | d D ƒ¡f 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   rb   Nrr   r   c                 s   r   r   r   r   r   r   r   r   v  r   zvrange_str.<locals>.<genexpr>c                 s   r   r   r   r   r   r   r   r   x  r   c                 s   r   r   r   r   r   r   r   r   z  r   z%s-%sc                 s   r   r   r   r   r   r   r   r   |  r   c                 s   r   r   r   r   r   r   r   r   }  r   )r+   )rn   r   r   r   Ú
vrange_strc  s   ÿÿrƒ   c                 C   s€   t | tƒr| S t | ttfƒst | d tƒrd dd„ | D ƒ¡S g }| D ]}t |tƒr0| |¡ q#| d dd„ |D ƒ¡¡ q#|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   r   r   r   r   r   r   r   r   Ž  r   zvrepr.<locals>.<genexpr>c                 s   r   r   r   r   r   r   r   r   •  r   )r)   r    r   rl   r   r+   Úappend)r(   r9   Úversionr   r   r   Úvrepr€  s   

r†   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   r   r   r   r   r   r   r   r   ©  r   zgetver.<locals>.<genexpr>r   )r)   r   r   )r(   r   r   r   r}   ™  s
   
"r}   c                 C   sh   g }g }t | ƒD ]}t|tƒrt|ƒ}|tk r| |¡ q| |¡ q| t|ƒ¡ |r2|r2t|ƒ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	   r„   ÚextendÚreversedr†   )rp   Ú
return_strr9   Úold_versionsr…   r   r   r   Ú	debsorted¬  s   
rŒ   rs   r   )&Úloggingrx   Úosr   Úos.pathr   Úconfigparserr   Útypesr   ÚRANGE_PATTERNÚcompileru   ÚVERBOSEr/   Ú	getLoggerr_   ÚlogrZ   Ú
_supportedÚ_defaultÚ_configÚreadÚreplacer   r   r	   Ú	ExceptionÚ	exceptionrm   r   rq   rk   r‚   rƒ   r†   r}   rŒ   r   r   r   r   Ú<module>   sX   
û




ÿÿÿÿ 
&(,+