R" fh dZddlZddlZddlZddlmZmZmZmZm Z m Z m Z m Z ddl mZddlmZe eefZe deZeeegefZd ed efd ZGd d eZGddej2ZGddeZej8dZd ed eefdZdeed efdZded efdZ deedeed e eeeeffdZ!GddeZ"y)z .. testsetup:: from packaging.specifiers import Specifier, SpecifierSet, InvalidSpecifier from packaging.version import Version N)CallableIterableIteratorListOptionalTupleTypeVarUnion)canonicalize_version)VersionUnparsedVersionVar)boundversionreturnc<t|ts t|}|SN) isinstancer )rs 6/usr/lib/python3/dist-packages/packaging/specifiers.py_coerce_versionrs gw ''" NceZdZdZy)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__rrrrsrrc xeZdZejdefdZejdefdZejde de fdZ e ejde e fdZejde ddfd Zejdd ed e e de fd Zej dd eed e e deefdZy) BaseSpecifierrcy)z Returns the str representation of this Specifier-like object. This should be representative of the Specifier itself. Nrselfs r__str__zBaseSpecifier.__str__+rcy)zF Returns a hash value for this Specifier-like object. Nrr"s r__hash__zBaseSpecifier.__hash__2r%rothercy)z Returns a boolean representing whether or not the two Specifier-like objects are equal. :param other: The other object to check against. Nrr#r(s r__eq__zBaseSpecifier.__eq__8r%rcy)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. Nrr"s r prereleaseszBaseSpecifier.prereleasesAr%rvalueNcy)zQSetter for :attr:`prereleases`. :param value: The value to set. Nrr#r.s rr-zBaseSpecifier.prereleasesJr%ritemr-cy)zR Determines if the given item is contained within this specifier. Nr)r#r1r-s rcontainszBaseSpecifier.containsQr%riterablecy)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#r4r-s rfilterzBaseSpecifier.filterWr%rr)rrrabcabstractmethodstrr$intr'objectboolr+propertyrr-setterr3rrrr6rrrr r *s7     #    F t   Xd^    $    S x~    TX  !34 CKD> $ %  rr ) metaclassc eZdZdZdZdZejdezezdzejejzZ dddd d d d d dZ d0de de eddfdZedefdZej$deddfdZede fdZede fdZde fdZde fdZedee e ffdZdefdZdedefdZde defd Zd!ede defd"Z d!ede defd#Z!d!ede defd$Z"d!ede defd%Z#d!ede defd&Z$d!ed'e defd(Z%d!ed'e defd)Z&d!ede defd*Z'd+e(e efdefd,Z) d1d+e*de edefd-Z+ d1d.e,e-de ede.e-fd/Z/y)2 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. (?=<>===Nspecr-rc|jj|}|std|d|jdj |jdj f|_||_y)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: ''operatorrN)_regexsearchrgroupstrip_spec _prereleases)r#rQr-matchs r__init__zSpecifier.__init__so ""4("%9$q#AB B KK # ) ) + KK " ( ( *'  (rc|j |jS|j\}}|dvr1|dk(r|jdr|dd}t|jryy)N)rKrMrLrJrPrK.*TF)rZrYendswithr is_prerelease)r#rTrs rr-zSpecifier.prereleasessm    ($$ $ !JJ' 6 64G$4$4T$:!#2,w--rr.c||_yrrZr0s rr-zSpecifier.prereleases !rc |jdS)z`The operator of this specifier. >>> Specifier("==1.2.3").operator '==' rrYr"s rrTzSpecifier.operatorzz!}rc |jdS)zaThe version of this specifier. >>> Specifier("==1.2.3").version '1.2.3' r rfr"s rrzSpecifier.versionrgrc|jd|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)> , prereleases=rN()>)rZr- __class__rr9r#pres r__repr__zSpecifier.__repr__$sU  ,T--0 1 4>>**+1SYM#bAArc4dj|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{}{})formatrYr"s rr$zSpecifier.__str__6sv}}djj))rcxt|jd|jddk7}|jd|fS)Nr rrJstrip_trailing_zero)r rY)r#canonical_versions r_canonical_speczSpecifier._canonical_spec@s>0 JJqM!%A$!6 zz!}///rc,t|jSr)hashrxr"s rr'zSpecifier.__hash__HsD(())rr(ct|tr |jt|}nt||jstS|j |j k(S#t$r tcYSwxYw)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 )rr9rnrNotImplementedrxr*s rr+zSpecifier.__eq__Ksi& eS ! &s5z2E4>>2! !##u'<'<<< $ &%% &sA""A43A4opc>t|d|j|}|S)N _compare_)getattr _operators)r#r}operator_callables r _get_operatorzSpecifier._get_operatorhs+.5 Idoob123/ ! r prospectivec tttjtt |dd}|dz }|j d||xr|j d||S)Nr^rMrK) _version_joinlist itertools takewhile_is_not_suffix_version_splitr)r#rrQprefixs r_compare_compatiblezSpecifier._compare_compatiblensw $$^^D5IJ KCR P  $'t!!$' T: ?Wt?Q?QRV?W @  rcD|jdr_t|jd}t|ddd}t|}t|}t ||\}}|dt |} | |k(St |} | jst |j}|| k(S)Nr^Frur_)r`r publicr _pad_versionlenr local) r#rrQnormalized_prospectivenormalized_spec split_specsplit_prospectivepadded_prospective_shortened_prospective spec_versions r_compare_equalzSpecifier._compare_equals == %9""& "349RWXO(8J !//E F %11BJ$O !  %77HZ$I !(J6 6#4=L  %%%k&8&89 ,. .rc(|j|| Sr)rr#rrQs r_compare_not_equalzSpecifier._compare_not_equals&&{D999rcDt|jt|kSrr rrs r_compare_less_than_equalz"Specifier._compare_less_than_equal {))*gdm;;rcDt|jt|k\Srrrs r_compare_greater_than_equalz%Specifier._compare_greater_than_equalrrspec_strct|}||ksy|js8|jr,t|jt|jk(ryyNFT)r ra base_versionr#rrrQs r_compare_less_thanzSpecifier._compare_less_thansTx  T! !!k&?&?{//0GD>> "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 r3r#r1s r __contains__zSpecifier.__contains__&}}T""rc| |j}t|}|jr|sy|j|j}|||j S)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 F)r-rrarrTr)r#r1r-normalized_itemrs rr3zSpecifier.contains sY8  **K*$/  ( (/3.@.@.O $,,??rr4c#Kd}g}d||ndi}|D]S}t|}|j|fi|s"|jr |s|js|j |Nd}|U|s|r |D]}|yyyw)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)rr3rar-append)r#r4r-yieldedfound_prereleaseskwrparsed_versions rr6zSpecifier.filter;s<K,C[ N  "G,W5Nt}}^2r2"//4#3#3%,,W5#G!M "(,,   -ws 0A9AA9rkNr)0rrrr_operator_regex_str_version_regex_strrecompileVERBOSE IGNORECASErUrr9rr<r\r=r-r>rTrrqr$rrxr:r'r;r+CallableOperatorrr rrrrrrrrr rUnparsedVersionr3rrrr6rrrrArAas \ |RZZ%%(::WD R]]"F "   J(S(HTN(d(4T.""$""#B#B$**0sCx00*#*=F=t=:!!(8!  w c d *'/''/'/'/R:g:S:T:=g=S=T=#sG|!4##,DH,@#,@2:4.,@ ,@^UY; !34;CKD>; $ %;rrAz^([0-9]+)((?:a|b|c|rc)[0-9]+)$cg}|jd\}}}|j|xsd|jdD]J}tj |}|r |j |j :|j|L|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_regexrVextendgroups)rresultepochrrestr1r[s rrr|s~F'',NE1d MM%,3 3 $$T*  MM%,,. ) MM$   Mr componentsc6|^}}|ddj|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)rrrs rrrs'LEDWAchhtn% &&rsegmentc.tfddD S)Nc3@K|]}j|ywr) startswith).0rrs r z!_is_not_suffix..s!'-6"s)devabrcpost)any)rs`rrrs"1P rleftrightc gg}}|jttjd||jttjd||j|t |dd|j|t |dd|j ddgt dt |dt |dz z|j ddgt dt |dt |dz zttjj|ttjj|fS)Nc"|jSrisdigitxs rz_pad_version..s rc"|jSrrrs rrz_pad_version..s !))+rrr r) rrrrrinsertmaxchain from_iterable)rr left_split right_splits rrrs5 " Jd9../DdKLMtI//0EuMNOd3z!}-/01uSQ0234a#QKN(;c*Q->P(P!QQRq3%#aZ]);c+a.>Q)Q"RRS Y__ * *: 67 Y__ * *; 78 rc HeZdZdZ ddedeeddfdZedeefdZ e jdeddfd Z defd Z defd Z de fd Zd edefddfdZd edefdZde fdZdeefdZdedefdZ ddedeedeedefdZ ddeedeedeefdZy) 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. N specifiersr-rc|jdDcgc]#}|js|j%}}ttt||_||_ycc}w)aNInitialize 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. :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)rrX frozensetmaprA_specsrZ)r#rr-ssplit_specifierss rr\zSpecifierSet.__init__sW(0:/?/?/DR! AGGIRR I/? @A (Ss A$A$c|j |jS|jsytd|jDS)Nc34K|]}|jywrr-rrs rrz+SpecifierSet.prereleases..s6Q1==6s)rZrrr"s rr-zSpecifierSet.prereleasess?    ($$ $ {{6$++666rr.c||_yrrcr0s rr-zSpecifierSet.prereleasesrdrc^|jd|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)> rjrkz>> 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' rc32K|]}t|ywr)r9rs rrz'SpecifierSet.__str__..s;!s1v;s)rsortedrr"s rr$zSpecifierSet.__str__s"xx;t{{;;<>> 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')> zFCannot combine SpecifierSets with True and False prerelease overrides.)rr9rr|rrrZ ValueError)r#r( specifiers r__and__zSpecifierSet.__and__s eS ! 'EE<0! ! N $T[[5<<%?@     $););)G%*%7%7I "   *u/A/A/I%)%6%6I "  %"4"4 4%)%6%6I "  rct|ttfrtt|}nt|tstS|j |j k(S)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 )rr9rArr|rr*s rr+zSpecifierSet.__eq__6sD& ec9- . U,EE<0! !{{ell**rc,t|jS)z7Returns the number of specifiers in this specifier set.)rrr"s r__len__zSpecifierSet.__len__Ps4;;rc,t|jS)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')>] )iterrr"s r__iter__zSpecifierSet.__iter__TsDKK  rr1c$|j|S)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 rrs rrzSpecifierSet.__contains__^rr installedctts t |js jry|r!jrtjt fd|j DS)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 Fc3DK|]}|jyw)rNr)rrr1r-s rrz(SpecifierSet.contains..sR1::d :<Rs )rr r-rarallr)r#r1r-rs `` rr3zSpecifierSet.containsssm<$(4=D  **Kt11 ++4,,-D RdkkRRRrr4cr| |j}|jr8|jD]}|j|t|} t |Sg}g}|D]A}t |}|j r|s|r|j|1|j|C|s|r | t |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'] r)r-rr6r<rrrar)r#r4r-rQfilteredrr1rs rr6zSpecifierSet.filtersX  **K ;;  P;;xT+=N;O P> ! 24H:<  *!0!6"// #)006OOD) * 1k6I-..> !rr)NNr)rrrrr9rr<r\r=r-r>rqr$r:r'r r r;r+r rrArrrr3rrr6rrrrrstCG((19$( (:7Xd^77 ""$""5#5* = =!#!U>3#67N@+F+t+4  !(9-!##T#0'+$( 7S7Sd^7SD> 7S  7StUYM" !34M"CKD>M" $ %M"rr)#rr7rrtypingrrrrrrr r utilsr rr r9rrr<rrrrABCMetar rArrrrrrrrrrrs)  VVV' %1IWcND01_ z 4 ckk4 nU Up <= CDI,'d3i'C'CD tCycuT#YS =Q7R*A"=A"r