
    siW              
         S r SSKJr  SSKrSSKrSSKJrJrJr  SSK	J
r
  SSKJr  SSKJr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSKJrJr  SSKJr  SSKJr  SSKJr  SSK J!r"  SSK#J$r$J%r%J&r&  SSK'J(r(J)r)J*r*  SSK+J,r,J-r-  SSK.J/r/  SSK0J1r1J2r2   SSK3J3r3  \" \65      r7 " S S\85      r9 " S S\9S9r:S r;S r<S  r=0 r>S8S! jr?S" r@ " S# S$\S9rA " S% S&5      rB " S' S(\B\A5      rC " S) S*\C5      rD " S+ S,\B\A5      rE " S- S.\E5      rF " S/ S0\A5      rG " S1 S2\A5      rH " S3 S4\E5      rI " S5 S6\F5      rJ\I\F\2\E\1\H\H\J\JS7.	rKg! \4 a	    SSK5J3r3   Nf = f)9zImplements the query language for conda packages (a.k.a, MatchSpec).

The MatchSpec is the conda package specification (e.g. `conda==23.3`, `python<3.7`,
`cryptography * *_0`) and is used to communicate the desired packages to install.
    )annotationsN)ABCMetaabstractmethodabstractproperty)Mapping)reduce)chain)	getLogger)
attrgetter)basename   )memoizedproperty)CONDA_PACKAGE_EXTENSION_V1CONDA_PACKAGE_EXTENSION_V2)context)
isiterable)dashlist)groupby_to_dict)expandstrip_pkg_extensionurl_to_path)is_urlpath_to_urlunquote)InvalidMatchSpecInvalidSpec   )Channel)BuildNumberMatchVersionSpec)
frozendictc                  ,   ^  \ rS rSrSU 4S jjrSrU =r$ )MatchSpecType)   c                  >  U(       Ga  [        U[        5      (       a	  U(       d  U$ [        U[        5      (       a~  [        UR                  5      nUR	                  SUR
                  5        UR	                  SUR                  5        UR                  US'   UR                  " S0 UD6  [        TU ](  " S0 UD6$ [        U[        5      (       aU  [        U5      nU(       a3  [        U40 UD6n[        U5      SS1-
  (       a  UR                  SS 5        [        TU ](  " S0 UD6$ [        U[        5      (       a  [        U40 UD6n[        TU ](  " S0 UD6$ [!        US5      (       a%  UR#                  5       nU(       a  [        U40 UD6$ U$ [%        SU SU 35      e[        TU ](  " S0 UD6$ ! [$         aP  nSnU(       a  Xq -  nU(       a,  USS	R'                  S
 UR)                  5        5       5      -   -  n[+        XvS9UeS nAff = f)Noptionaltarget_original_spec_strto_match_speczInvalid MatchSpec:
  spec_arg=z

  kwargs=  , c              3  4   #    U  H  u  pU S U 3v   M     g7f)=N ).0kvs      7lib/python3.13/site-packages/conda/models/match_spec.py	<genexpr>)MatchSpecType.__call__.<locals>.<genexpr>S   s     &Mnda!AaSzns   )detailsr/   )
isinstance	MatchSpecdict_match_components
setdefaultr&   r'   original_spec_strupdatesuper__call__str_parse_spec_strsetpopr   hasattrr)   r   joinitemsr   )	clsspec_argkwargs
new_kwargsparsedspecemsg	__class__s	           r3   r?   MatchSpecType.__call__*   s   )	:h	226#O)44!%h&@&@!AJ))*h6G6GH))(HOOD7?7Q7QJ34%%// 7+9j99#..,X6F!%f!7!7v;*h)?? #JJ';TB 7+5f55'22!(5f5F 7+5f55X77#113D(888#%9(;vhW  w'1&11 	:C$sTYY&Mflln&MMMM"329	:s=   %F. BF. <A)F. &0F. 3F. F.  F. .
H8AHHr/   N)__name__
__module____qualname____firstlineno__r?   __static_attributes____classcell__rO   s   @r3   r#   r#   )   s    *: *:    r#   c                     \ rS rSrSrSr\" \5      r0 rS(S jr	\
S 5       rS rS rS)S	 jr\S
 5       rS r\S 5       r\S 5       r\S 5       rS rS rS rS rS rS rS rS rS rS rS rS r \!S 5       r"S r#S r$\%S 5       r&\S 5       r'\S  5       r(\S! 5       r)\S" 5       r*\S# 5       r+\
S*S$ j5       r,\
S% 5       r-S*S& jr.S'r/g)+r8   W   a  The query language for conda packages.

Any of the fields that comprise a :class:`PackageRecord` can be used to compose a
:class:`MatchSpec`.

:class:`MatchSpec` can be composed with keyword arguments, where keys are any of the
attributes of :class:`PackageRecord`.  Values for keyword arguments are the exact values the
attribute should match against.  Many fields can also be matched against non-exact values--by
including wildcard `*` and `>`/`<` ranges--where supported.  Any non-specified field is
the equivalent of a full wildcard match.

:class:`MatchSpec` can also be composed using a single positional argument, with optional
keyword arguments.  Keyword arguments also override any conflicting information provided in
the positional argument.  The positional argument can be either an existing :class:`MatchSpec`
instance or a string.  Conda has historically supported more than one string representation
for equivalent :class:`MatchSpec` queries.  This :class:`MatchSpec` should accept any existing
valid spec string, and correctly compose a :class:`MatchSpec` instance.

A series of rules are now followed for creating the canonical string representation of a
:class:`MatchSpec` instance.  The canonical string representation can generically be
represented by

    (channel(/subdir):(namespace):)name(version(build))[key1=value1,key2=value2]

where `()` indicate optional fields.  The rules for constructing a canonical string
representation are:

1. `name` (i.e. "package name") is required, but its value can be '*'.  Its position is always
   outside the key-value brackets.
2. If `version` is an exact version, it goes outside the key-value brackets and is prepended
   by `==`. If `version` is a "fuzzy" value (e.g. `1.11.*`), it goes outside the key-value
   brackets with the `.*` left off and is prepended by `=`.  Otherwise `version` is included
   inside key-value brackets.
3. If `version` is an exact version, and `build` is an exact value, `build` goes outside
   key-value brackets prepended by a `=`.  Otherwise, `build` goes inside key-value brackets.
   `build_string` is an alias for `build`.
4. The `namespace` position is being held for a future conda feature.
5. If `channel` is included and is an exact value, a `::` separator is ued between `channel`
   and `name`.  `channel` can either be a canonical channel name or a channel url.  In the
   canonical string representation, the canonical channel name will always be used.
6. If `channel` is an exact value and `subdir` is an exact value, `subdir` is appended to
   `channel` with a `/` separator.  Otherwise, `subdir` is included in the key-value brackets.
7. Key-value brackets can be delimited by comma, space, or comma+space.  Value can optionally
   be wrapped in single or double quotes, but must be wrapped if `value` contains a comma,
   space, or equal sign.  The canonical format uses comma delimiters and single quotes.
8. When constructing a :class:`MatchSpec` instance from a string, any key-value pair given
   inside the key-value brackets overrides any matching parameter given outside the brackets.

When :class:`MatchSpec` attribute values are simple strings, the are interpreted using the
following conventions:

  - If the string begins with `^` and ends with `$`, it is converted to a regex.
  - If the string contains an asterisk (`*`), it is transformed from a glob to a regex.
  - Otherwise, an exact match to the string is sought.


Examples:
    >>> str(MatchSpec(name='foo', build='py2*', channel='conda-forge'))
    'conda-forge::foo[build=py2*]'
    >>> str(MatchSpec('foo 1.0 py27_0'))
    'foo==1.0=py27_0'
    >>> str(MatchSpec('foo=1.0=py27_0'))
    'foo==1.0=py27_0'
    >>> str(MatchSpec('conda-forge::foo[version=1.0.*]'))
    'conda-forge::foo=1.0'
    >>> str(MatchSpec('conda-forge/linux-64::foo>=1.0'))
    "conda-forge/linux-64::foo[version='>=1.0']"
    >>> str(MatchSpec('*/linux-64::foo>=1.0'))
    "foo[subdir=linux-64,version='>=1.0']"

To fully-specify a package with a full, exact spec, the fields
  - channel
  - subdir
  - name
  - version
  - build
must be given as exact values.  In the future, the namespace field will be added to this list.
Alternatively, an exact spec is given by '*[md5=12345678901234567890123456789012]'
or '*[sha256=f453db4ffe2271ec492a2913af4e61d4a6c118201f07de757df0eff769b65d2e]'.
)channelsubdirnameversionbuildbuild_numbertrack_featuresfeaturesurlmd5sha256licenselicense_familyfnNc                x    Xl         X l        UR                  SS 5      U l        U R                  " S0 UD6U l        g )Nr(   r/   )	_optional_targetrC   r(   _build_componentsr:   )selfr&   r'   rI   s       r3   __init__MatchSpec.__init__   s6    !"(**-A4"H!%!7!7!A&!ArY   c                   0 nU[        [        5      * S  [        :X  a  US [        [        5      *  nO.U[        [        5      * S  [        :X  a  US [        [        5      *  nSU;   aZ  UR                  SS5      u  p1SU;   a<  UR	                  SS5      u  pEU[
        R                  ;  a  UnS nXBS'   U(       a  XRS'   OX2S'   UR	                  SS5      u  pgnUR                  UUUS.5        U " S	0 UD6$ )
N::r   /r\   r]   -r   r^   r_   r`   r/   )lenr   r   splitrsplitr   known_subdirsr=   )	rG   dist_strpartschannel_subdir_strchannel_strr]   r^   r_   r`   s	            r3   from_dist_strMatchSpec.from_dist_str   s   S34467;UU B3'A#B"BCHs56689=WW B3'A#B"BCH8+3>>$+B(((&8&?&?Q&G#!6!66"4K!F#.i &,(O#5i 'sA6u"	
 |U|rY   c                b    U R                   R                  U5      nU=(       a    UR                  $ rQ   )r:   getexact_valuern   
field_namer2   s      r3   get_exact_valueMatchSpec.get_exact_value   s'    ""&&z2"Q]]"rY   c                b    U R                   R                  U5      nU=(       a    UR                  $ rQ   )r:   r   	raw_valuer   s      r3   get_raw_valueMatchSpec.get_raw_value   s'    ""&&z2 Q[[ rY   c                2    U R                  U5      nUc  U$ U$ rQ   )r   )rn   r   defaultr2   s       r3   r   MatchSpec.get   s!    z*)w**rY   c                    [        U R                  5      S:H  =(       a%    SU R                  ;   =(       a    U R                  S:g  $ )Nr   r^   *)rv   r:   r^   rn   s    r3   is_name_only_specMatchSpec.is_name_only_spec   s@     &&'1, !$000!		S 	
rY   c                "    U R                  5       $ rQ   __str__r   s    r3   rz   MatchSpec.dist_str       ||~rY   c                    U R                   $ rQ   )rk   r   s    r3   r&   MatchSpec.optional   s    ~~rY   c                    U R                   $ rQ   )rl   r   s    r3   r'   MatchSpec.target   s    ||rY   c                    U R                   $ rQ   )r(   r   s    r3   r<   MatchSpec.original_spec_str   s    &&&rY   c                    [        U[        5      (       a  SSKJn  UR	                  U5      nU R
                  R                  5        H  u  p4U R                  XU5      (       a  M    g   g)z
Accepts a `PackageRecord` or a dict, and matches can pull from any field
in that record.  Returns True for a match, and False for no match.
r   )PackageRecordFT)r7   r9   recordsr   from_objectsr:   rF   _match_individual)rn   recr   r   r2   s        r3   matchMatchSpec.match  sZ    
 c4  .,,S1C!3399;MJ))#1== < rY   c                d    [        X5      n UR                  U5      $ ! [         a    X4:H  s $ f = frQ   )getattrr   AttributeError)rn   recordr   match_componentvals        r3   r   MatchSpec._match_individual  s:    f)	*"((-- 	*"))	*s    //c                f    [        U R                  5      S:H  =(       a    U R                  S5      S L$ )Nr   r^   )rv   r:   r   r   s    r3   
_is_simpleMatchSpec._is_simple  s2    &&'1, 9$$V,D8	
rY   c                2    [        U R                  5      S:H  $ )Nr   )rv   r:   r   s    r3   
_is_singleMatchSpec._is_single  s    4))*a//rY   c                   ^  T R                  S5      nU(       a  U$ [        U 4S jS 5       5      n[        S U 5       5      (       d  SR                  " U6 [        -   $ g )Nri   c              3  F   >#    U  H  nTR                  U5      v   M     g 7frQ   r   )r0   xrn   s     r3   r4   4MatchSpec._to_filename_do_not_use.<locals>.<genexpr>(  s!     S6RT))!,,6Rs   !ru   c              3  (   #    U  H  oS L v   M
     g 7frQ   r/   )r0   r   s     r3   r4   r   )  s     +d9ds   z{}-{}-{})r   tupleanyformatr   )rn   fn_fieldvalss   `  r3   _to_filename_do_not_use!MatchSpec._to_filename_do_not_use"  sY     ''-OS6RSS+d+++%%t,0JJJrY   c                $   U R                   R                   SU  S3/nU R                  (       a  UR                  SU R                   S35        U R                  (       a  UR                  S5        UR                  S5        SR                  U5      $ )Nz(""z
, target="z, optional=True)r*   )rO   rR   r'   appendr&   rE   )rn   builders     r3   __repr__MatchSpec.__repr__.  sq    nn--.ba89;;NNZ}A67==NN,-swwwrY   c                  ^	^
^ / n/ nU R                   R                  S5      nU(       a,  UR                  (       a  UR                  [	        U5      5        O5U(       a.  UR
                  (       d  UR                  S[	        U5       35        U R                   R                  S5      nU(       aA  U(       a&  UR                  (       a  UR                  SU 35        OUR                  SU 35        U R                   R                  SS5      nUR                  U(       a  SOS	U-  5        U R                   R                  S
5      mU R                   R                  S5      m	SnT(       a  [	        T5      m[        U4S jS 5       5      (       a  UR                  ST S35        OTS S S;   a/  T	(       a  UR                  ST S35        OUR                  T5        OTSS  S:X  a  UR                  STS S -   5        OhTS:X  a  OaTS   S:X  a  UR                  STS S -   5        O@TR                  S5      (       a  UR                  T5        SnOUR                  ST-   5        SnT	(       a  [	        T	5      m	[        U	4S jS 5       5      (       a  UR                  ST	 S35        OKST	;   a  UR                  ST	 35        O0U(       a  UR                  ST	-   5        OUR                  ST	 35        1 SknSU R                   ;   a!  SU R                   ;   a  UR                  S5        U R                   H  nX;  d  M
  XR                   ;   d  M  US:X  a	  U(       a  M*  [	        U R                   U   5      m
[        U
4S jS  5       5      (       a  UR                  U S!T
 S35        Mu  UR                  U ST
 35        M     U(       a/  UR                  S"R                  S#R                  U5      5      5        S$R                  U5      $ )%Nr\   zchannel=r]   rs   zsubdir=r^   r   z::%sz%sr_   r`   Fc              3  ,   >#    U  H	  oT;   v   M     g 7frQ   r/   )r0   sr_   s     r3   r4   $MatchSpec.__str__.<locals>.<genexpr>P  s     2A<   z><$^|,z	version=''r   )z!=z~=.*r.   ==Tc              3  ,   >#    U  H	  oT;   v   M     g 7frQ   r/   )r0   r   r`   s     r3   r4   r   h  s     0x!:xr   zbuild='zbuild=>   r^   r`   r]   r\   r_   rd   ri   c              3  ,   >#    U  H	  oT;   v   M     g 7frQ   r/   )r0   r   values     r3   r4   r   z  s     15aEz5r   z, =z='[{}],r*   )r:   r   r   r   r@   matches_allr   
startswithaddFIELD_NAMESr   rE   )rn   r   bracketschannel_matchersubdir_matchername_matcherversion_exact_skipkeyr`   r   r_   s            @@@r3   r   MatchSpec.__str__7  sN   0044Y?::NN3/0_%@%@OOhs?';&<=>//33H=?#>#>>"234'.)9 :;--11&#>'t|CD((,,Y7&&**73'lG2222)G9A 67!,OOiy$:;NN7+%sWSb\12 C#sWSb\12##D))w' $tg~. $JE0x000'% 23& 01sU{+& 01AD***tt7M7M/MIIdO##CC+A+A$A%<OD2237815111OOse2eWA$67OOse1UG$45 $ NN6==();<=wwwrY   c                "    U R                  5       $ rQ   r   r   s    r3   __json__MatchSpec.__json__  r   rY   c                6   / nU R                  S5      nU(       d  [        S5      eUR                  U5        U R                  S5      nU R                  S5      nU(       a  U=(       d    SnXU/-  nOU(       a  UR                  U5        SR	                  U5      $ )Nr^   z3.conda_build_form() requires a non-empty spec name.r`   r_   r   r+   )r   
ValueErrorr   r   rE   )rn   r   r^   r`   r_   s        r3   conda_build_formMatchSpec.conda_build_form  s    ##F+RSSt""7+$$Y/nG''GNN7#xx  rY   c                    [        U 5      nSU;   a  UR                  SS5      S   nSU;   a  UR                  SSS5      nU$ )aj  
Return the package specification in conda environment export format.

This produces the format used by `conda env export`: name=version=build
(single equals), without channel prefixes and without .* patterns.

Examples:
    >>> MatchSpec("numpy==1.21.0=py39h1234567_0").conda_env_form()
    'numpy=1.21.0=py39h1234567_0'
    >>> MatchSpec("numpy=1.21.0").conda_env_form()  # no-builds case
    'numpy=1.21.0'
    >>> MatchSpec("conda-forge::numpy==1.21.0=py39h1234567_0").conda_env_form()
    'numpy=1.21.0=py39h1234567_0'  # channel prefix removed

Returns:
    str: Package specification in conda env export format
rr   r   r   r.   )r@   rw   replace)rn   spec_strs     r3   conda_env_formMatchSpec.conda_env_form  sO    & t9 8~~dA.q1H 8''c15HrY   c                `    [        U[        5      (       a  U R                  UR                  :H  $ g)NF)r7   r8   	_hash_keyrn   others     r3   __eq__MatchSpec.__eq__  s%    eY''>>U__44rY   c                ,    [        U R                  5      $ rQ   )hashr   r   s    r3   __hash__MatchSpec.__hash__  s    DNN##rY   c                H    U R                   U R                  U R                  4$ rQ   )r:   r&   r'   r   s    r3   r   MatchSpec._hash_key  s    %%t}}dkkAArY   c                    XR                   ;   $ rQ   r:   )rn   fields     r3   __contains__MatchSpec.__contains__  s    ....rY   c                   ^ [        U5      [        R                  -
  nU(       a  [        U R                  SU 35      e[        R
                  m[        U4S jUR                  5        5       5      $ )NzCannot match on field(s): c              3  8   >#    U  H  u  pT" X5      v   M     g 7frQ   r/   )r0   r   r   _make_components      r3   r4   .MatchSpec._build_components.<locals>.<genexpr>  s     W*#/#55s   )rB   r8   FIELD_NAMES_SETr   r(   r  r!   rF   )rn   rI   
not_fieldsr  s      @r3   rm   MatchSpec._build_components  s^    [9#<#<<
"''+Ej\)R  $33WWWWrY   c                    [        US5      (       a  UnX4$ [        R                  nX4nUR                  U5      nU(       a  X4$ U [        ;   a  [        U    " U5      nO[        [        U5      5      nX#X4'   X4$ )Nr   )rD   r8   _MATCHER_CACHEr   _implementorsExactStrMatchr@   )r   r   matcherr  	cache_keycached_matchers         r3   r  MatchSpec._make_component  s    5'""G&&"11'	'++I6--&#J/6G#CJ/G.5
*+""rY   c                6    U R                  S5      =(       d    S$ )Nr^   r   r   r   s    r3   r^   MatchSpec.name  s    ##F+2s2rY   c                   ^  [        U 4S jS 5       5      nU[        T R                  5      :  a  gT R                  S5      (       a  ST R                  ;   a  gST R                  ;   a  gg)	Nc              3  @   >#    U  H  oTR                   ;   v   M     g 7frQ   r   )r0   frn   s     r3   r4   'MatchSpec.strictness.<locals>.<genexpr>  s     R5QT+++5Qs   ru      r^   r`   r_   r   r   )sumrv   r:   r   )rn   r   s   ` r3   
strictnessMatchSpec.strictness  sa     R5QRRs4))**%%f--D<R<R1R$000rY   c                "    U R                  5       $ rQ   )r   r   s    r3   rL   MatchSpec.spec  s    $$&&rY   c                8    U R                   R                  S5      $ )Nr_   )r:   r   r   s    r3   r_   MatchSpec.version  s     %%)))44rY   c                    U R                  S5      =(       d    U R                  S5      nU(       a  [        U5      nU(       d  [        S5      eU$ )Nri   rd   z.fn cannot be empty.)r   r   r   )rn   r   s     r3   ri   MatchSpec.fn  sB      &C$*<*<U*C3-C344
rY   c                H  ^ ^ [        [        U 4S jU 5       5      [        S9n[        [	        S5      U5      nUR                  S/ 5      UR                  S / 5      -   n/ n[        [        R                  " S UR                  5        5       5      5      nU H  n[        [	        S5      U5      nUR                  S S 5        [        U5      S:  a  [        S[        U5       35      eUR                  [        U5      S:  a  [        U4S	 jU5      OUS
   5        M     / UQUQ7$ )Nc              3  D   >#    U  H  o(       d  M  T" U5      v   M     g 7frQ   r/   )r0   r   rG   s     r3   r4   "MatchSpec.merge.<locals>.<genexpr>  s     "D;a!63q66;s   
  )r   r^   r   c              3  X   #    U  H   n[        S  U5      R                  5       v   M"     g7f)c                    U R                   $ rQ   )r&   )r   s    r3   <lambda>+MatchSpec.merge.<locals>.<genexpr>.<lambda>  s    !**rY   N)groupbyvalues)r0   groups     r3   r4   r     s+       1E ,e4;;==1s   (*r'   r   zIncompatible MatchSpec merge:c                (   > U R                  UT5      $ rQ   )_merge)r   yunions     r3   r#  !MatchSpec.merge.<locals>.<lambda>  s    AHHQ$6rY   r   )sortedr   r@   r%  r   rC   r	   from_iterabler&  rv   r   r   r   r   )	rG   match_specsr+  name_groupsunmergeablemerged_specsmergeable_groupsr'  target_groupss	   ` `      r3   mergeMatchSpec.merge  s   U"D;"DD#Nj0+>!ooc2.r1JJ   (//1  
 &E#Jx$8%@MdD)=!A% #@%@Q!RSSu:> 6>1X & -,,,rY   c                "    U R                  USS9$ )NT)r+  )r5  )rG   r/  s     r3   r+  MatchSpec.union%  s    yyDy11rY   c                   U R                   UR                   :w  d  U R                  UR                  :w  a  [        SU  SU 35      e0 n[        U R                  5      [        UR                  5      -  nU H  nU R                  R                  U5      nUR                  R                  U5      nUc  Uc  MA  Uc  XsU'   MJ  Uc  XcU'   MS  U(       a   UR                  U5      nOUR                  U5      nXU'   M     U R                  " SU R                   U R                  S.UD6$ ! [        [        [        4 a
    U SU 3n NOf = f)Nz!Incompatible MatchSpec merge:  - 
  - |)r&   r'   r/   )r&   r'   r   rB   r:   r   r+  r   	TypeErrorr5  rO   )	rn   r   r+  final_componentscomponent_namescomponent_namethis_componentthat_componentfinals	            r3   r)  MatchSpec._merge)  sL   ==ENN*dkkU\\.I@fUGTUUd445E<S<S8TT-N!3377GN"4488HN%.*@'3A0'3A0E . 4 4^ D +00@E380# .$ ~~ 
]]4;;
:J
 	
 +J	B E#1"2!N3C DEs   D$$EE)r:   rk   r(   rl   )FNrQ   )F)0rR   rS   rT   rU   __doc__r   	frozensetr  r  ro   classmethodr~   r   r   r   propertyr   rz   r&   r'   r<   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rm   staticmethodr  r^   r  rL   r_   ri   r5  r+  r)  rV   r/   rY   r3   r8   r8   W   s   ObK   ,ONB  :#!+ 
 
     ' '*
0
 K Z!$>$ B B/X # #" 3 3   ' ' 5 5
   - -0 2 2
rY   r8   )	metaclassc                    [         R                  " SU 5      nU(       a,  UR                  5       u  p#U=(       a    UR                  5       nOU Sp2U=(       a    UR	                  SS5      U4$ )a  This should reliably pull the build string out of a version + build string combo.
Examples:
    >>> _parse_version_plus_build("=1.2.3 0")
    ('=1.2.3', '0')
    >>> _parse_version_plus_build("1.2.3=0")
    ('1.2.3', '0')
    >>> _parse_version_plus_build(">=1.0 , < 2.0 py34_0")
    ('>=1.0,<2.0', 'py34_0')
    >>> _parse_version_plus_build(">=1.0 , < 2.0 =py34_0")
    ('>=1.0,<2.0', 'py34_0')
    >>> _parse_version_plus_build("=1.2.3 ")
    ('=1.2.3', None)
    >>> _parse_version_plus_build(">1.8,<2|==1.7")
    ('>1.8,<2|==1.7', None)
    >>> _parse_version_plus_build("* openblas_0")
    ('*', 'openblas_0')
    >>> _parse_version_plus_build("* *")
    ('*', '*')
z<((?:.+?)[^><!,|]?)(?:(?<![=!|,<>~])(?:[ =])([^-=,|<>~]+?))?$Nr+   r*   )researchgroupsstripr   )v_plus_br{   r_   r`   s       r3   _parse_version_plus_buildrP  F  s[    ( IIGE '%++-!4/wsB/66rY   c                N    [        U 5      u  pU R                  SS5      u  p#nX#U4$ )z
Examples:
    >>> _parse_legacy_dist("_license-1.1-py27_1.tar.bz2")
    ('_license', '1.1', 'py27_1')
    >>> _parse_legacy_dist("_license-1.1-py27_1")
    ('_license', '1.1', 'py27_1')
rt   r   )r   rx   )rz   _r^   r_   r`   s        r3   _parse_legacy_distrS  e  s0     &h/KH#??32D5%rY   c                    U (       d  g[        U 5      nUR                  =(       d    UR                  nX!R                  4$ )NNN)r   r^   base_urlr]   )channel_valchnchannel_names      r3   _parse_channelrZ  r  s1    
+
C88+s||L##rY   c                  ^ U S;   a  U $ U R                  S5      (       d  U $ U R                  S5      mU R                  S5      (       a  Uc  T$ [        U4S jS 5       5      (       d   Uc  TR                  S5      (       d  TS-   $ T$ U $ )a  
Sanitize version strings for MatchSpec parsing.

Handles edge cases and translates version patterns for proper MatchSpec processing.

Empty operators like "==" are passed through so existing error handling code can
treat them like other incomplete operators ("<=" or ">="). This is necessary because
downstream translation code would mangle "==" into an empty string, resulting in an
empty version field that breaks logic expecting missing versions to be represented
as operators like "==", "<=", and ">=".

These missing version cases result from match specs like "numpy==", "numpy<=",
"numpy>=", "numpy= " (with trailing space), which should be treated as errors.
Note: "numpy=" (no trailing space) is treated as valid.

For simple versions starting with "=", translates patterns like "=1.2.3" to "1.2.3*"
when appropriate conditions are met.

Args:
    version: The version string to sanitize
    build: Optional build string that affects sanitization behavior

Returns:
    Sanitized version string

Examples:
    "==" or "=" -> passed through for error handling
    "==1.2.3" -> "1.2.3" (when build is None)
    "=1.2.3" -> "1.2.3*" (when build is None and no special chars)
    ">=1.0" -> ">=1.0" (unchanged, doesn't start with "=")
)r   r.   r.   r   c              3  ,   >#    U  H	  oT;   v   M     g 7frQ   r/   )r0   charversion_without_equalss     r3   r4   (_sanitize_version_str.<locals>.<genexpr>  s     @%$--%r   z=,|r   )r   lstripr   endswith)r_   r`   r^  s     @r3   _sanitize_version_strrb  }  s    B + c""$^^C0 $EM%% @%@@@=!7!@!@!E!E)C//%%NrY   c                	   [         R                  U 5      nU(       a  U$ U nU R                  S5      (       a  U S S nSU4S.$ SU ;   a)  U R                  S5      nU S U XS  pPU R	                  5         U R                  SS5      n[        U5      S:  a  [        R                  SU 5        US	   n [        R                  R                  U 5      (       a  [        U 5      (       d  [        [        [        U 5      5      5      n [!        U 5      nUR"                  (       aB  [%        UR&                  5      u  pn
UR(                  UR"                  UU	U
UR&                  U S
.nU$ U R+                  S5      (       a  [-        U 5      nOU nS[/        U5      U S.$ 0 n[0        R2                  " SU 5      nU(       a  UR5                  5       S	   nU R7                  US5      n USS n[0        R8                  " SU5      nU Hm  nUR5                  5       u  nnnnU(       a  U(       d  [;        US5      eUS:X  a0  U(       a)  [=        UUR?                  5       R                  S5      5      nUUU'   Mo     [0        R2                  " SU 5      n0 nU(       ao  UR5                  5       S	   nU R7                  US5      n USS n[0        R8                  " SU5      nU H  nUR5                  5       u  nnnnUUU'   M     SU;   a  SUS'   U RA                  SS5      n[        U5      nUS:X  a  Uu  nnn O*US:X  a  Uu  nn S nOU(       a  US	   n Su  nnO
[C        5       e[E        U5      u  nnSU;   a/  [E        URG                  S5      5      u  nnU(       a  UnU(       a  UnSU;   a  URG                  S5      n[0        R2                  " SU 5      nU(       a&  UR5                  5       u  pUc  [;        USU  S35      eO[;        US5      eU =(       a    U R	                  5       n U (       a+  S U ;   a  [;        US!5      e[I        U 5      u  p[=        X5      n	OSu  p0 nU=(       d    SUS"'   Ub  UUS'   Ub  UUS'   Ub   U	b  U	US'   U
b  U
US'   S"U;   a9  S"U;   a3  S#US"    S$US"    S%US"    S&3n [J        RL                  " U [N        5        US"	 URQ                  U5        UUS''   U[         U'   U$ )(N@r   r   )r^   rb   #z if r   zIgnoring conditional in spec %sr   )r\   r]   r^   r_   r`   ri   rd   zfile://)r^   ri   rd   z.*(?:(\[.*\]))r*   z2([a-zA-Z0-9_-]+?)=(["\']?)([^\'"]*?)(\2)(?:[, ]|$)zkey-value mismatch in bracketsr_   r`   z.*(?:(\(.*\)))r&   T:r   r  rU  r\   r]   z([^ =<>!~]+)?([><!=~ ].+)?zno package name found in 'r   zno package name found[z&multiple brackets sections not allowedr^   z'name' specified both inside (z) and outside (z.) of brackets. The value outside of brackets (z) will be used.r(   ))_PARSE_CACHEr   ra  indexrN  rw   rv   logdebugr   plugin_managerhas_package_extensionr   r   r   r   r   r]   rS  package_filenamecanonical_namer   r   r   rK  r   rM  r   finditerr   rb  	groupdictrx   NotImplementedErrorrZ  rC   rP  warningswarnUserWarningr=   )!r   cached_resultr<   feature_namendxrR  
spec_splitr\   r^   r_   r`   resultpath_or_urlr   m3brackets_strm3br   r   r   m4parens
parens_strm4bm5m5_lenr}   	namespacer]   	b_channelb_subdir
componentsrN   s!                                    r3   rA   rA     s0    $$X.M  }+o
 	
 hnnS!tnhtn! *J
:		3X>!}H 33H==h{6(+;<=H(#>>#5g6N6N#O D5"11!.."..F,  ""9--)(3& {+  H	#X	.B	yy{1~##L"5#Ab)kkA<
 E$||~CE1e&%'G  iE-eU__5F5J5J75ST!HSM  
#X	.BF	YY[^
##J3"%
kkA:
 E$||~CE1F3K  #!%F: 
a	 BWF{+-(Y	1 	8	a5!+Y!##$[1OGVH,X\\)-DE	8GF8h' 
/	:B	<"!%?z#K  
 02IJJ ,HNN,H
 (?"!#K  38<'7# JJv '
9%
8 '
9#
7 ( 2,Xf-=,> ?6"# $6"#?4 	
 	c;'Vh'8J#$&0L"#rY   c                  \    \ rS rSrS r\S 5       rS r\S 5       r	\
S 5       rS rS rS	rg
)MatchInterfaceik  c                    Xl         g rQ   
_raw_valuern   r   s     r3   ro   MatchInterface.__init__l  s    rY   c                    [        5       erQ   rr  r   s     r3   r   MatchInterface.matcho  s    !##rY   c                $    U R                  U5      $ rQ   )r   r  s     r3   matchesMatchInterface.matchess  s    zz%  rY   c                    U R                   $ rQ   r  r   s    r3   r   MatchInterface.raw_valuev      rY   c                    [        5       e)zYIf the match value is an exact specification, returns the value.
Otherwise returns None.
r  r   s    r3   r   MatchInterface.exact_valuez  s    
 "##rY   c                    U R                   UR                   :w  a'  [        SU R                   < SUR                   < 35      eU R                   $ )Nz"Incompatible component merge:
  - r:  )r   r   r   s     r3   r5  MatchInterface.merge  sE    >>U__,5dnn5GveooM`a  ~~rY   c                T    U R                   UR                   1nSR                  U5      $ )Nr;  )r   rE   )rn   r   optionss      r3   r+  MatchInterface.union  s#    >>5??3xx  rY   r  N)rR   rS   rT   rU   ro   r   r   r  rG  r   r   r   r5  r+  rV   r/   rY   r3   r  r  k  sR      $ $!   $ $!rY   r  c                  <    \ rS rSrS rS rS rS r\S 5       r	Sr
g)	_StrMatchMixini  c                    U R                   $ rQ   r  r   s    r3   r   _StrMatchMixin.__str__  s    rY   c                N    U R                   R                   SU R                   S3$ )Nz('z'))rO   rR   r  r   s    r3   r   _StrMatchMixin.__repr__  s%    ..))*"T__,=R@@rY   c                l    [        XR                  5      =(       a    U R                  UR                  :H  $ rQ   r7   rO   r  r   s     r3   r   _StrMatchMixin.__eq__  %    %0XT__HXHX5XXrY   c                ,    [        U R                  5      $ rQ   r   r  r   s    r3   r   _StrMatchMixin.__hash__      DOO$$rY   c                    U R                   $ rQ   r  r   s    r3   r   _StrMatchMixin.exact_value  r  rY   r/   N)rR   rS   rT   rU   r   r   r   r   rG  r   rV   r/   rY   r3   r  r    s,    AY%  rY   r  c                  2   ^  \ rS rSrSrU 4S jrS rSrU =r$ )r	  i  r  c                $   > [         TU ]  U5        g rQ   )r>   ro   rn   r   rO   s     r3   ro   ExactStrMatch.__init__  s    rY   c                p     UR                   nU R                   U:H  $ ! [         a    [        U5      n N&f = frQ   )r  r   r@   rn   r   
_other_vals      r3   r   ExactStrMatch.match  s=    	$))J *,,  	$UJ	$s    55r/   )	rR   rS   rT   rU   	__slots__ro   r   rV   rW   rX   s   @r3   r	  r	    s    I - -rY   r	  c                  .   ^  \ rS rSrU 4S jrS rSrU =r$ )ExactLowerStrMatchi  c                @   > [         TU ]  UR                  5       5        g rQ   r>   ro   lowerr  s     r3   ro   ExactLowerStrMatch.__init__      'rY   c                     UR                   nU R                   UR                  5       :H  $ ! [         a    [        U5      n N4f = frQ   )r  r   r@   r  r  s      r3   r   ExactLowerStrMatch.match  sF    	$))J *"2"2"444  	$UJ	$s   + AAr/   )rR   rS   rT   rU   ro   r   rV   rW   rX   s   @r3   r  r    s    (5 5rY   r  c                  ^   ^  \ rS rSrSrU 4S jrS r\S 5       r\S 5       r	U 4S jr
SrU =r$ )	GlobStrMatchi  )r  	_re_matchc                  > [         TU ]  U5        S U l         UR                  S5      (       a<  UR	                  S5      (       a&  [
        R                  " U5      R                  U l        g SU;   aP  [
        R                  " U5      R                  SS5      n[
        R                  " SU S35      R                  U l        g g ! [
        R                   a  n[        USU S	35      eS nAff = f)
N^$r   \*r   z^(?:)$)Contains an invalid regular expression. 'r   )r>   ro   r  r   ra  rK  compiler   escaper   errorr   rn   r   rM   rO   s      r3   ro   GlobStrMatch.__init__  s    		$$)<)<!#E!2!8!8		%(00>!#tE7",=!>!D!D  xx 	"B1#QG 	s   AC +AC C+C&&C+c                     UR                   nU R                  (       a  U R                  U5      $ U R                   U:H  $ ! [         a    [        U5      n NHf = frQ   )r  r   r@   r  r  s      r3   r   GlobStrMatch.match  sS    	$))J >>>>*--??j00  	$UJ	$s   ? AAc                8    U R                   c  U R                  $ S $ rQ   )r  r  r   s    r3   r   GlobStrMatch.exact_value  s    "&.."8tBdBrY   c                     U R                   S:H  $ )Nr   r  r   s    r3   r   GlobStrMatch.matches_all  s    #%%rY   c                  > U R                   UR                   :X  a  U R                   $ U R                  (       d(  [        U[        5      (       a  UR                  (       a  Xp[	        U5      nSU;  aB  U R                  (       a"  U R                  U5      (       a  UR                   $ [
        TU ]  U5      $ U R                   R                  S5      UR                  S5      s=:X  a  S:X  a  O  OU R                   S   US   s=:X  a  S:X  d"  O  U R                   S   US   s=:X  a  S:X  a`  O  O]U R                   R                  S5      nUR                  S5      nX4;   a  UR                   $ XC;   a  U R                   $ [
        TU ]  U5      $ / nU R                   U4 H  nUR                  S5      (       a,  UR                  S5      (       a  UR                  USS 5        ME  SU;   a9  [        R                  " U5      R                  SS5      nUR                  U5        M  UR                  U5        M     S	US    S
US    S3$ )Nr   r   r   r   r  r  r  r   z^(?=z)(?:r  )r   r  r7   r  r@   r>   r5  countrN  r   ra  r   rK  r  r   )rn   r   other_as_strself_strippedother_strippedpatternsr   rO   s          r3   r5  GlobStrMatch.merge  s   >>U__,>>!~~*UL"A"Aeoo4 5zl" ~~$..">">& w}U++  NN  %););C)@EAE^^A,q/8S8r"l2&6=#= NN005M)//4N.&.~~%7='' nnl3E$$)<)<a,		%(00>&& 4 x{m4}B77rY   r  )rR   rS   rT   rU   r  ro   r   rG  r   r   r5  rV   rW   rX   s   @r3   r  r    sH    )I	1 C C & &@8 @8rY   r  c                  (   ^  \ rS rSrU 4S jrSrU =r$ )GlobLowerStrMatchi!  c                @   > [         TU ]  UR                  5       5        g rQ   r  r  s     r3   ro   GlobLowerStrMatch.__init__"  r  rY   r/   )rR   rS   rT   rU   ro   rV   rW   rX   s   @r3   r  r  !  s    ( (rY   r  c                  `   ^  \ rS rSrSrU 4S jrS rS rS rS r	S r
S	 r\S
 5       rSrU =r$ )SplitStrMatchi&  r  c                B   > [         TU ]  U R                  U5      5        g rQ   r>   ro   _convertr  s     r3   ro   SplitStrMatch.__init__)      u-.rY   c                     [        UR                  SS5      R                  S5      5      $ ! [         a    [	        U5      (       a  [        U5      s $ e f = f)Nr+   r   )rE  r   rw   r   r   r  s     r3   r  SplitStrMatch._convert,  sP    	U]]34::3?@@ 	%   ''	s   ), %AAc                     U=(       a    U R                   UR                   -  $ ! [         a!    U R                   U R                  U5      -  s $ f = frQ   )r  r   r  r   s     r3   r   SplitStrMatch.match4  sH    	:?T__u/?/??? 	:??T]]5%999	:s   !$ (AAc                    U R                   (       a:  SR                  SR                  S [        U R                   5       5       5      5      $ g)Nz{{{}}}r,   c              3  .   #    U  H  nS U S 3v   M     g7fr   Nr/   )r0   r   s     r3   r4   )SplitStrMatch.__repr__.<locals>.<genexpr><  s     ,W?V!q1X?V   zset())r  r   rE   r-  r   s    r3   r   SplitStrMatch.__repr__:  s3    ????499,Wvdoo?V,W#WXXrY   c                J    SR                  [        U R                  5      5      $ Nr+   rE   r-  r  r   s    r3   r   SplitStrMatch.__str__@  s    xxt/00rY   c                l    [        XR                  5      =(       a    U R                  UR                  :H  $ rQ   r  r   s     r3   r   SplitStrMatch.__eq__D  r  rY   c                ,    [        U R                  5      $ rQ   r  r   s    r3   r   SplitStrMatch.__hash__G  r  rY   c                    U R                   $ rQ   r  r   s    r3   r   SplitStrMatch.exact_valueJ  r  rY   r/   rR   rS   rT   rU   r  ro   r  r   r   r   r   r   rG  r   rV   rW   rX   s   @r3   r  r  &  s@    I/:1Y%  rY   r  c                  `   ^  \ rS rSrSrU 4S jrS rS rS rS r	S r
S	 r\S
 5       rSrU =r$ )FeatureMatchiO  r  c                B   > [         TU ]  U R                  U5      5        g rQ   r  r  s     r3   ro   FeatureMatch.__init__R  r  rY   c                    U(       d
  [        5       $ [        U[        5      (       a8  [        S S UR                  SS5      R	                  S5       5        5       5      $ [        S S U 5        5       5      $ )Nc              3  8   #    U  H  nU(       d  M  Uv   M     g 7frQ   r/   r0   r  s     r3   r4   (FeatureMatch._convert.<locals>.<genexpr>Y  s      RA Rs   	c              3  @   #    U  H  oR                  5       v   M     g 7frQ   rN  r0   ffs     r3   r4   r  [  s     R/Q((**/Q   r+   r   c              3  6   #    U  H  o(       d  M  Uv   M     g 7frQ   r/   r  s     r3   r4   r  _  s     J(D1QQ(Ds   
	c              3  @   #    U  H  oR                  5       v   M     g 7frQ   r  r  s     r3   r4   r  _  s     (Deer
  )rE  r7   r@   r   rw   r  s     r3   r  FeatureMatch._convertU  sh    ;s## Ru}}S#/F/L/LS/QR   J(De(DJJJrY   c                B    U R                  U5      nU R                  U:H  $ rQ   )r  r  r   s     r3   r   FeatureMatch.matcha  s    e$%''rY   c                v    SR                  SR                  S [        U R                  5       5       5      5      $ )Nr   r,   c              3  .   #    U  H  nS U S 3v   M     g7fr  r/   )r0   r1   s     r3   r4   (FeatureMatch.__repr__.<locals>.<genexpr>f  s     &Q9PA1#Qx9Pr  )r   rE   r-  r  r   s    r3   r   FeatureMatch.__repr__e  s)    }}TYY&Q9P&QQRRrY   c                J    SR                  [        U R                  5      5      $ r  r  r   s    r3   r   FeatureMatch.__str__h  s    xxt/00rY   c                l    [        XR                  5      =(       a    U R                  UR                  :H  $ rQ   r  r   s     r3   r   FeatureMatch.__eq__k  r  rY   c                ,    [        U R                  5      $ rQ   r  r   s    r3   r   FeatureMatch.__hash__n  r  rY   c                    U R                   $ rQ   r  r   s    r3   r   FeatureMatch.exact_valueq  r  rY   r/   r  rX   s   @r3   r  r  O  sB    I/
K(S1Y%  rY   r  c                  :   ^  \ rS rSrU 4S jrS rS rS rSrU =r	$ )ChannelMatchiv  c                  > S U l          [        U[        5      (       a  UR                  S5      (       a<  UR	                  S5      (       a&  [
        R                  " U5      R                  U l         OVSU;   aE  [
        R                  " SR                  UR                  SS5      5      5      R                  U l         O[        U5      n[        [        U ]?  U5        g ! [
        R                   a  n[        USU S35      eS nAff = f)Nr  r  r   z^(?:{})$r   r  r   )r  r7   r@   r   ra  rK  r  r   r   r   r   r  r   r>   r  ro   r  s      r3   ro   ChannelMatch.__init__w  s    	%%%##C((U^^C-@-@%'ZZ%6%<%<DNE\%'ZZ#**5==e+DE&e N $ENE 	lD*51 xx 	"B1#QG 	s%   A&C 1A
C <C D/C??Dc                    [        UR                  5      nU R                  (       a  U R                  UR                  5      $ U R                  R
                  UR
                  UR                  4;   $ ! [         a    [        U5      n Nrf = frQ   )r   r  r   r  ro  r^   r  s      r3   r   ChannelMatch.match  su    	( !1!12J >>>>*";";<< ??''JOOZ=V=V+WWW  	( J	(s   A2 2B
	B
c                l     U R                   R                   $ ! [         a    U R                    s $ f = frQ   )r  r^   r   r   s    r3   r   ChannelMatch.__str__  s6    	(oo**+, 	(oo&'	(s    33c                *    SU R                  5        S3$ )Nr   r   r   s    r3   r   ChannelMatch.__repr__  s    4<<>"!$$rY   r  )
rR   rS   rT   rU   ro   r   r   r   rV   rW   rX   s   @r3   r  r  v  s    2(X(% %rY   r  c                      \ rS rSrS rSrg)CaseInsensitiveStrMatchi  c                     UR                   nUR                  5       nU R                  (       a  U R	                  U5      $ U R                   U:H  $ ! [         a    [        U5      n NXf = frQ   )r  r   r@   r  r  r  s      r3   r   CaseInsensitiveStrMatch.match  sa    	$))J  %%'
>>>>*--??j00  	$UJ	$s   A A'&A'r/   N)rR   rS   rT   rU   r   rV   r/   rY   r3   r'  r'    s    
1rY   r'  )	r\   r^   r_   r`   ra   rb   rc   rg   rh   )r_   r@   r`   z
str | Nonereturnr@   )LrD  
__future__r   rK  rs  abcr   r   r   collections.abcr   	functoolsr   	itertoolsr	   loggingr
   operatorr   os.pathr   auxlib.decoratorsr   base.constantsr   r   base.contextr   common.compatr   	common.ior   common.iteratorsr   r%  common.pathr   r   r   
common.urlr   r   r   
exceptionsr   r   r\   r   r_   r   r    r!   ImportErrorauxlib.collectionrR   rj  typer#   r8   rP  rS  rZ  rh  rb  rA   r  r  r	  r  r  r  r  r  r  r'  r  r/   rY   r3   <module>r?     sb   # 	  9 9 #      0 S " &   9 B B 5 5 6  2/% +:D +:\l
- l
^7>
 $ 4ntn!w !D $-NN -	5 	5e8>> e8P( (
&N &R$> $N)%< )%X1/ 1 $"&-
[$  /./s   D? ?EE