
    |Le                          d Z ddlZddlZddlZddlZddlZ G d dej                  Z G d dej                  Z	 G d de	          Z
d	 Zd
 Zd ZddZd Zd Zd ZdS )zJ
Utilities for manipulating the Abstract Syntax Tree of Python constructs
    Nc                   4     e Zd ZdZ fdZd Zd Zd Z xZS )NameVisitorzQ
    NodeVisitor that builds a set of all of the named identifiers in an AST
    c                 n     t          t          |           j        |i | t                      | _        d S N)superr   __init__setnames)selfargskwargs	__class__s      1lib/python3.11/site-packages/datashader/macros.pyr   zNameVisitor.__init__   s4    )k4  )4:6:::UU


    c                 D    | j                             |j                   d S r   )r
   addidr   nodes     r   
visit_NamezNameVisitor.visit_Name   s    
twr   c                     t          |d          r!| j                            |j                   d S t          |d          r!| j                            |j                   d S d S )Nargr   )hasattrr
   r   r   r   r   s     r   	visit_argzNameVisitor.visit_arg   sh    4 	$JNN48$$$$$T4   	$JNN47#####	$ 	$r   c                     t          j        d          fd| j        D             }|rt          d |D                       dz   }nd}d t	          |||z             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                 >    g | ]}                     |          |S  )match).0nprop_res     r   
<listcomp>z-NameVisitor.get_new_names.<locals>.<listcomp>0   s*    DDD7==3C3CD!DDDr   c                 <    g | ]}t          |d d                   S )   N)intr   r    s     r   r"   z-NameVisitor.get_new_names.<locals>.<listcomp>2   s&    CCCqAabbE

CCCr   r$   r   c                 2    g | ]}d t          |          z   S )_)strr&   s     r   r"   z-NameVisitor.get_new_names.<locals>.<listcomp>6   s.     ? ? ?c!ff ? ? ?r   )recompiler
   maxrange)r   	num_namesmatching_namesstart_numberr!   s       @r   get_new_nameszNameVisitor.get_new_names   s    & *[))DDDDTZDDD 	CCNCCCDDqHLLL? ?lL9$<==? ? ? 	?r   )	__name__
__module____qualname____doc__r   r   r   r1   __classcell__r   s   @r   r   r      so                  $ $ $? ? ? ? ? ? ?r   r   c                   "     e Zd ZdZ fdZ xZS )ExpandVarargTransformerz
    Node transformer that replaces the starred use of a variable in an AST
    with a collection of unstarred named variables.
    c                 d     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   r9   r   starred_nameexpand_names)r   r;   r<   r   r   r   s        r   r   z ExpandVarargTransformer.__init__?   s>     	6%t,,5tFvFFF((r   )r2   r3   r4   r5   r   r6   r7   s   @r   r9   r9   :   sB         ) ) ) ) ) ) ) ) )r   r9   c                       e Zd Zd ZdS )ExpandVarargTransformerStarredc                 X    j         j        | j        k    rfd| j        D             S S )Nc                 F    g | ]}t          j        |j                   S ))r   ctx)astNamerA   )r   namer   s     r   r"   z@ExpandVarargTransformerStarred.visit_Starred.<locals>.<listcomp>S   s6     ' ' 'CH$(333 ' ' 'r   )valuer   r;   r<   r   s    `r   visit_Starredz,ExpandVarargTransformerStarred.visit_StarredQ   sJ    :=D---' ' ' '%' ' ' ' Kr   N)r2   r3   r4   rF   r   r   r   r>   r>   O   s#            r   r>   c                 z    t          j        t          j        |                     }t	          j        |          }|S )z2
    Get the AST representation of a function
    )textwrapdedentinspect	getsourcerB   parse)fn	fn_sourcefn_asts      r   function_to_astrP   Y   s6      1" 5 566I Yy!!F
 Mr   c                 4    ddl }|                    |           S )z9Convert AST to source code string using the astor packager   N)astor	to_source)rB   rR   s     r   ast_to_sourcerT   j   s    LLL??3r   c                     t          | t          j                  sJ | j        d         }t          |t          j                  sJ t          | d|j        z  d          S )zO
    Compile function AST into a code object suitable for use in eval/exec
    r   z<%s>exec)mode)
isinstancerB   ModulebodyFunctionDefr+   rD   )rO   	fndef_asts     r   compile_function_astr]   p   s[     fcj)))))AIi1111166IN2@@@@r   r$   c                    t          | t          j                  sJ | j        d         }t          |t          j                  sJ t          |           }t          j                    }|}t          |          D ]	}|j	        }
|j
        }|j        }~t          j        |          }	|	                    |           t          ||	           |	|j                 S )Nr   )rX   rB   rY   rZ   r[   r]   rJ   currentframer-   f_backf_locals	f_globalscopyupdateevalrD   )
rO   
stacklevelr\   codecurrent_frame
eval_framer(   eval_localseval_globalsscopes
             r   function_ast_to_functionrm   z   s    fcj)))))AIi11111  ''D (**MJ: ' '&

%K'LIl##E	LL 	u   r   c                 ,    t          j        |           S )N)r   )rB   r   rD   s    r   
_build_argrp      s    7tr   c                 P   t          | t          j                  sJ t          j        |           } | j        d         }t          |t          j                  sJ |j        }|j        }|st          d          |sJ t          |t                    r|}n|j        }t                      }|                    |            |                    |          }t          } |||                              |           }	|	j        d         }
|
j        j                            d |D                        d|
j        _        t                      }|                    |	           ||j        v r#t          d                    |                    g |_        t          j        |	           |	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 signaturec                 .    g | ]}t          |           S )ro   )rp   )r   rD   s     r   r"   z/expand_function_ast_varargs.<locals>.<listcomp>   s#    8884			888r   NzNThe variable length positional argument {n} is used in an unsupported context
)r    )rX   rB   rY   rc   deepcopyrZ   r[   r   vararg
ValueErrorr)   r   r   visitr1   r>   extendr
   formatdecorator_listfix_missing_locations)rO   expand_numberr\   fn_args	fn_varargvararg_namebefore_name_visitorr<   expand_transformer
new_fn_astnew_fndef_astafter_name_visitors               r   expand_function_ast_varargsr      s   F fcj))))) ]6""F AIi11111 nG I  + * + + 	+  )S!! $m &--f%%%&44]CCL 8##\ eFmm  OA&M ""88<888   !%M %Z((((... 
F[F  	
  "I j))) r   c                 f     t           t                    r dk     rt          d           f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                 d    t          |           }t          |          }t          |d          S )N   )rf   )rP   r   rm   )rM   rO   fn_expanded_astr{   s      r   _expand_varargsz'expand_varargs.<locals>._expand_varargs  s2     $$5fmLL'AFFFFr   )rX   r%   ru   )r{   r   s   ` r   expand_varargsr     sW      mS)) I]Q->->GHHHG G G G G r   )r$   )r5   r*   rc   rJ   rB   rH   NodeVisitorr   NodeTransformerr9   r>   rP   rT   r]   rm   rp   r   r   r   r   r   <module>r      sB    
			   



 ,? ,? ,? ,? ,?#/ ,? ,? ,?^) ) ) ) )c1 ) ) )*    %<     "     A A A! ! ! !:  c c cL    r   