
    wi]                    f   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	      Zeeegef   Zdd
ZddZddZ G d de      Z G d dej8                        Z G d de      Z ej>                  d      Z ddZ!ddZ"ddZ#d dZ$ G d de      Z%y)!z
.. 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)boundc                `    t        | t              s	 t        |       } | S | S # t        $ r Y y w xY wN)
isinstancer   r   versions    S/var/www/feuerwehr-webapp/venv/lib/python3.12/site-packages/packaging/specifiers.py_coerce_versionr      s:    gw'	g&G N7N  		s   ! 	--c                &    | j                  d       S )N)local__replace__r   s    r   _public_versionr   #   s    T**    c                ,    | j                  d d d d       S )N)prepostdevr   r   r   s    r   _base_versionr!   '   s    4dDIIr   c                      e Zd ZdZy)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#   +   s    r   r#   c                  J   e Zd ZdZdZedd       Zej                  dd       Z	ej                  dd       Z
ej                  dd       Zeej                  dd              Zej                  dd       Zej                  ddd
       Zej                  	 d	 	 	 	 	 dd       Zy	)BaseSpecifierr(   )_strc                    t        |       S )z Internal property for match_argsstrselfs    r   r+   zBaseSpecifier._str;   s     4yr   c                     y)z
        Returns the str representation of this Specifier-like object. This
        should be representative of the Specifier itself.
        Nr(   r/   s    r   __str__zBaseSpecifier.__str__@       r   c                     y)zF
        Returns a hash value for this Specifier-like object.
        Nr(   r/   s    r   __hash__zBaseSpecifier.__hash__G   r3   r   c                     y)z
        Returns a boolean representing whether or not the two Specifier-like
        objects are equal.

        :param other: The other object to check against.
        Nr(   r0   others     r   __eq__zBaseSpecifier.__eq__M   r3   r   c                     y)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/   s    r   prereleaseszBaseSpecifier.prereleasesV   r3   r   c                     y)zQSetter for :attr:`prereleases`.

        :param value: The value to set.
        Nr(   r0   values     r   r;   zBaseSpecifier.prereleases_   r3   r   Nc                     y)zR
        Determines if the given item is contained within this specifier.
        Nr(   r0   itemr;   s      r   containszBaseSpecifier.containsf   r3   r   c                     y)z
        Takes an iterable of items and filters them so that only items which
        are contained within this specifier are allowed in it.
        Nr(   )r0   iterabler;   s      r   filterzBaseSpecifier.filterl   r3   r   returnr.   rG   intr8   objectrG   boolrG   bool | None)r>   rL   rG   Noner   )rA   r.   r;   rN   rG   rL   rD   zIterable[UnparsedVersionVar]r;   rN   rG   zIterator[UnparsedVersionVar])r$   r%   r&   	__slots____match_args__propertyr+   abcabstractmethodr2   r5   r9   r;   setterrB   rE   r(   r   r   r*   r*   7   s    IN  	  	 
 	       	 
 	QU4CN	% r   r*   )	metaclassc            	         e Zd ZU dZdZdZdZ ej                  dez   ez   dz   ej                  ej                  z        Zdddd	d
ddddZded<   d*d+dZd,dZd-dZed.d       Zej&                  d/d       Zed0d       Zed0d       Zd0dZd0dZed1d       Zd2dZd3dZd4dZd5dZd5d Zd5d!Zd5d"Zd5d#Z d6d$Z!d6d%Z"d7d&Z#d8d'Z$d9d:d(Z%	 d9	 	 	 	 	 d;d)Z&y)<	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   
_operatorsNc                    | j                   j                  |      }|st        d|      |j                  d      j	                         |j                  d      j	                         f| _        || _        d| _        y)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stripr[   rZ   r\   )r0   specr;   matchs       r   __init__zSpecifier.__init__   sw     %%d+"%8#ABB KK
#))+KK	"((*'

 ( :>r   c                    | j                   !| j                   d   |k(  r| j                   d   S t        |      }|y||f| _         |S )zDOne element cache, as only one spec Version is needed per Specifier.Nr   r
   )r\   r   )r0   r   version_specifiers      r   _get_spec_versionzSpecifier._get_spec_version  sY    )d.@.@.Cw.N%%a((+G4$%'89  r   c                0    | j                  |      }|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 ===).
        )rx   )r0   r   spec_versions      r   _require_spec_versionzSpecifier._require_spec_version  s&     --g6'''r   c                    | j                   | j                   S | j                  \  }}|dk7  r8|dk(  r|j                  d      ry| j                  |      }|y |j                  ryy)Nrg   rf   .*FT)rZ   r[   endswithrx   is_prerelease)r0   rn   version_strr   s       r   r;   zSpecifier.prereleases%  sy     ($$$ !%

+t 4K$8$8$> ,,[9G $$r   c                    || _         y r   rZ   r=   s     r   r;   zSpecifier.prereleasesB  
    !r   c                     | j                   d   S )z`The operator of this specifier.

        >>> Specifier("==1.2.3").operator
        '=='
        r   r[   r/   s    r   rn   zSpecifier.operatorF       zz!}r   c                     | j                   d   S )zaThe version of this specifier.

        >>> Specifier("==1.2.3").version
        '1.2.3'
        r
   r   r/   s    r   r   zSpecifier.versionO  r   r   c                    | j                   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)>
        , prereleases= ri   ()>)rZ   r;   	__class__r$   r.   r0   r   s     r   __repr__zSpecifier.__repr__X  sU       , T--01 	 4>>**+1SYM#bAAr   c                4     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{}{})formatr[   r/   s    r   r2   zSpecifier.__str__j  s     v}}djj))r   c                    | j                   \  }}|dk(  s|j                  d      r||fS | j                  |      }t        ||dk7        }||fS )Nrk   r}   re   strip_trailing_zero)r[   r~   r{   r   )r0   rn   r   rz   canonical_versions        r   _canonical_speczSpecifier._canonical_spect  sc     JJ'u 0 0 6W$$11':0x4/?
 ***r   c                ,    t        | j                        S r   )hashr   r/   s    r   r5   zSpecifier.__hash__  s    D(())r   c                    t        |t              r	 | j                  t        |            }nt        || j                        st        S | j
                  |j
                  k(  S # t        $ r	 t        cY S w xY w)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   r7   s     r   r9   zSpecifier.__eq__  si    & eS!&s5z2 E4>>2!!##u'<'<<< $ &%%&s   A" "A43A4c                >    t        | d| j                  |          }|S )N	_compare_)getattrrl   )r0   opoperator_callables      r   _get_operatorzSpecifier._get_operator  s+    .5Idoob123/
 ! r   c           
         t        t        t        j                  t        t        |                  d d       }|dz  } | j                  d      ||      xr  | j                  d      ||      S )Nr}   rh   rf   )_version_joinlist	itertools	takewhile_is_not_suffix_version_splitr   )r0   prospectivers   prefixs       r   _compare_compatiblezSpecifier._compare_compatible  sw     $$^^D5IJKCRP

 	$'t!!$'T: 
?Wt?Q?QRV?W@
 	
r   c                :   |j                  d      r^t        t        |      d      }t        |d d d      }t        |      }t        |      }t	        ||      \  }}|d t        |       }	|	|k(  S | j                  |      }
|
j                  st        |      }||
k(  S )Nr}   Fr   )r~   r   r   r   _pad_versionlenr{   r   )r0   r   rs   normalized_prospectivenormalized_spec
split_specsplit_prospectivepadded_prospective_shortened_prospectiverz   s              r   _compare_equalzSpecifier._compare_equal  s    ==%9,%&" 349RWXO (8J
 !//E F %11BJ$O!
 %77HZ$I!(J66  55d;L
  %%-k:,..r   c                (    | j                  ||       S r   )r   r0   r   rs   s      r   _compare_not_equalzSpecifier._compare_not_equal  s    &&{D999r   c                <    t        |      | j                  |      k  S r   r   r{   r   s      r   _compare_less_than_equalz"Specifier._compare_less_than_equal       {+t/I/I$/OOOr   c                <    t        |      | j                  |      k\  S r   r   r   s      r   _compare_greater_than_equalz%Specifier._compare_greater_than_equal  r   r   c                    | j                  |      }||k  sy|j                  s$|j                  rt        |      t        |      k(  ryyNFT)r{   r   r!   r0   r   spec_strrs   s       r   _compare_less_thanzSpecifier._compare_less_than  sO     ))(3
 T! ""))k*mD.AA
 r   c                    | j                  |      }||kD  sy|j                  s$|j                  rt        |      t        |      k(  ry|j                  t        |      t        |      k(  ryyr   )r{   is_postreleaser!   r   r   s       r   _compare_greater_thanzSpecifier._compare_greater_than  sy     ))(3
 T! ##**k*mD.AA (].
4 .! 
 r   c                h    t        |      j                         t        |      j                         k(  S r   )r.   lowerr   s      r   _compare_arbitraryzSpecifier._compare_arbitrary0  s&    ;%%'3t9??+<<<r   c                $    | j                  |      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
        rB   r0   rA   s     r   __contains__zSpecifier.__contains__3      & }}T""r   c                N    t        t        | j                  |g|                  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
        r;   )rL   r   rE   r@   s      r   rB   zSpecifier.containsH  s#    2 DdVEFGGr   c              #    K   g }d}||n| j                   }| j                  | j                        }|D ]  }t        |      }|2| j                  dk(  s | j	                  || j
                        s=| B ||| j
                        sV|j                  r|rd}| k|n| j                  dus}|j                  |        |s|| j                  dur|E d{    yyyy7 w)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']
        FNrk   T)	r;   r   rn   r   r   r   r   rZ   append)	r0   rD   r;   prereleases_versionsfound_non_prereleasesinclude_prereleasesr   r   parsed_versions	            r   rE   zSpecifier.filterc  s    0  " % '2K8H8H 	
 !..t}}=   	9G,W5N%==E)d.E.ET\\/ "M">4<<@%337J,0)!M (T->->e-K(//8	9( &#!!.+++ / $ & ,s0   AC&C&1C&
C&"C&1*C&C$	C&r   N)rs   r.   r;   rN   rG   rO   )r   r.   rG   Version | None)r   r.   rG   r   rM   r>   rN   rG   rO   rF   )rG   ztuple[str, str]rH   rJ   )r   r.   rG   CallableOperator)r   r   rs   r.   rG   rL   )r   r   r   r.   rG   rL   )r   zVersion | strrs   r.   rG   rL   )rA   zstr | VersionrG   rL   r   )rA   UnparsedVersionr;   rN   rG   rL   rP   )'r$   r%   r&   r'   rQ   _operator_regex_str_version_regex_strrecompileVERBOSE
IGNORECASEro   rl   __annotations__ru   rx   r{   rS   r;   rV   rn   r   r   r2   r   r5   r9   r   r   r   r   r   r   r   r   r   r   rB   rE   r(   r   r   rY   rY   v   sl    ;I\| RZZ$$'99FB


R]]"F "	J 	>8
!  8 " "    B$* + +*=:!
(&/P:PP6 D=#*H8 RV<,4<,CN<,	%<,r   rY   z([0-9]+)((?:a|b|c|rc)[0-9]+)c                   g }| j                  d      \  }}}|j                  |xs d       |j                  d      D ]J  }t        j	                  |      }|r |j                  |j                                :|j                  |       L |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_regexrp   extendgroups)r   resultepochr   restrA   rt   s          r   r   r     s~     F'',NE1d
MM%,3

3  ''-MM%,,.)MM$  Mr   c                6    | ^}}| ddj                  |       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)
componentsr   r   s      r   r   r     s'     LEDWAchhtn%&&r   c                .     t         fddD               S )Nc              3  @   K   | ]  }j                  |        y wr   )
startswith).0r   segments     r   	<genexpr>z!_is_not_suffix.<locals>.<genexpr>  s!      '-6"s   )r    abrcr   )any)r   s   `r   r   r     s"     1P   r   c                   g g }}|j                  t        t        j                  d |                    |j                  t        t        j                  d |                   |j                  | t	        |d         d         |j                  |t	        |d         d         |j                  ddgt        dt	        |d         t	        |d         z
        z         |j                  ddgt        dt	        |d         t	        |d         z
        z         t        t        j                  j                  |            t        t        j                  j                  |            fS )Nc                "    | j                         S r   isdigitxs    r   <lambda>z_pad_version.<locals>.<lambda>  s     r   c                "    | j                         S r   r   r  s    r   r  z_pad_version.<locals>.<lambda>  s    !))+ r   r   r
   r   )	r   r   r   r   r   insertmaxchainfrom_iterable)leftright
left_splitright_splits       r   r   r     s5    "J d9../DdKLMtI//0EuMNO d3z!}-/01uSQ0234 a#QKN(;c*Q->P(P!QQRq3%#aZ]);c+a.>Q)Q"RRS 	Y__**:67Y__**;78 r   c                      e Zd ZdZdZ	 	 d	 	 	 	 	 ddZedd       Zej                  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	 	 	 	 	 ddZy)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.
    )rZ   _specsNc                "   t        |t              rc|j                  d      D cg c]#  }|j                         s|j                         % }}t	        t        t        |            | _        || _        yt	        |      | _        || _        yc c}w )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.
        ,N)	r   r.   r   rr   	frozensetmaprY   r  rZ   )r0   
specifiersr;   ssplit_specifierss        r   ru   zSpecifierSet.__init__  s{    , j#& 4>3C3CC3HVaAGGI	VV $C	3C$DEDK (	 $J/DK (  Ws
   BBc                    | j                   | j                   S | j                  sy t        d | j                  D              ryy )Nc              3  4   K   | ]  }|j                     y wr   r   r   r  s     r   r   z+SpecifierSet.prereleases.<locals>.<genexpr>  s     2q}}2s   T)rZ   r  r   r/   s    r   r;   zSpecifierSet.prereleases  sB     ($$$
 {{ 2dkk22r   c                    || _         y r   r   r=   s     r   r;   zSpecifierSet.prereleases$  r   r   c                ^    | j                   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)>
        r   r   z<SpecifierSet(r   )rZ   r;   r.   r   s     r   r   zSpecifierSet.__repr__(  sD       , T--01 	  D	}SE44r   c                X    dj                  t        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              3  2   K   | ]  }t        |        y wr   r-   r  s     r   r   z'SpecifierSet.__str__.<locals>.<genexpr>H  s     ;!s1v;s   )r   sortedr  r/   s    r   r2   zSpecifierSet.__str__=  s"     xx;t{{;;<<r   c                ,    t        | j                        S r   )r   r  r/   s    r   r5   zSpecifierSet.__hash__J  s    DKK  r   c                   t        |t              rt        |      }nt        |t              st        S t               }t	        | j
                  |j
                  z        |_        | j                  |j                  |j                  |_        |S | j                  |j                  | j                  |j                  k(  r| 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')>
        zFCannot combine SpecifierSets with True and False prerelease overrides.)r   r.   r  r   r  r  rZ   
ValueError)r0   r8   	specifiers      r   __and__zSpecifierSet.__and__M  s     eS! 'EE<0!! N	$T[[5<<%?@	$););)G%*%7%7I"  )e.@.@.H%"4"44%)%6%6I" 	 X r   c                    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.   rY   r  r   r  r7   s     r   r9   zSpecifierSet.__eq__l  sD    & ec9-. U,EE<0!!{{ell**r   c                ,    t        | j                        S )z7Returns the number of specifiers in this specifier set.)r   r  r/   s    r   __len__zSpecifierSet.__len__  s    4;;r   c                ,    t        | j                        S )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/   s    r   __iter__zSpecifierSet.__iter__  s     DKK  r   c                $    | j                  |      S )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   s     r   r   zSpecifierSet.__contains__  r   r   c                    t        |      }||r|j                  rd}||n|}t        t        | j	                  |g|                  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
        Tr   )r   r   rL   r   rE   )r0   rA   r;   	installedr   
check_items         r   rB   zSpecifierSet.contains  sN    @ "$'91F1FK$_T'
Dj\{KLMMr   c                  	 || j                   | j                   }| j                  r5| j                  D ]  }|j                  ||dn|      } |)t        |      S |du rt        |      S |du r	fd|D        S g }g }d}|D ]c  }t	        |      }|#|j                  |       |j                  |       3|j                  r|j                  |       Q|j                  |       d}e t        |r|      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']
        Tr   Fc              3  T   K   | ]  }t        |      xj                  s| ! y wr   )r   r   )r   rA   r   s     r   r   z&SpecifierSet.filter.<locals>.<genexpr>  s2      #24#88A"00 s   %()r;   r  rE   r)  r   r   r   )
r0   rD   r;   rs   filtered_itemsfound_prereleasesfound_final_releaserA   r   r   s
            @r   rE   zSpecifierSet.filter  s5   N 4#3#3#?**K
 ;;  ;;+2E$; ' 
 & H~% d"H~%e# (  4668# 	+D,T2N %%%d+!((.--!((.%%d+&*#	+ &9NQQ?PQQr   r   )r  zstr | Iterable[Specifier]r;   rN   rG   rO   rM   r   rF   rH   )r8   zSpecifierSet | strrG   r  rJ   )rG   zIterator[Specifier])rA   r   rG   rL   )NN)rA   r   r;   rN   r-  rN   rG   rL   r   rP   )r$   r%   r&   r'   rQ   ru   rS   r;   rV   r   r2   r5   r$  r9   r'  r*  r   rB   rE   r(   r   r   r  r    s     +I 13#'$(-$( !$( 
	$(L  & " "5*=!>+4 !#0 $(!%	&N&N !&N 	&N
 
&NR RV[R4[RCN[R	%[Rr   r  )r   r   rG   r   )r   r   rG   r   )r   r.   rG   	list[str])r   r4  rG   r.   )r   r.   rG   rL   )r
  r4  r  r4  rG   ztuple[list[str], list[str]])&r'   
__future__r   rT   r   r   typingr   r   r   r   r   r	   utilsr   r   r   r   r.   r   r   rL   r   r   r   r!   r"  r#   ABCMetar*   rY   r   r   r   r   r   r   r  r(   r   r   <module>r9     s    # 
  	 F F ' ,%1I WcND01 +J	z 	<ckk <~i, i,X 

:;,'*KR= KRr   