
    \Zii                    *   S r SSKJr  SSKrSSKrSSKrSSK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  SS
KJrJrJrJr  SSKrSSKrSSKJr  SSKJr  SSKJ r J!r!  SSK"J#r#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K0J1r1  SSK2J3r3  SSK4J5r5  SSK6J7r7  SSK8J9r9  \(       a&  SSK:r;SSK<J=r=J>r>  SSKJ?r?J@r@JArAJBrBJCrC  SSKDJErE  SSKFJGrG  \" \H5      rI\" S5      rJ\R                  " S S!9S" 5       rL\R                  " S#S$9S% 5       rM\R                  " S S!9S& 5       rN\R                  " S#S$9S' 5       rO\R                  " 5       SRS) j5       rP\R                  " \R                  R                  S*S+5      R                  S,5      S-9    SSS. j5       rT\R                      STS/ j5       rU\R                      SUS0 j5       rV\" S1\S2   \S3   5      rW      SVS4 jrX\ " S5 S65      5       rY\R                  SWS7 j5       rZ\R                  " S8S$9SXS9 j5       r[\ " S: S;5      5       r\\R                  " S8S$9SYS< j5       r]\ " S= S>5      5       r^\R                  SZS? j5       r_\ " S@ SA5      5       r`\R                        S[SB j5       ra\R                  S\SC j5       rb\R                  " S8S$9      S]SD j5       rc\ " SE SF5      5       rd\R                        S^SG j5       re\R                  " S(SH9S_SI j5       rf\R                        S`SJ j5       rg\R                        S`SK j5       rh\R                  " S8S SL9SM 5       ri\R                  SaSN j5       rj\ " SO SP5      5       rk\R                        SbSQ j5       rlg)cz2Collection of pytest fixtures used in conda tests.    )annotationsN)contextmanagernullcontext)	dataclass)chain)	getLogger)Path)copyfile)TYPE_CHECKINGLiteralTypeVaroverload   )CONDA_SOURCE_ROOT)dals)PACKAGE_CACHE_MAGIC_FILEPREFIX_MAGIC_FILE)contextreset_context)main_subshell)YamlRawParameter)jsonyaml)path_to_url)PackageCacheData)
SubdirData)CondaExitZero)TemporaryDirectory)PackageRecord   )PYTHON_BINARY)IterableIterator)CaptureFixtureExceptionInfoFixtureRequestMonkeyPatchTempPathFactory)MockerFixture)PathTypea  
    custom_channels:
      darwin: https://some.url.somewhere/stuff
      chuck: http://another.url:8080/with/path
    custom_multichannels:
      michele:
        - https://do.it.with/passion
        - learn_from_every_thing
      steve:
        - more-downloads
    channel_settings:
      - channel: darwin
        param_one: value_one
        param_two: value_two
      - channel: "http://localhost"
        param_one: value_one
        param_two: value_two
    migrated_custom_channels:
      darwin: s3://just/cant
      chuck: file:///var/lib/repo/
    migrated_channel_aliases:
      - https://conda.anaconda.org
    channel_alias: ftp://new.url:8082
    conda-build:
      root-dir: /some/test/path
    proxy_servers:
      http: http://user:pass@corp.com:8080
      https: none
      ftp:
      sftp: ''
      ftps: false
      rsync: 'false'
    aggressive_update_packages: []
    channel_priority: false
    T)autousec                 6    [         R                  " S[        S9  g)z
Suppress `Unclosed Socket Warning`

It seems urllib3 keeps a socket open to avoid costly recreation costs.

xref: https://github.com/kennethreitz/requests/issues/1882
ignore)categoryN)warningsfilterwarningsResourceWarning     6lib/python3.13/site-packages/conda/testing/fixtures.pysuppress_resource_warningr5   _   s     H?r3   function)scopec                    [        [        U 5      S9n UR                  U R                  5        [        R
                  R                  U R                  5      $ )N)dir)r   straddfinalizercleanuppypathlocalname)tmpdirrequests     r4   rA   rA   k   s9    CK0F(77==%%r3   c                 .    [         R                  " 5         g N)r   clear_cached_local_channel_datar2   r3   r4   clear_subdir_cacherF   r   s    ..0r3   c               #  (   #    Sv   [        5         g7f)z:Resets the context object after each test function is run.N)r   r2   r3   r4   reset_conda_contextrH   w   s      
Os   monkeypatchc              #     #    U R                  S5      nUR                  S[        U5      5        [        5         Uv   g7f)z:
Used to isolate package or index cache from other tests.
pkgsCONDA_PKGS_DIRSN)mktempsetenvr:   r   )tmp_path_factoryrI   pkgs_dirs      r4   temp_package_cacherQ      s6     
  &&v.H(#h-8O
Ns   <>CONDA_TEST_SOLVERSzlibmamba,classic,)paramsc              #  J   #    [        X R                  5       Sh  vN   g N7f)a4  
A parameterized fixture that sets the solver backend to (1) libmamba
and (2) classic for each test. It's using autouse=True, so only import it in
modules that actually need it.

Note that skips and xfails need to be done _inside_ the test body.
Decorators can't be used because they are evaluated before the
fixture has done its work!

So, instead of:

    @pytest.mark.skipif(context.solver == "libmamba", reason="...")
    def test_foo():
        ...

Do:

    def test_foo():
        if context.solver == "libmamba":
            pytest.skip("...")
        ...
N)_solver_helperparamrB   s    r4   parametrized_solver_fixturerY      s     : g}}555s   #!#c              #  8   #    [        U S5       S h  vN   g  N7f)NclassicrV   rX   s    r4   solver_classicr]      s      gy111   c              #  8   #    [        U S5       S h  vN   g  N7f)Nlibmambar\   rX   s    r4   solver_libmambara      s      gz222r^   Solverr`   r[   c              #  P  #    [         R                  R                  R                  5         U R	                  [         R                  R                  R                  5        U R                  S5      nUR                  SU5        [        5         [         R                  U:X  d   eUv   g 7f)NrI   CONDA_SOLVER)	r   plugin_managerget_cached_solver_backendcache_clearr;   getfixturevaluerN   r   solver)rB   ri   mps      r4   rV   rV      sy     
 44@@B//IIUUV		 	 	/BIInf%O>>V###
Ls   B$B&c                      \ rS rSr% S\S'   \      SS j5       r\    SS j5       rSS.     SS jjr\SS	 j5       rS
r	g)CondaCLIFixture   zCaptureFixture | Nonecapsysc                   g rD   r2   )selfraisesargvs      r4   __call__CondaCLIFixture.__call__   s    
 *-r3   c                    g rD   r2   )rp   rr   s     r4   rs   rt      s      #r3   Nrq   c                  U R                   (       a  U R                   R                  5         SnU(       a  [        R                  " U5      O	[	        5        n[        U R                  U5      6 nSSS5        U R                   (       a  U R                   R                  5       u  pVOS=pV[        5         XVU(       a  W4$ U4$ ! , (       d  f       NW= f)ax  Test conda CLI. Mimic what is done in `conda.cli.main.main`.

`conda ...` == `conda_cli(...)`

:param argv: Arguments to parse.
:param raises: Expected exception to intercept. If provided, the raised exception
    will be returned instead of exit code (see pytest.raises and pytest.ExceptionInfo).
:return: Command results (stdout, stderr, exit code or pytest.ExceptionInfo).
N)rn   
readouterrpytestrq   r   r   
_cast_argsr   )rp   rq   rr   code	exceptionouterrs          r4   rs   rt      s     ;;KK""$ &,V]]6"+-?9 $//$"78D @ ;;{{--/HCC 	f66$66 @?s   B>>
Cc                "    [        [        U 5      $ )zCast args to string.)mapr:   )rr   s    r4   rz   CondaCLIFixture._cast_args   s     3~r3   r2   )rr   r*   rq   -type[Exception] | tuple[type[Exception], ...]returntuple[str, str, ExceptionInfo])rr   r*   r   tuple[str, str, int])rr   r*   rq   4type[Exception] | tuple[type[Exception], ...] | Noner   2tuple[str | None, str | None, int | ExceptionInfo])rr   ztuple[PathType, ...]r   zIterable[str])
__name__
__module____qualname____firstlineno____annotations__r   rs   staticmethodrz   __static_attributes__r2   r3   r4   rl   rl      s    !!-- >- 
(	- - ## 
# # HL77 E7 
<	7B  r3   rl   c              #  &   #    [        U 5      v   g7f)zA function scoped fixture returning CondaCLIFixture instance.

Use this for any commands that are local to the current test (e.g., creating a
conda environment only used in the test).
Nrl   )rn   s    r4   	conda_clir     s      &
!!   sessionc               #  &   #    [        S5      v   g7f)zA session scoped fixture returning CondaCLIFixture instance.

Use this for any commands that are global to the test session (e.g., creating a
conda environment shared across tests, `conda info`, etc.).
Nr   r2   r3   r4   session_conda_clir     s      $
r   c                  |    \ rS rSrSr\        S	S j5       r\      S
S j5       rSS.       SS jjrSrg)PipCLIFixturei  z7Fixture for calling pip in specific conda environments.c                   g rD   r2   )rp   prefixrq   rr   s       r4   rs   PipCLIFixture.__call__  s     *-r3   c                   g rD   r2   )rp   r   rr   s      r4   rs   r   $  s    
  #r3   Nrv   c               `   [        U5      nU[        -  n[        U5      SS/U Vs/ s H  n[        U5      PM     sn-   nU(       a  [        R                  " U5      O	[        5        n [        R                  " USSSS9n	U	R                  n
U	R                  nU	R                  nSSS5        WWU(       a  W4$ W
4$ s  snf ! [        R                   a.  nUR                  n
UR                  nUR                  n SnANYSnAf[         a    [        SU SU 35      ef = f! , (       d  f       N= f)a  Test pip CLI in a specific conda environment.

`pip ...` in environment == `pip_cli(..., prefix=env_path)`

:param argv: Arguments to pass to pip.
:param prefix: Path to the conda environment containing pip.
:param raises: Expected exception to intercept. If provided, the raised exception
    will be returned instead of exit code (see pytest.raises and pytest.ExceptionInfo).
:return: Command results (stdout, stderr, exit code or pytest.ExceptionInfo).
z-mpipT)capture_outputtextcheckNz Python not found in environment z: )r	   r!   r:   ry   rq   r   
subprocessrun
returncodestdoutstderrCalledProcessErrorFileNotFoundErrorRuntimeError)rp   r   rq   rr   prefix_path
python_exeargcmdr|   resultr{   r   r   es                 r4   rs   r   +  s   " 6l =0
:e,D/IDSCD/II '-V]]6"+-?9##'	 (( @* vFy<<<<1 0J 00 "||$ "6{m2j\R  @?s5   B;'D);C  D$C=8D=DD
D-r2   )rr   r*   r   r*   rq   r   r   r   )rr   r*   r   r*   r   r   )rr   r*   r   r*   rq   r   r   r   )r   r   r   r   __doc__r   rs   r   r2   r3   r4   r   r     s    A-- - >	-
 
(- - ## # 
	# # HL	+=+= += E	+=
 
<+= +=r3   r   c               #  $   #    [        5       v   g7f)a  A function scoped fixture returning PipCLIFixture instance.

Use this for calling pip commands in specific conda environments during tests.
Uses `python -m pip` for reliable cross-platform execution.

Example:
    def test_pip_install(tmp_env, pip_cli):
        with tmp_env("python=3.10", "pip") as prefix:
            stdout, stderr, code = pip_cli("install", "requests", prefix=prefix)
            assert code == 0
N)r   r2   r3   r4   pip_clir   Y  s      /s   c                  N    \ rS rSr% S\S'    SSSSS.         S	S jjjrSrg)
PathFactoryFixtureii  r	   tmp_pathN)r   infixsuffixc               6   U(       a   U(       d  U(       d  U(       a  [        S5      eU(       a  U R                  U-  $ [        R                  " 5       R                  nU=(       d    USS nU=(       d    USS nU=(       d    USS nU R                  X#-   U-   -  $ )u  Unique, non-existent path factory.

Extends pytest's `tmp_path` fixture with a new unique, non-existent path for usage in cases
where we need a temporary path that doesn't exist yet.

Default behavior (no arguments):
   ``path_factory()`` → ``tmp_path/ab12cd34ef56`` (12-char UUID)

Two modes of operation (mutually exclusive):

1. Name mode: Pass a complete path name.
   ``path_factory("myfile.txt")`` → ``tmp_path/myfile.txt``

2. Parts mode: Pass prefix/infix/suffix; unspecified parts get UUID defaults.
   ``path_factory(infix="!")`` → ``tmp_path/ab12!ef56``
   ``path_factory(suffix=".yml")`` → ``tmp_path/ab12cd34.yml``

:param name: Complete path name (mutually exclusive with prefix/infix/suffix)
:param prefix: Prefix for generated name (mutually exclusive with name param)
:param infix: Infix for generated name (mutually exclusive with name param)
:param suffix: Suffix for generated name (mutually exclusive with name param)
:return: A new unique path
z;name and (prefix or infix or suffix) are mutually exclusiveN         )
ValueErrorr   uuiduuid4hex)rp   r@   r   r   r   randoms         r4   rs   PathFactoryFixture.__call__m  s    > VuM  ==4''ZZ\%%F)vbqzF(VAa[E+va|F==FNV$;<<r3   r2   rD   
r@   
str | Noner   r   r   r   r   r   r   r	   )r   r   r   r   r   rs   r   r2   r3   r4   r   r   i  sV    N  *= " !*=*= 	*=
 *= *= 
*= *=r3   r   c              #  &   #    [        U 5      v   g7f)zA function scoped fixture returning PathFactoryFixture instance.

Use this to generate any number of temporary paths for the test that are unique and
do not exist yet.
N)r   )r   s    r4   path_factoryr     s      X
&&r   c                      \ rS rSr% S\S'   S\S'       S         SS jjr\SSSSSSS.               SS	 jj5       rS
rg)TmpEnvFixturei  z$PathFactoryFixture | TempPathFactoryr   rl   r   Nc                    [        U R                  [        5      (       a  U R                  UUUUS9$ U R                  R                  U=(       d#    U=(       d    SU=(       d    S-   U=(       d    S-   5      $ )N)r@   r   r   r   ztmp_env- )
isinstancer   r   rM   )rp   r@   r   r   r   s        r4   get_pathTmpEnvFixture.get_path  sv     d'');<<$$	 %   $$++Q&.J5;B?6<RP r3   )r   r@   path_prefix
path_infixpath_suffixshallowc             '    #    U(       a  U(       a  [        S5      eU(       a'  U(       d  U(       d  U(       d  U(       a  [        S5      e[        U=(       d    U R                  UUUU5      5      nU(       d
  Uc;  U(       d4  U[        -  nUR                  R                  SSS9  UR                  5         OU R                  " SSU 3/UQSPS	P76   Uv   g7f)
u  Generate a conda environment with the provided packages.

Path customization (mutually exclusive options):

1. Auto-generated path (default): Unique path in tmp_path.
   ``tmp_env()`` → ``tmp_path/ab12cd34ef56`` (12-char UUID)

2. Custom prefix: Specify exact location.
   ``tmp_env(prefix="/path/to/env")`` → ``/path/to/env``

3. Name mode: Specify env name directly.
   ``tmp_env(name="my-test-env")`` → ``tmp_path/my-test-env``

4. Parts mode: Customize path name generation (useful for special char testing).
   ``tmp_env(path_infix="!")`` → ``tmp_path/ab12!ef56``

:param args: Arguments to pass to conda create (e.g., packages, flags)
:param prefix: Exact prefix path (mutually exclusive with name/path_* params)
:param name: Env name (mutually exclusive with prefix/path_* params)
:param path_prefix: Prefix for path name (mutually exclusive with prefix/name params)
:param path_infix: Infix for path name (mutually exclusive with prefix/name params)
:param path_suffix: Suffix for path name (mutually exclusive with prefix/name params)
:param shallow: If True, create env on disk only without conda create
:return: The conda environment's prefix
z.shallow=True cannot be used with any argumentszTprefix and (name or path_prefix or path_infix or path_suffix) are mutually exclusiveNT)parentsexist_okcreate	--prefix=--yes--quiet)r   r	   r   r   parentmkdirtouchr   )	rp   r   r@   r   r   r   r   argsr>   s	            r4   rs   TmpEnvFixture.__call__  s     H tMNNt{jKf   }}	
 wt--DKKdT:JJLNNF8$  	
  s   CCr2   )NNNNr   )r   r:   r   zstr | os.PathLike | Noner@   r   r   r   r   r   r   r   r   zbool | Noner   Iterator[Path])	r   r   r   r   r   r   r   rs   r   r2   r3   r4   r   r     s    66  ! !  	
  
*  ,0"&!%"&#CC )C 	C
  C C  C C 
C Cr3   r   c              #  &   #    [        X5      v   g7f)zA function scoped fixture returning TmpEnvFixture instance.

Use this when creating a conda environment that is local to the current test.
Nr   r   r   s     r4   tmp_envr     s      
00r   c                H    U " SS9 nUsSSS5        $ ! , (       d  f       g= f)zuA function scoped fixture returning an empty environment.

Use this when creating a conda environment that is empty.
T)r   Nr2   )r   r   s     r4   	empty_envr     s     
	& 
		s   
!c              #  &   #    [        X5      v   g7f)zA session scoped fixture returning TmpEnvFixture instance.

Use this when creating a conda environment that is shared across tests.
Nr   )rO   r   s     r4   session_tmp_envr     s      (
<<r   c                  >    \ rS rSr% S\S'   S\S'   \S	S j5       rSrg)
TmpChannelFixturei)  r   r   rl   r   c              '    #    U R                   " SSU R                  5        3/UQSPSPSP7S[        06  [        [        R
                  " 5       R                  5      n[	        U5      nU R                  5       nU[        R                  -  nUR                  SS9  US	-  nUR                  SS9  S
S	00 0 S.nS
UR                  00 0 S.n[        U5      n	0 n
U	(       Ga2  U	R                  S5      nUR                  U5       GH  nUS   nX;   a  X   R                  U5        OU1X'   UR                  n[        U5      R!                  5       (       a  UnOX--  nUR                  S	:X  a  UnUnOUnUn[#        UUU-  5        UR%                  S5      (       a  SOSn['        S0 UR)                  5       R+                  5        VVs0 s H  u  nnUS;  d  M  UU_M     snnD6UU   U'   U	R-                  UR.                  5        GM     U	(       a  GM2  US-  R1                  [2        R4                  " U5      5        US-  R1                  [2        R4                  " U5      5        [6        R8                  " U
R;                  5       5       H-  n[=        [	        U5      R                  U5      5      (       a  M-   e   U[?        [A        U5      5      4v   g s  snnf 7f)Nr   r   r   r   z--download-onlyrq   Tr   noarchsubdir)infopackagespackages.condar   fnz.tar.bz2r   r   )urlchannelschannelchannel_namezrepodata.jsonr2   )!r   r   r   r	   r   first_writablerP   r   r   r   r@   listpopqueryaddpackage_tarball_full_pathis_filer
   endswithr   dumpitemsextenddepends
write_textr   dumpsr   from_iterablevaluesanyr   r:   )rp   specsrP   
pkgs_cacher   r   r   noarch_packagessubdir_packages
iter_specsseenspecpackage_recordfnametarballsourcetargetr   keyfieldvalues                        r4   rs   TmpChannelFixture.__call__.  s     	))+,-	
 	
 		

 	
 	
 !	
 (779BBC%h/
##%7>>)T"8#T" x( 9
 v{{+ 9

 %[
$&>>!$D","2"24"8&t,=KOOD)#'&DK )BB=((**$F%-F!((H4#F.H#F.H%0 %*NN:$>$>jDT'4 ( -;,?,?,A,G,G,I,ILE5 (VV %u,I(e$ !!."8"89A #9 jJ 
/	!--djj.IJ	/	!--djj.IJ ''6D'177=>>>> 7 {3w<000!s%   F?KKK3KBK0#Kr2   N)r  r:   r   zIterator[tuple[Path, str]])r   r   r   r   r   r   rs   r   r2   r3   r4   r   r   )  s"    $$M1 M1r3   r   c              #  &   #    [        X5      v   g7f)z?A function scoped fixture returning TmpChannelFixture instance.N)r   r   s     r4   tmp_channelr    s      L
44r   r@   c              #  X  #    U v   U R                    VVVs/ s H5  u  pnU[        R                  L d  M  UR                  S5      (       d  M3  UPM7     snnn=n(       aC  [        R                  SSR                  U5       35        U R                  5         [        / 5        ggs  snnnf 7f)z:A monkeypatch fixture that resets context after each test.CONDA_z+monkeypatch cleanup: undo & reset context: z, N)	_setitemosenviron
startswithlogdebugjoinundor   )rI   objr@   _
conda_varss        r4   context_aware_monkeypatchr$    s      
 (000LCq"** 	!%!: 	0 z 
 			?		*@U?VWXb s   B*B#B#B#AB*c              #  0  #    U " 5       S-  nUR                  SS9  U[        -  R                  5         UR                  SUR                  [        U5      =n4S9  [        R                  U4:X  d   eUv   [        R                  R                  US5        g7f)zHA function scoped fixture returning a temporary package cache directory.rK   Tr   z$conda.base.context.Context.pkgs_dirsnew_callablereturn_valueN)r   r   r   patchPropertyMockr:   r   	pkgs_dirsr   _cache_r   )r   mockerrP   pkgs_dir_strs       r4   tmp_pkgs_dirr/    s     
 ~&HNN4N ((//1
LL.((&)(m3l5  
 ///
N  t4s   BBc              #     #    U " 5       S-  nUR                  SS9  UR                  SUR                  [        U5      =n4S9  [        R
                  U4:X  d   eUv   g7f)zFA function scoped fixture returning a temporary environment directory.envsTr   z$conda.base.context.Context.envs_dirsr&  N)r   r)  r*  r:   r   	envs_dirs)r   r-  envs_direnvs_dir_strs       r4   tmp_envs_dirr5    sj     
 ~&HNN4N 
LL.((&)(m3l5  
 ///
Ns   AA)r7   r+   c               #     #    S[         R                  ;   a  Sv   g[        R                  R	                  5        n U R                  S[        5        Sv   SSS5        g! , (       d  f       g= f7f)a  
We need to set this so Python loads the dev version of 'conda', usually taken
from `conda/` in the root of the cloned repo. This root is usually the working
directory when we run `pytest`.
Otherwise, it will import the one installed in the base environment, which might
have not been overwritten with `pip install -e . --no-deps`. This doesn't happen
in other tests because they run with the equivalent of `python -m conda`. However,
some tests directly run `conda (shell function) which calls `conda` (Python entry
point). When a script is called this way, it bypasses the automatic "working directory
is first on sys.path" behavior you find in `python -m` style calls. See
https://docs.python.org/3/library/sys_path_init.html for details.

PYTHONPATHN)r  r  ry   r'   r   rN   r   )rI   s    r4   r7  r7    sI      rzz!'')[|->? *))s   8A/A	A/
A,(A/c            	         [        5         [        R                  " S[        R                  " S[
        R                  " [        5      5      05        g )Ntestdata)r   r   _set_raw_datar   make_raw_parametersr   loadsTEST_CONDARCr2   r3   r4   context_testdatar>    s9    O(<<DJJ|4	
r3   c                  `    \ rS rSr% SrS\S'   S\S'   S\S'   S\S	'   S
\S'   S rSSS jjrSrg)HttpTestServerFixturei  z;Fixture providing HTTP test server for serving local files.zhttp.server.ThreadingHTTPServerserverr:   hostintportr   r	   	directoryc                H    [         R                  SU R                   35        g)z!Log server startup for debugging.zHTTP test server started: N)r  r  r   )rp   s    r4   __post_init__#HttpTestServerFixture.__post_init__  s    		.txxj9:r3   c                l    UR                  S5      nU(       a  U R                   SU 3$ U R                  $ )z
Get full URL for a given path on the server.

:param path: Relative path on the server (e.g., "subdir/package.tar.bz2")
:return: Full URL
/)lstripr   )rp   r>   s     r4   get_urlHttpTestServerFixture.get_url  s2     {{3'+$((1TF#99r3   r2   N)r   )r>   r:   r   r:   )	r   r   r   r   r   r   rG  rL  r   r2   r3   r4   r@  r@    s.    E++
I
I	HO;: :r3   r@  c           	   #  8  #    SSK Jn  [        U SS5      =n(       ak  [        U5      nUR	                  5       (       d  [        SU 35      eUR                  5       (       d  [        SU 35      e[        UR                  5       5      nO!U" SS9nUR                  5         [        U5      nUR                  U5      nUR                  R                  5       SS	 u  pxS
U;   a  SU S3OUn	SU	 S
U 3n
[        UUUU
[        U5      S9nUv   UR                  5         g7f)a  
Function-scoped HTTP test server for serving local files.

This fixture starts an HTTP server on a random port and serves files
from a directory. The server supports both IPv4 and IPv6.

Usage without parametrize (dynamic content):
    def test_dynamic(http_test_server):
        # Server uses temporary directory automatically
        (http_test_server.directory / "file.txt").write_text("content")
        url = http_test_server.get_url("file.txt")
        response = requests.get(url)
        assert response.status_code == 200

Usage with parametrize (pre-existing directory):
    @pytest.mark.parametrize("http_test_server", ["tests/data/mock-channel"], indirect=True)
    def test_existing(http_test_server):
        url = http_test_server.get_url("file.txt")
        response = requests.get(url)
        assert response.status_code == 200

Use ``None`` in parametrize to mix pre-existing directories with dynamic content:
    @pytest.mark.parametrize("http_test_server", ["tests/data", None], indirect=True)

:param request: pytest fixture request object
:param path_factory: path_factory fixture for creating unique temp directories
:return: HttpTestServerFixture with server, host, port, url, and directory attributes
:raises ValueError: If parametrized directory is invalid
r    )http_test_serverrW   NzDirectory does not exist: zPath is not a directory: rO  r  r   :[]zhttp://)rA  rB  rD  r   rE  )r   rO  getattrr	   existsr   is_dirr:   resolver   run_test_serversocketgetsocknamer@  shutdown)rB   r   http_server_modulerE  directory_path
server_dirrA  rB  rD  url_hostr   fixtures               r4   rO  rO    s%    D 9GWd33y3 i$$&&9)EFF$$&&8DEE..01	 "'9:

O	//	:F**,Ra0JD!Tk4&{tHH:Qtf
%C#y/G M OOs   DD)rI   r'   r   r   )rB   r&   r   z(Iterable[Literal['libmamba', 'classic']])rB   r&   r   zIterable[Literal['classic']])rB   r&   r   zIterable[Literal['libmamba']])rB   r&   ri   rb   r   zIterable[Solver])rn   r$   r   Iterator[CondaCLIFixture])r   r`  )r   zIterator[PipCLIFixture])r   r	   r   zIterator[PathFactoryFixture])r   r   r   rl   r   Iterator[TmpEnvFixture])r   r   r   r	   )rO   r(   r   rl   r   ra  )r   r   r   rl   r   zIterator[TmpChannelFixture])rI   r'   r   r'   )r   r   r-  r)   r   r   )r   None)rB   r&   r   r   r   zIterator[HttpTestServerFixture])mr   
__future__r   r  r   r   r/   
contextlibr   r   dataclassesr   	itertoolsr   loggingr   pathlibr	   shutilr
   typingr   r   r   r   r=   ry   r   r   
auxlib.ishr   base.constantsr   r   base.contextr   r   cli.mainr   common.configurationr   common.serializer   r   
common.urlr   core.package_cache_datar   core.subdir_datar   
exceptionsr   gateways.disk.creater   models.recordsr   integrationr!   http.serverhttpcollections.abcr"   r#   r$   r%   r&   r'   r(   pytest_mockr)   common.pathr*   r   r  r=  r_  r5   rA   rF   rH   rQ   r  getsplitrY   r]   ra   rb   rV   rl   r   r   r   r   r   r   r   r   r   r   r   r  r$  r/  r5  r7  r>  r@  rO  r2   r3   r4   <module>r     s   9 " 	    2 !     < < 	     H 1 $ 3 ) $ 6 ) & 5 * &2  *&  "$N @ @ j!& "& 1 1 j! "   ::>>.0BCII#N66-6	68 22!2 2 33"3 3 
7:.	0B	C " 4 4 4n " " i   !  == == ==@ i  ! -= -= -=` ' ' ] ] ]D 1$11 1 1   i =%=&= = != R1 R1 R1j 5$55 !5 5 ]# $  5$5.;55 5( $.; " i. /*   : : :0 BB$B %B Br3   