o
    ci-                     @   s   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Zd dlZd dl	m
Z
 d dlmZmZ e
dddZe
dd	 Zd
d ZG dd dZe ZdS )    )deepcopy)partialN)DeveloperAPI)
force_listmerge_dictsc                 K   s  |du rt | ttfr| }d} nt | trt || r|S zt|}W n	 ty+   Y nw t |trJ|dd}|du rBt | trB| }|}|| n|}|du rYd|v rY|d}|}t|dg }|du r| durt	| dr| j
dur|g krt	| jd dr| jd j
du s| jd j
| j
ur| j
}t |trt||j}t|jfi |}i }n| }nt| |}|durn|du s|du r|S t|r|}nt |trtd|rt| |g|R i |S t|}t |trt| |S zt| t|}W |S  tjy   Y nw |dd	kr2|dd
\}}	zt|}
t|
|	}W n t t!t"fy1   Y nw |du rt | trEt#d| dzt| j$}
t|
|}W n0 t t!t"fy   zt| j$j%}t&||gd}
t|
|}W n t t!t"fy   Y nw Y nw |du rt#d| d| j$ d| j' d|st(d)|z	||i |}W n  t(y } zt*d|j+d rW Y d}~dS |d}~ww t|j'dkrt |t |tr|jn|sJ |S )a  Uses the given config to create an object.

    If `config` is a dict, an optional "type" key can be used as a
    "constructor hint" to specify a certain class of the object.
    If `config` is not a dict, `config`'s value is used directly as this
    "constructor hint".

    The rest of `config` (if it's a dict) will be used as kwargs for the
    constructor. Additional keys in **kwargs will always have precedence
    (overwrite keys in `config` (if a dict)).
    Also, if the config-dict or **kwargs contains the special key "_args",
    it will be popped from the dict and used as *args list to be passed
    separately to the constructor.

    The following constructor hints are valid:
    - None: Use `cls` as constructor.
    - An already instantiated object: Will be returned as is; no
        constructor call.
    - A string or an object that is a key in `cls`'s `__type_registry__`
        dict: The value in `__type_registry__` for that key will be used
        as the constructor.
    - A python callable: Use that very callable as constructor.
    - A string: Either a json/yaml filename or the name of a python
        module+class (e.g. "ray.rllib. [...] .[some class name]")

    Args:
        cls: The class to build an instance for (from `config`).
        config (Optional[dict, str]): The config dict or type-string or
            filename.

    Keyword Args:
        kwargs: Optional possibility to pass the constructor arguments in
            here and use `config` as the type-only info. Then we can call
            this like: from_config([type]?, [**kwargs for constructor])
            If `config` is already a dict, then `kwargs` will be merged
            with `config` (overwriting keys in `config`) after "type" has
            been popped out of `config`.
            If a constructor of a Configurable needs *args, the special
            key `_args` can be passed inside `kwargs` with a list value
            (e.g. kwargs={"_args": [arg1, arg2, arg3]}).

    Returns:
        any: The object generated from the config.
    Ntype_args__default_constructor__r   Fz\.(yaml|yml|json)$.   zFull classpath specifier (zS) must be a valid full [module].[class] string! E.g.: `my.cool.module.MyCoolClass`.)fromlistzString specifier (z@) must be a valid filename, a [module].[class], a class within 'z', or a key into z.__type_registry__!z/Invalid type '{}'. Cannot create `from_config`.z Can't instantiate abstract classfunction),
isinstancedictstrr   r   	Exceptionpopupdater   hasattrr	   	__bases__r   r   keywordsfunc_lookup_typecallableresearch	from_fileyaml	safe_loadfrom_configjsonloadsJSONDecodeErrorfindrsplit	importlibimport_modulegetattrModuleNotFoundErrorImportErrorAttributeError
ValueError
__module____package__
__import____name__	TypeErrorformatmatchargs)clsconfigkwargstype_ctor_kwargs	ctor_argsconstructorobjmodule_namefunction_namemodulepackage_nameobject_e rC   O/home/ubuntu/.local/lib/python3.10/site-packages/ray/rllib/utils/from_config.pyr       s   /













r    c                 O   s   t jt  |}t j|std|t|d}|ds&|dr,t	
|}nt|}W d   n1 s;w   Y  ||d< t| fd|i|S )z
    Create object from config saved in filename. Expects json or yaml file.

    Args:
        filename: File containing the config (json or yaml).

    Returns:
        any: The object generated from the file.
    zFile '{}' not found!rtz.yamlz.ymlNr   r6   )ospathjoingetcwdisfileFileNotFoundErrorr2   openendswithr   r   r!   loadr    )r5   filenamer4   r7   rG   fpr6   rC   rC   rD   r      s   
r   c                 C   s~   | d ur=t | dr=t| jtr=|| jv s%t|tr=tdd| | jv r=| j|}|d u r;| jtdd|  }|S d S )N__type_registry__z[\W_] )	r   r   rQ   r   r   r   sublowerget)r5   r8   available_class_for_typerC   rC   rD   r      s    

r   c                   @   s*   e Zd ZdZG dd dZdZdd ZdS )_NotProvidedad  Singleton class to provide a "not provided" value for AlgorithmConfig signatures.

    Using the only instance of this class indicates that the user does NOT wish to
    change the value of some property.

    .. testcode::
        :skipif: True

        from ray.rllib.algorithms.algorithm_config import AlgorithmConfig
        config = AlgorithmConfig()
        # Print out the default learning rate.
        print(config.lr)

    .. testoutput::

        0.001

    .. testcode::
        :skipif: True

        # Print out the default `preprocessor_pref`.
        print(config.preprocessor_pref)

    .. testoutput::

        "deepmind"

    .. testcode::
        :skipif: True

        # Will only set the `preprocessor_pref` property (to None) and leave
        # all other properties at their default values.
        config.training(preprocessor_pref=None)
        config.preprocessor_pref is None

    .. testoutput::

        True

    .. testcode::
        :skipif: True

        # Still the same value (didn't touch it in the call to `.training()`.
        print(config.lr)

    .. testoutput::

        0.001
    c                   @   s   e Zd ZdS )z_NotProvided.__NotProvidedN)r0   r-   __qualname__rC   rC   rC   rD   __NotProvided8  s    rY   Nc                 C   s   t jd u rt  t _d S d S N)rW   instance_NotProvided__NotProvided)selfrC   rC   rD   __init__=  s   
z_NotProvided.__init__)r0   r-   rX   __doc__r\   r[   r^   rC   rC   rC   rD   rW     s
    2rW   rZ   )copyr   	functoolsr   r&   r!   rF   r   r   ray.rllib.utils.annotationsr   ray.rllib.utilsr   r   r    r   r   rW   NotProvidedrC   rC   rC   rD   <module>   s"     H

@