o
    $i?                     @  s   d dl mZ d dlZd dlZd dlZd dlZd dlmZ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mZmZmZmZmZmZ g d
ZG dd deZG dd dZG dd dZG dd deeZ G dd deZ!dS )    )annotationsN)ABCabstractmethod)MappingSequence)import_module)pformat)Any)EXPR_KEY)CompInitModeensure_tuplefirstinstantiateoptional_import	run_debugrun_eval)ComponentLocator
ConfigItemConfigExpressionConfigComponentInstantiablec                   @  s,   e Zd ZdZedddZedd
dZdS )r   z0
    Base class for an instantiable object.
    argsr	   kwargsreturnboolc                 O     t d| jj d)z^
        Return a boolean flag to indicate whether the object should be instantiated.
        	subclass  must implement this method.NotImplementedError	__class____name__selfr   r    r$   Z/home/dell461/cl/sdc2/last_ska_mid/HISourceFinder-master-l/src/monai/bundle/config_item.pyis_disabled#      zInstantiable.is_disabledobjectc                 O  r   )zK
        Instantiate the target component and return the instance.
        r   r   r   r"   r$   r$   r%   r   *   r'   zInstantiable.instantiateN)r   r	   r   r	   r   r   )r   r	   r   r	   r   r(   )r!   
__module____qualname____doc__r   r&   r   r$   r$   r$   r%   r      s    r   c                   @  s>   e Zd ZdZdZddddZdd
dZdddZdddZdS )r   a7  
    Scan all the available classes and functions in the MONAI package and map them with the module paths in a table.
    It's used to locate the module path for provided component name.

    Args:
        excludes: if any string of the `excludes` exists in the full module name, don't import this module.

    monaiNexcludesSequence[str] | str | Nonec                 C  s    |d u rg nt || _d | _d S N)r   r-   _components_table)r#   r-   r$   r$   r%   __init__>   s   
zComponentLocator.__init__r   	list[str]c                   s    fddt jD S )za
        Find all the modules start with MOD_START and don't contain any of `excludes`.

        c                   s4   g | ]   jrt fd djD r qS )c                 3  s    | ]}| vV  qd S r/   r$   ).0smr$   r%   	<genexpr>G   s    zAComponentLocator._find_module_names.<locals>.<listcomp>.<genexpr>)
startswith	MOD_STARTallr-   )r3   r#   r5   r%   
<listcomp>G   s   4 z7ComponentLocator._find_module_names.<locals>.<listcomp>)sysmodulesr;   r$   r;   r%   _find_module_namesB   r'   z#ComponentLocator._find_module_namesmodnamesSequence[str] | strdict[str, list]c              	   C  s   i }t |D ]9}z.t|}t|D ]"\}}t|s t|r4|j|kr4||vr-g ||< || | qW q ty?   Y qw |S )z
        Find all the classes and functions in the modules with specified `modnames`.

        Args:
            modnames: names of the target modules to find all the classes and functions.

        )	r   r   inspect
getmembersisclass
isfunctionr)   appendModuleNotFoundError)r#   r@   tablemodnamemodulenameobjr$   r$   r%   _find_classes_or_functionsI   s   z+ComponentLocator._find_classes_or_functionsrL   strlist[str] | str | Nonec                 C  sb   t |tstd| d| jdu r| |  | _| j|}t |tr/t|dkr/|d }|S )a  
        Get the full module name of the class or function with specified ``name``.
        If target component name exists in multiple packages or modules, return a list of full module names.

        Args:
            name: name of the expected class or function.

        z(`name` must be a valid string, but got: .N   r   )	
isinstancerO   
ValueErrorr0   rN   r?   getlistlen)r#   rL   modsr$   r$   r%   get_component_module_name`   s   
	
z*ComponentLocator.get_component_module_namer/   )r-   r.   )r   r2   )r@   rA   r   rB   )rL   rO   r   rP   )	r!   r)   r*   r+   r9   r1   r?   rN   rY   r$   r$   r$   r%   r   2   s    	

r   c                   @  sB   e Zd ZdZddd	d
ZdddZdddZdd ZdddZdS )r   a  
    Basic data structure to represent a configuration item.

    A `ConfigItem` instance can optionally have a string id, so that other items can refer to it.
    It has a build-in `config` property to store the configuration object.

    Args:
        config: content of a config item, can be objects of any types,
            a configuration resolver may interpret the content to generate a configuration object.
        id: name of the current config item, defaults to empty string.

     configr	   idrO   r   Nonec                 C  s   || _ || _d S r/   r[   r\   )r#   r[   r\   r$   r$   r%   r1      s   
zConfigItem.__init__c                 C     | j S )zj
        Get the ID name of current config item, useful to identify config items during parsing.

        )r\   r;   r$   r$   r%   get_id      zConfigItem.get_idc                 C  s
   || _ dS )z
        Replace the content of `self.config` with new `config`.
        A typical usage is to modify the initial config content at runtime.

        Args:
            config: content of a `ConfigItem`.

        Nr[   )r#   r[   r$   r$   r%   update_config   s   
	zConfigItem.update_configc                 C  r_   )zA
        Get the config content of current config item.

        rb   r;   r$   r$   r%   
get_config   ra   zConfigItem.get_configc                 C  s   t | j dt| j S )Nz: 
)typer!   r   r[   r;   r$   r$   r%   __repr__   s   zConfigItem.__repr__N)rZ   )r[   r	   r\   rO   r   r]   )r   rO   )r[   r	   r   r]   )	r!   r)   r*   r+   r1   r`   rc   rd   rf   r$   r$   r$   r%   r   u   s    

r   c                      sd   e Zd ZdZh dZ			dd fddZed ddZdd Zdd Z	d!ddZ
d"ddZ  ZS )#r   a
  
    Subclass of :py:class:`monai.bundle.ConfigItem`, this class uses a dictionary with string keys to
    represent a component of `class` or `function` and supports instantiation.

    Currently, three special keys (strings surrounded by ``_``) are defined and interpreted beyond the regular literals:

        - class or function identifier of the python module, specified by ``"_target_"``,
          indicating a monai built-in Python class or function such as ``"LoadImageDict"``,
          or a full module name, e.g. ``"monai.transforms.LoadImageDict"``, or a callable, e.g. ``"$@model.forward"``.
        - ``"_requires_"`` (optional): specifies reference IDs (string starts with ``"@"``) or ``ConfigExpression``
          of the dependencies for this ``ConfigComponent`` object. These dependencies will be
          evaluated/instantiated before this object is instantiated.  It is useful when the
          component doesn't explicitly depend on the other `ConfigItems` via its arguments,
          but requires the dependencies to be instantiated/evaluated beforehand.
        - ``"_disabled_"`` (optional): a flag to indicate whether to skip the instantiation.
        - ``"_desc_"`` (optional): free text descriptions of the component for code readability.
        - ``"_mode_"`` (optional): operating mode for invoking the callable ``component`` defined by ``"_target_"``:

            - ``"default"``: returns ``component(**kwargs)``
            - ``"callable"``: returns ``component`` or, if ``kwargs`` are provided, ``functools.partial(component, **kwargs)``
            - ``"debug"``: returns ``pdb.runcall(component, **kwargs)``

    Other fields in the config content are input arguments to the python module.

    .. code-block:: python

        from monai.bundle import ComponentLocator, ConfigComponent

        locator = ComponentLocator(excludes=["modules_to_exclude"])
        config = {
            "_target_": "LoadImaged",
            "keys": ["image", "label"]
        }

        configer = ConfigComponent(config, id="test", locator=locator)
        image_loader = configer.instantiate()
        print(image_loader)  # <monai.transforms.io.dictionary.LoadImaged object at 0x7fba7ad1ee50>

    Args:
        config: content of a config item.
        id: name of the current config item, defaults to empty string.
        locator: a ``ComponentLocator`` to convert a module name string into the actual python module.
            if `None`, a ``ComponentLocator(excludes=excludes)`` will be used.
        excludes: if ``locator`` is None, create a new ``ComponentLocator`` with ``excludes``.
            See also: :py:class:`monai.bundle.ComponentLocator`.

    >   Z_desc__mode__target_
_disabled_Z
_requires_rZ   Nr[   r	   r\   rO   locatorComponentLocator | Noner-   r.   r   r]   c                   s2   t  j||d |d u rt|d| _d S || _d S )Nr^   )r-   )superr1   r   rj   )r#   r[   r\   rj   r-   r    r$   r%   r1      s   "zConfigComponent.__init__r   c                 C  s   t | tod| v S )z
        Check whether this config represents a `class` or `function` that is to be instantiated.

        Args:
            config: input config content to check.

        rh   )rS   r   rb   r$   r$   r%   is_instantiable   s   	zConfigComponent.is_instantiablec              	   C  s~   t |  }|d}t|ts|S | j|}|du r|S t|tr8t	d| d| d|d  d |d }| d| S )	z
        Resolve the target module name from current config content.
        The config content must have ``"_target_"`` key.

        rh   Nz+there are more than 1 component have name `z`: z, use the first one `r   zP. if want to use others, please set its full module path in `_target_` directly.rQ   )
dictrd   rU   rS   rO   rj   rY   rV   warningswarn)r#   r[   targetrK   r$   r$   r%   resolve_module_name   s   


z#ConfigComponent.resolve_module_namec                   s    fdd    D S )zq
        Utility function used in `instantiate()` to resolve the arguments from current config content.

        c                   s    i | ]\}}| j vr||qS r$   )non_arg_keys)r3   kvr;   r$   r%   
<dictcomp>	  s     z0ConfigComponent.resolve_args.<locals>.<dictcomp>)rd   itemsr;   r$   r;   r%   resolve_args  s   zConfigComponent.resolve_argsc                 C  s2   |   dd}t|tr|  dkS t|S )zg
        Utility function used in `instantiate()` to check whether to skip the instantiation.

        ri   Ftrue)rd   rU   rS   rO   lowerstripr   )r#   Z_is_disabledr$   r$   r%   r&     s   "zConfigComponent.is_disabledr   r(   c                 K  sX   |  |  r|  rdS |  }|  dtj}|  }|| t	||fi |S )a  
        Instantiate component based on ``self.config`` content.
        The target component must be a `class` or a `function`, otherwise, return `None`.

        Args:
            kwargs: args to override / add the config args when instantiation.

        Nrg   )
rn   rd   r&   rs   rU   r   DEFAULTry   updater   )r#   r   rJ   moder   r$   r$   r%   r     s   	
zConfigComponent.instantiate)rZ   NN)
r[   r	   r\   rO   rj   rk   r-   r.   r   r]   )r[   r	   r   r   )r   r   )r   r	   r   r(   )r!   r)   r*   r+   rt   r1   staticmethodrn   rs   ry   r&   r   __classcell__r$   r$   rm   r%   r      s    0


r   c                      s^   e Zd ZdZeZeZdd fddZdddZdd ddZ	e
d!ddZe
d!ddZ  ZS )"r   a  
    Subclass of :py:class:`monai.bundle.ConfigItem`, the `ConfigItem` represents an executable expression
    (execute based on ``eval()``, or import the module to the `globals` if it's an import statement).

    See also:

        - https://docs.python.org/3/library/functions.html#eval.

    For example:

    .. code-block:: python

        import monai
        from monai.bundle import ConfigExpression

        config = "$monai.__version__"
        expression = ConfigExpression(config, id="test", globals={"monai": monai})
        print(expression.evaluate())

    Args:
        config: content of a config item.
        id: name of current config item, defaults to empty string.
        globals: additional global context to evaluate the string.

    rZ   Nr[   r	   r\   rO   globalsdict | Noner   r]   c                   s,   t  j||d |d ur|| _d S i | _d S )Nr^   )rl   r1   r   )r#   r[   r\   r   rm   r$   r%   r1   E  s   zConfigExpression.__init__import_string
Any | Nonec                 C  s   t tt|}t|tjtjfsdS t|jdk rdS t|jdkr.t	
d| d |jd j |jd j}}|du rB|n| }t|tjr^t|j | d\| j|< }| j| S t|tjrst| \| j|< }| j| S dS )zJparse single import statement such as "from monai.transforms import ResizeNrR   z ignoring multiple import alias 'z'.r   )rL   )r   astiter_child_nodesparserS   Import
ImportFromrW   namesrp   rq   rL   asnamer   rK   r   )r#   r   noderL   r   _r$   r$   r%   _parse_import_stringI  s    

z%ConfigExpression._parse_import_stringlocalsstr | Any | Nonec           
   
   C  s  |   }t|sdS | |t| jd }|dur|S | js*|t| jd  S t| j}|durM|	 D ]\}}||v rHt
d| d |||< q7tsrzt|t| jd ||W S  tyq } ztd|  |d}~ww t
d| d ddl}	|	|t| jd || dS )a  
        Execute the current config content and return the result if it is expression, based on Python `eval()`.
        For more details: https://docs.python.org/3/library/functions.html#eval.

        Args:
            globals: besides ``self.globals``, other global symbols used in the expression at runtime.
            locals: besides ``globals``, may also have some local symbols used in the expression at runtime.

        Nzthe new global variable `z-` conflicts with `self.globals`, override it.zFailed to evaluate z

pdb: value=zV
See also Debugger commands documentation: https://docs.python.org/3/library/pdb.html
r   )rd   r   is_expressionr   rW   prefixr   ro   r   rx   rp   rq   r   eval	ExceptionRuntimeErrorpdbrun)
r#   r   r   valueoptional_moduleglobals_ru   rv   er   r$   r$   r%   evaluate\  s6   




zConfigExpression.evaluatedict | list | strr   c                 C  s   t |to
|| jS )z
        Check whether the config is an executable expression string.
        Currently, a string starts with ``"$"`` character is interpreted as an expression.

        Args:
            config: input config content to check.

        )rS   rO   r8   r   clsr[   r$   r$   r%   r     s   
zConfigExpression.is_expressionc              	   C  sL   |  |sdS d|vrdS tttt|t| jd  tjtj	fS )z
        Check whether the config is an import statement (a special case of expression).

        Args:
            config: input config content to check.
        FimportN)
r   rS   r   r   r   r   rW   r   r   r   r   r$   r$   r%   is_import_statement  s   
,z$ConfigExpression.is_import_statement)rZ   N)r[   r	   r\   rO   r   r   r   r]   )r   rO   r   r   )NN)r   r   r   r   r   r   )r[   r   r   r   )r!   r)   r*   r+   r
   r   r   r1   r   r   classmethodr   r   r   r$   r$   rm   r%   r   '  s    
&r   )"
__future__r   r   rC   r=   rp   abcr   r   collections.abcr   r   	importlibr   pprintr   typingr	   monai.bundle.utilsr
   monai.utilsr   r   r   r   r   r   r   __all__r   r   r   r   r   r$   r$   r$   r%   <module>   s&   $C/ 