U
    ZfP                     @   s,  d dl Z d dlmZ d dlZd dlmZ d dlmZ d dlZddl	m
Z
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 Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Z d d! Z!d"d# Z"d$d% Z#d&d' Z$d(d) Z%d*d+ Z&d,d- Z'd.d/ Z(d0d1 Z)d2d3 Z*dS )4    N)MutableSequence)dedent)	iskeyword   )grouping_lenmap_grouping)	Component)
exceptions)patch_collections_abcstringify_idto_jsoncoerce_to_listclean_property_namec           
      C   s   |\}}}|rlt |d |||fs@ttdt|d  dttd| | | d d|d d| ||fD ]}|D ]}	t|	 q~qvd S )Nr   z
                    Callback arguments must be `Output`, `Input`, or `State` objects,
                    optionally wrapped in a list or tuple. We found (possibly after
                    unwrapping a list or tuple):
                    
                    z
                In a callback definition, you must provide all Outputs first,
                then all Inputs, then all States. After this item:
                z:
                we found this item next:
                
                )
isinstancer	   IncorrectTypeExceptionr   reprvalidate_callback_arg)
outputsinputsstate
extra_argstypesZInputOutputStateargsarg r   2/tmp/pip-unpacked-wheel-47crqvv_/dash/_validate.pyvalidate_callback   s$    

 r!   c                 C   s   t t| dd ts*ttd| jdt| dr>tdt | j	t
rTt|  n.t | j	trjt|  nttd| j	dd S )Ncomponent_propertyz<
                component_property must be a string, found r   Zcomponent_eventzd
            Events have been removed.
            Use the associated property instead.
            z>
                component_id must be a string or dict, found )r   getattrstrr	   r   r   r"   hasattrZNonExistentEventExceptioncomponent_iddictvalidate_id_dictvalidate_id_string)r   r   r   r    r   4   s&    


r   c              	   C   s:   | j }|D ]*}t|ts
ttd|d|dq
d S )Nz[
                    Wildcard ID keys must be non-empty strings,
                    found z in id r   )r&   r   r$   r	   r   r   )r   arg_idkr   r   r    r(   V   s    
r(   c              
      sN   | j  d} fdd|D }|rJtd  dd| dd| dd S )	Nz.{c                    s   g | ]}| kr|qS r   r   .0xr*   r   r    
<listcomp>l   s      z&validate_id_string.<locals>.<listcomp>z
            The element `z` contains `z`, `z%` in its ID.
            Characters `z&` are not allowed in IDs.
            )r&   r	   ZInvalidComponentIdErrorjoin)r   Zinvalid_charsZinvalid_foundr   r/   r    r)   h   s    r)   c                 C   s   t | ttfs| g|g } }nt| t|kr8tdt| |D ]N\}}t |ttfr\|n|g}|D ](}||d t|d |ksftdqfqBdS )z
    This validation is for security and internal debugging, not for users,
    so the messages are not intended to be clear.
    `output` comes from the callback definition, `output_spec` from the request.
    zWrong length output_specidpropertyz)Output does not match callback definitionN)r   listtuplelenr	   CallbackExceptionzipr   )outputoutput_specr   ZoutiZspeciZ
speci_listZspecijr   r   r    validate_output_specv   s    
r;   c                    s   t |t krtdt fdd|}t|trbg }|}|D ]}| sBt| dqBn&t|tt	fr~t	|}i }n
|g}i }||fS )Nz'Inputs do not match callback definitionc                    s    |  S Nr   )ind	flat_argsr   r    <lambda>       z/validate_and_group_input_args.<locals>.<lambda>z$ is not a valid Python variable name)
r   r6   r	   r7   r   r   r'   isidentifierr5   r4   )r?   Zarg_index_groupingZargs_grouping	func_argsZfunc_kwargskeyr   r>   r    validate_and_group_input_args   s"    

rE   c                 C   s
  t |ttfs*ttd| d|dt|t| kr`td| dt|  dt| dt| D ]\}}t |trh|| }t |ttfsttd| d	| d
|d|d	t|t|krhttd| d| dt| dt| d|d|dqhd S )Nz
                The callback zl is a multi-output.
                Expected the output type to be a list or tuple but got:
                z.
                z1
            Invalid number of output values for z.
            Expected z, got 
            z&
                        The callback z output z is a wildcard multi-output.
                        Expected the output type to be a list or tuple but got:
                        z'.
                        output spec: z
                        z=
                        Invalid number of output values for z item z#.
                        Expected z&
                        output spec: z'
                        output value: )r   r4   r5   r	   InvalidCallbackReturnValuer   r6   	enumerate)Zoutput_listsZoutput_valuesZcallback_idir:   output_valuer   r   r    validate_multi_return   sZ    

rK   c                    s   t tttd tft tttd ttfdfdd	fddfddfdd	 d fd
d	}t| trt	| D ]\}}|||d q~n||  t
ddd S )NFc                    s   t | j}t|ddr&d|jddnd}t |j}|rBtd}n<|d krNdnd	|d
d}	td|	 d| d| d| d	}|sdnd}
ttd d|
dd| d| d|  dd S )Nr2   Fz(id=s) z
                The value in question is either the only value returned,
                or is in the top level of the returned list,
                z[*][d]zE
                The value in question is located at
                 r   z,
                ztree with one valuevaluez#
                The callback for `z`
                returned a z having type `zC`
                which is not JSON serializable.

                z@
                and has string representation
                `z`

                In general, Dash properties can only be
                dash components, strings, dictionaries, numbers, None,
                or lists of those.
                )type__name__r#   r2   r   r	   rG   )bad_val	outer_valpathindextoplevelZbad_typeZouter_idZ
outer_typelocationZindex_stringobj)r9   r   r    _raise_invalid   s>    
 
z,fail_callback_output.<locals>._raise_invalidc                    s
   t |  S r<   r   val)valid_childrenr   r    _valid_child  s    z*fail_callback_output.<locals>._valid_childc                    s
   t |  S r<   r^   r_   )valid_propsr   r    _valid_prop  s    z)fail_callback_output.<locals>._valid_propc                    s<    | s| sdS zt |  W n tk
r6   Y dS X dS )NFT)r   	TypeErrorr_   )rb   rd   r   r    _can_serialize  s    z,fail_callback_output.<locals>._can_serializec                    sP  t | tr*g }|  D ]\ }|s8||  |d |s~ fdd|D }|rZ qt fdd|D r~| |f t|dd }t |ttfs|r|s||  d d t|j	 |d q|r|d	 \ }||  |d t| dd }t |ttfs*|r*| s*|| t|j	|d | sL| t| j	d
|dd d S )N)rV   rW   rX   rY   c                    s   g | ]}  |d  s|qS r   
startswithr-   rI   pr   r    r0     s     zAfail_callback_output.<locals>._validate_value.<locals>.<listcomp>c                 3   s   | ]}|d     V  qdS )r   Nrh   rj   rk   r   r    	<genexpr>%  s     z@fail_callback_output.<locals>._validate_value.<locals>.<genexpr>children
z[*] r   rN   T)rV   rW   rX   rY   rZ   )
r   r   Z_traverse_with_pathsallappendr#   r5   r   rT   rU   )r`   rY   Zunserializable_itemsjchild)rf   r]   rb   rk   r    _validate_value  sT    

z-fail_callback_output.<locals>._validate_valuerY   z"
        The callback for output `z`
        returned a value which is not JSON serializable.

        In general, Dash properties can only be dash components, strings,
        dictionaries, numbers, None, or lists of those.
        )NF)N)r$   intfloatrT   r   r5   r   r   r4   rH   r	   rG   )rJ   r9   rt   rI   r`   r   )rf   r]   rb   rd   r9   ra   rc   r    fail_callback_output   s    (	=

rx   c                 C   sV   | D ]L}|dkr"t d| d|dkr@t| dtjd qtd| dqd S )	N)Zcomponents_cache_max_ageZstatic_folderr   z is no longer a valid keyword argument in Dash since v1.0.
                See https://dash.plotly.com for details.
                )Zdynamic_loadingZpreloaded_librarieszA has been removed and no longer a valid keyword argument in Dash.)filez+Dash() got an unexpected keyword argument '')r	   ZObsoleteKwargExceptionprintsysstderrre   )kwargsrD   r   r   r    check_obsolete_  s    r   c              	   C   sV   || kr(t d| dt|   d|| | krRt d| d| d|  dd S )Nz(
            Error loading dependency. "zQ" is not a registered library.
            Registered libraries are:
            rF   z
            "zV" is registered but the path requested is not valid.
            The path requested: "z("
            List of registered paths: )r	   ZDependencyExceptionr4   keys)Zregistered_pathspackage_nameZpath_in_package_distr   r   r    validate_js_paths  s$    
r   c              	      sR    fdd|D }|rNt |dkr&dnd}td| dd| d	|  d
d S )Nc                    s$   g | ]\}}t | s|qS r   )recompilesearch)r-   checkrI   ru   r   r    r0     s      z"validate_index.<locals>.<listcomp>r   rL   rN   zMissing itemrR   z, z in .)r6   r	   ZInvalidIndexExceptionr1   )nameZchecksrY   missingpluralr   ru   r    validate_index  s    r   c                 C   s$   t | ttdttfs tdd S )NCallablez
            Layout must be a single dash component, a list of dash components,
            or a function that returns a dash component.
            )r   r   r
   r4   r5   r	   NoLayoutException)rS   r   r   r    validate_layout_type  s     r   c                    sx   | d krt dt   fdd}t|ttfrl|D ]2}t|tfrHq6t|tfr^|| q6t dq6n|| d S )Nz
            The layout was `None` at the time that `run_server` was called.
            Make sure to set the `layout` attribute of your application
            before running the server.
            c                    s.    fdd}||  |   D ]}|| qd S )Nc                    s<   t t| dd }|r.| kr.td| d | d S )Nr2   zJ
                    Duplicate component id found in the initial layout: `z`
                    )r   r#   r	   ZDuplicateIdErroradd)compr&   Zcomponent_idsr   r    _validate_id  s    z8validate_layout.<locals>._validate.<locals>._validate_id)Z	_traverse)rS   r   	componentr   r   r    	_validate  s    
z"validate_layout.<locals>._validatez9Only strings and components are allowed in a list layout.)r	   r   setr   r4   r5   r$   r   )layoutZlayout_valuer   r   r   r   r    validate_layout  s     
r   c                 C   s@   t d| }|D ]*}| r$t|rtd| d|  dqd S )Nz<(.*?)>`z;` is not a valid Python variable name in `path_template`: "z".)r   findallrB   r   	Exception)templateZvariable_namesr   r   r   r    validate_template  s    r   c                 C   sv   i }|   D ]:}|d |kr0|d g||d < q||d  |d  q|  D ] }t|dkrPtd| dqPd S )NrX   moduler   zmodules z have duplicate paths)valuesrq   r6   r   )registryZpath_to_modulepagemodulesr   r   r    check_for_duplicate_pathnames  s    r   c                 C   sD   |   D ]6}d|kr*td|d  d|d dkrtdqd S )Nr   zNo layout in module `r   z` in dash.page_registry__main__z
                When registering pages from app.py, `__name__` is not a valid module name.  Use a string instead.
                For example, `dash.register_page("my_module_name")`, rather than `dash.register_page(__name__)`
                )r   r	   r   r   )r   r   r   r   r    validate_registry  s    r   c                 C   s    t |dstd|  dd S )Nr   z'
            No layout found in module zN
            A variable or a function named "layout" is required.
            )r%   r	   r   )r   r   r   r   r    validate_pages_layout  s    
r   c                 C   s,   |  dd stdt r(tdd S )NZassets_folderz=`dash.register_page()` must be called after app instantiationu  
            dash.register_page() can’t be called within a callback as it updates dash.page_registry, which is a global variable.
             For more details, see https://dash.plotly.com/sharing-data-between-callbacks#why-global-variables-will-break-your-app
            )getr	   	PageErrorflaskZhas_request_context)configr   r   r    validate_use_pages  s    r   c                 C   s   t | tstd| S )NzJThe first attribute of dash.register_page() must be a string or '__name__')r   r$   r	   r   )r   r   r   r    validate_module_name  s
    
r   c           
         s   t  }i }|  D ]H}t|d }|| |D ](}||t   || t|d  q0qdd |  D D ]}|d }|dg }|dg }t|d  t dd	 |D |  fd
d	t fdd| D D }	|	rntd|	 dqnd S )Nr9   Z
raw_inputsc                 s   s   | ]}| d r|V  qdS )longN)r   r,   r   r   r    rm     s     
 z*validate_long_callbacks.<locals>.<genexpr>r   progressrunningc                 S   s   g | ]}|d  qS rg   r   r,   r   r   r    r0     s     z+validate_long_callbacks.<locals>.<listcomp>c                    s   g | ]}| kr|qS r   r   r,   )long_inputsr   r    r0      s   c                 3   s    | ]\}}|  r|V  qd S r<   )intersection)r-   r+   v)r   r   r    rm   "  s     
 zLong callback circular error!
z~ is used as input for a long callback but also used as output from an input that is updated with progress or running argument.)	r   r   r   update
setdefaultr   itemsr	   ZLongCallbackError)
Zcallback_mapZall_outputsZinput_indexedcallbackoutoZ	long_infor   r   Zcircularr   )r   r   r    validate_long_callbacks  s*    


r   c                    sN   d fkrd S  fdd}t | ttfrB| D ]}|| q0d S ||  d S )NZinitial_duplicatec                    s   | j rs stdd S )Na*  allow_duplicate requires prevent_initial_call to be True. The order of the call is not guaranteed to be the same on every page load. To enable duplicate callback with initial call, set prevent_initial_call='initial_duplicate'  or globally in the config prevent_initial_callbacks='initial_duplicate')Zallow_duplicater	   ZDuplicateCallback)r   config_prevent_initial_callprevent_initial_callr   r    _valid3  s    z)validate_duplicate_output.<locals>._valid)r   r4   r5   )r9   r   r   r   r   r   r   r    validate_duplicate_output-  s    
r   )+r|   collections.abcr   r   textwrapr   keywordr   r   Z	_groupingr   r   Zdevelopment.base_componentr   rN   r	   _utilsr
   r   r   r   r   r!   r   r(   r)   r;   rE   rK   rx   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    <module>   s>   	 "0 	*

 