o
    ?߱i4>                     @   s  d dl Z d dlZd dlZd 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 d dlmZmZmZmZmZ d dlZd dlZd dlmZmZmZ zd dlZW n eyc   dZY nw zd dlZW n eyu   dZY nw d dlmZ d dl m!Z!m"Z" d	d
gZ#dee$ef de	e$ef fddZ%dej&de	e$ef dej'j(fddZ)deee$ef ee ef dee	e$ef ee ef fddZ*e+e	e) e,ddd  e,ddd  dd Z-dd Z.dd  Z/d!Z0	 d"d# Z1ed$d% Z2G d&d
 d
Z3dS )'    N)OrderedDict)contextmanager)deepcopy)AnyDictListTupleUnion)
DictConfig
ListConfig	OmegaConf)PathManager)LazyCallget_default_paramsr   
LazyConfigdreturnc                 C   s   t t|  dd dS )Nc                 S   s   | d S )Nr    )xr   r   Z/data/cameron/vidgen/cosmos-predict2.5/cosmos_predict2/_src/imaginaire/lazy_config/lazy.py<lambda>2       zsort_dict.<locals>.<lambda>)key)r   sorteditems)r   r   r   r   	sort_dict1   s   r   dumperdatac                 C   s   |  d| S )Nztag:yaml.org,2002:map)represent_mappingr   )r   r   r   r   r   dict_representer5   s   r   objc                 C   s<   t | trtdd |  D S t | trdd | D S | S )Nc                 S   s   i | ]	\}}|t |qS r   sort_recursive).0kvr   r   r   
<dictcomp>;   s    z"sort_recursive.<locals>.<dictcomp>c                 S   s   g | ]}t |qS r   r!   )r#   itemr   r   r   
<listcomp>=   s    z"sort_recursive.<locals>.<listcomp>)
isinstancedictr   r   listr    r   r   r   r"   9   s
   

r"   addc                  G   s   t | S Nsumvalsr   r   r   r   C   r   r   subtractc                  G   s   | d t | dd   S )Nr      r/   r1   r   r   r   r   D   s    c                 C   sT   t | tr||  |  D ]}t|| qdS t | tr&| D ]	}t|| qdS dS )z:
    Apply func recursively to all DictConfig in cfg.
    N)r)   r
   values_visit_dict_configr   )cfgfuncr%   r   r   r   r6   G   s   

r6   c              
   C   sp   t | d}| }W d    n1 sw   Y  zt| W d S  ty7 } z	td|  d|d }~ww )NrConfig file z has syntax error!)r   openreadastparseSyntaxError)filenamefcontenter   r   r   _validate_py_syntaxT   s   
rD   c                 C   s   t | trt| ddidS | S )Nallow_objectsTflags)r)   r*   r
   r,   r   r   r   _cast_to_config^   s   
rH   zdetectron2._cfg_loaderc                 C   s(   t tt d d  d tj|  S )N   .)_CFG_PACKAGE_NAMEstruuiduuid4ospathbasename)r@   r   r   r   _random_package_namek   s   (rR   c                  #   s6    t jdd  d fdd	} | t _| V  t _dS )	a  
    Enhance relative import statements in config files, so that they:
    1. locate files purely based on relative location, regardless of packages.
       e.g. you can import file without having __init__
    2. do not cache modules globally; modifications of module states has no side effect
    3. support other storage system through PathManager, so config files can be in the cloud
    4. imported dict are turned into omegaconf.DictConfig automatically
    c           	      S   s   d dd}t|st|tj| }t|d D ]}tj|}q|d}|dD ]	}tj	||}q-|
ds@|d7 }t|sk|d td  }t|r]td| d| td| d	|  d
| d|S )Nz
Relative import of directories is not allowed within config files.
Within a config file, relative import can only import other config files.

 r4   rJ   .pyzCannot import from zCannot import name z from : z does not exist.)replacelenImportErrorrO   rP   dirnamerangelstripsplitjoinendswithr   isfileisdir)	Zoriginal_fileZrelative_import_pathlevelZrelative_import_errcur_file_cur_namepartZcur_file_no_suffixr   r   r   find_relative_file|   s*   



z)_patch_import.<locals>.find_relative_fileNr   r   c                    s   |dkri|d uri| ddpdtri |d | |}t| tjjt|d |d}tj	|}||_
t|}| }	W d    n1 sGw   Y  tt|	|d|j |D ]} t|j|  }
|
|j| < qX|S | ||||dS )Nr   __package__ __file__)originexec)fromlistrb   )get
startswithrK   rD   	importlib	machinery
ModuleSpecrR   utilmodule_from_specrj   r   r;   r<   rl   compile__dict__rH   )nameglobalslocalsrm   rb   rc   specmodulerA   rB   valrg   Z
old_importr   r   
new_import   s   &
z!_patch_import.<locals>.new_import)NNr   r   )builtins
__import__)r~   r   r}   r   _patch_importp   s   

r   c                   @   s   e Zd ZdZeddededeeedf f fddZeddededeeedf f fdd	Z	eded
efddZ
eded
efddZdS )r   z
    Provide methods to save, load, and overrides an omegaconf config object
    which may contain definition of lazily-constructed objects.
    Nr@   keys.c                 C   sN   t  d }|d jj}|dksJ dtj|}tj|| } t	| |S )a  
        Similar to :meth:`load()`, but load path relative to the caller's
        source file.

        This has the same functionality as a relative import, except that this method
        accepts filename as a string, so more characters are allowed in the filename.
        r4   r   z<string>zload_rel Unable to find caller)
inspectstackf_codeco_filenamerO   rP   rZ   r^   r   load)r@   r   caller_frameZcaller_fnameZ
caller_dirr   r   r   load_rel   s   	zLazyConfig.load_relc              	      sj  |du}|  dd} tj| d dvrtd|  d| drdt|  t 1 | t| d	}t	
| }| }W d   n1 sDw   Y  tt|| d
| W d   n1 s\w   Y  | n#t	
| }t|}W d   n1 syw   Y  tj|ddid |rt|trt | S t fdd|D S | drtdd   D ddid  S )a  
        Load a config file.

        Args:
            filename: absolute path or relative path w.r.t. the current working directory
            keys: keys to load and return. If not given, return all keys
                (whose values are config objects) in a dict.
        Nz/.//r4   )rU   z.yamlz.ymlr:   z! has to be a python or yaml file.rU   )rj   rh   rl   rE   TrF   c                 3   s    | ]	}t  | V  qd S r.   )rH   )r#   aretr   r   	<genexpr>   s    z"LazyConfig.load.<locals>.<genexpr>c                 S   s4   i | ]\}}t |tttfr|d s|t|qS )rd   )r)   r
   r   r*   ro   rH   )r#   rw   valuer   r   r   r&      s    z#LazyConfig.load.<locals>.<dictcomp>)rW   rO   rP   splitext
ValueErrorr_   rD   r   rR   r   r;   r<   rl   ru   yamlunsafe_loadr   creater)   rL   rH   tupler
   r   )r@   r   Zhas_keysZmodule_namespacerA   rB   r    r   r   r   r      s@   




zLazyConfig.loadr   c                 C   s  t t}zt| } W n	 ty   Y nw z(t|d}t| | W d   n1 s-w   Y  |	d| d W |S  ty
 } z|
d| d| d trz,t|d}ttj| dd	| |	d
| d W d   n1 szw   Y  W nw ty } zd|
d| d| d trz*t|d}tt| | W d   n1 sw   Y  |	d| d W n% ty } z|
d| d| d W Y d}~nd}~ww |
d |W Y d}~nd}~ww W Y d}~|S W Y d}~|S W Y d}~|S d}~ww )a  
        Saves a Config object to a file using pickle serialization. This method is typically used
        when the configuration object contains complex objects, such as lambdas, that are not supported by
        simpler serialization methods like YAML. The function attempts to create a deep copy of the configuration
        object before serialization to ensure that the original object remains unmodified.

        Args:
            cfg: A Config object to be serialized and saved.
            filename: The path and name of the file where the configuration should be saved. The function
                      assumes the file extension indicates a pickle format (e.g., .pkl).

        Returns:
            str: The filename to which the configuration was saved. This can be used to verify the file location
                 or log the outcome.

        Notes:
            - The function logs a warning if the configuration is successfully saved using pickle.
            - If saving fails, an error is logged with the exception details.
        wbNz Config is saved using pickle at rJ   zFailed to save config to rV   z$. Trying dill or cloudpickle insteadT)recursezConfig is saved using dill at z%Config is saved using cloudpickle at z5cloudpickle is not available. Cannot save the config.)logging	getLogger__name__r   	Exceptionr   r;   pickledumpwarningerrordill_pickledumpscloudpickle)r7   r@   loggerrA   rC   r   r   r   save_pkl   sZ   
$


 
 zLazyConfig.save_pklc                    s   t tzt| } W n	 ty   Y nw dd   fddt| }t|ddid}|}tj	|dd}t
|}t|d	}tj||d
d W d   n1 sUw   Y  d| d |S )a-  
        Saves a Config object to a file using YAML serialization. This method is beneficial when the configuration object's content needs to be human-readable and easily editable. YAML is suitable for configurations that do not contain complex types like lambdas, which must be handled differently. The function converts unserializable items to strings before saving to ensure compatibility with YAML serialization.

        Args:
            cfg: A Config object to be serialized and saved. It handles both DictConfig and ListConfig types.
            filename: The path and name of the file where the configuration should be saved. The function does not require a specific file extension but typically uses '.yaml'.

        Returns:
            str: The filename to which the configuration was saved. This can be used to verify the file location or log the outcome.

        Notes:
            - The function logs a warning if the configuration is successfully saved using YAML.
            - If saving fails, an error is logged with the exception details.
        c              
   S   s8   zt |  W dS  ty } zW Y d }~dS d }~ww )NTF)r   to_yamlr   )r'   rC   r   r   r   is_serializableI  s   
z-LazyConfig.save_yaml.<locals>.is_serializablec           	         s   t | trb|  D ]V\}}t |ttfrQzd|v r0t|d }| D ]\}}||vr/|||< q#W n tyK } zd|  W Y d }~nd }~ww | q	 |s_|d ur_t|| |< q	| S t | trt| D ]\}}t |ttfr{| qk |s|d urt|| |< qk| S t	d)N_target_z'Failed to add default argument values: z0Input config must be a DictConfig or ListConfig.)
r)   r
   r   r   r   r   r   rL   	enumerateNotImplementedError)	configr   r   default_paramsZdefault_keyZ	default_vrC   ir'   r   r   serialize_configr   r   r   Q  s8   




z.LazyConfig.save_yaml.<locals>.serialize_configrE   T)rB   rG   )resolvewF)default_flow_styleNz#Config is saved using omegaconf at rJ   )r   r   r   r   r   attrsasdictr
   r   to_containerr"   r;   r   r   r   )r7   r@   config_dictZconfig_omegaconfZsorted_configrA   r   r   r   	save_yaml2  s$   

zLazyConfig.save_yamlr.   )r   
__module____qualname____doc__staticmethodrL   r	   r   r   r   r   r   r   r   r   r   r      s    ((54)4r=   r   rp   r   r   rO   r   rM   collectionsr   
contextlibr   copyr   typingr   r   r   r   r	   r   r   	omegaconfr
   r   r   dillr   rY   r   Z3cosmos_predict2._src.imaginaire.lazy_config.file_ior   5cosmos_predict2._src.imaginaire.lazy_config.lazy_callr   r   __all__rL   r   DumpernodesMappingNoder   r"   add_representerregister_new_resolverr6   rD   rH   rK   rR   r   r   r   r   r   r   <module>   sV   "$>

@