ó
¼S]c           @@ sz  d  Z  d d l m Z m Z y@ d d l Z d d l m Z d d l m	 Z	 d d l m
 Z
 WnP e k
 r® d d l j Z d d l m Z d d l m	 Z	 d d l m
 Z
 n Xd d l Z d d l Z d d l Z d d l Z d d l Z d d l m Z d d l m Z d d	 l m Z e Z e	 Z e
 Z d
 d „ Z d „  Z d „  Z  d d „ Z" d „  Z# d e$ f d „  ƒ  YZ% d S(   s#   YAML file loading and manipulation.i    (   t   absolute_importt   print_functionN(   t	   YAMLError(   t   CommentedMap(   t   CommentedSeq(   t   makedirs_ok_if_exists(   t   rename_over_existing(   t	   is_strings   utf-8c      	   C@ s   |  d t  t j ƒ  ƒ } zP t j | d | ƒ ( } | j | ƒ | j ƒ  | j ƒ  Wd  QXt | |  ƒ Wd  y t	 j
 | ƒ Wn t t f k
 r— n XXd  S(   Ns   .tmp-t   w(   t   strt   uuidt   uuid4t   codecst   opent   writet   flusht   closeR   t   ost   removet   IOErrort   OSError(   t   patht   contentst   encodingt   tmpt   file(    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   _atomic_replace-   s    
c         C@ sN   |  j  ƒ  d k r i  St t j t j j ƒ s4 t ‚ t j |  d t j ƒSd  S(   Nt    t   Loader(   t   stript
   issubclasst   ryamlt   RoundTripLoadert   constructort   SafeConstructort   AssertionErrort   load(   R   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   _load_string<   s    c         C@ s   t  j |  d t  j ƒS(   Nt   Dumper(   R   t   dumpt   RoundTripDumper(   t   yaml(    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   _dump_stringH   s    c         C@ sù   | d  k r t |  ƒ } n  y t j | d t j ƒWn t k
 r¶ } t d d t j ƒt d t	 | ƒ d t j ƒt d d t j ƒt | d t j ƒt
 d t	 | ƒ ƒ ‚ n Xt j j | ƒ sè t j j | ƒ } t | ƒ n  t | | ƒ d  S(   NR   s=   ruamel.yaml bug; it failed to parse a file that it generated.R   s     the parse error was: s   Generated file was:sF   Bug in ruamel.yaml library; failed to parse a file that it generated: (   t   NoneR*   R   R$   R    R   t   printt   syst   stderrR	   t   RuntimeErrorR   R   t   isfilet   dirnameR   R   (   R)   t   filenameR   t   eR1   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt
   _save_fileL   s    c         C@ sƒ   t  |  d ƒ r |  j j ƒ  n  t |  t ƒ rL xN |  D] } t | ƒ q5 Wn3 t |  t ƒ r x! |  j ƒ  D] } t | ƒ qh Wn  d  S(   Nt   fa(   t   hasattrR5   t   set_block_stylet
   isinstancet   listt   _block_style_all_nodest   dictt   values(   R)   t   elementt   value(    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyR:   a   s    t   YamlFilec           B@ s  e  Z d  Z d Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 e
 d „  ƒ Z e
 d	 „  ƒ Z e
 d
 „  ƒ Z e
 d „  ƒ Z e
 d „  ƒ Z e
 d „  ƒ Z e
 d „  ƒ Z d „  Z d „  Z e d „  ƒ Z d „  Z d „  Z d „  Z d „  Z d d „ Z e
 d „  ƒ Z RS(   s  Abstract YAML file, base class for ``ProjectFile`` and ``LocalStateFile``.

    Be careful with creating your own instance of this class,
    because you have to think about when other code might load or
    save in a way that conflicts with your loads and saves.

    s   # yaml file
__dummy__: dummyc         C@ s)   | |  _  d |  _ d |  _ |  j ƒ  d S(   s“  Load a YamlFile with the given filename.

        Raises an exception on an IOError, but if the file is
        missing this succeeds (then creates the file if and when
        you call ``save()``).

        If the file has syntax problems, this sets the
        ``corrupted`` and ``corrupted_error_message`` properties,
        and attempts to modify the file will raise an
        exception.

        R   i    N(   R2   t   _previous_contentt   _change_countR$   (   t   selfR2   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   __init__z   s    			c         C@ sé  t  |  _ d |  _ d |  _ d |  _ |  j d |  _ yR t j |  j	 d d ƒ  } | j
 ƒ  } Wd QXt | ƒ |  _ t |  j ƒ |  _ Wnå t k
 r¿ } | j t j k r¶ d |  _ qn| ‚ n¯ t k
 rm} t |  _ t | ƒ |  _ t | d d ƒ } | d k	 ra| j d k	 r1| j d k r1| j |  _ n  | j d k	 ra| j d k ra| j |  _ qan  d |  _ n X|  j d k rå|  j r•t ƒ  |  _ qå|  j ƒ  |  _ |  j |  j ƒ t |  j ƒ |  j ƒ  såt |  j ƒ |  _ qån  d S(   s)  Reload the file from disk, discarding any unsaved changes.

        If the file has syntax problems, this sets the
        ``corrupted`` and ``corrupted_error_message`` properties,
        and attempts to modify the file will raise an
        exception.

        Returns:
            None
        i   t   rs   utf-8Nt   problem_marki    (   t   Falset
   _corruptedR+   t   _corrupted_error_messaget   _corrupted_maybe_linet   _corrupted_maybe_columnRA   R   R   R2   t   readR%   t   _yamlR*   R@   R   t   errnot   ENOENTR   t   TrueR	   t   getattrt   linet   columnR;   t   _load_templatet   _fill_default_contentR:   t   _save_default_content(   RB   R   R   R3   t   mark(    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyR$   Œ   s@    							c         C@ s>   |  j  d  k	 s t ‚ t |  j  j ƒ  ƒ } | j d d  ƒ | S(   Nt	   __dummy__(   t   templateR+   R#   R%   t   lstript   pop(   RB   t   result(    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyRS   É   s    c         C@ s   d  S(   N(    (   RB   RX   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyRT   Ô   s    c         C@ s   t  S(   sH   Override to change whether we consider a default, unmodified file dirty.(   RO   (   RB   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyRU   ×   s    c         C@ s,   |  j  r( t d |  j |  j f ƒ ‚ n  d  S(   Ns'   Cannot modify corrupted YAML file %s
%s(   RG   t
   ValueErrorR2   RH   (   RB   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   _throw_if_corruptedÛ   s    	c         C@ s   t  j j |  j ƒ S(   s   Basename of the filename.(   R   R   t   basenameR2   (   RB   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyR^   à   s    c         C@ s   |  j  S(   só   Get whether the file is corrupted.

        A corrupted file has a syntax error so we can't modify and save it.
        See ``corrupted_error_message`` for what's wrong with it.

        Returns:
            True if file is corrupted.
        (   RG   (   RB   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt	   corruptedå   s    
c         C@ s   |  j  S(   sÆ   Get the error message if file is corrupted, or None if it isn't.

        Use this to display the problem if the file is corrupted.

        Returns:
            Corruption message or None.
        (   RH   (   RB   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   corrupted_error_messageñ   s    	c         C@ s   |  j  S(   s}   Get the line number for syntax error, or None if unavailable.

        Returns:
            Corruption line or None.
        (   RI   (   RB   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   corrupted_maybe_lineü   s    c         C@ s   |  j  S(   sz   Get the column for syntax error, or None if unavailable.

        Returns:
            Corruption column or None.
        (   RJ   (   RB   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   corrupted_maybe_column  s    c         C@ s   |  j  S(   sB  Get the number of times we've resynced with the file on disk (reloaded or saved changes).

        This is used for cache invalidation. If a cached value becomes invalid whenever
        ``change_count`` increments, then the cached value will be recomputed whenever
        we save new changes or reload the file.
        (   RA   (   RB   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   change_count  s    c         C@ s   |  j  t |  j ƒ k S(   s"   Get whether changes are all saved.(   R@   R*   RL   (   RB   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   has_unsaved_changes  s    c         C@ s   |  j  d |  _  d S(   s¹   Apply any in-memory changes as if we'd saved, but don't actually save.

        This is used to "try out" a change before we save it. We can load()
        to undo our changes.
        i   N(   RA   (   RB   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   use_changes_without_saving  s    c         C@ s^   |  j  ƒ  t |  j ƒ } | |  j k rZ t |  j |  j | ƒ |  j d |  _ | |  _ n  d S(   s    Write the file to disk, only if any changes have been made.

        Raises ``IOError`` if it fails for some reason.

        Returns:
            None
        i   N(   R]   R*   RL   R@   R4   R2   RA   (   RB   R   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   save&  s    
c         C@ sO   t  | ƒ r | f Sy t d „  | Dƒ ƒ SWn t k
 rJ t d ƒ ‚ n Xd  S(   Nc         s@ s   |  ] } | Vq d  S(   N(    (   t   .0R=   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pys	   <genexpr><  s    s9   YAML file path must be a string or an iterable of strings(   R   R9   t	   TypeErrorR\   (   t   clsR   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   _path6  s    c         C@ sN   |  j  } x> | D]6 } | | k rB t | | t ƒ rB | | } q d  Sq W| S(   N(   RL   R8   R;   R+   (   RB   t   piecest   currentt   p(    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   _get_dict_or_none@  s    	c         C@ sp   |  j  ƒ  |  j } xV | D]N } | | k s@ t | | t ƒ r^ t ƒ  | | <t | | ƒ n  | | } q W| S(   N(   R]   RL   R8   R;   R   R:   (   RB   Rk   Rl   Rm   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   _ensure_dicts_at_pathI  s    
	 c         C@ s>   |  j  ƒ  |  j | ƒ } |  j | d  ƒ } | | | d <d S(   s6  Set a single value at the given path.

        Overwrites any existing value at the path.

        This method does not save the file, call ``save()`` to do that.

        Args:
            path (str or list of str): single key, or list of nested keys
            value: any YAML-compatible value type
        iÿÿÿÿN(   R]   Rj   Ro   (   RB   R   R>   t   existing(    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt	   set_valueW  s    
c         C@ s\   |  j  ƒ  |  j | ƒ } |  j | d  ƒ } | d } | d k	 rX | | k rX | | =n  d S(   sÓ   Remove a single value at the given path.

        This method does not save the file, call ``save()`` to do that.

        Args:
            path (str or list of str): single key, or list of nested keys
        iÿÿÿÿN(   R]   Rj   Rn   R+   (   RB   R   Rp   t   key(    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   unset_valueh  s    

c         C@ sJ   |  j  | ƒ } |  j | d  ƒ } | d k r2 | S| j | d | ƒ Sd S(   s
  Get a single value from the YAML file.

        Args:
            path (str or list of str): single key, or list of nested keys
            default: any YAML-compatible value type

        Returns:
            the value from the file or the provided default
        iÿÿÿÿN(   Rj   Rn   R+   t   get(   RB   R   t   defaultRp   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt	   get_valuey  s
    
c         C@ s   |  j  ƒ  |  j S(   s+   Get the outermost value from the yaml file.(   R]   RL   (   RB   (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   rootŠ  s    
N(   t   __name__t
   __module__t   __doc__RX   RC   R$   RS   RT   RU   R]   t   propertyR^   R_   R`   Ra   Rb   Rc   Rd   Re   Rf   t   classmethodRj   Rn   Ro   Rq   Rs   R+   Rv   Rw   (    (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyR?   m   s0   		=						
		
					(&   Rz   t
   __future__R    R   t   ruamel_yamlR   t   ruamel_yaml.errorR   t   ruamel_yaml.commentsR   R   t   ImportErrort   ruamel.yamlR)   t   ruamel.yaml.errort   ruamel.yaml.commentsR   RM   R   R-   R
   t"   anaconda_project.internal.makedirsR   t    anaconda_project.internal.renameR   t$   anaconda_project.internal.py2_compatR   t
   _YAMLErrort   _CommentedMapt   _CommentedSeqR   R%   R*   R+   R4   R:   t   objectR?   (    (    (    s9   lib/python2.7/site-packages/anaconda_project/yaml_file.pyt   <module>   s8   			