o
    年f7                     @   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 )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   sB   d | }dD ]}t| |}|s |d S |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&   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 )zReturn 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 )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   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 )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   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   





 
&(,+