a
    `"                     @   s   d dl Z d dlZd dlZd dlZd dlZG dd dejZG dd dejZG dd deZ	G dd	 d	eZ
d
d Zdd Zdd ZdddZdd Zdd Zdd ZdS )    Nc                       s8   e Zd ZdZ fddZdd Zdd Zdd	 Z  ZS )
NameVisitorzQ
    NodeVisitor that builds a set of all of the named identifiers in an AST
    c                    s"   t t| j|i | t | _d S N)superr   __init__setnames)selfargskwargs	__class__ 0lib/python3.9/site-packages/datashader/macros.pyr      s    zNameVisitor.__init__c                 C   s   | j |j d S r   )r   addidr   noder   r   r   
visit_Name   s    zNameVisitor.visit_Namec                 C   s6   t |dr| j|j nt |dr2| j|j d S )Nargr   )hasattrr   r   r   r   r   r   r   r   	visit_arg   s    

zNameVisitor.visit_argc                    sV   t d  fdd| jD }|r:tdd |D d }nd}dd t||| D S )aD  
        Returns a list of new names that are not already present in the AST.

        New names will have the form _N, for N a non-negative integer. If the
        AST has no existing identifiers of this form, then the returned names
        will start at 0 ('_0', '_1', '_2'). If the AST already has identifiers
        of this form, then the names returned will not include the existing
        identifiers.

        Parameters
        ----------
        num_names: int
            The number of new names to return

        Returns
        -------
        list of str
        z^_(\d+)$c                    s   g | ]}  |r|qS r   )match.0nZprop_rer   r   
<listcomp>0       z-NameVisitor.get_new_names.<locals>.<listcomp>c                 S   s   g | ]}t |d d qS )   N)intr   r   r   r   r   2   r   r   r   c                 S   s   g | ]}d t | qS )_)strr   r   r   r   r   6   r   )recompiler   maxrange)r   Z	num_namesZmatching_namesZstart_numberr   r   r   get_new_names   s    
zNameVisitor.get_new_names)	__name__
__module____qualname____doc__r   r   r   r&   __classcell__r   r   r   r   r      s
   r   c                       s    e Zd ZdZ fddZ  ZS )ExpandVarargTransformerz
    Node transformer that replaces the starred use of a variable in an AST
    with a collection of unstarred named variables.
    c                    s&   t t| j|i | || _|| _dS )a  
        Parameters
        ----------
        starred_name: str
            The name of the starred variable to replace
        expand_names: list of stf
            List of the new names that should be used to replace the starred
            variable

        N)r   r,   r   starred_nameexpand_names)r   r-   r.   r	   r
   r   r   r   r   ?   s    z ExpandVarargTransformer.__init__)r'   r(   r)   r*   r   r+   r   r   r   r   r,   :   s   r,   c                   @   s   e Zd Zdd ZdS )ExpandVarargTransformerStarredc                    s*    j j| jkr" fdd| jD S  S d S )Nc                    s   g | ]}t j| jd qS r   ctx)astNamer2   r   namer   r   r   r   S   r   z@ExpandVarargTransformerStarred.visit_Starred.<locals>.<listcomp>)valuer   r-   r.   r   r   r7   r   visit_StarredQ   s
    
z,ExpandVarargTransformerStarred.visit_StarredN)r'   r(   r)   r9   r   r   r   r   r/   O   s   r/   c                   @   s   e Zd Zdd ZdS )ExpandVarargTransformerCallArgc                 C   sD   t |dd r<|jj| jkr<d |_|jdd | jD  |S |S d S )Nstarargsc                 S   s   g | ]}t j|t  d qS r0   )r3   r4   ZLoadr5   r   r   r   r   ^   s   z=ExpandVarargTransformerCallArg.visit_Call.<locals>.<listcomp>)getattrr;   r   r-   r	   extendr.   r   r   r   r   
visit_Call[   s    z)ExpandVarargTransformerCallArg.visit_CallN)r'   r(   r)   r>   r   r   r   r   r:   Y   s   r:   c                 C   s   t t| }t|}|S )z2
    Get the AST representation of a function
    )textwrapdedentinspectZ	getsourcer3   parse)fnZ	fn_sourcefn_astr   r   r   function_to_aste   s    
rE   c                 C   s   ddl }|| S )z9Convert AST to source code string using the astor packager   N)astorZ	to_source)r3   rF   r   r   r   ast_to_sourcev   s    rG   c                 C   s>   t | tjsJ | jd }t |tjs*J t| d|j ddS )zO
    Compile function AST into a code object suitable for use in eval/exec
    r   z<%s>exec)mode)
isinstancer3   ModulebodyFunctionDefr#   r6   )rD   	fndef_astr   r   r   compile_function_ast|   s    
rO   r   c           
      C   s   t | tjsJ | jd }t |tjs*J t| }t }|}t|D ]
}|j	}qF|j
}|j}~t|}	|	| t||	 |	|j S )Nr   )rJ   r3   rK   rL   rM   rO   rA   Zcurrentframer%   f_backf_locals	f_globalscopyupdateevalr6   )
rD   
stacklevelrN   codeZcurrent_frameZ
eval_framer    Zeval_localsZeval_globalsZscoper   r   r   function_ast_to_function   s    



rX   c                 C   s8   zt j| dW S  ty2   t j| t  d Y S 0 d S )N)r   r1   )r3   r   AttributeErrorr4   ZParamr6   r   r   r   
_build_arg   s    r[   c                 C   s  t | tjsJ t| } | jd }t |tjs4J |j}|j}|sLt	d|sTJ t |t
rd|}n|j}t }||  ||}ttdrt}nt}|||| }	|	jd }
|
jjdd |D  d|
j_t }||	 ||jv rt	dj|dg |_t|	 |	S )	a  
    Given a function AST that use a variable length positional argument
    (e.g. *args), return a function that replaces the use of this argument
    with one or more fixed arguments.

    To be supported, a function must have a starred argument in the function
    signature, and it may only use this argument in starred form as the
    input to other functions.

    For example, suppose expand_number is 3 and fn_ast is an AST
    representing this function...

    def my_fn1(a, b, *args):
        print(a, b)
        other_fn(a, b, *args)

    Then this function will return the AST of a function equivalent to...

    def my_fn1(a, b, _0, _1, _2):
        print(a, b)
        other_fn(a, b, _0, _1, _2)

    If the input function uses `args` for anything other than passing it to
    other functions in starred form, an error will be raised.

    Parameters
    ----------
    fn_ast: ast.FunctionDef
    expand_number: int

    Returns
    -------
    ast.FunctionDef
    r   zmInput function AST does not have a variable length positional argument
(e.g. *args) in the function signatureZStarredc                 S   s   g | ]}t |d qS )rZ   )r[   r5   r   r   r   r      r   z/expand_function_ast_varargs.<locals>.<listcomp>NzNThe variable length positional argument {n} is used in an unsupported context
)r   )rJ   r3   rK   rS   deepcopyrL   rM   r	   vararg
ValueErrorr!   r   r   Zvisitr&   r   r/   r:   r=   r   formatdecorator_listZfix_missing_locations)rD   expand_numberrN   Zfn_argsZ	fn_varargZvararg_nameZbefore_name_visitorr.   Zexpand_transformerZ
new_fn_astZnew_fndef_astZafter_name_visitorr   r   r   expand_function_ast_varargs   sJ    #









rb   c                    s*   t  tr dk rtd fdd}|S )aX  
    Decorator to expand the variable length (starred) argument in a function
    signature with a fixed number of arguments.

    Parameters
    ----------
    expand_number: int
        The number of fixed arguments that should replace the variable length
        argument

    Returns
    -------
    function
        Decorator Function
    r   z,expand_number must be a non-negative integerc                    s   t | }t| }t|ddS )N   )rV   )rE   rb   rX   )rC   rD   Zfn_expanded_astra   r   r   _expand_varargs*  s    
z'expand_varargs.<locals>._expand_varargs)rJ   r   r^   )ra   re   r   rd   r   expand_varargs  s    rf   )r   )r"   rS   rA   r3   r?   ZNodeVisitorr   ZNodeTransformerr,   r/   r:   rE   rG   rO   rX   r[   rb   rf   r   r   r   r   <module>   s   /


	k