U
    ZfX                     @   s   d dl mZ d dl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 ddlmZmZ dd	lmZ d+d
dZd,ddZdd Zdd Zd-ddZdd Zd.ddZdd Zdd Zdd Zdd Zd d! Zd/d#d$Zd%d& Zd'd( Z d0d)d*Z!dS )1    )OrderedDictN)filldedent)_explicitize_argsNonExistentEventException   )python_keywords)collect_nodesfilter_base_nodes)	Componentc                    s  d}|dk	r| |ks$|dk	r,d|kr,t  n
tt  }tt }tttt| }	t| |||d	dd}
t
|}d|k}dd	 |D }t  t  }d krd|	kr|d d
}d}d}nd}d}d}t|dkrd}nd| d}|r|d7 } fdd	|D }|rT|d kr,dnd }t||krT|d| }|
d7 }
|d|dg 7 }tdd   D }t|j| ||||	|
|||||t|dg dS )a;  Dynamically generate class strings to have nicely formatted docstrings,
    keyword arguments, and repr.
    Inspired by http://jameso.be/2013/08/06/namedtuple.html
    Parameters
    ----------
    typename
    props
    description
    namespace
    prop_reorder_exceptions
    Returns
    -------
    string
    a  class {typename}(Component):
    """{docstring}"""
    _children_props = {children_props}
    _base_nodes = {base_nodes}
    _namespace = '{namespace}'
    _type = '{typename}'
    @_explicitize_args
    def __init__(self, {default_argtext}):
        self._prop_names = {list_of_valid_keys}
        self._valid_wildcard_attributes =            {list_of_valid_wildcard_attr_prefixes}
        self.available_properties = {list_of_valid_keys}
        self.available_wildcard_properties =            {list_of_valid_wildcard_attr_prefixes}
        _explicit_args = kwargs.pop('_explicit_args')
        _locals = locals()
        _locals.update(kwargs)  # For wildcard attrs and excess named props
        args = {args}
        {required_validation}
        super({typename}, self).__init__({argtext})
NALL)component_namepropsdescriptionprop_reorder_exceptionsz

childrenc                 S   s   g | ]}|d kr|qS r    ).0argr   r   N/tmp/pip-unpacked-wheel-47crqvv_/dash/development/_py_components_generation.py
<listcomp>Y   s      z)generate_class_string.<locals>.<listcomp>zchildren=None, z:{k: _locals[k] for k in _explicit_args if k != 'children'}zchildren=children, **args z'{k: _locals[k] for k in _explicit_args}z**argsr   z
        for k in z:
            if k not in args:
                raise TypeError(
                    'Required argument `' + k + '` was not specified.')
        z
        if 'children' not in _explicit_args:
            raise TypeError('Required argument children was not specified.')
        c                    sJ   g | ]B}| d s|tkr|dkr | d r:|ddn
|ddqS )z-*ZsetPropsrequiredsz=Component.REQUIREDz=Component.UNDEFINED)endswithr	   )r   pr   r   r   r   y   s   
  
r   z

Note: due to the large number of props for this component,
not all of them appear in the constructor signature, but
they may still be used as keyword arguments., z**kwargsc                 S   s   i | ]\}}|d kr||qS r   r   )r   kvr   r   r   
<dictcomp>   s       z)generate_class_string.<locals>.<dictcomp>)typename	namespacefiltered_props$list_of_valid_wildcard_attr_prefixeslist_of_valid_keys	docstringdefault_argtextargsargtextrequired_validationZchildren_propsZ
base_nodes)filter_propsreorder_propsreprparse_wildcardslistmapstrkeyscreate_docstringreplacerequired_propsprohibit_eventsremovelenjoinr
   itemsr   formatr   )r$   r   r   r%   r   	max_propscr&   Zwildcard_prefixesr(   r)   Zrequired_argsZis_children_requiredZ	prop_keysr*   r+   r,   r-   Zdefault_arglistZfinal_max_propsZnodesr   r   r   generate_class_string   s    %

 


rA   c              	   C   sp   d}t | |||||}| dd}tj||}	t|	ddd}
|
| |
| W 5 Q R X td|  dS )	zGenerate a Python class file (.py) given a class string.
    Parameters
    ----------
    typename
    props
    description
    namespace
    prop_reorder_exceptions
    Returns
    -------
    zp# AUTO GENERATED FILE - DO NOT EDIT

from dash.development.base_component import Component, _explicitize_args


r   z.pywutf-8encodingz
Generated N)rA   ospathr<   openwriteprint)r$   r   r   r%   r   r?   Zimport_stringZclass_string	file_name	file_pathfr   r   r   generate_class_file   s          
rN   c              	   C   sj   t tj| ddddH}ddd |D }dd	d |D }| d
| d}|| W 5 Q R X d S )Nz_imports_.pyrB   rC   rD   r   c                 s   s   | ]}d | d| V  qdS )zfrom .z import Nr   r   xr   r   r   	<genexpr>   s     z#generate_imports.<locals>.<genexpr>z,
c                 s   s   | ]}d | dV  qdS )z    ""Nr   rO   r   r   r   rQ      s     z

__all__ = [
z
])rH   rF   rG   r<   rI   )project_shortname
componentsrM   Zcomponent_importsZall_listZimports_stringr   r   r   generate_imports   s      rU   c                 G   s\   g }|  D ]J\}}|dd dd }|| |D ]}|||d |d |  q:q|S )N/.r   r   r   )r=   splitappend)rS   metadataZcomponent_generatorsrT   Zcomponent_pathZcomponent_datar   	generatorr   r   r   generate_classes_files   s    
r]   c                 C   s0   t | ||||}ttd}t|| ||  }|S )zGenerate a Python class object given a class string.
    Parameters
    ----------
    typename
    props
    description
    namespace
    Returns
    -------
    )r   r   )rA   r   r   exec)r$   r   r   r%   r   stringZscoperesultr   r   r   generate_class   s        

ra   c                 C   s   dd t |  D S )zPull names of required props from the props object.
    Parameters
    ----------
    props: dict
    Returns
    -------
    list
        List of prop names (str) that are required for the Component
    c                 S   s   g | ]\}}|d  r|qS )r   r   r   	prop_namepropr   r   r   r     s      z"required_props.<locals>.<listcomp>)r2   r=   r   r   r   r   r8      s    
r8   c                 C   s|   |dk	r| |ks |dk	r$d|kr$|nt |}| d  dkr@dnd}ddd	 t| D }d
| d|  d| d| S )a5  Create the Dash component docstring.
    Parameters
    ----------
    component_name: str
        Component name
    props: dict
        Dictionary with {propName: propMetadata} structure
    description: str
        Component description
    Returns
    -------
    str
        Dash component docstring
    Nr   r   Zaeiounr   r   c              
   s   sV   | ]N\}}t |d |kr|d  n|d |d |d |ddd|koHd |kdV  qdS )typeflowTyper   r   defaultValuer   rc   type_objectr   r   default
indent_numis_flow_typeNcreate_prop_docstringget)r   r   rd   r   r   r   rQ   $  s   
z#create_docstring.<locals>.<genexpr>A z component.
z

Keyword arguments:
)r/   lowerr<   r.   r=   )r   r   r   r   re   r+   r   r   r   r6   	  s     



r6   c                 C   s   d| ksd| krt ddS )zEvents have been removed. Raise an error if we see dashEvents or
    fireEvents.
    Parameters
    ----------
    props: dict
        Dictionary with {propName: propMetadata} structure
    Raises
    -------
    ?
    Z
dashEventsZ
fireEventsziEvents are no longer supported by dash. Use properties instead, eg `n_clicks` instead of a `click` event.Nr   r   r   r   r   r9   6  s    r9   c                 C   s,   g }dD ]}|| kr| |dd  q|S )zPull out the wildcard attributes from the Component props.
    Parameters
    ----------
    props: dict
        Dictionary with {propName: propMetadata} structure
    Returns
    -------
    list
        List of Dash valid wildcard prefixes
    )zdata-*zaria-*NrW   )rZ   )r   r'   Zwildcard_attrr   r   r   r1   H  s
    r1   c                 C   s@   d| krdgng }d| kr dgng }t || tt|   S )aV  If "children" is in props, then move it to the front to respect dash
    convention, then 'id', then the remaining props sorted by prop name
    Parameters
    ----------
    props: dict
        Dictionary with {propName: propMetadata} structure
    Returns
    -------
    dict
        Dictionary with {propName: propMetadata} structure
    r   )r   r   id)rt   r   )r   sortedr2   r=   )r   Zprops1Zprops2r   r   r   r/   Z  s    r/   c                 C   s   t | }t| D ]\}}d|kr:d|kr:|| qd|krb|d d }|dkr|| qd|kr|d d }|dkrd|d ks|d d dkr|| qtq|S )a  Filter props from the Component arguments to exclude:
        - Those without a "type" or a "flowType" field
        - Those with arg.type.name in {'func', 'symbol', 'instanceOf'}
    Parameters
    ----------
    props: dict
        Dictionary with {propName: propMetadata} structure
    Returns
    -------
    dict
        Filtered dictionary with {propName: propMetadata} structure
    Examples
    --------
    ```python
    prop_args = {
        'prop1': {
            'type': {'name': 'bool'},
            'required': False,
            'description': 'A description',
            'flowType': {},
            'defaultValue': {'value': 'false', 'computed': False},
        },
        'prop2': {'description': 'A prop without a type'},
        'prop3': {
            'type': {'name': 'func'},
            'description': 'A function prop',
        },
    }
    # filtered_prop_args is now
    # {
    #    'prop1': {
    #        'type': {'name': 'bool'},
    #        'required': False,
    #        'description': 'A description',
    #        'flowType': {},
    #        'defaultValue': {'value': 'false', 'computed': False},
    #    },
    # }
    filtered_prop_args = filter_props(prop_args)
    ```
    rf   rg   name>   
instanceOfsymbolfunc	signatureobject)copydeepcopyr2   r=   pop
ValueError)r   r&   Zarg_namer   Zarg_typeZarg_type_namer   r   r   r.   o  s     *

r.   c                 C   s.   dddd}|  D ]\}}| ||} q| S )zM
    replaces javascript keywords true, false, null with Python keywords
    TrueFalseNone)truefalsenull)r=   r7   )txtZfix_wordZ
js_keywordZpython_keywordr   r   r   fix_keywords  s    r   Fc                 C   s  t |||d}d| }|r"|d nd}t|}d}	|r<d}	n|rX|dkrXd|d	d }	|r`d
nd}
| d
dd|
 }|d }t|||ddd}|rd	| nd}|rdnd}t|}d	|kr|drdnd}|d\}}}d|  d| | }t|||ddd}d|krH|dd\}}d|d|g}| d| }|	d	
d}|t|kr~ddd | D }d	| d|  d | d!|	 d"| | d#| | S |r| d!nd}d	| d|  d | |	 d"| | 
S )$a  Create the Dash component prop docstring.
    Parameters
    ----------
    prop_name: str
        Name of the Dash component prop
    type_object: dict
        react-docgen-generated prop type dictionary
    required: bool
        Component is required?
    description: str
        Dash component description
    default: dict
        Either None if a default value is not defined, or
        dict containing the key 'value' that defines a
        default value for the prop
    indent_num: int
        Number of indents to use for the context block
        (creates 2 spaces for every indent)
    is_flow_type: bool
        Does the prop use Flow types? Otherwise, uses PropTypes
    Returns
    -------
    str
        Dash component prop docstring
    )rj   rm   rl   z  valuer   optionalr   )r   z{}z[]zdefault r   rX   rR   z\"z    F)initial_indentsubsequent_indentbreak_long_wordsbreak_on_hyphens:r2   zlist of dictsdictz
with keys:`z` is a z| dict with keys:z |r   Orz

  -c                 s   s   | ]}|d krd| V  qdS )r   z

    Nr   )r   liner   r   r   rQ     s     z(create_prop_docstring.<locals>.<genexpr>z- z (z; )z

)js_to_py_typer   r7   stripr   
startswith	partitionrY   r<   lstripfindr;   
splitlines)rc   rj   r   r   rk   rl   rm   Zpy_type_nameZindent_spacingZis_requiredZperiodZdesc_indentcolonZdict_or_listZintro1Zintro2Z
dict_descrZintroZ
dict_part1Z
dict_part2current_indenttnr   r   r   ro     sd    "  
	

.ro   c                    s    fdd}fdd}fdd}t dd d	d d
d dd dd dd dd dd fddfdd|fdd|||dS )z=Mapping from the PropTypes js type object to the Python type.c                      s,   dd  fddttd  D  S )Ndict with keys:
r   c              	   3   s<   | ]4\}}t |||d  |dd|d d dV  qdS )r   r   r   rh      )rc   rj   r   r   rk   rl   Nrn   rb   rl   r   r   rQ   '  s   	
zHmap_js_to_py_types_prop_types.<locals>.shape_or_exact.<locals>.<genexpr>r   )r<   ru   r2   r=   r   rl   rj   r   r   shape_or_exact&  s    	z5map_js_to_py_types_prop_types.<locals>.shape_or_exactc                     s@   t  d } | r<d| dd dkr,| d n| ddd S d	S )
Nr   list of rr   r   r   r   Zdictsr   r2   )r   rY   r7   )innerrj   r   r   array_of3  s    
z/map_js_to_py_types_prop_types.<locals>.array_ofc                     s.   dd  d D } dt |  dd|  dS )Nc                 S   s   g | ]}t |qS r   r   )r   elementr   r   r   r   >  s     zCmap_js_to_py_types_prop_types.<locals>.tuple_of.<locals>.<listcomp>elementsr   z elements: [r    ])r;   r<   )r   r   r   r   tuple_of=  s    z/map_js_to_py_types_prop_types.<locals>.tuple_ofc                   S   s   dS Nr2   r   r   r   r   r   <lambda>B      z/map_js_to_py_types_prop_types.<locals>.<lambda>c                   S   s   dS Nbooleanr   r   r   r   r   r   C  r   c                   S   s   dS Nnumberr   r   r   r   r   r   D  r   c                   S   s   dS Nr_   r   r   r   r   r   r   E  r   c                   S   s   dS Nr   r   r   r   r   r   r   F  r   c                   S   s   dS )Nz'boolean | number | string | dict | listr   r   r   r   r   r   G  r   c                   S   s   dS Nzdash componentr   r   r   r   r   r   H  r   c                   S   s   dS Nz8a list of or a singular dash component, string or numberr   r   r   r   r   r   I  r   c                      s   dd dd  d D  S )Nza value equal to: r    c                 s   s   | ]}t |d  V  qdS )r   N)r4   )r   tr   r   r   rQ   M  s     Bmap_js_to_py_types_prop_types.<locals>.<lambda>.<locals>.<genexpr>r   r<   r   r   r   r   r   K  s    c                      s   d dd  d D S )N | c                 s   s"   | ]}t |d krt |V  qdS r   Nr   r   ZsubTyper   r   r   rQ   P  s   r   r   r   r   r   r   r   r   P  s   
c                      s   dt  d  S )Nz-dict with strings as keys and values of type r   r   r   r   r   r   r   X  s    
)arrayboolr   r_   r{   anyr   nodeenumunionZarrayOfZobjectOfshapeexacttupler   )rj   rl   r   r   r   r   r   r   map_js_to_py_types_prop_types#  s(    



r   c                    sV   t dd dd dd dd dd dd dd d	d  fd
d fdd fdddS )z2Mapping from the Flow js types to the Python type.c                   S   s   dS r   r   r   r   r   r   r   g  r   z/map_js_to_py_types_flow_types.<locals>.<lambda>c                   S   s   dS r   r   r   r   r   r   r   h  r   c                   S   s   dS r   r   r   r   r   r   r   i  r   c                   S   s   dS r   r   r   r   r   r   r   j  r   c                   S   s   dS r   r   r   r   r   r   r   k  r   c                   S   s   dS )Nz!bool | number | str | dict | listr   r   r   r   r   r   l  r   c                   S   s   dS r   r   r   r   r   r   r   m  r   c                   S   s   dS r   r   r   r   r   r   r   n  r   c                      s   d dd  d D S )Nr   c                 s   s"   | ]}t |d krt |V  qdS r   r   r   r   r   r   rQ   p  s   Bmap_js_to_py_types_flow_types.<locals>.<lambda>.<locals>.<genexpr>r   r   r   r   r   r   r   p  s   
c                      s4   dt  d d dkr.dt  d d  dnd S )Nr2   r   r   r   z of r   r   r   r   r   r   r   v  s   c                    s$   dd  fddd d D  S )Nr   r   c              
   3   sJ   | ]B}t |d  |d |d d |d dd|d d ddV  qd	S )
keyr   r   r   r   rh   r   Tri   Nrn   )r   rd   r   r   r   rQ     s   

r   rz   Z
propertiesr   r   r   r   r   r   }  s
    

)r   r   r   r_   ZObjectr   ElementNoder   Arrayrz   r   r   r   r   r   map_js_to_py_types_flow_typesd  s    


r   c                 C   sp   | d }|rt | dn
t| |d}d| kr2| d sB| dddkrFdS ||krl|dkrb|| |S ||  S dS )	a  Convert JS types to Python types for the component definition.
    Parameters
    ----------
    type_object: dict
        react-docgen-generated prop type dictionary
    is_flow_type: bool
        Does the prop use Flow types? Otherwise, uses PropTypes
    indent_num: int
        Number of indents to use for the docstring for the prop
    Returns
    -------
    str
        Python type string
    rv   r   )rj   rl   Zcomputedrf   r   functionrz   )r   r   rp   )rj   rm   rl   Zjs_type_nameZjs_to_py_typesr   r   r   r     s(     	
r   )NN)NN)N)N)F)Fr   )"collectionsr   r|   rF   textwrapr   r   Zdash.development.base_componentr   Zdash.exceptionsr   Z_all_keywordsr	   Z_collect_nodesr
   r   Zbase_componentr   rA   rN   rU   r]   ra   r8   r6   r9   r1   r/   r.   r   ro   r   r   r   r   r   r   r   <module>   s>   	  
   
& 

-D 
dA+