o
    )ri]                     @  s$  d Z ddlmZ ddlZddlZddlZddlmZmZm	Z	m
Z
mZmZ ddlmZ ddlmZmZ eeef Zeded	Zeeegef Zd/ddZd0ddZd0ddZG dd deZG dd dejdZG dd deZedZ d1dd Z!d2d"d#Z"d3d&d'Z#d4d+d,Z$G d-d. d.eZ%dS )5z
.. testsetup::

    from packaging.specifiers import Specifier, SpecifierSet, InvalidSpecifier
    from packaging.version import Version
    )annotationsN)CallableFinalIterableIteratorTypeVarUnion   )canonicalize_version)InvalidVersionVersionUnparsedVersionVar)boundversionUnparsedVersionreturnVersion | Nonec                 C  s2   t | tszt| } W | S  ty   Y d S w | S N)
isinstancer   r   r    r   S/home/air/biblejyuku/back/venv/lib/python3.10/site-packages/packaging/specifiers.py_coerce_version   s   

r   r   c                 C  s   | j d dS )N)local__replace__r   r   r   r   _public_version#   s   r   c                 C  s   | j d d d d dS )N)prepostdevr   r   r   r   r   r   _base_version'   s   r    c                   @  s   e Zd ZdZdS )InvalidSpecifiera  
    Raised when attempting to create a :class:`Specifier` with a specifier
    string that is invalid.

    >>> Specifier("lolwat")
    Traceback (most recent call last):
        ...
    packaging.specifiers.InvalidSpecifier: Invalid specifier: 'lolwat'
    N)__name__
__module____qualname____doc__r   r   r   r   r!   +   s    r!   c                   @  s   e Zd ZdZdZed!ddZejd!ddZ	ejd"d
dZ
ejd#ddZeejd$ddZejd%ddZejd&d'ddZej	d&d(dd ZdS ))BaseSpecifierr   )_strr   strc                 C  s   t | S )z Internal property for match_argsr(   selfr   r   r   r'   ;   s   zBaseSpecifier._strc                 C     dS )z
        Returns the str representation of this Specifier-like object. This
        should be representative of the Specifier itself.
        Nr   r*   r   r   r   __str__@       zBaseSpecifier.__str__intc                 C  r,   )zF
        Returns a hash value for this Specifier-like object.
        Nr   r*   r   r   r   __hash__G   r.   zBaseSpecifier.__hash__otherobjectboolc                 C  r,   )z
        Returns a boolean representing whether or not the two Specifier-like
        objects are equal.

        :param other: The other object to check against.
        Nr   r+   r1   r   r   r   __eq__M   r.   zBaseSpecifier.__eq__bool | Nonec                 C  r,   )zWhether or not pre-releases as a whole are allowed.

        This can be set to either ``True`` or ``False`` to explicitly enable or disable
        prereleases or it can be set to ``None`` (the default) to use default semantics.
        Nr   r*   r   r   r   prereleasesV   r.   zBaseSpecifier.prereleasesvalueNonec                 C  r,   )zQSetter for :attr:`prereleases`.

        :param value: The value to set.
        Nr   r+   r8   r   r   r   r7   _   r.   Nitemr7   c                 C  r,   )zR
        Determines if the given item is contained within this specifier.
        Nr   r+   r;   r7   r   r   r   containsf   r.   zBaseSpecifier.containsiterableIterable[UnparsedVersionVar]Iterator[UnparsedVersionVar]c                 C  r,   )z
        Takes an iterable of items and filters them so that only items which
        are contained within this specifier are allowed in it.
        Nr   )r+   r>   r7   r   r   r   filterl   r.   zBaseSpecifier.filterr   r(   r   r/   r1   r2   r   r3   r   r6   )r8   r3   r   r9   r   )r;   r(   r7   r6   r   r3   r>   r?   r7   r6   r   r@   )r"   r#   r$   	__slots____match_args__propertyr'   abcabstractmethodr-   r0   r5   r7   setterr=   rA   r   r   r   r   r&   7   s*    r&   )	metaclassc                	   @  sj  e Zd ZU dZdZdZdZede e d ej	ej
B Zdddd	d
ddddZded< d\d]ddZd^ddZd_d d!Zed`d"d#Zejdad%d#Zedbd&d'Zedbd(d)Zdbd*d+Zdbd,d-Zedcd/d0Zddd2d3Zded7d8Zdfd;d<Zdgd>d?Zdgd@dAZdgdBdCZdgdDdEZdgdFdGZ dhdIdJZ!dhdKdLZ"didNdOZ#djdRdSZ$dkdldUdVZ%	dkdmdZd[Z&dS )n	Specifiera?  This class abstracts handling of version specifiers.

    .. tip::

        It is generally not required to instantiate this manually. You should instead
        prefer to work with :class:`SpecifierSet` instead, which can parse
        comma-separated version specifiers (which is what package metadata contains).
    )_prereleases_spec_spec_versionz8
        (?P<operator>(~=|==|!=|<=|>=|<|>|===))
        a  
        (?P<version>
            (?:
                # The identity operators allow for an escape hatch that will
                # do an exact string match of the version you wish to install.
                # This will not be parsed by PEP 440 and we cannot determine
                # any semantic meaning from it. This operator is discouraged
                # but included entirely as an escape hatch.
                (?<====)  # Only match for the identity operator
                \s*
                [^\s;)]*  # The arbitrary version can be just about anything,
                          # we match everything except for whitespace, a
                          # semi-colon for marker support, and a closing paren
                          # since versions can be enclosed in them.
            )
            |
            (?:
                # The (non)equality operators allow for wild card and local
                # versions to be specified so we have to define these two
                # operators separately to enable that.
                (?<===|!=)            # Only match for equals and not equals

                \s*
                v?
                (?:[0-9]+!)?          # epoch
                [0-9]+(?:\.[0-9]+)*   # release

                # You cannot use a wild card and a pre-release, post-release, a dev or
                # local version together so group them with a | and make them optional.
                (?:
                    \.\*  # Wild card syntax of .*
                    |
                    (?:                                  # pre release
                        [-_\.]?
                        (alpha|beta|preview|pre|a|b|c|rc)
                        [-_\.]?
                        [0-9]*
                    )?
                    (?:                                  # post release
                        (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
                    )?
                    (?:[-_\.]?dev[-_\.]?[0-9]*)?         # dev release
                    (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local
                )?
            )
            |
            (?:
                # The compatible operator requires at least two digits in the
                # release segment.
                (?<=~=)               # Only match for the compatible operator

                \s*
                v?
                (?:[0-9]+!)?          # epoch
                [0-9]+(?:\.[0-9]+)+   # release  (We have a + instead of a *)
                (?:                   # pre release
                    [-_\.]?
                    (alpha|beta|preview|pre|a|b|c|rc)
                    [-_\.]?
                    [0-9]*
                )?
                (?:                                   # post release
                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
                )?
                (?:[-_\.]?dev[-_\.]?[0-9]*)?          # dev release
            )
            |
            (?:
                # All other operators only allow a sub set of what the
                # (non)equality operators do. Specifically they do not allow
                # local versions to be specified nor do they allow the prefix
                # matching wild cards.
                (?<!==|!=|~=)         # We have special cases for these
                                      # operators so we want to make sure they
                                      # don't match here.

                \s*
                v?
                (?:[0-9]+!)?          # epoch
                [0-9]+(?:\.[0-9]+)*   # release
                (?:                   # pre release
                    [-_\.]?
                    (alpha|beta|preview|pre|a|b|c|rc)
                    [-_\.]?
                    [0-9]*
                )?
                (?:                                   # post release
                    (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
                )?
                (?:[-_\.]?dev[-_\.]?[0-9]*)?          # dev release
            )
        )
        z\s*
compatibleequal	not_equalless_than_equalgreater_than_equal	less_thangreater_than	arbitrary)~===!=z<=>=<>===r   
_operators Nspecr(   r7   r6   r   r9   c                 C  sL   | j |}|std||d |d f| _|| _d| _dS )a  Initialize a Specifier instance.

        :param spec:
            The string representation of a specifier which will be parsed and
            normalized before use.
        :param prereleases:
            This tells the specifier if it should accept prerelease versions if
            applicable or not. The default of ``None`` will autodetect it from the
            given specifiers.
        :raises InvalidSpecifier:
            If the given specifier is invalid (i.e. bad syntax).
        zInvalid specifier: operatorr   N)_regex	fullmatchr!   groupstriprP   rO   rQ   )r+   rc   r7   matchr   r   r   __init__   s   
zSpecifier.__init__r   r   c                 C  sD   | j dur| j d |kr| j d S t|}|du rdS ||f| _ |S )zDOne element cache, as only one spec Version is needed per Specifier.Nr   r	   )rQ   r   )r+   r   version_specifierr   r   r   _get_spec_version  s   

zSpecifier._get_spec_versionr   c                 C  s   |  |}|dusJ |S )zGet spec version, asserting it's valid (not for === operator).

        This method should only be called for operators where version
        strings are guaranteed to be valid PEP 440 versions (not ===).
        N)rl   )r+   r   spec_versionr   r   r   _require_spec_version  s   
zSpecifier._require_spec_versionc                 C  s\   | j d ur| j S | j\}}|dkr,|dkr|drdS | |}|d u r'd S |jr,dS dS )Nr\   r[   .*FT)rO   rP   endswithrl   is_prerelease)r+   rd   version_strr   r   r   r   r7   %  s   


zSpecifier.prereleasesr8   c                 C  
   || _ d S r   rO   r:   r   r   r   r7   B     
c                 C  
   | j d S )z`The operator of this specifier.

        >>> Specifier("==1.2.3").operator
        '=='
        r   rP   r*   r   r   r   rd   F     
zSpecifier.operatorc                 C  rv   )zaThe version of this specifier.

        >>> Specifier("==1.2.3").version
        '1.2.3'
        r	   rw   r*   r   r   r   r   O  rx   zSpecifier.versionc                 C  s8   | j durd| jnd}d| jj dt| | dS )aT  A representation of the Specifier that shows all internal state.

        >>> Specifier('>=1.0.0')
        <Specifier('>=1.0.0')>
        >>> Specifier('>=1.0.0', prereleases=False)
        <Specifier('>=1.0.0', prereleases=False)>
        >>> Specifier('>=1.0.0', prereleases=True)
        <Specifier('>=1.0.0', prereleases=True)>
        N, prereleases=rb   r^   ()>)rO   r7   	__class__r"   r(   r+   r   r   r   r   __repr__X  s
   
zSpecifier.__repr__c                 C  s   dj | j S )zA string representation of the Specifier that can be round-tripped.

        >>> str(Specifier('>=1.0.0'))
        '>=1.0.0'
        >>> str(Specifier('>=1.0.0', prereleases=False))
        '>=1.0.0'
        z{}{})formatrP   r*   r   r   r   r-   j  s   zSpecifier.__str__tuple[str, str]c                 C  sF   | j \}}|dks|dr||fS | |}t||dkd}||fS )Nr`   ro   rZ   strip_trailing_zero)rP   rp   rn   r
   )r+   rd   r   rm   canonical_versionr   r   r   _canonical_spect  s   

zSpecifier._canonical_specr/   c                 C  
   t | jS r   )hashr   r*   r   r   r   r0        
zSpecifier.__hash__r1   r2   r3   c                 C  sP   t |trz	| t|}W n ty   t Y S w t || js"tS | j|jkS )a>  Whether or not the two Specifier-like objects are equal.

        :param other: The other object to check against.

        The value of :attr:`prereleases` is ignored.

        >>> Specifier("==1.2.3") == Specifier("== 1.2.3.0")
        True
        >>> (Specifier("==1.2.3", prereleases=False) ==
        ...  Specifier("==1.2.3", prereleases=True))
        True
        >>> Specifier("==1.2.3") == "==1.2.3"
        True
        >>> Specifier("==1.2.3") == Specifier("==1.2.4")
        False
        >>> Specifier("==1.2.3") == Specifier("~=1.2.3")
        False
        )r   r(   r|   r!   NotImplementedr   r4   r   r   r   r5     s   
zSpecifier.__eq__opCallableOperatorc                 C  s   t | d| j|  }|S )N	_compare_)getattrra   )r+   r   operator_callabler   r   r   _get_operator  s   zSpecifier._get_operatorprospectivec                 C  sH   t tttt|d d }|d7 }| d||o#| d||S )Nro   r]   r[   )_version_joinlist	itertools	takewhile_is_not_suffix_version_splitr   )r+   r   rc   prefixr   r   r   _compare_compatible  s   	zSpecifier._compare_compatiblec                 C  s   | dr2tt|dd}t|d d dd}t|}t|}t||\}}|d t| }	|	|kS | |}
|
js>t|}||
kS )Nro   Fr   )rp   r
   r   r   _pad_versionlenrn   r   )r+   r   rc   normalized_prospectivenormalized_spec
split_specsplit_prospectivepadded_prospective_shortened_prospectiverm   r   r   r   _compare_equal  s   

zSpecifier._compare_equalc                 C  s   |  || S r   )r   r+   r   rc   r   r   r   _compare_not_equal  s   zSpecifier._compare_not_equalc                 C  s   t || |kS r   r   rn   r   r   r   r   _compare_less_than_equal     z"Specifier._compare_less_than_equalc                 C  s   t || |kS r   r   r   r   r   r   _compare_greater_than_equal  r   z%Specifier._compare_greater_than_equalspec_strc                 C  s:   |  |}||k sdS |js|jrt|t|krdS dS NFT)rn   rq   r    r+   r   r   rc   r   r   r   _compare_less_than  s   
zSpecifier._compare_less_thanc                 C  sX   |  |}||ksdS |js|jrt|t|krdS |jd ur*t|t|kr*dS dS r   )rn   is_postreleaser    r   r   r   r   r   _compare_greater_than  s    
zSpecifier._compare_greater_thanVersion | strc                 C  s   t | t | kS r   )r(   lowerr   r   r   r   _compare_arbitrary0  s   zSpecifier._compare_arbitraryr;   str | Versionc                 C  
   |  |S )a:  Return whether or not the item is contained in this specifier.

        :param item: The item to check for.

        This is used for the ``in`` operator and behaves the same as
        :meth:`contains` with no ``prereleases`` argument passed.

        >>> "1.2.3" in Specifier(">=1.2.3")
        True
        >>> Version("1.2.3") in Specifier(">=1.2.3")
        True
        >>> "1.0.0" in Specifier(">=1.2.3")
        False
        >>> "1.3.0a1" in Specifier(">=1.2.3")
        True
        >>> "1.3.0a1" in Specifier(">=1.2.3", prereleases=True)
        True
        r=   r+   r;   r   r   r   __contains__3     
zSpecifier.__contains__r   c                 C  s   t t| j|g|dS )as  Return whether or not the item is contained in this specifier.

        :param item:
            The item to check for, which can be a version string or a
            :class:`Version` instance.
        :param prereleases:
            Whether or not to match prereleases with this Specifier. If set to
            ``None`` (the default), it will follow the recommendation from
            :pep:`440` and match prereleases, as there are no other versions.

        >>> Specifier(">=1.2.3").contains("1.2.3")
        True
        >>> Specifier(">=1.2.3").contains(Version("1.2.3"))
        True
        >>> Specifier(">=1.2.3").contains("1.0.0")
        False
        >>> Specifier(">=1.2.3").contains("1.3.0a1")
        True
        >>> Specifier(">=1.2.3", prereleases=False).contains("1.3.0a1")
        False
        >>> Specifier(">=1.2.3").contains("1.3.0a1")
        True
        r7   )r3   r   rA   r<   r   r   r   r=   H  s   zSpecifier.containsr>   r?   r@   c           	      c  s    g }d}|dur|n| j }| | j}|D ]9}t|}|du r0| jdkr/| || jr/|V  q||| jrO|jr;|rAd}|V  q|du rO| jdurO|| q|sb|du rd| jdurf|E dH  dS dS dS dS )a  Filter items in the given iterable, that match the specifier.

        :param iterable:
            An iterable that can contain version strings and :class:`Version` instances.
            The items in the iterable will be filtered according to the specifier.
        :param prereleases:
            Whether or not to allow prereleases in the returned iterator. If set to
            ``None`` (the default), it will follow the recommendation from :pep:`440`
            and match prereleases if there are no other versions.

        >>> list(Specifier(">=1.2.3").filter(["1.2", "1.3", "1.5a1"]))
        ['1.3']
        >>> list(Specifier(">=1.2.3").filter(["1.2", "1.2.3", "1.3", Version("1.4")]))
        ['1.2.3', '1.3', <Version('1.4')>]
        >>> list(Specifier(">=1.2.3").filter(["1.2", "1.5a1"]))
        ['1.5a1']
        >>> list(Specifier(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True))
        ['1.3', '1.5a1']
        >>> list(Specifier(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"]))
        ['1.3', '1.5a1']
        FNr`   T)	r7   r   rd   r   r   r   rq   rO   append)	r+   r>   r7   prereleases_versionsfound_non_prereleasesinclude_prereleasesr   r   parsed_versionr   r   r   rA   c  s:   


zSpecifier.filterrb   N)rc   r(   r7   r6   r   r9   )r   r(   r   r   )r   r(   r   r   rE   r8   r6   r   r9   rB   )r   r   rC   rD   )r   r(   r   r   )r   r   rc   r(   r   r3   )r   r   r   r(   r   r3   )r   r   rc   r(   r   r3   )r;   r   r   r3   r   )r;   r   r7   r6   r   r3   rF   )'r"   r#   r$   r%   rG   _operator_regex_str_version_regex_strrecompileVERBOSE
IGNORECASEre   ra   __annotations__rj   rl   rn   rI   r7   rL   rd   r   r~   r-   r   r0   r5   r   r   r   r   r   r   r   r   r   r   r=   rA   r   r   r   r   rN   v   s`   
 	^












(




"
rN   z([0-9]+)((?:a|b|c|rc)[0-9]+)r(   	list[str]c                 C  s^   g }|  d\}}}||pd |dD ]}t|}|r'||  q|| q|S )a  Split version into components.

    The split components are intended for version comparison. The logic does
    not attempt to retain the original version string, so joining the
    components back with :func:`_version_join` may not produce the original
    version string.
    !0.)
rpartitionr   split_prefix_regexrf   extendgroups)r   resultepochr   restr;   ri   r   r   r   r     s   
r   
componentsc                 C  s   | ^}}| dd | S )zJoin split version components into a version string.

    This function assumes the input came from :func:`_version_split`, where the
    first component must be the epoch (either empty or numeric), and all other
    components numeric.
    r   r   )join)r   r   r   r   r   r   r     s   r   segmentr3   c                   s   t  fdddD  S )Nc                 3  s    | ]}  |V  qd S r   )
startswith).0r   r   r   r   	<genexpr>  s    

z!_is_not_suffix.<locals>.<genexpr>)r   abrcr   )anyr   r   r   r   r     s   
r   leftrighttuple[list[str], list[str]]c              
   C  s   g g }}| ttdd |  | ttdd | | | t|d d   | |t|d d   |ddgtdt|d t|d    |ddgtdt|d t|d    ttj|ttj|fS )Nc                 S     |   S r   isdigitxr   r   r   <lambda>      z_pad_version.<locals>.<lambda>c                 S  r   r   r   r   r   r   r   r     r   r   r	   r   )	r   r   r   r   r   insertmaxchainfrom_iterable)r   r   
left_splitright_splitr   r   r   r     s   
,,r   c                   @  s   e Zd ZdZdZ		d2d3ddZed4ddZejd5ddZd6ddZ	d6ddZ
d7ddZd8ddZd9dd Zd7d!d"Zd:d$d%Zd;d(d)Z		d<d=d+d,Z	d>d?d0d1ZdS )@SpecifierSetzThis class abstracts handling of a set of version specifiers.

    It can be passed a single specifier (``>=3.0``), a comma-separated list of
    specifiers (``>=3.0,!=3.1``), or no specifier at all.
    )rO   _specsrb   N
specifiersstr | Iterable[Specifier]r7   r6   r   r9   c                 C  sD   t |trdd |dD }ttt|| _nt|| _|| _dS )a  Initialize a SpecifierSet instance.

        :param specifiers:
            The string representation of a specifier or a comma-separated list of
            specifiers which will be parsed and normalized before use.
            May also be an iterable of ``Specifier`` instances, which will be used
            as is.
        :param prereleases:
            This tells the SpecifierSet if it should accept prerelease versions if
            applicable or not. The default of ``None`` will autodetect it from the
            given specifiers.

        :raises InvalidSpecifier:
            If the given ``specifiers`` are not parseable than this exception will be
            raised.
        c                 S  s   g | ]
}|  r|  qS r   )rh   r   sr   r   r   
<listcomp>  s    z)SpecifierSet.__init__.<locals>.<listcomp>,N)r   r(   r   	frozensetmaprN   r   rO   )r+   r   r7   split_specifiersr   r   r   rj     s
   


zSpecifierSet.__init__c                 C  s6   | j d ur| j S | jsd S tdd | jD rdS d S )Nc                 s  s    | ]}|j V  qd S r   r   r   r   r   r   r     s    z+SpecifierSet.prereleases.<locals>.<genexpr>T)rO   r   r   r*   r   r   r   r7     s   
zSpecifierSet.prereleasesr8   c                 C  rs   r   rt   r:   r   r   r   r7   $  ru   r(   c                 C  s.   | j durd| jnd}dt| | dS )a  A representation of the specifier set that shows all internal state.

        Note that the ordering of the individual specifiers within the set may not
        match the input string.

        >>> SpecifierSet('>=1.0.0,!=2.0.0')
        <SpecifierSet('!=2.0.0,>=1.0.0')>
        >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=False)
        <SpecifierSet('!=2.0.0,>=1.0.0', prereleases=False)>
        >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=True)
        <SpecifierSet('!=2.0.0,>=1.0.0', prereleases=True)>
        Nry   rb   z<SpecifierSet(r{   )rO   r7   r(   r}   r   r   r   r~   (  s
   
zSpecifierSet.__repr__c                 C  s   d tdd | jD S )an  A string representation of the specifier set that can be round-tripped.

        Note that the ordering of the individual specifiers within the set may not
        match the input string.

        >>> str(SpecifierSet(">=1.0.0,!=1.0.1"))
        '!=1.0.1,>=1.0.0'
        >>> str(SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False))
        '!=1.0.1,>=1.0.0'
        r   c                 s  s    | ]}t |V  qd S r   r)   r   r   r   r   r   H  s    z'SpecifierSet.__str__.<locals>.<genexpr>)r   sortedr   r*   r   r   r   r-   =  s   zSpecifierSet.__str__r/   c                 C  r   r   )r   r   r*   r   r   r   r0   J  r   zSpecifierSet.__hash__r1   SpecifierSet | strc                 C  s   t |tr
t|}nt |tstS t }t| j|jB |_| jdu r-|jdur-|j|_|S | jdur7|jdu s=| j|jkrC| j|_|S td)a  Return a SpecifierSet which is a combination of the two sets.

        :param other: The other object to combine with.

        >>> SpecifierSet(">=1.0.0,!=1.0.1") & '<=2.0.0,!=2.0.1'
        <SpecifierSet('!=1.0.1,!=2.0.1,<=2.0.0,>=1.0.0')>
        >>> SpecifierSet(">=1.0.0,!=1.0.1") & SpecifierSet('<=2.0.0,!=2.0.1')
        <SpecifierSet('!=1.0.1,!=2.0.1,<=2.0.0,>=1.0.0')>
        NzFCannot combine SpecifierSets with True and False prerelease overrides.)r   r(   r   r   r   r   rO   
ValueError)r+   r1   	specifierr   r   r   __and__M  s    




zSpecifierSet.__and__r2   r3   c                 C  s6   t |ttfrtt|}nt |tstS | j|jkS )a  Whether or not the two SpecifierSet-like objects are equal.

        :param other: The other object to check against.

        The value of :attr:`prereleases` is ignored.

        >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.1")
        True
        >>> (SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False) ==
        ...  SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True))
        True
        >>> SpecifierSet(">=1.0.0,!=1.0.1") == ">=1.0.0,!=1.0.1"
        True
        >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0")
        False
        >>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.2")
        False
        )r   r(   rN   r   r   r   r4   r   r   r   r5   l  s
   
zSpecifierSet.__eq__c                 C  r   )z7Returns the number of specifiers in this specifier set.)r   r   r*   r   r   r   __len__  ru   zSpecifierSet.__len__Iterator[Specifier]c                 C  r   )z
        Returns an iterator over all the underlying :class:`Specifier` instances
        in this specifier set.

        >>> sorted(SpecifierSet(">=1.0.0,!=1.0.1"), key=str)
        [<Specifier('!=1.0.1')>, <Specifier('>=1.0.0')>]
        )iterr   r*   r   r   r   __iter__  s   
zSpecifierSet.__iter__r;   r   c                 C  r   )aq  Return whether or not the item is contained in this specifier.

        :param item: The item to check for.

        This is used for the ``in`` operator and behaves the same as
        :meth:`contains` with no ``prereleases`` argument passed.

        >>> "1.2.3" in SpecifierSet(">=1.0.0,!=1.0.1")
        True
        >>> Version("1.2.3") in SpecifierSet(">=1.0.0,!=1.0.1")
        True
        >>> "1.0.1" in SpecifierSet(">=1.0.0,!=1.0.1")
        False
        >>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1")
        True
        >>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True)
        True
        r   r   r   r   r   r     r   zSpecifierSet.__contains__	installedc                 C  sF   t |}|dur|r|jrd}|du r|n|}tt| j|g|dS )a  Return whether or not the item is contained in this SpecifierSet.

        :param item:
            The item to check for, which can be a version string or a
            :class:`Version` instance.
        :param prereleases:
            Whether or not to match prereleases with this SpecifierSet. If set to
            ``None`` (the default), it will follow the recommendation from :pep:`440`
            and match prereleases, as there are no other versions.
        :param installed:
            Whether or not the item is installed. If set to ``True``, it will
            accept prerelease versions even if the specifier does not allow them.

        >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.2.3")
        True
        >>> SpecifierSet(">=1.0.0,!=1.0.1").contains(Version("1.2.3"))
        True
        >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.0.1")
        False
        >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1")
        True
        >>> SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False).contains("1.3.0a1")
        False
        >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1", prereleases=True)
        True
        NTr   )r   rq   r3   r   rA   )r+   r;   r7   r  r   
check_itemr   r   r   r=     s
    zSpecifierSet.containsr>   r?   r@   c           	        s   |du r| j dur| j }| jr+| jD ]}|j||du rdn|d}q|dur*t|S n|du r3t|S |du r@ fdd|D S g }g }d}|D ]%}t|}|du r]|| || qH|jrf|| qH|| d}qHt|rt|S |S )a  Filter items in the given iterable, that match the specifiers in this set.

        :param iterable:
            An iterable that can contain version strings and :class:`Version` instances.
            The items in the iterable will be filtered according to the specifier.
        :param prereleases:
            Whether or not to allow prereleases in the returned iterator. If set to
            ``None`` (the default), it will follow the recommendation from :pep:`440`
            and match prereleases if there are no other versions.

        >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", "1.5a1"]))
        ['1.3']
        >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", Version("1.4")]))
        ['1.3', <Version('1.4')>]
        >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.5a1"]))
        ['1.5a1']
        >>> list(SpecifierSet(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True))
        ['1.3', '1.5a1']
        >>> list(SpecifierSet(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"]))
        ['1.3', '1.5a1']

        An "empty" SpecifierSet will filter items based on the presence of prerelease
        versions in the set.

        >>> list(SpecifierSet("").filter(["1.3", "1.5a1"]))
        ['1.3']
        >>> list(SpecifierSet("").filter(["1.5a1"]))
        ['1.5a1']
        >>> list(SpecifierSet("", prereleases=True).filter(["1.3", "1.5a1"]))
        ['1.3', '1.5a1']
        >>> list(SpecifierSet("").filter(["1.3", "1.5a1"], prereleases=True))
        ['1.3', '1.5a1']
        NTr   Fc                 3  s*    | ]}t |  d u s js|V  qd S r   )r   rq   )r   r;   r   r   r   r     s    z&SpecifierSet.filter.<locals>.<genexpr>)r7   r   rA   r  r   r   rq   )	r+   r>   r7   rc   filtered_itemsfound_prereleasesfound_final_releaser;   r   r   r   r   rA     s:   '

	

zSpecifierSet.filterr   )r   r   r7   r6   r   r9   rE   r   rB   rC   )r1   r   r   r   rD   )r   r   )r;   r   r   r3   )NN)r;   r   r7   r6   r  r6   r   r3   r   rF   )r"   r#   r$   r%   rG   rj   rI   r7   rL   r~   r-   r0   r   r5   r   r  r   r=   rA   r   r   r   r   r     s.    &








)r   )r   r   r   r   )r   r   r   r   )r   r(   r   r   )r   r   r   r(   )r   r(   r   r3   )r   r   r   r   r   r   )&r%   
__future__r   rJ   r   r   typingr   r   r   r   r   r   utilsr
   r   r   r   r(   r   r   r3   r   r   r   r    r   r!   ABCMetar&   rN   r   r   r   r   r   r   r   r   r   r   r   <module>   s6    

	
?    
0



