a
    7a͂                     @   s  d Z ddlmZ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ZddlZddlZddlmZmZ ddlmZmZmZmZmZmZ ddlmZmZmZmZmZmZmZm Z m!Z!m"Z" dd	l#m$Z$ dd
l%m&Z& ddl'm(Z(m)Z) ddl*m+Z+ d, Z-d, Z.e/edsdge_0dZ1e	j23ddZ4e45 dv r>dZ6n e45 dv rRdZ6ne7de4 dd Z8G dd de9Z:G dd dej;Z<G dd deZ=e=j>Z?e=j@ZAd%d d!ZBd"d# ZCeDd$kre=E  dS )&z,A base class for a configurable application.    )defaultdictOrderedDict)deepcopyN)ConfigurableSingletonConfigurable)KVArgParseConfigLoaderPyFileConfigLoaderConfigArgumentErrorConfigFileNotFoundJSONFileConfigLoader)
BoolUnicodeListEnumDictInstance
TraitErrorobserveobserve_compatdefault   )import_itemcast_unicode)indentwrap_paragraphs)dedentz
The options below are convenience aliases to configurable class-options,
as listed in the "Equivalent to" description-line of the aliases.
To see all configurable class-options for some <cmd>, use:
    <cmd> --help-all
z
The command-line option below sets the respective configurable class-parameter:
    --Class.parameter=value
This line is evaluated in Python, so simple expressions are allowed.
For instance, to set `C.a=[0,1,2]`, you may type this:
    --C.a='range(3)'
argv zp
Subcommands are launched as `{app} cmd [args]`. For information on using
subcommand 'cmd', do: `{app} cmd -h`.
-TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR>   true1T>   r   Zfalse0FzUnsupported value for environment variable: 'TRAITLETS_APPLICATION_RAISE_CONFIG_FILE_ERROR' is set to '%s' which is none of  {'0', '1', 'false', 'true', ''}.c                    s   t   fdd}|S )a  Method decorator for catching invalid config (Trait/ArgumentErrors) during init.

    On a TraitError (generally caused by bad config), this will print the trait's
    message, and exit the app.

    For use on init methods, to prevent invoking excepthook on invalid input.
    c              
      sn   z | g|R i |W S  t tfyh } z4| jd| | jd| j | d W Y d }~n
d }~0 0 d S )Nz0Bad config encountered during initialization: %szConfig at the time: %s   )r   r
   logZfataldebugconfigexit)appargskwargsemethod ;lib/python3.9/site-packages/traitlets/config/application.pyinnerU   s    z!catch_config_error.<locals>.inner)	functoolswraps)r.   r1   r/   r-   r0   catch_config_errorM   s    r4   c                   @   s   e Zd ZdS )ApplicationErrorN)__name__
__module____qualname__r/   r/   r/   r0   r5   `   s   r5   c                       s*   e Zd ZdZejZdZ fddZ  Z	S )LevelFormattera  Formatter with additional `highlevel` record

    This field is empty if log level is less than highlevel_limit,
    otherwise it is formatted with self.highlevel_format.

    Useful for adding 'WARNING' to warning messages,
    without adding 'INFO' to info, etc.
    z %(levelname)s |c                    s2   |j | jkr| j|j |_nd|_tt| |S )Nr   )Zlevelnohighlevel_limithighlevel_format__dict__Z	highlevelsuperr9   format)selfrecord	__class__r/   r0   r>   p   s    zLevelFormatter.format)
r6   r7   r8   __doc__loggingWARNr:   r;   r>   __classcell__r/   r/   rA   r0   r9   d   s   r9   c                       s  e Zd ZdZedZedZeeZeeZee	Z	e
ZeZe Zg ZdsddZedZe ZeeZedejd	d
jddZededd ZeZ edddjddZ!edddjddZ"eddedd Z#e$ddd Z%ddiZ&d dej'iidfd ddiid fd d!diid"fd#Z(e) Z*e+d$dd%Z,ee Z-e+e.d&i d'dZ/e Z0ed(djddZ1ed)djddZ2ed!d*d+ Z3edd,d- Z4d.d/ Z5ed0e fd1d2Z6e7dtd3d4Z8d5d6 Z9d7d8 Z:d9d: Z;d;d< Z<d=d> Z=d?d@ Z>dAdB Z?dCdD Z@dEdF ZAdGdH ZBdIdJ ZCdudLdMZDdvdNdOZEdPdQ ZFdRdS ZGdTdU ZHdVdW ZIdXdY ZJdZd[ ZKe7dwd\d]ZLd^d_ ZMd`da ZNe7dxdbdcZOePdydddeZQeRdfdg ZSe7dzdhdiZTd{djdkZUd|dldmZVd}dodpZWePd~dqdrZX  ZYS )Applicationz8A singleton application with full configuration support.ZapplicationzThis is an application.Nc                 c   sV   |du r| j }t }|D ]8}t| D ]&}t|tr(||vr(|| |V  q(qdS )a  Iterate through configurable classes, including configurable parents

        :param classes:
            The list of classes to iterate; if not set, uses :attr:`classes`.

        Children should always be after parents, and each class should only be
        yielded once.
        N)classessetreversedmro
issubclassr   add)r?   rH   seencparentr/   r/   r0   _classes_inc_parents   s    	
z Application._classes_inc_parentsz0.0)r   
         (   2   DEBUGINFOrE   ZERRORZCRITICALz#Set the log level by value or name.)Zdefault_valuehelpTr'   	log_levelc                 C   s0   |j }t|tr tt|}|| _| j| dS )z+Adjust the log level when log_level is set.N)new
isinstancestrgetattrrD   r[   r%   setLevel)r?   changer\   r/   r/   r0   _log_level_changed   s
    

zApplication._log_level_changedz%Y-%m-%d %H:%M:%Sz:The date format used by logging formatters for %(asctime)s)rY   z#[%(name)s]%(highlevel)s %(message)szThe Logging format templatelog_datefmt
log_formatc                 C   sF   |   }|s&td| j dt dS | j| j| jd}|| dS )z0Change the log formatter when log_format is set.zNo Handler found on z(, setting log_format will have no effectNZfmtZdatefmt)	Z_get_log_handlerwarningswarnr%   RuntimeWarning_log_formatter_clsrd   rc   setFormatter)r?   ra   _log_handler_log_formatterr/   r/   r0   _log_format_changed   s    zApplication._log_format_changedr%   c                 C   s   t | jj}|| j d|_|}|rD|jr2|S |js<qDq$|j}q$t	j
rjt	j
drjt ttjd}nt  }| j| j| jd}|| || |S )a
  Start logging for this application.

        The default is to log to stderr using a StreamHandler, if no default
        handler already exists.  The log level starts at logging.WARN, but this
        can be adjusted by setting the ``log_level`` attribute.
        Fzpythonw.exewre   )rD   Z	getLoggerrB   r6   r`   r[   Z	propagatehandlersrP   sys
executableendswithZStreamHandleropenosdevnullri   rd   rc   rj   Z
addHandler)r?   r%   Z_logrk   rl   r/   r/   r0   _log_default   s"    

zApplication._log_defaultz	log-levelzApplication.log_levelz5Set log-level to debug, for the most verbose logging.show_configz<Show the application's configuration (human-readable format)show_config_jsonz2Show the application's configuration (json format))r&   zshow-configzshow-config-jsonz(traitlets.config.application.Application)Z
allow_noner/   zThe subset of our configuration that came from the command-line

        We re-load this configuration after loading config files,
        to ensure that it maintains highest priority.
        zAInstead of starting the Application, dump configuration to stdoutzKInstead of starting the Application, dump configuration to stdout (as JSON)c                 C   s   |j | _d S N)r\   rw   r?   ra   r/   r/   r0   _show_config_json_changed,  s    z%Application._show_config_json_changedc                 C   s   |j r| j| _| j| _d S ry   )r\   startZ_save_startstart_show_configrz   r/   r/   r0   _show_config_changed0  s    z Application._show_config_changedc                 K   sR   t j| fi | | j}|| jvrN| j|ju r>|g| j | _n| jd| j d S )Nr   )r   __init__rB   rH   insert)r?   r+   clsr/   r/   r0   r   6  s    
zApplication.__init__r'   c                    s$   t t| | | jd|j d S )NzConfig changed: %r)r=   rG   _config_changedr%   r&   r\   rz   rA   r/   r0   r   B  s    zApplication._config_changedc                 C   s   |  | dS )zMDo the basic steps to configure me.

        Override in subclasses.
        N)parse_command_line)r?   r   r/   r/   r0   
initializeH  s    zApplication.initializec                 C   s   | j dur| j  S dS )zAStart the app mainloop.

        Override in subclasses.
        N)subappr|   r?   r/   r/   r0   r|   Q  s    
zApplication.startc           
   
   C   s  | j  }| j D ]0}|j|v r||j }|dd |dd q| jrrtj|t	j
ddtd t	j
d dS | jrtd | jD ]}td	|  qt  t|D ]Z}|| }|sqt| td
dd}t|D ]*}|| }	td|tj|	fi | qqdS )z,start function used when show_config is Truerw   Nrx   r$   T)r   Z	sort_keysr   
zLoaded config files:z     )r   Zcompactz
  .{} = {})r'   copyrB   rK   r6   poprx   jsondumprp   stdoutreprwrite_loaded_config_filesprintsorteddictr>   pprintZpformat)
r?   r'   r   Z
cls_configf	classnameZclass_configZpformat_kwargs	traitnamevaluer/   r/   r0   r}   Y  s:    




zApplication.start_show_configc                 C   s   t d|   dS )z"Print the alias parts of the help.r   N)r   joinemit_alias_helpr   r/   r/   r0   print_alias_help~  s    zApplication.print_alias_helpc                 c   s^  | j s
dS i }| jD ]$}| dd D ]}|||j< q(q| j  D ]\}}zt|trd|\}}nd}|ddd \}}|d | }|| }|jdd| }	|j	|	|d
 }t|ts|f}t|td}d	d
d |D }|d d| ||d< |D ]}
|
V  q td| V  W qD tyV } z| jd||  W Y d}~qDd}~0 0 qDdS )z+Yield the lines for alias part of the help.N.TrZ   )Zhelptextkey, c                 s   s&   | ]}t |d krdnd| V  qdS r$   z--%sz-%sNlen.0mr/   r/   r0   	<genexpr>  s   z.Application.emit_alias_help.<locals>.<genexpr>r   --zEquivalent to: [--%s]z7Failed collecting help-message for alias %r, due to: %s)aliasesrH   rK   r6   itemsr]   tuplesplitZclass_traitsZclass_get_trait_help
splitlinesr   r   r   replacer   	Exceptionr%   error)r?   	classdictr   rO   aliaslongnamefhelpr   r   traitlexr/   r/   r0   r     s>    





zApplication.emit_alias_helpc                 C   s   t d|   dS )z Print the flag part of the help.r   N)r   r   emit_flag_helpr   r/   r/   r0   print_flag_help  s    zApplication.print_flag_helpc                 c   s   | j s
dS | j  D ]\}\}}zzt|ts2|f}t|td}ddd |D }|V  tt|	 V  ddd | D }d| }tt|V  W q t
y } z| jd	||  W Y d}~qd}~0 0 qdS )
z.Yield the lines for the flag part of the help.Nr   r   c                 s   s&   | ]}t |d krdnd| V  qdS r   r   r   r/   r/   r0   r     s   z-Application.emit_flag_help.<locals>.<genexpr> c                 s   s2   | ]*\}}|  D ]\}}d |||f V  qqdS )z
--%s.%s=%sN)r   )r   ZclnameZ
props_dictZpropvalr/   r/   r0   r     s   zEquivalent to: [%s]z6Failed collecting help-message for flag %r, due to: %s)flagsr   r]   r   r   r   r   r   r   stripr   r%   r   )r?   r   Zcfgr   Zcfg_listZcfg_txtr   r/   r/   r0   r     s,    


zApplication.emit_flag_helpc                 C   s   t d|   dS )z#Print the options part of the help.r   N)r   r   emit_options_helpr   r/   r/   r0   print_options  s    zApplication.print_optionsc                 c   sv   | j s| jsdS d}|V  dt| V  t| jD ]}|V  dV  q2|  D ]
}|V  qL|  D ]
}|V  q`dV  dS )z1Yield the lines for the options part of the help.NZOptions=r   )r   r   r   r   option_descriptionr   r   )r?   headerpr   r/   r/   r0   r     s    zApplication.emit_options_helpc                 C   s   t d|   dS )z&Print the subcommand part of the help.r   N)r   r   emit_subcommands_helpr   r/   r/   r0   print_subcommands  s    zApplication.print_subcommandsc                 c   s   | j s
dS d}|V  dt| V  t| jj| jdD ]}|V  dV  q6| j  D ](\}\}}|V  |rRtt|	 V  qRdV  dS )z4Yield the lines for the subcommand part of the help.NZSubcommandsr   )r)   r   )
subcommandsr   r   subcommand_descriptionr>   namer   r   r   r   )r?   r   r   subcr   rY   r/   r/   r0   r     s    z!Application.emit_subcommands_helpc                 c   s   |sdV  dV  dS )zzYield the very bottom lines of the help message.

        If classes=False (the default), print `--help-all` msg.
        z5To see all available configurables, use `--help-all`.r   Nr/   r?   rH   r/   r/   r0   emit_help_epilogue  s    zApplication.emit_help_epilogueFc                 C   s   t d| j|d dS )zPrint the help for each Configurable class in self.classes.

        If classes=False (the default), only flags and aliases are printed.
        r   rH   N)r   r   	emit_helpr   r/   r/   r0   
print_help  s    zApplication.print_helpc                 c   s   |   D ]
}|V  q|  D ]
}|V  q|  D ]
}|V  q0|r|  }|rtdV  dV  t| jD ]}|V  dV  qb|D ]}| V  dV  qx|  D ]
}|V  q| |D ]
}|V  qdS )zYield the help-lines for each Configurable class in self.classes.

        If classes=False (the default), only flags and aliases are printed.
        zClass optionsz=============r   N)	emit_descriptionr   r   _classes_with_config_traitsr   keyvalue_descriptionZclass_get_helpemit_examplesr   )r?   rH   r   Zhelp_classesr   r   r/   r/   r0   r     s*    
zApplication.emit_helpc                 C   s   d dd |  D S )zwGenerate rST format documentation for the config options this application

        Returns a multiline string.
        r   c                 s   s   | ]}|  V  qd S ry   )Zclass_config_rst_doc)r   rO   r/   r/   r0   r   %  s   z6Application.document_config_options.<locals>.<genexpr>)r   rQ   r   r/   r/   r0   document_config_options   s    
z#Application.document_config_optionsc                 C   s   t d|   dS )z"Print the application description.r   N)r   r   r   r   r/   r/   r0   print_description(  s    zApplication.print_descriptionc                 c   s&   t | jp| jD ]}|V  dV  qdS )z-Yield lines with the application description.r   N)r   descriptionrC   )r?   r   r/   r/   r0   r   ,  s    zApplication.emit_descriptionc                 C   s   t d|   dS )z2Print usage and examples (see `emit_examples()`). r   N)r   r   r   r   r/   r/   r0   print_examples2  s    zApplication.print_examplesc                 c   s6   | j r2dV  dV  dV  tt| j  V  dV  dS )zYield lines with the usage and examples.

        This usage string goes at the end of the command line help string
        and should contain examples of the application's usage.
        ZExamplesz--------r   N)examplesr   r   r   r   r/   r/   r0   r   6  s    zApplication.emit_examplesc                 C   s   t | j dS )zPrint the version string.N)r   versionr   r/   r/   r0   print_versionC  s    zApplication.print_versionc                 C   s   | j |\}}t|tr"t|}t|trPt|trP| j	  |j
| d| _n t|rd|| | _ntd| | j| dS )z"Initialize a subcommand with argv.)rP   z%Invalid mappings for subcommand '%s'!N)r   getr]   r^   r   typerL   rG   rB   Zclear_instanceinstancer   callableAssertionErrorr   )r?   r   r   r   _r/   r/   r0   initialize_subcommandG  s    

z!Application.initialize_subcommandc                 C   sf  t t}| jD ]0}|j}| dd D ]}||j | q(qi }| j D ]r\}}t|t	rh|\}}|
dd\}}	|| }
t|
dkr|
d }t|t	s|f}|D ]}d||	g||< qqNi }| j D ]\}\}}i }| D ]H\}}|| }
t|
dkr|
d }||v r(|| | q|||< qt|t	sD|f}|D ]}||f||< qHq||fS )a  Flatten flags and aliases for loaders, so cl-args override as expected.

        This prevents issues such as an alias pointing to InteractiveShell,
        but a config file setting the same trait in TerminalInteraciveShell
        getting inappropriate priority over the command-line arg.
        Also, loaders expect ``(key: longname)`` and not ````key: (longname, help)`` items.

        Only aliases with exactly one descendent in the class list
        will be promoted.

        r$   r   r   r   )r   listrH   r6   rK   appendr   r   r]   r   r   r   r   r   update)r?   Zmro_treer   ZclsnamerP   r   r   r   r   r   ZchildrenZalr   r   ZflagdictrY   ZnewflagZsubdictkr/   r/   r0   flatten_flags^  s@    




zApplication.flatten_flagsc                 C   s   t ||||| jdS )N)rH   r%   )r   r%   )r?   r   r   r   rH   r/   r/   r0   _create_loader  s    
zApplication._create_loaderc                    s  t |trJ |du r$tjdd n|}dd |D | _|rZ|d dkrZ|dd dg }| jrt|dkr|d |dd  }}td|r|| jv r| ||S z|d|	d	  W n t
y   | Y n0 t fd
ddD r| d v  | d d v sd v r(|   | d |  \}}t|  }| j||||d}zt| | _W n tyz    Y n0 | | j |j| _dS )z!Parse the command line arguments.Nr$   c                 S   s   g | ]}t |qS r/   r   )r   argr/   r/   r0   
<listcomp>      z2Application.parse_command_line.<locals>.<listcomp>r   rY   -hz^\w(\-?\w)*$r   c                 3   s   | ]}| v V  qd S ry   r/   )r   xZinterpreted_argvr/   r0   r     r   z1Application.parse_command_line.<locals>.<genexpr>)r   
--help-allz--helpr   z	--versionz-Vr   )r]   r^   rp   r   r   r   rematchr   index
ValueErroranyr   r(   r   r   r   r   r   r   load_config
cli_config
SystemExitupdate_config
extra_args)r?   r   r   Zsubargvr   r   rH   loaderr/   r   r0   r     s8    


zApplication.parse_command_linec                 c   sX  t |ts|g}|ddd D ]2}| j|d ||d}|rR|d||pNt  | j|d ||d}g }g }||fD ]}	d}
z|	 }
W nF ty   Y nH t	y   |	j
p|}|r |r|jd|dd	 Y n0 |r|d
|	j
 |
rvt||D ]:\}}||
}|r|r|d||	j
tj|dd q|
|	j
fV  ||
 ||	j
 qvqdS )zeLoad config files (py,json) by filename and path.

        yield each config object in turn.
        Nz.py)pathr%   zLooking for %s in %sz.jsonz&Exception while loading config file %sT)exc_infozLoaded config file: %szMCollisions detected in {0} and {1} config files. {1} has higher priority: {2}r   )r   )r]   r   python_config_loader_classr&   rt   getcwdjson_config_loader_classr   r   r   Zfull_filenamer   zip
collisionsZwarningr>   r   dumpsr   )r   Zbasefilenamer   r%   raise_config_file_errorsZpyloaderZ
jsonloaderZloaded	filenamesr   r'   filenameZearlier_configr  r/   r/   r0   _load_config_files  sF    



zApplication._load_config_filesc                 C   s   | j dd S )z$Currently loaded configuration filesN)r   r   r/   r/   r0   loaded_config_files  s    zApplication.loaded_config_filesc                 C   sp   t j|\}}t }| j||| j| jdD ](\}}|| || jvr,| j	| q,|| j
 | | dS )z'Load config files by filename and path.)r   r%   r  N)rt   r   splitextr	   r  r%   r  merger   r   r   r   )r?   r  r   extZ
new_configr'   r/   r/   r0   load_config_file  s    

zApplication.load_config_filec                 #   s   |du r| j }tdd | |D   fdd  }tfdd  D   |kr2q`q2  D ]\}}|rh|V  qhdS )a  
        Yields only classes with configurable traits, and their subclasses.

        :param classes:
            The list of classes to iterate; if not set, uses :attr:`classes`.

        Thus, produced sample config-file will contain all classes
        on which a trait-value may be overridden:

        - either on the class owning the trait,
        - or on its subclasses, even if those subclasses do not define
          any traits themselves.
        Nc                 s   s"   | ]}|t |jd dfV  qdS )TrZ   N)boolZclass_own_traits)r   r   r/   r/   r0   r   #  s   z:Application._classes_with_config_traits.<locals>.<genexpr>c                    s   t  fdd| jD S )Nc                 3   s   | ]}| v o | V  qd S ry   r/   )r   bcls_to_configr/   r0   r   (  r   zZApplication._classes_with_config_traits.<locals>.is_any_parent_included.<locals>.<genexpr>)r   	__bases__)r   r  r/   r0   is_any_parent_included'  s    zGApplication._classes_with_config_traits.<locals>.is_any_parent_includedc                 3   s"   | ]\}}||p |fV  qd S ry   r/   )r   r   inc_yes)r  r/   r0   r   /  s   )rH   r   rQ   r   r   )r?   rH   Zto_incl_origZclr  r/   )r  r  r0   r     s    z'Application._classes_with_config_traitsc                 C   sZ   d| j  g}|d |du r$| jn|}t| |}|D ]}||| q:d|S )z/generate default config file from Configurablesz# Configuration file for %s.r   Nr   )r   r   rH   r   r   Zclass_config_sectionr   )r?   rH   linesZconfig_classesr   r/   r/   r0   generate_config_file8  s    
z Application.generate_config_filer   c                 C   s    | j d| j  t| d S )NzExiting application: %s)r%   r&   r   rp   r(   )r?   exit_statusr/   r/   r0   r(   B  s    zApplication.exitc                 K   s&   | j f i |}|| |  dS )zLaunch a global instance of this Application

        If a global instance already exists, this reinitializes and starts it
        N)r   r   r|   )r   r   r+   r)   r/   r/   r0   launch_instanceF  s    
zApplication.launch_instance)N)N)F)F)N)N)NNF)N)N)N)r   )N)Zr6   r7   r8   rC   r   r   r   r   r   r   r   r   r   r   r   rH   rQ   r   r   r   r   r    r  r   rD   rE   tagr[   r   r   rb   r9   ri   rc   rd   rm   r   rv   r   rW   r   r   r   r   r   r   r	   r   r   rw   rx   r{   r~   r   r   r4   r   r|   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   classmethodr  propertyr  r  r   r  r(   r  rF   r/   r/   rA   r0   rG   x   s   

 


%(	

;0/

&


rG   c                 C   sV   |p
d| }|pd| }| d\}}||dii}||dii}| ||fd|  ||fiS )a  Helper for building basic --trait, --no-trait flags.

    Parameters
    ----------
    name : str
        The name of the flag.
    configurable : str
        The 'Class.trait' string of the trait to be set/unset with the flag
    set_help : unicode
        help string for --name flag
    unset_help : unicode
        help string for --no-name flag

    Returns
    -------
    cfg : dict
        A dict with two keys: 'name', and 'no-name', for setting and unsetting
        the trait, respectively.
    zset %s=Truezset %s=Falser   TFzno-)r   )r   ZconfigurableZset_helpZ
unset_helpr   r   setterZunsetterr/   r/   r0   boolean_flagW  s    r  c                   C   s   t  rt  jS t S dS )z|Get the config object for the global Application instance, if there is one

    otherwise return an empty config object
    N)rG   Zinitializedr   r'   r	   r/   r/   r/   r0   
get_configv  s    
r  __main__)r   r   )FrC   collectionsr   r   r   r   r2   r   rD   rt   r   r   rp   rf   Ztraitlets.config.configurabler   r   Ztraitlets.config.loaderr   r   r	   r
   r   r   Ztraitlets.traitletsr   r   r   r   r   r   r   r   r   r   Zutils.importstringr   Zutilsr   Ztraitlets.utils.textr   r   textwrapr   r   r   r   hasattrr   r   environr   Z_envvarlowerr    r   r4   r   r5   Z	Formatterr9   rG   r   Zdefault_aliasesr   Zdefault_flagsr  r  r6   r  r/   r/   r/   r0   <module>   sV    0
     a

