U
    b%                     @   sp  d dl mZmZ d dlmZ d dlmZ d dlZd dlZd dl	Z	d dl
mZ d dlmZmZ d dlmZ d dlmZ d d	lmZmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlmZ d dl m!Z! d dl"m#Z# zd dl$m%Z%m&Z& W n& e'k
r   d dl(m%Z%m&Z& Y nX dZ)dd Z*dd Z+d$ddZ,dd Z-dd Z.G dd deZ/d%d d!Z0G d"d# d#e1Z2dS )&    )absolute_importprint_function)OrderedDict)chainN)context)EnvironmentFileEmptyEnvironmentFileNotFound)common)odict)yaml_safe_loadyaml_safe_dump)
PrefixData)download_text)CONDA_SESSION_SCHEMES)PackageType)	MatchSpec)PrefixGraph)History)concatvgroupby)namedependenciesprefixchannels	variablesc                    s"  g }| r|   ni }|  D ] }|tkr|| || q|r|d}t|dkr\dnd}t|dkrpdnd}tdj|||d |D ]}td	| qtd | d
g }t	
d  fddtfdd|D }	|D ]8}
t|
trd|
kr|	std |d
 dd  qq|S )z8Check for unknown keys, remove them and print a warning.filename   Zareiss zn
EnvironmentSectionNotValid: The following section{plural} on '{filename}' {verb} invalid and will be ignored:)r   pluralverbz - {}r   z[<>~\s=]c                    s   d  | d  dkS )Npipr   z::)split)dep)depsplit ,lib/python3.8/site-packages/conda_env/env.py<lambda>8       zvalidate_keys.<locals>.<lambda>c                 3   s    | ]}t |ts |V  qd S N)
isinstancedict).0_)is_pipr&   r'   	<genexpr>9   s     
 z validate_keys.<locals>.<genexpr>r"   aE  Warning: you have pip-installed dependencies in your environment file, but you do not list pip itself as one of your conda dependencies.  Conda may not use the correct pip to install your packages, and they may end up in the wrong place.  Please add an explicit pip dependency.  I'm adding one for you, but still nagging you.r   )copykeys
VALID_KEYSappendpopgetlenprintformatrecompileanyr+   r,   insert)datakwargsZinvalid_keysZnew_datakeyr   r!   r    depsZ	lists_pipr$   r&   )r%   r/   r'   validate_keys"   s8    

  
rB   c              	   C   sl   ddg}|D ]2}zt tj| |W   S  tk
r<   Y qX q| }tj| } | |krq\qt|d dS )z=Load and return an ``Environment`` from a given ``directory``zenvironment.ymlzenvironment.yamlr   N)	from_fileospathjoinr   dirname)Z	directoryfilesfZold_directoryr&   r&   r'   load_from_directoryF   s    rJ   Fc                 C   sd  t |dd}| }|rNt| }dd | D }t| |ttj||dS t	t
| j}	tdd |	}
tt|
dd	|
tjd	|
tjd	d
d d}tt|
tjd	|
tjd	|
tjd	dd d}|rdd |D }ndd |D }|r|ddd |D i ttj}|sR|D ]$}|jj}||kr,|d| q,t| ||||dS )af  
        Get environment object from prefix
    Args:
        name: The name of environment
        prefix: The path of prefix
        no_builds: Whether has build requirement
        ignore_channels: whether ignore_channels
        from_history: Whether environment file should be based on explicit specs in history

    Returns:     Environment object
    T)Zpip_interop_enabledc                 S   s   g | ]}t |qS r&   )str)r-   packager&   r&   r'   
<listcomp>i   s     z$from_environment.<locals>.<listcomp>)r   r   r   r   r   c                 S   s   | j S r*   )Zpackage_typexr&   r&   r'   r(   n   r)   z"from_environment.<locals>.<lambda>Nr&   c                 S   s   | j S r*   r   rN   r&   r&   r'   r(   s   r)   )r@   c                 S   s   | j S r*   rP   rN   r&   r&   r'   r(   z   r)   c                 S   s   g | ]}d  |j|jfqS =)rF   r   versionr-   ar&   r&   r'   rM   }   s     c                 S   s"   g | ]}d  |j|j|jfqS rQ   )rF   r   rS   ZbuildrT   r&   r&   r'   rM      s     r"   c                 S   s   g | ]}d |j |jf qS )z%s==%s)r   rS   rT   r&   r&   r'   rM      s     r   )r   Zget_environment_env_varsr   Zget_requested_specs_mapvaluesEnvironmentlistr   r   tupler   Ziter_recordsZgraphr   sortedr   r6   r   ZNOARCH_GENERICZNOARCH_PYTHONZVIRTUAL_PYTHON_WHEELZVIRTUAL_PYTHON_EGG_MANAGEABLEZVIRTUAL_PYTHON_EGG_UNMANAGEABLEr4   Zchannelcanonical_namer=   )r   r   Z	no_buildsZignore_channelsZfrom_historyZpdr   historyrA   ZprecsZgrouped_precsZconda_precsZ	pip_precsr   r   Zprecr[   r&   r&   r'   from_environmentW   sN     



r]   c                 K   sX   t | }|d}|dkr"t|t||}|dk	rN| D ]\}}|||< q<tf |S )z>Load and return a ``Environment`` from a given ``yaml string``r   N)r   r6   r   rB   itemsrW   )yamlstrr?   r>   r   r@   valuer&   r&   r'   	from_yaml   s    


ra   c              	   C   s   |  ddd }|tkr"t| }nbtj| s8t| nLt| d<}| }z|	d}W n t
k
rx   |	d}Y nX W 5 Q R X t|| dS )Nz://r   r   rbutf-8zutf-16)r   )r#   r   r   rD   rE   existsr   openreaddecodeUnicodeDecodeErrorra   )r   Z
url_schemer_   fpZyamlbr&   r&   r'   rC      s    

rC   c                       s,   e Zd Z fddZdd Zdd Z  ZS )Dependenciesc                    s$   t t| j|| || _|   d S r*   )superrj   __init__rawparse)selfrm   argsr?   	__class__r&   r'   rl      s    zDependencies.__init__c                 C   s   | j s
d S | dg i | j D ].}t|tr8| | q| d t| qd| kr| d sd| d= tdd | d D s| d d d S )NZcondar"   c                 s   s   | ]}t |jd kV  qdS )r"   N)r   r   )r-   r   r&   r&   r'   r0      s     z%Dependencies.parse.<locals>.<genexpr>)rm   updater+   r,   r4   r	   Zarg2specr<   )ro   liner&   r&   r'   rn      s    

zDependencies.parsec                 C   s   | j | |   d S r*   )rm   r4   rn   )ro   Zpackage_namer&   r&   r'   add   s    zDependencies.add)__name__
__module____qualname__rl   rn   ru   __classcell__r&   r&   rq   r'   rj      s   rj   c                 c   sb   t  }|j}|dkr6| D ]}||kr|| |V  qn(| D ]"}||}||kr:|| |V  q:dS )a   Return only unique elements of a sequence
    >>> tuple(unique((1, 2, 3)))
    (1, 2, 3)
    >>> tuple(unique((1, 2, 1, 3)))
    (1, 2, 3)
    Uniqueness can be defined by key keyword
    >>> tuple(unique(['cat', 'mouse', 'dog', 'hen'], key=len))
    ('cat', 'mouse')
    N)setru   )seqr@   seenZseen_additemvalr&   r&   r'   unique   s    

r   c                   @   sB   e Zd ZdddZdd Zdd Zddd	Zdd
dZdd ZdS )rW   Nc                 C   s8   || _ || _|| _t|| _|| _|d kr.g }|| _d S r*   )r   r   r   rj   r   r   r   )ro   r   r   r   r   r   r   r&   r&   r'   rl      s    
zEnvironment.__init__c                 C   s   t tt|| jf| _d S r*   )rX   r   r   from_iterabler   )ro   r   r&   r&   r'   add_channels   s    zEnvironment.add_channelsc                 C   s
   g | _ d S r*   )r   )ro   r&   r&   r'   remove_channels   s    zEnvironment.remove_channelsc                 C   sr   t d| jfg}| jr | j|d< | jr2| jj|d< | jrB| j|d< | jrR| j|d< |d kr^|S |t	| d S )Nr   r   r   r   r   )
r
   r   r   r   rm   r   r   writejsondumps)ro   streamdr&   r&   r'   to_dict   s    


zEnvironment.to_dictc                 C   sV   |   }t|}|d kr|S z|t|dd W n tk
rP   || Y nX d S )Nrc   )encoding)r   r   r   bytes	TypeError)ro   r   r   outr&   r&   r'   to_yaml  s    zEnvironment.to_yamlc              	   C   s(   t | jd}| j|d W 5 Q R X d S )Nwb)r   )re   r   r   )ro   ri   r&   r&   r'   save  s    zEnvironment.save)NNNNNN)N)N)	rv   rw   rx   rl   r   r   r   r   r   r&   r&   r&   r'   rW      s         



rW   )FFF)N)3Z
__future__r   r   collectionsr   	itertoolsr   rD   r:   r   Zconda.base.contextr   Zconda.exceptionsr   r   Z	conda.clir	   Zconda.common.compatr
   Zconda.common.serializer   r   Zconda.core.prefix_datar   Z"conda.gateways.connection.downloadr   Z!conda.gateways.connection.sessionr   Zconda.models.enumsr   Zconda.models.match_specr   Zconda.models.prefix_graphr   Zconda.historyr   Zcytoolz.itertoolzr   r   ImportErrorZconda._vendor.toolz.itertoolzr3   rB   rJ   r]   ra   rC   rj   r   objectrW   r&   r&   r&   r'   <module>   s<   $
6
