o knhw@sdZddlmZddlZddlZddlZddlmZmZm Z m Z m Z ddl m Z ddlmZe eefZe ded ZeeegefZd*ddZGdddeZGdddejdZGdddeZedZd+ddZd,ddZd-d!d"Zd.d&d'Z Gd(d)d)eZ!dS)/z .. testsetup:: from packaging.specifiers import Specifier, SpecifierSet, InvalidSpecifier from packaging.version import Version ) annotationsN)CallableIterableIteratorTypeVarUnion)canonicalize_version)VersionUnparsedVersionVar)boundversionUnparsedVersionreturnr cCst|ts t|}|SN) isinstancer )r r?/usr/local/lib/python3.10/dist-packages/packaging/specifiers.py_coerce_versions rc@seZdZdZdS)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__rrrrr src@seZdZejdddZejdddZejdd d Zeejd ddZ e j d!ddZ ejd"d#ddZ ej d"d$ddZ dS)% BaseSpecifierrstrcCdS)z Returns the str representation of this Specifier-like object. This should be representative of the Specifier itself. Nrselfrrr__str__-zBaseSpecifier.__str__intcCr)zF Returns a hash value for this Specifier-like object. Nrrrrr__hash__4r zBaseSpecifier.__hash__otherobjectboolcCr)z Returns a boolean representing whether or not the two Specifier-like objects are equal. :param other: The other object to check against. Nrrr#rrr__eq__:r zBaseSpecifier.__eq__ bool | NonecCr)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. Nrrrrr prereleasesCr zBaseSpecifier.prereleasesvalueNonecCr)zQSetter for :attr:`prereleases`. :param value: The value to set. Nrrr*rrrr)Lr Nitemr)cCr)zR Determines if the given item is contained within this specifier. Nr)rr-r)rrrcontainsSr zBaseSpecifier.containsiterableIterable[UnparsedVersionVar]Iterator[UnparsedVersionVar]cCr)z Takes an iterable of items and filters them so that only items which are contained within this specifier are allowed in it. Nr)rr/r)rrrfilterYr zBaseSpecifier.filterrrrr!r#r$rr%rr(r*r%rr+r)r-rr)r(rr%r/r0r)r(rr1) rrrabcabstractmethodrr"r'propertyr)setterr.r2rrrrr,s"    r) metaclassc @sHeZdZdZdZdZedeedejej BZ dddd d d d d dZ dSdTddZ e dUddZejdVddZe dWddZe dWd d!ZdWd"d#ZdWd$d%Ze dXd'd(ZdYd*d+ZdZd.d/Zd[d2d3Zd\d6d7Zd\d8d9Zd\d:d;Zd\dd?Zd]dAdBZd]dCdDZd\dEdFZd^dIdJZ d_d`dLdMZ! d_dadQdRZ"dS)b 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). z8 (?P(~=|==|!=|<=|>=|<|>|===)) a (?P (?: # 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. (?=<>===Nspecrr)r(rr+cCsF|j|}|std||d|df|_||_dS)aInitialize 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). zInvalid specifier: operatorr N)_regexsearchrgroupstrip_spec _prereleases)rrOr)matchrrr__init__s    zSpecifier.__init__r%cCsR|jdur|jS|j\}}|dvr'|dkr |dr |dd}t|jr'dSdS)N)rHrJrIrGrMrLrKrH.*TF)rVrUendswithr is_prerelease)rrPr rrrr)s    zSpecifier.prereleasesr*cC ||_dSrrVr,rrrr) cC |jdS)z`The operator of this specifier. >>> Specifier("==1.2.3").operator '==' rrUrrrrrP zSpecifier.operatorcCr`)zaThe version of this specifier. >>> Specifier("==1.2.3").version '1.2.3' rrarrrrr rbzSpecifier.versioncCs8|jdur d|jnd}d|jjdt||dS)aTA representation of the Specifier that shows all internal state. >>> Specifier('>=1.0.0') =1.0.0')> >>> Specifier('>=1.0.0', prereleases=False) =1.0.0', prereleases=False)> >>> Specifier('>=1.0.0', prereleases=True) =1.0.0', prereleases=True)> N, prereleases=rNrK()>)rVr) __class__rrrprerrr__repr__&s zSpecifier.__repr__cCs dj|jS)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{}{})formatrUrrrrr8s zSpecifier.__str__tuple[str, str]cCs*t|jd|jddkd}|jd|fS)NrrrGstrip_trailing_zero)r rU)rcanonical_versionrrr_canonical_specBs  zSpecifier._canonical_specr!cC t|jSr)hashrorrrrr"J zSpecifier.__hash__r#r$cCsPt|trz |t|}WntytYSwt||js"tS|j|jkS)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 )rrrfrNotImplementedror&rrrr'Ms    zSpecifier.__eq__opCallableOperatorcCst|d|j|}|S)N _compare_)getattr _operators)rrtoperator_callablerrr _get_operatorjszSpecifier._get_operator prospectiver cCsHttttt|dd}|d7}|d||o#|d||S)NrYrJrH) _version_joinlist itertools takewhile_is_not_suffix_version_splitrz)rr{rOprefixrrr_compare_compatibleps zSpecifier._compare_compatiblec Cs|dr1t|jdd}t|dddd}t|}t|}t||\}}|dt|} | |kSt|} | js=t|j}|| kS)NrYFrlrZ)r[r publicr _pad_versionlenr local) rr{rOnormalized_prospectivenormalized_spec split_specsplit_prospectivepadded_prospective_shortened_prospective spec_versionrrr_compare_equals  zSpecifier._compare_equalcCs||| Sr)rrr{rOrrr_compare_not_equalszSpecifier._compare_not_equalcCst|jt|kSrr rrrrr_compare_less_than_equalz"Specifier._compare_less_than_equalcCst|jt|kSrrrrrr_compare_greater_than_equalrz%Specifier._compare_greater_than_equalspec_strcCs<t|}||ks dS|js|jrt|jt|jkrdSdSNFT)r r\ base_versionrr{rrOrrr_compare_less_thans zSpecifier._compare_less_thancCs^t|}||ks dS|js|jrt|jt|jkrdS|jdur-t|jt|jkr-dSdSr)r is_postreleaserrrrrr_compare_greater_thans  zSpecifier._compare_greater_thancCst|t|kSr)rlowerrrrr_compare_arbitraryszSpecifier._compare_arbitraryr- str | VersioncC ||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") False >>> "1.3.0a1" in Specifier(">=1.2.3", prereleases=True) True r.rr-rrr __contains__ zSpecifier.__contains__rcCs<|dur|j}t|}|jr|sdS||j}|||jS)alReturn 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 uses :attr:`prereleases` to determine whether or not prereleases are allowed. >>> 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") False >>> Specifier(">=1.2.3", prereleases=True).contains("1.3.0a1") True >>> Specifier(">=1.2.3").contains("1.3.0a1", prereleases=True) True NF)r)rr\rzrPr )rr-r)normalized_itemryrrrr. s   zSpecifier.containsr/r0r1ccsd}g}d|dur |ndi}|D]"}t|}|j|fi|r3|jr.|s.|js.||qd}|Vq|s@|rB|D] }|Vq:dSdSdS)aOFilter 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 be intelligently decide whether to allow prereleases or not (based on the :attr:`prereleases` attribute, and whether the only versions matching are prereleases). This method is smarter than just ``filter(Specifier().contains, [...])`` because it implements the rule from :pep:`440` that a prerelease item SHOULD be accepted if no other versions match the given specifier. >>> 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', ] >>> 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'] Fr)NT)rr.r\r)append)rr/r)yieldedfound_prereleaseskwr parsed_versionrrrr25s* zSpecifier.filterrNN)rOrr)r(rr+)rr%r7r3)rrkr4r5)rtrrru)r{r rOrrr%)r{r rrrr%)r-rrr%r)r-rr)r(rr%r8)#rrrr_operator_regex_str_version_regex_strrecompileVERBOSE IGNORECASErQrxrXr;r)r<rPr rirror"r'rzrrrrrrrrrr.r2rrrrr>csZ ^               (       -r>z^([0-9]+)((?:a|b|c|rc)[0-9]+)$r list[str]cCs^g}|d\}}}||pd|dD]}t|}|r'||q||q|S)aSplit 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.) rpartitionrsplit _prefix_regexrRextendgroups)r resultepochrrestr-rWrrrrvs  r componentscCs|^}}|dd|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. rr)join)rrrrrrr}sr}segmentr%cstfdddD S)Nc3s|]}|VqdSr) startswith).0rrrr s  z!_is_not_suffix..)devabrcpost)anyrrrrrs  rleftrighttuple[list[str], list[str]]c Csgg}}|ttdd||ttdd|||t|dd||t|dd|ddgtdt|dt|d|ddgtdt|dt|dttj|ttj|fS)NcS|Srisdigitxrrrz_pad_version..cSrrrrrrrrrrrr) rr~rrrinsertmaxchain from_iterable)rr left_split right_splitrrrrs ,,rc@seZdZdZ  d1d2d d Zed3d d Zejd4dd Zd5ddZd5ddZ d6ddZ d7ddZ d8ddZ d6d d!Z d9d#d$Zd:d'd(Z  d;dd/d0ZdS)? 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. rNN specifiersstr | Iterable[Specifier]r)r(rr+cCsDt|trdd|dD}ttt||_nt||_||_dS)aInitialize 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. cSsg|] }|r|qSr)rTrsrrr sz)SpecifierSet.__init__..,N)rrr frozensetmapr>_specsrV)rrr)split_specifiersrrrrXs   zSpecifierSet.__init__cCs.|jdur|jS|js dStdd|jDS)Ncss|]}|jVqdSrr)rrrrrsz+SpecifierSet.prereleases..)rVrrrrrrr)s zSpecifierSet.prereleasesr*r%cCr]rr^r,rrrr)r_rcCs.|jdur d|jnd}dt||dS)aA 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') =1.0.0')> >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=False) =1.0.0', prereleases=False)> >>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=True) =1.0.0', prereleases=True)> NrcrNz>> 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' rcss|]}t|VqdSr)rrrrrrsz'SpecifierSet.__str__..)rsortedrrrrrr s zSpecifierSet.__str__r!cCrpr)rqrrrrrr"rrzSpecifierSet.__hash__r#SpecifierSet | strcCst|tr t|}nt|tstSt}t|j|jB|_|jdur-|jdur-|j|_|S|jdur=|jdur=|j|_|S|j|jkrI|j|_|Std)aReturn 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' =1.0.0')> >>> SpecifierSet(">=1.0.0,!=1.0.1") & SpecifierSet('<=2.0.0,!=2.0.1') =1.0.0')> NzFCannot combine SpecifierSets with True and False prerelease overrides.)rrrrsrrrV ValueError)rr# specifierrrr__and__s$    zSpecifierSet.__and__r$cCs6t|ttfrtt|}nt|tstS|j|jkS)aWhether 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 )rrr>rrsrr&rrrr'8s   zSpecifierSet.__eq__cCrp)z7Returns the number of specifiers in this specifier set.)rrrrrr__len__Rr_zSpecifierSet.__len__Iterator[Specifier]cCrp)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) [, =1.0.0')>] )iterrrrrr__iter__Vs zSpecifierSet.__iter__r-rcCr)arReturn 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") False >>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True) True rrrrrr`rzSpecifierSet.__contains__ installedcs\tts tdur|jsjrdS|r!jr!tjtfdd|jDS)aReturn 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 uses :attr:`prereleases` to determine whether or not prereleases are allowed. >>> 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") False >>> SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True).contains("1.3.0a1") True >>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1", prereleases=True) True NFc3s|] }|jdVqdS)rNrrr-r)rrrsz(SpecifierSet.contains..)rr r)r\rallr)rr-r)rrrrr.us    zSpecifierSet.containsr/r0r1cCs|dur|j}|jr|jD] }|j|t|d}q t|Sg}g}|D]}t|}|jr6|s6|s5||q#||q#|sH|rH|durHt|St|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 be intelligently decide whether to allow prereleases or not (based on the :attr:`prereleases` attribute, and whether the only versions matching are prereleases). This method is smarter than just ``filter(SpecifierSet(...).contains, [...])`` because it implements the rule from :pep:`440` that a prerelease item SHOULD be accepted if no other versions match the given specifier. >>> 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', ] >>> list(SpecifierSet(">=1.2.3").filter(["1.2", "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'] Nr)r)rr2r%rrr\r)rr/r)rOfilteredrr-rrrrr2s$,    zSpecifierSet.filterr)rrr)r(rr+r6r7r3r4)r#rrrr5)rr)r-rrr%)NN)r-rr)r(rr(rr%rr8)rrrrrXr;r)r<rirr"rr'rrrr.r2rrrrrs, &          :r)r rrr )r rrr)rrrr)rrrr%)rrrrrr)"r __future__rr9rrtypingrrrrrutilsr r r rrr r%rurrrABCMetarr>rrrr}rrrrrrrs2       7