o
    ȷe	R                     @   s   d Z ddlZddl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mZmZ ddlmZmZ ddlmZmZmZmZ G d	d
 d
eZG dd deZG dd deZG dd deZG dd deZdS )z/A base class for objects that are configurable.    N)deepcopy)dedent)	Any	ContainerDict	HasTraitsInstancedefaultobserveobserve_compatvalidate)indentwrap_paragraphs   )ConfigDeferredConfigLazyConfigValue_is_section_keyc                   @      e Zd ZdS )ConfigurableErrorN__name__
__module____qualname__ r   r   T/var/www/ideatree/venv/lib/python3.10/site-packages/traitlets/config/configurable.pyr           r   c                   @   r   )MultipleInstanceErrorNr   r   r   r   r   r   $   r   r   c                       s   e Zd Zeedi ZedddZ fddZedd Z	d	d
 Z
dddZededd Zdd Zed ddZedddZed ddZedd Zed ddZedd Z  ZS )!Configurabler   z*traitlets.config.configurable.ConfigurableT)
allow_nonec                    s    dd}|durdddu r|jd< || _ dd}t jdi  t   fdd}| | |dur@|| _n| | j | 	|  D ]
}t
| ||  qMdS )a  Create a configurable given a config config.

        Parameters
        ----------
        config : Config
            If this is empty, default values are used. If config is a
            :class:`Config` instance, it will be used to configure the
            instance.
        parent : Configurable instance, optional
            The parent Configurable instance of this object.

        Notes
        -----
        Subclasses of Configurable must call the :meth:`__init__` method of
        :class:`Configurable` *before* doing anything else and using
        :func:`super`::

            class MyConfigurable(Configurable):
                def __init__(self, config=None):
                    super(MyConfigurable, self).__init__(config=config)
                    # Then any other code you need to finish initialization.

        This ensures that instances will be configured properly.
        parentNconfigc                    s   | j v r | j  dS dS )zRecord traits set by both config and kwargs.

            They will need to be overridden again after loading config.
            N)nameadd)changeconfig_override_nameskwargsr   r   notice_config_overrideZ   s   
z5Configurable.__init__.<locals>.notice_config_overrider   )popgetr!   r    super__init__setr
   _load_config	unobservesetattr)selfr'   r    r!   r(   r"   	__class__r%   r   r,   2   s"   


zConfigurable.__init__c                    s    fddt  jD S )zreturn section names as a listc                    s&   g | ]}t |trt  |r|jqS r   
issubclassr   r   ).0cclsr   r   
<listcomp>}   s    z.Configurable.section_names.<locals>.<listcomp>)reversed__mro__r8   r   r8   r   section_namesz   s   
zConfigurable.section_namesc                 C   sX   |g}| j r|| j | t }|D ]}|  D ]}||r(|||  qq|S )a  extract my config from a global Config object

        will construct a Config object of only the config values that apply to me
        based on my mro(), as well as those of my parent(s) if they exist.

        If I am Bar and my parent is Foo, and their parent is Tim,
        this will return merge following config sections, in this order::

            [Bar, Foo.Bar, Tim.Foo.Bar]

        With the last item being the highest priority.
        )r    append_find_my_configr   r=   _has_sectionmerge)r1   cfgcfgs	my_configr7   snamer   r   r   r?      s   
zConfigurable._find_my_configNc                 C   sf  |du r
| j dd}|du r|  }| |}|   | D ]\}}||v rMt|tr8t| |}||}nt|t	rD||| }t
| |t| q t|st|tsddlm} t| trf| jj}	ndd }	|||}
dj|| jjd	}t|
d
kr|d|
d  d7 }nt|
d
kr|djdt|
d7 }|	| q W d   dS 1 sw   Y  dS )z load traits from a Config objectNTr!   r   )get_close_matchesc                 S   s   t j| ddS )N	   )
stacklevel)warningswarn)msgr   r   r   <lambda>   s    z+Configurable._load_config.<locals>.<lambda>z5Config option `{option}` not recognized by `{klass}`.)optionklassr   z  Did you mean `z`?z#  Did you mean one of: `{matches}`?, )matches)traitsr=   r?   hold_trait_notificationsitems
isinstancer   getattr	get_valuer   r0   r   r   r   difflibrG   LoggingConfigurablelogwarningformatr3   r   lenjoinsorted)r1   rB   r=   rR   rD   r"   config_valueinitialrG   rK   rQ   rL   r   r   r   r.      sB   







"zConfigurable._load_configr!   c                 C   s*   | j dd}|  }| j|j||d dS )zUpdate all the class traits having ``config=True`` in metadata.

        For any class trait with a ``config`` metadata attribute that is
        ``True``, we update the trait with the value of the corresponding
        config entry.
        TrF   )rR   r=   N)rR   r=   r.   new)r1   r$   rR   r=   r   r   r   _config_changed   s   
zConfigurable._config_changedc                 C   s&   t | j| _| | | j| dS )z%Update config and load the new valuesN)r   r!   r.   rA   )r1   r!   r   r   r   update_config   s   
zConfigurable.update_configc                 C   s   |du st || sJ g }ddd | jD }|| j d| d |t|d d  t| jd	d
 D ]\}}| 	||}|| q9d|S )zGet the help string for this class in ReST format.

        If `inst` is given, it's current trait values will be used in place of
        class defaults.
        NrP   c                 s   s    | ]}|j V  qd S N)r   r6   pr   r   r   	<genexpr>   s    z.Configurable.class_get_help.<locals>.<genexpr>(z	) optionsr   -TrF   
)
rU   r^   	__bases__r>   r   r]   r_   class_traitsrT   class_get_trait_help)r9   inst
final_helpbase_classes_vhelpr   r   r   class_get_help   s   
zConfigurable.class_get_helpc           	      C   s  |du st || sJ g }d| j d|j }t |ttfrK|jdd}t |tr-d}nd|jj  }|dkrB| d| d	}n| d
| d	}n
| d|jj d}|	| |du ra|j
}|dkrtdt|d}|	t| d|jjv r|	td|   |dur|	tdt||j n-z| }W n ty   d}Y nw |durt|dkr|dd d	 }|	td|  d|S )a  Get the helptext string for a single trait.

        :param inst:
            If given, it's current trait values will be used in place of
            the class default.
        :param helptext:
            If not given, uses the `help` attribute of the current trait.
        Nz--.multiplicityr>   z<key-1>=<value-1>z<%s-item-1>=... z=<> rk   L   EnumzChoices: %sz	Current: @   =   zDefault: %s)rU   r   r"   r   r   metadatar*   r3   lowerr>   rt   r^   r   r   inforV   default_value_repr	Exceptionr]   )	r9   traitro   helptextlinesheaderrw   sample_valuedvrr   r   r   rn      s@   



z!Configurable.class_get_trait_helpc                 C   s   t | | dS )z4Get the help string for a single trait and print it.N)printru   )r9   ro   r   r   r   class_print_help1  s   zConfigurable.class_print_helpc                 C   sF   | }|   D ]}t|tr ||v r |jdd|jd|u r |}q|S )a7  Get the class that defines a trait

        For reducing redundant help output in config files.
        Returns the current class if:
        - the trait is defined on this class, or
        - the class where it is defined would not be in the config file

        Parameters
        ----------
        trait : Trait
            The trait to look for
        classes : list
            The list of other classes to consider for redundancy.
            Will return `cls` even if it is not defined on `cls`
            if the defining class is not in `classes`.
        TrF   N)mror5   r   class_own_traitsr*   r"   )r9   r   classesdefining_clsr    r   r   r   _defining_class6  s   zConfigurable._defining_classc              	   C   sz  dd }d}d dd | jD }d| j d| d	}|||g}|  d
}|r,|j}|s4t| dd}|rB||| |d t| jdd	 D ]k\}}	|	
 }
|r]| |	|}n| }|| u r|	jrn|||	j dt|	jv r~|d|	   |d|
  n|	jr|||	jddd  |d|j d|  |d| j d| d|
  |d qLd |S )zGet the config section for this class.

        Parameters
        ----------
        classes : list, optional
            The list of other classes in the config file.
            Used to reduce redundant information.
        c                 S   s    d t| d} d| dd S )z"return a commented, wrapped block.z

N   z## rk   z
#  )r^   r   replace)sr   r   r   r7   ]  s   z,Configurable.class_config_section.<locals>.czO#------------------------------------------------------------------------------rP   c                 s   s     | ]}t |tr|jV  qd S re   r4   rf   r   r   r   rh   e  s    z4Configurable.class_config_section.<locals>.<genexpr>z# ri   z) configurationdescription__doc__r|   TrF   r~   z#  Choices: %sz#  Default: %srk   r   r   z#  See also: rv   z# c.z = )r^   rl   r   rm   r*   default_valuerV   r>   r_   rT   r   r   rt   typer   split)r9   r   r7   breakerparent_classesr   r   descr"   r   default_reprdefining_classr   r   r   class_config_sectionR  s<   


z!Configurable.class_config_sectionc           	   	   C   s  g }| j }t| jdd D ]r\}}|jj }|d |j }d|v r+|d|  7 }n|d| 7 }|| z| }W n t	yG   d}Y nw |durnt
|dkrZ|dd d	 }|d
d}|td|  |d |jprd}|tt| |d qd|S )zwGenerate rST documentation for this class' config options.

        Excludes traits defined on parent classes.
        TrF   rv   r~   z : Nr   r   ry   z\nz\\nzDefault: ``%s``r|   zNo descriptionrk   )r   r_   rm   rT   r3   r"   info_rstr>   r   r   r]   r   r   rt   r   r^   )	r9   r   	classnamerr   r   ttypetermliner   rt   r   r   r   class_config_rst_doc  s0   



z!Configurable.class_config_rst_doc)NNre   )r   r   r   r   r   r!   r    r,   classmethodr=   r?   r.   r
   r   rc   rd   ru   rn   r   r   r   r   __classcell__r   r   r2   r   r   -   s0    H

.3
;r   c                   @   sB   e Zd ZdZeddZeddd Zeddd Z	d	d
 Z
dS )rY   zA parent class for Configurables that log.

    Subclasses have a log trait, and the default behavior
    is to get the logger from the currently running Application.
    z Logger or LoggerAdapter instance)rt   rZ   c                 C   s6   t |jtjtjfst| jj d|j d |jS )Nz..log should be a Logger or LoggerAdapter, got rv   )	rU   valueloggingLoggerLoggerAdapterrJ   rK   r3   r   )r1   proposalr   r   r   _validate_log  s   
z!LoggingConfigurable._validate_logc                 C   s(   t | jtr
| jjS ddlm} | S )Nr   )rZ   )rU   r    rY   rZ   	traitlets
get_logger)r1   rZ   r   r   r   _log_default  s   z LoggingConfigurable._log_defaultc                 C   s2   | j }t|tjr|j}t|ddsdS |jd S )zReturn the default Handler

        Returns None if none can be found

        Deprecated, this now returns the first log handler which may or may
        not be the default one.
        handlersNr   )rZ   rU   r   r   loggerrV   r   )r1   r   r   r   r   _get_log_handler  s   
z$LoggingConfigurable._get_log_handlerN)r   r   r   r   r   rZ   r   r   r	   r   r   r   r   r   r   rY     s    

	
rY   c                   @   sD   e Zd ZdZdZedd Zedd Zedd Zed	d
 Z	dS )SingletonConfigurablezA configurable that only allows one instance.

    This class is for classes that should only have one instance of itself
    or *any* subclass. To create and retrieve such a class use the
    :meth:`SingletonConfigurable.instance` method.
    Nc                 c   s6    |   D ]}t| |rt|tr|tkr|V  qdS )zfWalk the cls.mro() for parent classes that are also singletons

        For use in instance()
        N)r   r5   r   r9   subclassr   r   r   	_walk_mro  s   zSingletonConfigurable._walk_mroc                 C   s0   |   sdS |  D ]}t|j| rd|_q
dS )z5unset _instance for this class and singleton parents.N)initializedr   rU   	_instancer   r   r   r   clear_instance  s   z$SingletonConfigurable.clear_instancec                 O   sX   | j du r| |i |}|  D ]}||_ qt| j | r| j S td| jt| j jf )a  Returns a global instance of this class.

        This method create a new instance if none have previously been created
        and returns a previously created instance is one already exists.

        The arguments and keyword arguments passed to this method are passed
        on to the :meth:`__init__` method of the class upon instantiation.

        Examples
        --------
        Create a singleton class using instance, and retrieve it::

            >>> from traitlets.config.configurable import SingletonConfigurable
            >>> class Foo(SingletonConfigurable): pass
            >>> foo = Foo.instance()
            >>> foo == Foo.instance()
            True

        Create a subclass that is retrived using the base class instance::

            >>> class Bar(SingletonConfigurable): pass
            >>> class Bam(Bar): pass
            >>> bam = Bam.instance()
            >>> bam == Bar.instance()
            True
        NzHAn incompatible sibling of '%s' is already instanciated as singleton: %s)r   r   rU   r   r   r   )r9   argsr'   ro   r   r   r   r   instance	  s   
zSingletonConfigurable.instancec                 C   s   t | do	| jduS )zHas an instance been created?r   N)hasattrr   r8   r   r   r   r   5  s   z!SingletonConfigurable.initialized)
r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     s    



+r   )r   r   rJ   copyr   textwrapr   traitlets.traitletsr   r   r   r   r   r	   r
   r   r   traitlets.utils.textr   r   loaderr   r   r   r   r   r   r   r   rY   r   r   r   r   r   <module>   s     ,	   ,