
    cD@                     ,   d Z ddlmZ ddlmZmZ ddlmZ ddlZddl	m
Z
mZmZ ddlmZ ddlmZ dd	lmZ g add
Zd Zd Zd Zd Zd ZddZ G d de          Z G d d ee                    Z G d de          Zd Z G d de          Z dS )z'Abstract high-level interface to Conda.    )absolute_import)ABCMetaabstractmethod)deepcopyN)_CommentedMap_CommentedSeq_block_style_all_nodes)with_metaclass)	conda_api)pip_apic                     d }|t          fd|D                       t          fd| D                       }|t          |          z   }t          |          S )Nc                     | S N )items    >lib/python3.11/site-packages/anaconda_project/conda_manager.pydefault_keyz4_combine_keeping_last_duplicate.<locals>.default_key   s        c                 &    g | ]} |          S r   r   ).0r   key_funcs     r   
<listcomp>z3_combine_keeping_last_duplicate.<locals>.<listcomp>   s!    999$xx~~999r   c                 .    g | ]} |          v|S r   r   )r   r   items2_keysr   s     r   r   z3_combine_keeping_last_duplicate.<locals>.<listcomp>   s+    RRRdk0QRTRRRr   )setlisttuple)items1items2r   r   combinedr   s     `  @r   _combine_keeping_last_duplicater!      s        9999&999::KRRRRRfRRRSSH$v,,&H??r   c                 @    t          j        |           }|| S |j        S r   )r   
parse_specnamespecparseds     r   _conda_combine_keyr(   #   s'    !$''F {r   c                 @    t          j        |           }|| S |j        S r   )r   r#   r$   r%   s     r   _pip_combine_keyr*   ,   s'    %%F {r   c                 0    t          | |t                    S )N)r   )r!   r(   )firstseconds     r   _combine_conda_package_listsr.   5   s    *5&CUVVVVr   c                 h    t          | t                    sJ t                              |            dS )z9Push the concrete subtype of ``CondaManager`` to be used.N)
issubclassCondaManager_conda_manager_classesappend)klasss    r   push_conda_manager_classr5   9   s4     e\*****!!%(((((r   c                  l    t          t                    dk    sJ t                                           dS )zERemove the most recently-pushed concrete subtype of ``CondaManager``.r   N)lenr2   popr   r   r   pop_conda_manager_classr9   @   s6     %&&****     r   c                 v    t          t                    dk    r	ddlm} |}nt          d         } ||           S )z'Create a new concrete ``CondaManager``.r   )DefaultCondaManager)frontend)r7   r2   /anaconda_project.internal.default_conda_managerr;   )r=   r;   r4   s      r   new_conda_managerr?   G   sP     !""a' +WWWWWW#&r*5(####r   c                       e Zd ZdZdS )CondaManagerErrorzGeneral Conda error.N)__name__
__module____qualname____doc__r   r   r   rA   rA   R   s        Dr   rA   c                   l    e Zd ZdZed             Zed             Zedd            Zed             ZdS )	r1   aJ  Methods for interacting with Conda.

    This is meant to be a stateless class. Multiple may be created
    and they may be used from multiple threads. If instances are
    implemented using any global state under the hood, that global
    state should be protected by locks, and shared among
    ``CondaManager`` instances.

    c                     dS )a  Compute the full transitive graph to install to satisfy package_specs.

        Raised exceptions that are user-interesting conda problems
        should be subtypes of ``CondaManagerError``.

        The passed-in package specs can be any constraints we want
        to "hold constant" while computing the other deps.

        The returned value is a ``CondaLockSet``.

        Args:
            package_specs (list of str): list of specs to hold constant
            channels (list of str): list of channels to resolve against
            platforms (list of str): list of platforms to resolve for

        Returns:
            a ``CondaLockSet`` instance

        Nr   )selfpackage_specschannels	platformss       r   resolve_dependenciesz!CondaManager.resolve_dependenciesb   s	    * 	r   c                     dS )a  Compute a ``CondaEnvironmentDeviations`` describing deviations of the env at prefix from the spec.

        Raised exceptions that are user-interesting conda problems
        should be subtypes of ``CondaManagerError``.

        The prefix may not exist (which would be considered a
        deviation).

        Args:
            prefix (str): the environment prefix (absolute path)
            spec (EnvSpec): specification for the environment

        Returns:
            a ``CondaEnvironmentDeviations`` instance

        Nr   )rH   prefixr&   s      r   find_environment_deviationsz(CondaManager.find_environment_deviationsy   	    $ 	r   NTc                     dS )ar  Fix deviations of the env in prefix from the spec.

        Raised exceptions that are user-interesting conda problems
        should be subtypes of ``CondaManagerError``.

        The prefix may not exist (this method should then try to create it).

        Args:
            prefix (str): the environment prefix (absolute path)
            spec (EnvSpec): specification for the environment
            deviations (CondaEnvironmentDeviations): optional previous result from find_environment_deviations()
            create (bool): True if we should create if completely nonexistent

        Returns:
            None
        Nr   )rH   rN   r&   
deviationscreates        r   fix_environment_deviationsz'CondaManager.fix_environment_deviations   rP   r   c                     dS )a  Remove the given package name from the environment in prefix.

        This method ideally would not exist. The ideal approach is
        that in find_enviroment_deviations, the generated
        deviation could include "pruned" or "unnecessary" packages
        that are in the prefix but aren't needed for the
        spec. fix_environment_deviations would then remove any
        extra packages. In effect we'd always force the
        environment to be the fresh env we would install from
        scratch, given the spec.

        Args:
           prefix (str): environment path
           package (list of str): package names
           pip (bool): remove packages using pip

        Returns:
           None

        Nr   )rH   rN   packagespips       r   remove_packageszCondaManager.remove_packages   s	    , 	r   )NT)	rB   rC   rD   rE   r   rL   rO   rT   rX   r   r   r   r1   r1   X   s            ^,   ^&    ^&   ^  r   r1   c                       e Zd ZdZ	 	 ddZed             Zed             Zed             Zed             Z	ed             Z
ed	             Zed
             ZdS )CondaEnvironmentDeviationszDRepresents differences between actual and desired environment state.Fc                    || _         || _        || _        t          |          | _        t          |          | _        t          |          | _        t          |          | _        | j        r| j	        r| j        rJ dS dS )a  Construct a ``CondaEnvironmentDeviations``.

        Args:
          summary (str): the most immediate reason the environment deviates
          missing_packages (iterable of str): packages that aren't in the env
          wrong_version_packages (iterable of str): packages that are the wrong version
          broken (bool): True if it's broken for some other reason besides wrong packages
          unfixable (bool): True if fix_environment_deviations won't be able to solve it
        N)
_summary_broken
_unfixabler   _missing_packages_wrong_version_packages_missing_pip_packages_wrong_version_pip_packages	unfixableok)rH   summarymissing_packageswrong_version_packagesmissing_pip_packageswrong_version_pip_packagesbrokenrc   s           r   __init__z#CondaEnvironmentDeviations.__init__   s    "  #!&'7!8!8',-C'D'D$%*+?%@%@"+01K+L+L( EtwEt~EEEEEEEr   c                     t          | j                  dk    oOt          | j                  dk    o7t          | j                  dk    ot          | j                  dk    o| j         S )a  True if no deviations were found, environment exists and looks good.

        If the deviations are "ok" then
        ``CondaManager.fix_environment_deviations()`` would be
        expected to have no work to do and doesn't need to be
        called.

        r   )r7   rf   rg   rh   ri   r]   rH   s    r   rd   zCondaEnvironmentDeviations.ok   su     4())Q. +,,1)**a/ /00A5 		r   c                     | j         S )z6True if fix_environment_deviations can't resolve this.)r^   rm   s    r   rc   z$CondaEnvironmentDeviations.unfixable        r   c                     | j         S )zSummary description of status.)r\   rm   s    r   re   z"CondaEnvironmentDeviations.summary        }r   c                     | j         S )z-Iterable collection of missing package names.)r_   rm   s    r   rf   z+CondaEnvironmentDeviations.missing_packages   s     %%r   c                     | j         S )zGIterable collection of package names an unacceptable version installed.)r`   rm   s    r   rg   z1CondaEnvironmentDeviations.wrong_version_packages   s     ++r   c                     | j         S )z1Iterable collection of missing pip package names.)ra   rm   s    r   rh   z/CondaEnvironmentDeviations.missing_pip_packages   s     ))r   c                     | j         S )zKIterable collection of pip package names an unacceptable version installed.)rb   rm   s    r   ri   z5CondaEnvironmentDeviations.wrong_version_pip_packages  s     //r   N)FF)rB   rC   rD   rE   rk   propertyrd   rc   re   rf   rg   rh   ri   r   r   r   rZ   rZ      s        NN  F F F F8   X   X   X & & X& , , X, * * X* 0 0 X0 0 0r   rZ   c                     t          t          j        | |                    }t          d |          }t          d |          }fd}t	          ||          }t          |          S )Nc                     | d         dk    S )Nr    r   xs    r   <lambda>z_pretty_diff.<locals>.<lambda>      AaDCK r   c                     | d         dk    S )Nr   ?r   rz   s    r   r|   z_pretty_diff.<locals>.<lambda>  r}   r   c                     |                      d          rdz   | dd          z   S |                      d          rdz   | dd          z   S | S )Nz+    z- )
startswith)sindents    r   indent_morez!_pretty_diff.<locals>.indent_more  s^    << 	&=1QRR5((\\$ 	&=1QRR5((Hr   )r   difflibndifffiltermap)old_listnew_listr   diffr   s     `  r   _pretty_diffr     sz    h1122D ''..D''..D     {D!!D::r   c                      e Zd ZdZddZed             Zed             Zed             Zed	             Z	ed
             Z
e
j        d             Z
d Zd Zd Zed             Zed             Zed             Zd ZdS )CondaLockSetz,Represents a locked set of package versions.TNFc                     |J |J t          |          | _        t          t          j        |                    | _        || _        || _        || _        dS )aB  Construct a ``CondaLockSet``.

        The passed-in dict should be like:

        {
           "all" : [ "bokeh=0.12.4=1" ],
           "linux-64" : [ "libffi=1.2=0" ]
        }

        Args:
          packages_by_platform (dict): dict from platform to spec list
          platforms (list of str): platform list
        N)	r   _package_specs_by_platformr   r   sort_platform_list
_platforms_enabled_env_spec_hash_missing)rH   package_specs_by_platformrK   enabledenv_spec_hashmissings         r   rk   zCondaLockSet.__init__$  sa     )444$$$*23L*M*M'	 <Y G GHH+r   c                     | j         S )z,Platform list the lock set was resolved for.)r   rm   s    r   rK   zCondaLockSet.platforms;  ro   r   c                     | j         S )z0Whether locking is enabled for this environment.r   rm   s    r   r   zCondaLockSet.enabled@  rq   r   c                     | j          S )zWhether locking is disabled for this environment.

        (yes, this is just "not enabled" but this can be more readable sometimes)
        r   rm   s    r   disabledzCondaLockSet.disabledE  s     =  r   c                     | j         S )zWhether a lock set existed in the lock file.

        This says whether the lock set was loaded from anaconda-project-lock.yml
        or was just a default we made up on the fly.
        )r   rm   s    r   r   zCondaLockSet.missingM  s     }r   c                     | j         S )z2Hash of the env spec we created this lock set for.r   rm   s    r   r   zCondaLockSet.env_spec_hashV  s     ""r   c                 &    | j         J || _         d S r   r   )rH   values     r   r   zCondaLockSet.env_spec_hash[  s!     "***#r   c                 ^    | j         |j         k    o| j        |j        k    o| j        |j        u S )z3Determine if this lock set the same as another one.)r   r   r   )rH   others     r   equivalent_tozCondaLockSet.equivalent_toa  s:    
 .%2RR ,Ou//,MU^+	,r   c                 J   t          | j                                                  }|E|t          |j                                                  z   }t          t          |                    }t	          j        |          }g }|D ]}|g }n|j                            |g           }| j                            |g           }t          ||d          }|r|	||j        vr|                    d|z             n:|| j        vr|                    d|z             n|                    d|z             |	                    t          d |                     |rdg|z   }|g }n|j        }t          || j        d	          }	|	rd
g|	z   }	d                    |	|z             S )zA string showing the comparison between this lock set and another one.

        "old" can be None to mean diff vs. nothing.
        Nz    )r   z+   %s:z-   %s:z    %s:c                     | S r   r   rz   s    r   r|   z(CondaLockSet.diff_from.<locals>.<lambda>  s    1 r   z  packages:z  z  platforms:
)r   r   keysr   r   r   getr   r3   extendr   rK   join)
rH   oldr   packages_diffkeyr   r   r   old_platformsplatforms_diffs
             r   	diff_fromzCondaLockSet.diff_fromj  s   
 D388::;; 	#$s=BBDDEEEDD		??D +D11 	= 	=C G9==c2FF6::3CCH(6BBBD = :#S-K"K :!((S9999 ?? :!((S9999!((S999$$Sd%;%;<<< 	<*Om;M 	*MMMM%mT^DQQQ 	?,->Nyy-7888r   c                    || j         v sJ | j        sJ | j                            dg           }t	          j        |          d         }|t          j        v r+| j                            dg           }t          ||          }| j                            |g           }t          ||          }| j                            |g           }t          ||          S )z<Sequence of package spec strings for the requested platform.allr   unix)rK   r   r   r   r   parse_platformunix_platform_namesr.   )rH   platformsharedplatform_nameshared_unixshared_across_bitsper_platforms          r   package_specs_for_platformz'CondaLockSet.package_specs_for_platform  s    4>))))| 044UB??!0::1=I99 	G9==fbIIK1&+FFF!<@@PRSS-f6HII6::8RHH+FLAAAr   c                 8    | j                             dg           S )zSequence of pip packages.rW   )r   r   rm   s    r   pip_package_specszCondaLockSet.pip_package_specs  s     .225"===r   c                 b    | j         sJ |                     t          j                              S )z:Sequence of package spec strings for the current platform.)r   )supports_current_platformr   r   current_platformrm   s    r   "package_specs_for_current_platformz/CondaLockSet.package_specs_for_current_platform  s3     ----..	8R8T8T.UUUr   c                 D    | j         ot          j                    | j        v S )z5Whether we have locked deps for the current platform.)r   r   r   rK   rm   s    r   r   z&CondaLockSet.supports_current_platform  s!     |N	 : < < NNr   c                    t                      }| j        |d<   | j        
| j        |d<   t                      }| j        D ]}|                    |           ||d<   t                      }t          j        | j        	                                          D ]:}t                      }| j        |         D ]}|                    |           |||<   ;||d<   t          |           |S )z"JSON/YAML version of the lock set.lockedNr   rK   rV   )r   r   r   r   rK   r3   r   r   r   r   r	   )rH   	yaml_dictplatforms_listr   packages_dictrV   packages          r   to_jsonzCondaLockSet.to_json  s    !OO	"l	( 	<)-);Io&& 	, 	,H!!(++++!/	+%!4T5T5Y5Y5[5[\\ 	/ 	/H$H:8D ) )((((&.M(## -	*y)))r   )TNF)rB   rC   rD   rE   rk   rv   rK   r   r   r   r   setterr   r   r   r   r   r   r   r   r   r   r   r   "  sk       66       .   X   X ! ! X!   X # # X# $ $ $
, , ,-9 -9 -9^B B B( > > X> V V XV
 O O XO    r   r   r   )!rE   
__future__r   abcr   r   copyr   r   anaconda_project.yaml_filer   r   r	   #anaconda_project.internal.metaclassr
   anaconda_project.internalr   r   r2   r!   r(   r*   r.   r5   r9   r?   	ExceptionrA   r1   objectrZ   r   r   r   r   r   <module>r      s	   . - & & & & & & ' ' ' ' ' ' ' '        ] ] ] ] ] ] ] ] ] ] > > > > > > / / / / / / - - - - - - 	 	 	 	    W W W) ) )! ! !$ $ $ $	 	 	 	 		 	 	 	_ _ _ _ _>>'** _ _ _DJ0 J0 J0 J0 J0 J0 J0 J0Z  6r r r r r6 r r r r rr   