a
    b                    @   s  d dl mZ d dlZejeeeeeeeeeeeeeed d dlZd dlZddlmZ ddlm	Z	 ddlm
Z
 ddl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mZmZ ddlmZmZ ddlmZ ddlmZmZ ddlmZmZmZmZ ddl m!Z! G dd deZ"G dd deZ#G dd deZ$dZ%dZ&dZ'G dd deZ(dd Z)d d! Z*d"d# Z+d$d% Z,d&d' Z-G d(d) d)ee"Z.G d*d+ d+ee"Z/G d,d- d-eZ0G d.d/ d/ee"Z1G d0d1 d1ee"Z2G d2d3 d3ee"Z3G d4d5 d5ee"Z4G d6d7 d7eZ5G d8d9 d9eZ6G d:d; d;eZ7G d<d= d=eZ8G d>d? d?eZ9G d@dA dAeZ:G dBdC dCee"Z;G dDdE dEeZ<G dFdG dGeZ=G dHdI dIeZ>G dJdK dKeZ?G dLdM dMeZ@G dNdO dOee"ZAG dPdQ dQeZBG dRdS dSeZCG dTdU dUeZDG dVdW dWeZEdS )X    )absolute_importN)
PyrexTypesNaming	ExprNodesNodesOptions	UtilNodesLetNode
LetRefNodeTreeFragmentEncodedStringerrorwarningcopy_unicode   )r   )r   )r   )r   )r   )Builtin)Errors)VisitorTransformTreeVisitor)CythonTransformEnvTransformScopeTrackingTransform)r	   r
   )r   )r   r   )r   r   CompileErrorInternalError)UtilityCodec                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )SkipDeclarationsa)  
    Variable and function declarations can often have a deep tree structure,
    and yet most transformations don't need to descend to this depth.

    Declaration nodes are removed after AnalyseDeclarationsTransform, so there
    is no need to use this for transformations after that point.
    c                 C   s   |S N selfnoder   r   s/Users/vegardjervell/Documents/master/model/venv/lib/python3.9/site-packages/Cython/Compiler/ParseTreeTransforms.pyvisit_CTypeDefNode%   s    z#SkipDeclarations.visit_CTypeDefNodec                 C   s   |S r   r   r   r   r   r"   visit_CVarDefNode(   s    z"SkipDeclarations.visit_CVarDefNodec                 C   s   |S r   r   r   r   r   r"   visit_CDeclaratorNode+   s    z&SkipDeclarations.visit_CDeclaratorNodec                 C   s   |S r   r   r   r   r   r"   visit_CBaseTypeNode.   s    z$SkipDeclarations.visit_CBaseTypeNodec                 C   s   |S r   r   r   r   r   r"   visit_CEnumDefNode1   s    z#SkipDeclarations.visit_CEnumDefNodec                 C   s   |S r   r   r   r   r   r"   visit_CStructOrUnionDefNode4   s    z,SkipDeclarations.visit_CStructOrUnionDefNodeN)
__name__
__module____qualname____doc__r#   r$   r%   r&   r'   r(   r   r   r   r"   r      s   r   c                       sj   e Zd ZdZ f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 Zdd Z  ZS )NormalizeTreea\  
    This transform fixes up a few things after parsing
    in order to make the parse tree more suitable for
    transforms.

    a) After parsing, blocks with only one statement will
    be represented by that statement, not by a StatListNode.
    When doing transforms this is annoying and inconsistent,
    as one cannot in general remove a statement in a consistent
    way and so on. This transform wraps any single statements
    in a StatListNode containing a single statement.

    b) The PassStatNode is a noop and serves no purpose beyond
    plugging such one-statement blocks; i.e., once parsed a
`    "pass" can just as well be represented using an empty
    StatListNode. This means less special cases to worry about
    in subsequent transforms (one always checks to see if a
    StatListNode has no children to see if the block is empty).
    c                    s    t t| | d| _d| _d S NF)superr-   __init__is_in_statlist
is_in_exprr    context	__class__r   r"   r0   M   s    zNormalizeTree.__init__c                 C   s    | j }d| _ | | || _ |S NT)r2   visitchildren)r    r!   stacktmpr   r   r"   visit_ExprNodeR   s
    
zNormalizeTree.visit_ExprNodeFc                 C   sB   | j }|| _ | | || _ | j s:| js:tj|j|gdS |S d S )Nposstats)r1   r8   r2   r   StatListNoder<   )r    r!   Zis_listcontainerr9   r   r   r"   visit_StatNodeY   s    
zNormalizeTree.visit_StatNodec                 C   s   d| _ | | d| _ |S NTF)r1   r8   r   r   r   r"   visit_StatListNodec   s    
z NormalizeTree.visit_StatListNodec                 C   s   |  |dS r7   r?   r   r   r   r"   visit_ParallelAssignmentNodei   s    z*NormalizeTree.visit_ParallelAssignmentNodec                 C   s   |  |dS r7   rB   r   r   r   r"   r'   l   s    z NormalizeTree.visit_CEnumDefNodec                 C   s   |  |dS r7   rB   r   r   r   r"   r(   o   s    z)NormalizeTree.visit_CStructOrUnionDefNodec                 C   s   | j stj|jg dS g S dS )zEliminate PassStatNoder;   N)r1   r   r>   r<   r   r   r   r"   visit_PassStatNoder   s    z NormalizeTree.visit_PassStatNodec                 C   s    |j jr| |S | |S dS )z!Eliminate useless string literalsN)expris_string_literalrD   r?   r   r   r   r"   visit_ExprStatNodey   s    
z NormalizeTree.visit_ExprStatNodec                 C   s   |S r   r   r   r   r   r"   r%      s    z#NormalizeTree.visit_CDeclaratorNode)F)r)   r*   r+   r,   r0   r:   r?   rA   rC   r'   r(   rD   rG   r%   __classcell__r   r   r5   r"   r-   8   s   

r-   c                   @   s   e Zd ZdS )PostParseErrorN)r)   r*   r+   r   r   r   r"   rI          rI   zHCannot assign default value to fields in cdef classes, structs or unionsz0Invalid buffer defaults specification (see docs)z0Special attributes must not have a type declaredc                       sx   e Zd ZdZ f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  ZS )	PostParseaf  
    Basic interpretation of the parse tree, as well as validity
    checking that can be done on a very basic level on the parse
    tree (while still not being a problem with the basic syntax,
    as such).

    Specifically:
    - Default values to cdef assignments are turned into single
    assignments following the declaration (everywhere but in class
    bodies, where they raise a compile error)

    - Interpret some node structures into Python runtime values.
    Some nodes take compile-time arguments (currently:
    TemplatedTypeNode[args] and __cythonbufferdefaults__ = {args}),
    which should be interpreted. This happens in a general way
    and other steps should be taken to ensure validity.

    Type arguments cannot be interpreted in this way.

    - For __cythonbufferdefaults__ the arguments are checked for
    validity.

    TemplatedTypeNode has its directives interpreted:
    Any first positional argument goes into the "dtype" attribute,
    any "ndim" keyword argument goes into the "ndim" attribute and
    so on. Also it is checked that the directive combination is valid.
    - __cythonbufferdefaults__ attributes are parsed and put into the
    type information.

    Note: Currently Parsing.py does a lot of interpretation and
    reorganization that can be refactored into this transform
    if a more pure Abstract Syntax Tree is wanted.
    c                    s    t t| | d| ji| _d S )NZ__cythonbufferdefaults__)r/   rK   r0   handle_bufferdefaultsspecialattribute_handlersr3   r5   r   r"   r0      s    zPostParse.__init__c              	   C   s   t  }||j |js,|js,t|jtjrBtj	|jj
|jd}ntj|jj
|jd}tj|j
|j|j|j|j|d d|_| | |S )NrE   value)nameargsstar_argstarstar_argbodydoc)YieldNodeCollectorr8   Zresult_expr	has_yield	has_await
isinstancer   ZYieldExprNoder   ExprStatNoder<   ZReturnStatNodeDefNoderQ   rR   rS   rT   def_node)r    r!   	collectorrU   r   r   r"   visit_LambdaNode   s"    


zPostParse.visit_LambdaNodec              
   C   sD   t  }||j tj|j|jd g d d |j|jd|_| | |S )N)rQ   rV   rR   rS   rT   rU   is_async_def)	rW   r8   loopr   r\   r<   rQ   rY   r]   r    r!   r^   r   r   r"   visit_GeneratorExpressionNode   s    

z'PostParse.visit_GeneratorExpressionNodec                 C   s2   |j s$t }||j |jr$d|_ | | |S r7   )has_local_scoperW   r8   ra   rY   rb   r   r   r"   visit_ComprehensionNode   s    
z!PostParse.visit_ComprehensionNodec                 C   s2   t |jtjst|jt|j| j_|j| j_	d S r   )
rZ   defaultr   ZDictNoderI   r<   ERR_BUF_DEFAULTS
scope_nodeZbuffer_defaults_nodeZbuffer_defaults_pos)r    declr   r   r"   rL      s    
zPostParse.handle_bufferdefaultsc           	   
   C   s,  z|  | |g}g }|jD ]}|}t|tjr8|j}q$t|tjr|jd ur| jdv rt| j	tj
r| j|j}|r||urt|jt|| qt|jt| jdk}|tj|jtj|j|jd|j|d d |_|| q||_|W S  ty& } z| j| W Y d }~d S d }~0 0 d S )N)cclasspyclassstructmodulerQ   )lhsrhsfirst)r8   ZdeclaratorsrZ   r   ZCPtrDeclaratorNodebaseZCNameDeclaratorNoderf   
scope_typerh   CClassDefNoderM   getrQ   rI   r<   ERR_INVALID_SPECIALATTR_TYPEERR_CDEF_INCLASSappendSingleAssignmentNoder   NameNoder4   nonfatal_error)	r    r!   r=   Znewdeclsri   ZdeclbasehandlerZfirst_assignmenter   r   r"   r$      s>    




zPostParse.visit_CVarDefNodec                 C   s   |  | | ||j|jgS r   )r8   _visit_assignment_nodero   rp   r   r   r   r"   visit_SingleAssignmentNode  s    
z$PostParse.visit_SingleAssignmentNodec                 C   s    |  | | ||j|jg S r   )r8   r~   lhs_listrp   r   r   r   r"   visit_CascadedAssignmentNode  s    
z&PostParse.visit_CascadedAssignmentNodec                 C   s  t dd |D dk r|S g }t|| g }t|| g }|D ]X}|dd }|d }t|dkrztj|j|d |d}ntj|j||d	}|| q>t|dkr|d }ntj	|d j|d
}|rdd |D }	t
|	 |	ddd D ]\}
}t||}q|S )zgFlatten parallel assignments into separate single
        assignments or cascaded assignments.
        c                 S   s   g | ]}|j s|jrd qS r   )is_sequence_constructorrF   .0rE   r   r   r"   
<listcomp>  s   z4PostParse._visit_assignment_node.<locals>.<listcomp>   Nr   r   ro   rp   )r   rp   r=   c                 S   s   g | ]}|j |fqS r   )Z
expression)r   tempr   r   r"   r   6  s   )sumflatten_parallel_assignmentseliminate_rhs_duplicateslenr   ry   r<   ZCascadedAssignmentNoderx   ZParallelAssignmentNodesort_common_subsequencesr	   )r    r!   	expr_listexpr_list_listZ	temp_refsnodesr   rp   Zassign_nodeZduplicates_and_temps_Ztemp_refr   r   r"   r~     s>    


z PostParse._visit_assignment_nodec                 C   s.   |j D ]"}|jr| || q|| q|S r   )rR   r   _flatten_sequencerx   )r    seqresultargr   r   r"   r   >  s
    
zPostParse._flatten_sequencec                 C   s   |  | | |g |_|S r   )r8   r   rR   r   r   r   r"   visit_DelStatNodeF  s    
zPostParse.visit_DelStatNodec              	   C   sl   |j r^tj|jtj|jj|jjdgdd}tj|jtj	|j|j
tj|j|gddgd|_
| | |S )Nrn   T)rR   Zignore_nonexistingr   )rU   finally_clause)Zis_except_asr   ZDelStatNoder<   r   rz   targetrQ   r>   TryFinallyStatNoderU   r8   )r    r!   Z
del_targetr   r   r"   visit_ExceptClauseNodeK  s*    
z PostParse.visit_ExceptClauseNode)r)   r*   r+   r,   r0   r_   rc   re   rL   r$   r   r   r~   r   r   r   rH   r   r   r5   r"   rK      s   "-(rK   c                    s   t  i  fdd | D ]}|d } | q s>dS fddD ]}|jrPtt|j|_qP| D ]}|d |d< qrdS )zReplace rhs items by LetRefNodes if they appear more than once.
    Creates a sequence of LetRefNodes that set up the required temps
    and appends them to ref_node_sequence.  The input list is modified
    in-place.
    c                    sd   | j s| jrd S | v r<| vr`t| }|| < | n$|  | jr`| jD ]} | qRd S r   )
is_literalis_namer
   rx   addr   rR   )r!   Zref_nodeitem)find_duplicatesref_node_sequence	ref_nodes
seen_nodesr   r"   r   g  s    

z1eliminate_rhs_duplicates.<locals>.find_duplicatesr   Nc                    s,   |  v r |  S | j r(tt| j| _| S r   )r   listmaprR   )r!   )r   substitute_nodesr   r"   r   }  s
    z2eliminate_rhs_duplicates.<locals>.substitute_nodes)setr   r   r   rR   )r   r   r   rp   r!   r   )r   r   r   r   r   r"   r   _  s    
r   c                    s    fdd  fdd}t | D ]r\}}|d }|}t|d ddD ]}||| | d rD|}qD||kr t||dD ]}| |d  | |< qt|| |< q dS )	a  Sort items/subsequences so that all items and subsequences that
    an item contains appear before the item itself.  This is needed
    because each rhs item must only be evaluated once, so its value
    must be evaluated first and then reused when packing sequences
    that contain it.

    This implies a partial order, and the sort must be stable to
    preserve the original order as much as possible, so we use a
    simple insertion sort (which is very fast for short sequences, the
    normal case in practice).
    c                    s4   | D ]*}||u r dS |j r |j|r dS qdS r@   r   rR   )r   xr   containsr   r"   r     s    z*sort_common_subsequences.<locals>.containsc                    s   |j o |j| S r   r   )abr   r   r"   
lower_than  s    z,sort_common_subsequences.<locals>.lower_thanr   r   r   N)	enumeraterange)itemsr   r<   r   keynew_posir   r   r"   r     s    r   c                 C   sF   g }| j }| j}| j}|j}|D ] }||}|||||d q |S )N)rP   Zconstant_result)r<   r6   rP   rx   )literalcharsr<   stypeZsvalZ	sval_typecharcvalr   r   r"   #unpack_string_to_character_literals  s    r   c                 C   s&  | d }|j st|tjr4tdd | d d D sB||  d S g }|j rT|j}n|jrbt|}t	|}dd t
|D }g }| d d D ]}|j s|jrt|jd || qt	|j}	tdd |jD }
|
dkrt|jd |||g qq|	|
 |kr>t|jd	||dkr"d
p$df  |||g qq|
rVt|||j| q|	|k rt|jd|	|f  |||g qqt||jD ]\}}|| qq|r|| || t||D ]$\}}|r|| t|| q|D ](}|d j rt|| n
|| qd S )Nr   c                 S   s   g | ]
}|j qS r   )r   )r   ro   r   r   r"   r     rJ   z0flatten_parallel_assignments.<locals>.<listcomp>c                 S   s   g | ]}g qS r   r   r   r   r   r   r"   r     rJ   z4starred assignment target must be in a list or tuplec                 S   s   g | ]}|j rd qS r   )
is_starredr   r   r   r"   r     rJ   r   z,more than 1 starred expression in assignmentz#need more than %d value%s to unpacks z/too many values to unpack (expected %d, got %d)r   )r   rZ   r   UnicodeNoder   rx   rR   rF   r   r   r   r   r   r<   map_starred_assignmentzipr   )inputoutputrp   Zcomplete_assignmentsrhs_argsZrhs_sizelhs_targetsstarred_assignmentsro   Zlhs_sizeZstarred_targetstargetsrE   Zcascader   r   r"   r     sn    






r   c                 C   s   t t| |D ]4\}\}}|jr8|}t|| d } qL|| qtdt t| | d  ||d d  D ]\}\}}|| qp|| j}	||d  }
|r|
d |  }
|
r|
d j}n|	j}||	tj	||
dg d S )Nr   z6no starred arg found when splitting starred assignmentr   )r<   rR   )
r   r   r   r   rx   r   r   r<   r   ListNode)r   r   Zlhs_argsr   r   r   rE   ZstarredZlhs_remainingr   Zstarred_rhsr<   r   r   r"   r     s*    	
r   c                       s8   e Zd ZdZdZdZ fddZdd Zdd	 Z  Z	S )
PxdPostParsea  
    Basic interpretation/validity checking that should only be
    done on pxd trees.

    A lot of this checking currently happens in the parser; but
    what is listed below happens here.

    - "def" functions are let through only if they fill the
    getbuffer/releasebuffer slots

    - cdef functions are let through only if they are on the
    top level and are declared "inline"
    z>function definition in pxd file must be declared 'cdef inline'z5inline function definition in pxd file cannot be '%s'c                    s   d| _ tt| |S )Npxd)rs   r/   r   __call__r   r5   r   r"   r   3  s    zPxdPostParse.__call__c                 C   s    | j }d| _ | | || _ |S Nrj   )rs   r8   )r    r!   oldr   r   r"   visit_CClassDefNode7  s
    
z PxdPostParse.visit_CClassDefNodec                 C   s   | j }t|tjr*| jdkr*|jdv r*d }t|tjrd|jv r| jdv rd|_|j	dkrh| j
|j	 }q|jrz| j
d }qd }n| j }|r| jt|j| d S |S d S )Nrj   )Z__getbuffer__Z__releasebuffer__inline)r   rj   Tprivateapi)ERR_INLINE_ONLYrZ   r   r\   rs   rQ   CFuncDefNode	modifiersZinline_in_pxd
visibilityERR_NOGO_WITH_INLINEr   r4   r{   rI   r<   )r    r!   errr   r   r"   visit_FuncDefNode>  s(    

zPxdPostParse.visit_FuncDefNode)
r)   r*   r+   r,   r   r   r   r   r   rH   r   r   r5   r"   r   "  s   r   c                       s2   e Zd Z fddZdd Zdd ZejZ  Z	S )TrackNumpyAttributesc                    s   t t|   t | _d S r   )r/   r   r0   r   numpy_module_namesr    r5   r   r"   r0   ]  s    zTrackNumpyAttributes.__init__c                 C   s    |j dkr| j|jpd |S )NZnumpy)module_namer   r   as_namer   r   r   r"   visit_CImportStatNodea  s    
z*TrackNumpyAttributes.visit_CImportStatNodec                 C   s2   |  | |j}|jr"|j| jv s(|jr.d|_|S r7   )r8   objr   rQ   r   Zis_numpy_attribute)r    r!   r   r   r   r"   visit_AttributeNodef  s
    
z(TrackNumpyAttributes.visit_AttributeNode)
r)   r*   r+   r0   r   r   r   recurse_to_children
visit_NoderH   r   r   r5   r"   r   [  s   r   c                
       s2  e Zd ZdZejejejeddeddeddeddej	ejd	Z
dediZeg d	Zee
 eg d
Z f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/d0 Z#d1d2 Z$d3d4 Z%  Z&S )5InterpretCompilerDirectivesaq  
    After parsing, directives can be stored in a number of places:
    - #cython-comments at the top of the file (stored in ModuleNode)
    - Command-line arguments overriding these
    - @cython.directivename decorators
    - with cython.directivename: statements

    This transform is responsible for interpreting these various sources
    and store the directive in two ways:
    - Set the directives attribute of the ModuleNode for global directives.
    - Use a CompilerDirectivesNode to override directives for a subtree.

    (The first one is primarily to not have to modify with the tree
    structure, so that ModuleNode stay on top.)

    The directives are stored in dictionaries from name to value in effect.
    Each such dictionary is always filled in for all possible directives,
    using default values where no value is given by the user.

    The available directives are controlled in Options.py.

    Note that we have to run this prior to analysis, and so some minor
    duplication of functionality has to occur: We manually track cimports
    and which names the "cython" module may have been imported to.
    Tz++z--F)	Ztypeofzoperator.addresszoperator.dereferencezoperator.preincrementzoperator.predecrementzoperator.postincrementzoperator.postdecrementzoperator.typeidaddresszoperator.comma,)declareunionrl   ZtypedefsizeofcastpointercompiledNULLZ
fused_typeparallel)r   prangeZthreadidc                    sd   t t| | t | _ddi| _i | _tt	
 }| D ]\}}t||t|< q>|| _d S )Nstaticmethod)r/   r   r0   r   cython_module_namesdirective_namesparallel_directivesr   deepcopyr   get_directive_defaultsr   r   
directives)r    r4   Zcompilation_directive_defaultsr   r   rP   r5   r   r"   r0     s    
z$InterpretCompilerDirectives.__init__c                 C   sZ   t j|d }|r8||vr8| jt|d||f  dS |t jvrRt|d|f  dS d S )Nz4The %s compiler directive is not allowed in %s scopeFzInvalid directive: '%s'.T)r   Zdirective_scopesru   r4   r{   rI   directive_typesr   )r    r<   	directivescopeZlegal_scopesr   r   r"   check_directive_scope  s    
z1InterpretCompilerDirectives.check_directive_scopec                 C   st   t |jD ],}| |j|ds
| |j|d |j|= q
|j| _| j|j | j|_| j	|_	| 
| | j|_|S )Nrm   )sortedZdirective_commentsr   r<   Zwrong_scope_errorr   module_scoper   updater   r8   r   )r    r!   r   r   r   r"   visit_ModuleNode  s    

z,InterpretCompilerDirectives.visit_ModuleNodec                 C   s   |t jv p|| jv pt|S r   )r   r   special_methodsr   parse_basic_type)r    rQ   r   r   r"   is_cython_directive  s
    
z/InterpretCompilerDirectives.is_cython_directivec                 C   s   |d  d}|r|d}|dkr0d| jd< nL|dkrT| jD ]}d| | j|< q>n(t|dksn|d | jvr|t|d	|  | jt	d
d |S )z
        Checks to see if fullname (e.g. cython.parallel.prange) is a valid
        parallel directive. If it is a star import it also updates the
        parallel_directives.
        .cython.parallel.cython.parallelr   zcython.parallel.*zcython.parallel.%s   r   zNo such directive: %sInitThreadsModuleSetupCode.c)

startswithsplitr   valid_parallel_directivesr   r   r   use_utility_coder   load_cached)r    	full_namer<   r   r   rQ   r   r   r"   is_parallel_directive  s     


z1InterpretCompilerDirectives.is_parallel_directivec                 C   s   |j dkr| j|jpd n|j dr|j drHt|j|j d  |j dkr|jrr|jdkrr|j | j|j< n| jd |j | jd< | j	t
dd n*|jr|j dd  | j|j< n| jd d S |S )	Ncythoncython.r  z is not a moduler  r  r     )r   r   r   r   r	  r   r<   r   r   r  r   r  r   r   r   r   r"   r     s*    


z1InterpretCompilerDirectives.visit_CImportStatNodec           
      C   s   |j s|jdks|jdr|jd dd  }g }|jD ]\}}}}|| }d| }	| |	|jrr|	| j|pn|< q8| |r|| j|p|< |d ur| j	
t|d q8|||||f q8|sd S ||_|S )Nr  r  r  r  z0Compiler directive imports must be plain imports)Zrelative_levelr   r	  imported_namesr  r<   r   r  r   r4   r{   rI   rx   )
r    r!   	submodulenewimpr<   rQ   r   kindr  qualified_namer   r   r"   visit_FromCImportStatNode  s.    


z5InterpretCompilerDirectives.visit_FromCImportStatNodec                 C   s   |j jjdks|j jjdr|j jjd dd  }g }|jD ]Z\}}|| }d| }| ||jrr|| j|j< q>| 	|r|| j
|j< q>|||f q>|sd S ||_|S )Nr  r  r  r  )rm   r   rP   r	  r   r  r<   r   rQ   r  r   rx   )r    r!   r  r  rQ   	name_noder  r  r   r   r"   visit_FromImportStatNode!  s"    
z4InterpretCompilerDirectives.visit_FromImportStatNodec                 C   st   t |jtjrf|jjj}|d d}|dkr6|s6|S |jjj}|jj}t	j
|j||d}| |}n
| | |S )Nr  r  r  )r   r   )rZ   rp   r   Z
ImportNoder   rP   r	  ro   rQ   r   ZCImportStatNoder<   r   r8   )r    r!   r   Zis_parallelr   r   r   r"   r   4  s    


z6InterpretCompilerDirectives.visit_SingleAssignmentNodec                 C   s4   |j | jv rd|_n| j|j }|d ur0||_|S r7   )rQ   r   is_cython_moduler   ru   Zcython_attribute)r    r!   r   r   r   r"   visit_NameNodeH  s    z*InterpretCompilerDirectives.visit_NameNodec                 C   s   |  |j | | |S r   )visitcppclassr8   r   r   r   r"   visit_NewExprNodeQ  s    
z-InterpretCompilerDirectives.visit_NewExprNodec              	   C   s~  t |tjr| |j |j }|rtj|}|r|	 \}}g }g }|d ur|t
ur|jD ]L}|\}	}
d||	jf }tj|r|| ||
gd |j q`|| q`|sd }n||_|r|s|s|S || ||||jj |S nt |tjtjfrz| | | }|rztj|}|tu rVtj|jdd}| ||gd |jgS |d u rj|d fgS t|jd| d S )N%s.%sTrO   z5The '%s' directive should be used as a function call.)rZ   r   CallNoder  functionas_cython_attributer   r   ru   explicit_args_kwdsdictkey_value_pairsrP   rx   try_to_parse_directiver<   AttributeNoderz   boolBoolNoderI   )r    r!   optnamedirectivetyperR   kwdsr   r&  Zkeyvaluer   rP   Zsub_optnamer   r   r   r"   try_to_parse_directivesV  sJ    






z3InterpretCompilerDirectives.try_to_parse_directivesc           	      C   s  |dkr | j js t|d| n|dkrt|dk}d}|r|jr|jd }t|jdkr|jjr|jjdkrt|jt	j
r|jj}nd}|rt|dd|r|d nd |ffS tj|}t|dkrt|d t	jr|t | fS |tu r8|d ust|dkst|d t	j
s*t|d	| ||d jfS |tu r|d uslt|dkslt|d t	jszt|d
| |t|d jfS |tu r|d ust|dkst|d t	jt	jfst|d| |t|d jfS |tu r"|d ust|dkrt|d| ||d fS |tu r`t|dkrHt|d| |tdd |jD fS |tu r|rt|jdkrt|d| |dd |D fS t|r |d ust|dkst|d t	jt	jfst|d| |||t|d jfS ds
J d S )NZ
np_pythranz.The %s directive can only be used in C++ mode.	exceptvalr   Tr   checkzYThe exceptval directive takes 0 or 1 positional arguments and the boolean keyword "check"z8The %s directive takes one compile-time boolean argumentz8The %s directive takes one compile-time integer argumentz7The %s directive takes one compile-time string argumentz(The %s directive takes one type argumentz1The %s directive takes no prepositional argumentsc                 S   s   g | ]\}}|j |fqS r   rO   )r   r   rP   r   r   r"   r     rJ   zFInterpretCompilerDirectives.try_to_parse_directive.<locals>.<listcomp>z+The %s directive takes no keyword argumentsc                 S   s   g | ]}t |jqS r   )strrP   )r   r   r   r   r"   r     rJ   F)r4   cpprI   r   r&  r   rF   rP   rZ   r   r*  r   r   ru   NoneNoder   r)  intZIntNoder1  
StringNoder   typer%  r   callable)	r    r+  rR   r-  r<   Z	arg_errorr0  kwr,  r   r   r"   r'    s    




*
*




z2InterpretCompilerDirectives.try_to_parse_directivec                 C   s~   |s|  |S | j}t|}|| ||kr8|  |S || _|  |}|| _t|tjsltj|j|gd}tj|j||dS )Nr   )r<   rU   r   )	r   r   r%  r   rZ   r   r>   r<   ZCompilerDirectivesNode)r    r!   r   old_directivesnew_directivesZretbodyr   r   r"   visit_with_directives  s    



z1InterpretCompilerDirectives.visit_with_directivesc                 C   s   |  |d}| ||S )Nr"  _extract_directivesr;  r    r!   r   r   r   r"   r     s    z-InterpretCompilerDirectives.visit_FuncDefNodec                 C   sZ   |  |d}| D ]8\}}|dkr,||_q|dvr| jt|jd|  q| ||S )Nr"  locals)finalr   zXCdef functions can only take cython.locals(), staticmethod, or final decorators, got %s.)r=  r   directive_localsr4   r{   rI   r<   r;  )r    r!   r   rQ   rP   r   r   r"   r$     s    z-InterpretCompilerDirectives.visit_CVarDefNodec                 C   s   |  |d}| ||S r   r<  r>  r   r   r"   r     s    z/InterpretCompilerDirectives.visit_CClassDefNodec                 C   s   |  |d}| ||S )Nr  r<  r>  r   r   r"   visit_CppClassNode  s    z.InterpretCompilerDirectives.visit_CppClassNodec                 C   s   |  |d}| ||S )Nclassr<  r>  r   r   r"   visit_PyClassDefNode  s    z0InterpretCompilerDirectives.visit_PyClassDefNodec                 C   s~  |j s
i S g }g }g }|j d d d D ]}| |j}|d ur|D ]l}| |j|d |r|\}	}
| j|	t |
kr|| |d dkr|| |d dkrB|dkrBd}qBq&|| q&|r|dkst	|t
jt
jt
jfrt|d jd|d d d |d d d  |_ i }|D ]b}|\}	}
|	|v rn||	 }t	|trL||
 n t	|trd||
 n|
||	< n|
||	< q|S )Nr   r   r   rj   rC  z8Cdef functions/classes cannot take arbitrary decorators.)
decoratorsr.  	decoratorr   r<   r   ru   objectrx   rZ   r   r   rt   ZCVarDefNoderI   r%  r   r   extend)r    r!   Z
scope_namer   ZrealdecsZbothdecr:  r   rQ   rP   optdict	old_valuer   r   r"   r=    sF    



z/InterpretCompilerDirectives._extract_directivesc                 C   s   i }|  |jpg D ]v}|d ur|jd ur@| jt|jd q|\}}|dv rrtj|j||j	d}| 
|  S | |j|dr|||< q|r| |j	|S | 
|S )Nz6Compiler directive with statements cannot contain 'as')nogilgilstaterU   zwith statement)r.  managerr   r4   r{   rI   r<   r   GILStatNoderU   r   r   r;  )r    r!   Zdirective_dictr   rQ   rP   r   r   r"   visit_WithStatNode   s     


z.InterpretCompilerDirectives.visit_WithStatNode)'r)   r*   r+   r,   r   Z
TypeofNodeZAmpersandNodeZDereferenceNodeZinc_dec_constructorZ
TypeidNodeunop_method_nodesZc_binop_constructorbinop_method_nodesr   r   r   r  r0   r   r   r  r  r   r  r  r   r  r  r.  r'  r;  r   r$   r   rB  rD  r=  rR  rH   r   r   r5   r"   r   p  sJ   






	,?.r   c                       s   e Zd ZdZdZdZdZdZej	e
jej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 fddZ  ZS )ParallelRangeTransforma  
    Transform cython.parallel stuff. The parallel_directives come from the
    module node, set there by InterpretCompilerDirectives.

        x = cython.parallel.threadavailable()   -> ParallelThreadAvailableNode
        with nogil, cython.parallel.parallel(): -> ParallelWithBlockNode
            print cython.parallel.threadid()    -> ParallelThreadIdNode
            for i in cython.parallel.prange(...):  -> ParallelRangeNode
                ...
    NF)zcython.parallel.parallelzcython.parallel.threadidzcython.parallel.prangec                 C   s   |j | jv p|jS r   )rQ   r   r  r   r   r   r"   node_is_parallel_directiveU  s    z1ParallelRangeTransform.node_is_parallel_directivec                 C   s   | j rd| j}n6| j| jd  }d|d| jdd f }|d}| j|}|du r| j rr| jd dkst|jd|  d| _ d| _|S )	z
        Figure out which parallel directive was used and return the associated
        Node class.

        E.g. for a cython.parallel.prange() call we return ParallelRangeNode
        r  r   r   r   Nr   zInvalid directive: %sF)	namenode_is_cython_modulejoinparallel_directiver   rstripdirective_to_noderu   r   r<   )r    r!   r   clsr   r   r"   get_directive_class_nodeX  s    
z/ParallelRangeTransform.get_directive_class_nodec                 C   s   |j r|j | _ | |S |S )zd
        If any parallel directives were imported, copy them over and visit
        the AST
        )r   r   r   r   r   r"   r   q  s    
z'ParallelRangeTransform.visit_ModuleNodec                 C   s    |  |r|jg| _|j| _|S r   )rV  rQ   rY  r  rW  r   r   r   r"   r  }  s    

z%ParallelRangeTransform.visit_NameNodec                 C   s"   |  | | jr| j|j |S r   )r8   rY  rx   	attributer   r   r   r"   r     s    
z*ParallelRangeTransform.visit_AttributeNodec                 C   sl   |  |j | js$| j|dd |S t|tjr@|jj}|j	}n
|j}i }| 
|}|rh||j||d}|S )N)r"  )exclude)rR   kwargs)r  r"  rY  r8   rZ   r   ZGeneralCallNodepositional_argsrR   keyword_argsr]  r<   )r    r!   rR   r`  parallel_directive_classr   r   r"   visit_CallNode  s    
z%ParallelRangeTransform.visit_CallNodec                 C   s   |  |j}t|tjrR| jdkr0t|jjd d| _|  |j}d| _||_|S | j	r| 
|}|sjdS |tju rt|jd dS |  |j|_|S )z.Rewrite with cython.parallel.parallel() blockszparallel withz*Nested parallel with blocks are disallowedNz%The parallel directive must be called)r  rP  rZ   r   ParallelWithBlockNoderO  r   r<   rU   rY  r]  )r    r!   ZnewnoderU   rc  r   r   r"   rR    s(    


z)ParallelRangeTransform.visit_WithStatNodec                 C   s   |  |j |  |j t|jjtj}| j}|rx|jj}|j|_|j|_|j	|_	|}t|jt
jsrt|jjd d| _|  |j || _|  |j	 |S )z/Rewrite 'for i in cython.parallel.prange(...):'z+Can only iterate over an iteration variabler   )r  iteratorr   rZ   sequencer   ParallelRangeNoderO  rU   else_clauser   rz   r   r<   )r    r!   Z	in_prangeprevious_stateZparallel_range_noder   r   r"   visit_ForInStatNode  s*    z*ParallelRangeTransform.visit_ForInStatNodec                    s   |durt t| |S dS )zVisit a node that may be NoneN)r/   rU  r  r   r5   r   r"   r    s    zParallelRangeTransform.visit)r)   r*   r+   r,   rY  rW  Zin_context_manager_sectionrO  r   re  r   ZParallelThreadIdNoderh  r[  rV  r]  r   r  r   rd  rR  rk  r  rH   r   r   r5   r"   rU  4  s$   rU  c                   @   s   e Zd Zdd Zdd ZdS )WithTransformc                    s  |  |d |j |j}|j|j|j  }}}tj tj t	|t
|rLdndddg dd|_|rxtj |jd|_|d urtj tj ||d|gd	}tj d fd
dtdD d}tj tj tj tj tj |d||rtj d dnd ddt dgd dd d |d}tj tj ||gd dtj tj |dtj  fddtdD d|rztj d dnd dddd|_|S )NrU   
__aenter__	__enter__T)r   r^  Zis_special_lookup)r"  rR   Zis_temp)r   )ro   Z	with_noder   c                    s   g | ]}t  qS r   )r   ZExcValueNoder   r<   r   r"   r     s   z4WithTransform.visit_WithStatNode.<locals>.<listcomp>r  )ZslowrR   F)Z	with_statZtest_if_runrR   Z
await_exproperand)	conditionrU   )
if_clausesri  )rU   patternr   excinfo_target)rU   Zexcept_clausesri  c                    s   g | ]}t  qS r   )r   r3  r   ro  r   r"   r     rJ   rR   rN   )rU   r   Zhandle_error_case)r8   r<   is_asyncrU   r   rP  r   SimpleCallNoder(  	CloneNoder   Z
enter_callZAwaitExprNoder   r>   ZWithTargetAssignmentStatNode	TupleNoder   ZExceptClauseNodeZ
IfStatNodeZIfClauseNodeZNotNodeZWithExitCallNodeZReraiseStatNoder   ZTryExceptStatNoder[   )r    r!   rw  rU   r   rP  ru  Zexcept_clauser   ro  r"   rR    s    

z WithTransform.visit_WithStatNodec                 C   s   |S r   r   r   r   r   r"   r:   !  s    zWithTransform.visit_ExprNodeN)r)   r*   r+   rR  r:   r   r   r   r"   rl    s   =rl  c                       sf   e Zd ZdZdZddddjZ fddZd	d
 Zdd Z	e
dd Ze
dd Ze
dd Z  ZS )DecoratorTransforma  
    Transforms method decorators in cdef classes into nested calls or properties.

    Python-style decorator properties are transformed into a PropertyNode
    with up to the three getter, setter and deleter DefNodes.
    The functional style isn't supported yet.
    N__get____set____del__)gettersetterdeleterc                    s:   | j d u rg | _ | j i  tt| | | j   |S r   )_propertiesrx   r/   r{  r   popr   r5   r   r"   r   6  s    

z&DecoratorTransform.visit_CClassDefNodec                 C   s0   t |jd trdnd}t|jd|j | |S )Nr   r   z4'property %s:' syntax is deprecated, use '@property')rZ   r<   r1  r   rQ   )r    r!   levelr   r   r"   visit_PropertyNode>  s    z%DecoratorTransform.visit_PropertyNodec                 C   s  | j }| |}|dks|js"|S | jd }|jd d d D ]L}|j}|jr|jdkrt|jdkrz| ||  S |j}t	d|_|j
| |g}||v r|| }|j|_|j|_||j_g   S tj|j|d}|j|_tj|j|d|_|||< |g  S |jr<|jj|v r<| |j}	|	r<|jj|jkrVt|jd|jj|jf  q<t|jdkrv| ||  S | |||	|  S q<|jD ]<}|j}
|
jr| j|
jd	kO  _| j|
jd
kO  _q|j}d |_| |||jS )Nrj   r   propertyr   r|  rn   r   z3Mismatching property names, expected '%s', got '%s'classmethodr   )rs   r   rE  r  rF  r   rQ   r   _reject_decorated_propertyr   remover<   rV   rU   r=   r   ZPropertyNoder>   is_attributer   _map_property_attributer^  r   _add_to_propertyZis_classmethodZis_staticmethodchain_decorators)r    r!   rs   
propertiesdecorator_noderF  rQ   Z	stat_listpropZhandler_namefuncZdecsr   r   r"   visit_DefNodeD  sZ    





z DecoratorTransform.visit_DefNodec                 C   s$   | j D ]}||krt|jd q| S )Nz=Property methods with additional decorators are not supported)rE  r   r<   )r!   r  decor   r   r"   r  z  s    
z-DecoratorTransform._reject_decorated_propertyc                 C   sZ   | |j  }||_ |j| |jj}t|D ]\}}|j |kr,|||<  qVq,|| g S r   )rQ   rE  r  rU   r=   r   rx   )r  r!   rQ   rF  r  r=   r   statr   r   r"   r    s    


z#DecoratorTransform._add_to_propertyc                 C   sv   t j| j|d}|ddd D ]}t j|j|j|gd}qt j| j|d}tj| j||d}t|g}|| _| |gS )af  
        Decorators are applied directly in DefNode and PyClassDefNode to avoid
        reassignments to the function/class name - except for cdef class methods.
        For those, the reassignment is required as methods are originally
        defined in the PyMethodDef struct.

        The IndirectionNode allows DefNode to override the decorator.
        rn   Nr   r"  rR   r   )	r   rz   r<   rx  rF  r   ry   ZIndirectionNodeZdecorator_indirection)r!   rE  rQ   Zdecorator_resultrF  r  Zreassignmentr   r   r"   r    s     
z#DecoratorTransform.chain_decorators)r)   r*   r+   r,   r  ru   r  r   r  r  r   r  r  r  rH   r   r   r5   r"   r{  &  s   6

r{  c                   @   s(   e Zd ZdZdd ZeZeZeZeZdS )CnameDirectivesTransformz
    Only part of the CythonUtilityCode pipeline. Must be run before
    DecoratorTransform in case this is a decorator for a cdef class.
    It filters out @cname('my_cname') decorators and rewrites them to
    CnameDecoratorNodes.
    c                 C   s   t |dd s| |S t|jD ]\}}|j}t|tjr |jj	r |jj
dkr | \}}|rftdt|dkrztd|d jr|d jtjkstd|d d }|j|= tj|j||d} qq | |S )	NrE  cnamez/cname decorator does not take keyword argumentsr   z*cname decorator takes exactly one argumentr   z4argument to cname decorator must be a string literal)r<   r!   r  )getattrr   r   rE  rF  rZ   r   r!  r"  r   rQ   r$  AssertionErrorr   r   r6  r   Zstr_typecompile_time_valuer   ZCnameDecoratorNoder<   )r    r!   r   rF  rR   r`  r  r   r   r"   handle_function  s>    



z(CnameDirectivesTransform.handle_functionN)	r)   r*   r+   r,   r  r   r   r'   r(   r   r   r   r"   r    s   !r  c                   @   s<   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdS )ForwardDeclareTypesc                 C   s(   | j }|j}|j|_| | ||_|S r   )r   r   r8   )r    r!   envr   r   r   r"   visit_CompilerDirectivesNode  s    
z0ForwardDeclareTypes.visit_CompilerDirectivesNodec                 C   s    |j | _|j| j_| | |S r   )r   r   r   r8   r   r   r   r"   r     s    

z$ForwardDeclareTypes.visit_ModuleNodec                 C   s&   | j j}d| j _| | || j _|S Nr   )r   Zin_cincluder8   )r    r!   Zold_cinclude_flagr   r   r"   visit_CDefExternNode  s
    
z(ForwardDeclareTypes.visit_CDefExternNodec                 C   s   | | j |S r   )r   r   r   r   r   r"   r'     s    z&ForwardDeclareTypes.visit_CEnumDefNodec                 C   s   |j | jjvr|| j |S r   )rQ   r   entriesr   r   r   r   r"   r(     s    z/ForwardDeclareTypes.visit_CStructOrUnionDefNodec                 C   sr   |j | jjvr|| j | jj|j  j}|d urn|jrn|jsn|jrn|j}|jD ]}|jrP|jj	rP|j
  qP|S r   )
class_namer   r  r   r6  is_extension_typeZis_builtin_typer   Zcfunc_entriesis_fusedZ"get_all_specialized_function_types)r    r!   r6  r   entryr   r   r"   r     s    
z'ForwardDeclareTypes.visit_CClassDefNodeN)	r)   r*   r+   r  r   r  r'   r(   r   r   r   r   r"   r    s   r  c                       s\  e Zd ZeddedgdZeddedgdZeddedgdZededgdZed	edgdZ	dZ
d
Z f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/d0 Zd1d2 Zd3d4 Z d5d6 Z!d7d8 Z"d9d: Z#d;d< Z$d=d> Z%d?d@ Z&dAdB Z'  Z(S )CAnalyseDeclarationsTransformzr
property NAME:
    def __get__(self):
        return ATTR
    def __set__(self, value):
        ATTR = value
    c_classNr  pipelinez
property NAME:
    def __get__(self):
        return ATTR
    def __set__(self, value):
        ATTR = value
    def __del__(self):
        ATTR = None
    z?
property NAME:
    def __get__(self):
        return ATTR
    a  
cdef class NAME:
    cdef TYPE value
    def __init__(self, MEMBER=None):
        cdef int count
        count = 0
        INIT_ASSIGNMENTS
        if IS_UNION and count > 1:
            raise ValueError, "At most one union member should be specified."
    def __str__(self):
        return STR_FORMAT % MEMBER_TUPLE
    def __repr__(self):
        return REPR_FORMAT % MEMBER_TUPLE
    )r  z;
if VALUE is not None:
    ATTR = VALUE
    count += 1
    r   c                    s*   g | _ t | _tt| }|j| _||S r   )seen_vars_stackr   fused_error_funcsr/   r  r   _super_visit_FuncDefNoder   )r    rootZsuper_classr5   r   r"   r   8  s
    
z%AnalyseDeclarationsTransform.__call__c                 C   s   | j d |j |S Nr   )r  r   rQ   r   r   r   r"   r  @  s    z+AnalyseDeclarationsTransform.visit_NameNodec                 C   sJ   g | _ | jt  ||   | | | j  |jj	
| j  |S r   )extra_module_declarationsr  rx   r   analyse_declarationscurrent_envr8   r  rU   r=   rH  r   r   r   r"   r   D  s    

z-AnalyseDeclarationsTransform.visit_ModuleNodec                 C   s8   |  j d7  _ ||   | | |  j d8  _ |S r  )	in_lambdar  r  r8   r   r   r   r"   r_   N  s
    
z-AnalyseDeclarationsTransform.visit_LambdaNodec                 C   s   |  |}|jr|jjr|jrg }|jjD ]4}|jr*| |}||j | | |	| q*|rt|j j
|7  _
|jdkr|jds|jds| | |S )Nextern
__reduce____reduce_ex__)visit_ClassDefNoder   ZimplementedrU   var_entriesZneeds_propertycreate_Propertyr  r  rx   r=   r   lookup_inject_pickle_methods)r    r!   r=   r  r  r   r   r"   r   U  s$    






z0AnalyseDeclarationsTransform.visit_CClassDefNodec                    s  |    |jjd du rd S |jjd du }g }|jj}d }d }|d ur|dd |jjD  |pn|jd}|p|jdp|jd}|j}q@|j	d	d
 d |rd S  fdd|D }dd |D }|s|s|r~|s~|rd}	n8|r
dd
dd |D  }	ndd
dd |D  }	|r4t|j|	 tdd|	i dtd gdi }
|
|j | |
 |jj|
 n|D ](}|jjs|j  |j  qtdd |D }dtd
|d d d  }d|j }td||d 
||jd!
d"d t|D t|d# d$td gdi }||jj | | | j | td%||d 
d&d |D t|d'krdnd( d)
d*d |D pd+gd, dtd gdi }
|
|j | !||j | |
 | "  |jj|
 d S )-NZauto_pickleFTc                 s   s   | ]}|j d vr|V  qdS ))__weakref____dict__Nrn   r   r}   r   r   r"   	<genexpr>s  rJ   zFAnalyseDeclarationsTransform._inject_pickle_methods.<locals>.<genexpr>Z	__cinit__r  r  c                 S   s   | j S r   rn   )r}   r   r   r"   <lambda>w  rJ   zEAnalyseDeclarationsTransform._inject_pickle_methods.<locals>.<lambda>)r   c                    s0   g | ](}|j js|j  r(|j  s|qS r   )r6  is_pyobjectZcan_coerce_to_pyobjectZcan_coerce_from_pyobjectr  r  r   r"   r     s   zGAnalyseDeclarationsTransform._inject_pickle_methods.<locals>.<listcomp>c                 S   s   g | ]}|j jr|qS r   )r6  Zis_struct_or_unionr  r   r   r"   r     rJ   z2no default __reduce__ due to non-trivial __cinit__z6%s cannot be converted to a Python object for picklingr   c                 s   s   | ]}d |j  V  qdS zself.%sNrn   r  r   r   r"   r    rJ   zZPickling of struct members such as %s must be explicitly requested with @auto_pickle(True)c                 s   s   | ]}d |j  V  qdS r  rn   r  r   r   r"   r    rJ   z
                def __reduce_cython__(self):
                    raise TypeError("%(msg)s")
                def __setstate_cython__(self, __pyx_state):
                    raise TypeError("%(msg)s")
                msgr  r  c                 S   s   g | ]
}|j qS r   rn   r  r   r   r"   r     rJ   z0x%s zutf-8r  z__pyx_unpickle_%sa  
                def %(unpickle_func_name)s(__pyx_type, long __pyx_checksum, __pyx_state):
                    cdef object __pyx_PickleError
                    cdef object __pyx_result
                    if __pyx_checksum != %(checksum)s:
                        from pickle import PickleError as __pyx_PickleError
                        raise __pyx_PickleError("Incompatible checksums (%%s vs %(checksum)s = (%(members)s))" %% __pyx_checksum)
                    __pyx_result = %(class_name)s.__new__(__pyx_type)
                    if __pyx_state is not None:
                        %(unpickle_func_name)s__set_state(<%(class_name)s> __pyx_result, __pyx_state)
                    return __pyx_result

                cdef %(unpickle_func_name)s__set_state(%(class_name)s __pyx_result, tuple __pyx_state):
                    %(assignments)s
                    if len(__pyx_state) > %(num_members)d and hasattr(__pyx_result, '__dict__'):
                        __pyx_result.__dict__.update(__pyx_state[%(num_members)d])
                z, z; c                 s   s   | ]\}}d ||f V  qdS )z!__pyx_result.%s = __pyx_state[%s]Nr   )r   ixvr   r   r"   r    s   )unpickle_func_namechecksummembersr  ZassignmentsZnum_membersrm   ap  
                def __reduce_cython__(self):
                    cdef tuple state
                    cdef object _dict
                    cdef bint use_setstate
                    state = (%(members)s)
                    _dict = getattr(self, '__dict__', None)
                    if _dict is not None:
                        state += (_dict,)
                        use_setstate = True
                    else:
                        use_setstate = %(any_notnone_members)s
                    if use_setstate:
                        return %(unpickle_func_name)s, (type(self), %(checksum)s, None), state
                    else:
                        return %(unpickle_func_name)s, (type(self), %(checksum)s, state)

                def __setstate_cython__(self, __pyx_state):
                    %(unpickle_func_name)s__set_state(self, __pyx_state)
                c                 s   s   | ]}d | V  qdS r  r   )r   r  r   r   r"   r    rJ   r   r   z or c                 S   s   g | ]}|j jrd |j qS )zself.%s is not None)r6  r  rQ   r  r   r   r"   r     rJ   False)r  r  r  Zany_notnone_members)#r  r   r   r  r6  rH  r  r  	base_typesortrX  r   r<   r   r-   
substituter  r  rU   r=   rx   r  Zcreate_to_py_utility_codeZcreate_from_py_utility_coder   hashlibmd5encode	hexdigestr  r   r   r  enter_scope
exit_scope)r    r!   Zauto_pickle_forcedZall_membersr\  ZcinitZinherited_reduceZnon_pystructsr  Zpickle_funcr}   Zall_members_namesr  r  Zunpickle_funcr   r  r"   r  g  s    



&



(

z3AnalyseDeclarationsTransform._inject_pickle_methodsc                 C   sx   g }|D ]0}|j }|jr.|jdvs.||jr|| q|rtt| j}|j}||||j\}	}
|
	| ||
g}|S )zd
        Create function calls to the decorators and reassignments to
        the function.
        )r   r  )
rF  r   rQ   lookup_hererx   r{  r4   r!   r  r  )r    Zold_decoratorsr  r!   rE  rF  r  	transformr]   r   Zreassignmentsr   r   r"   _handle_fused_def_decorators  s$    


z9AnalyseDeclarationsTransform._handle_fused_def_decoratorsc                 C   s~   |j d|j | |j|_|| tjj|jdd}t|	|}||_
| |jt|||_|rz| |||}|S )z#Handle def or cpdef fused functionsr   T)binding)r=   insertpy_funcr  Zupdate_fused_defnode_entryr   PyCFunctionNodefrom_defnodeZ	ProxyNodeZcoerce_to_tempZresulting_fused_function_create_assignmentry  Zfused_func_assignmentr  )r    rE  r  r!   Zpycfuncr   r   r"   _handle_def  s    
z(AnalyseDeclarationsTransform._handle_defc                 C   s   ddl m} | js| jr| j| jvrD| jr8t|jd nt|jd | j| j t	|j|_
|jD ]}|jjrf|j d |_qf|S t|dd}|||}|| _| | d| _|jr| |||}|S )z:Create a fused function for a DefNode with fused argumentsr   )	FusedNodezFused lambdas not allowedzCannot nest fused functionsr   rE  N)r   r  fused_functionr  r  r   r<   r   r   PassStatNoderU   rR   r6  r  Zget_fused_typesr  ZFusedCFuncDefNoder8   r  r  )r    r  r!   r  r   rE  r   r   r"   _create_fused_function  s(    

z3AnalyseDeclarationsTransform._create_fused_functionc                 C   s>   |j r:|jr:tj|jj|jt|jjt|jjd|_dS )z8Handle cleanup for 'with gil' blocks in nogil functions.)rU   r   Zfinally_except_clauseN)rL  Zhas_with_gil_blockr   ZNogilTryFinallyStatNoderU   r<   ZEnsureGILNode)r    lenvr!   r   r   r"   _handle_nogil_cleanup6  s    z2AnalyseDeclarationsTransform._handle_nogil_cleanupc                 C   s@   |j r:|jr:d|_t|jd tj|jg t|jd|_|jS )NFzFused generators not supported)r=   rU   )is_generatorhas_fused_argumentsr   r<   r   r>   r  gbodyr   r   r   r"   _handle_fusedC  s    
z*AnalyseDeclarationsTransform._handle_fusedc                 C   s   |   }| jt  |j}|| |j D ]>\}}||s0|	|}|rb|
|||j q0t|jd q0| |r| ||}n"|j| | || | | | j  |S )a  
        Analyse a function and its body, as that hasn't happened yet.  Also
        analyse the directive_locals set by @cython.locals().

        Then, if we are a function with fused arguments, replace the function
        (after it has declared itself in the symbol table!) with a
        FusedCFuncDefNode, and analyse its children (which are in turn normal
        functions). If we're a normal function, just analyse the body of the
        function.
        
Not a type)r  r  rx   r   local_scopeZdeclare_argumentsrA  r   r  analyse_as_typedeclare_varr<   r   r  r  rU   r  r  r  r  )r    r!   r  r  varZ	type_noder6  r   r   r"   r   M  s"    





z.AnalyseDeclarationsTransform.visit_FuncDefNodec                 C   s`   |  |}|  }t|tjr*|jr*|j}t|tjrL|jsL|jsL|	|sP|S || 
||gS r   )r   r  rZ   r   r\   
is_wrapperZparent_scopeZfused_py_funcis_generator_bodyZneeds_assignment_synthesis_synthesize_assignmentr    r!   r  r   r   r"   r  q  s    
z*AnalyseDeclarationsTransform.visit_DefNodec                 C   s
   |  |S r   )r   r   r   r   r"   visit_GeneratorBodyDefNode|  s    z7AnalyseDeclarationsTransform.visit_GeneratorBodyDefNodec                 C   s   |}|j s|jr|j}q|jrDtj|j||jjt	|d }|_
n2| jd}tj||}|j|_|jrv|j|j_|j rd|_|j|_| |||S )N)r]   pymethdef_cnamecode_objectr  T)is_py_class_scopeis_c_class_scopeouter_scopeis_closure_scoper   ZInnerFunctionNoder<   r  r  ZCodeObjectNodepy_cfunc_nodecurrent_directivesru   r  r  r  r  r  r  Zis_cyfunctionr  )r    r!   r  Zgenvrp   r  r   r   r"   r    s$    
z3AnalyseDeclarationsTransform._synthesize_assignmentc                 C   sf   |j r8|j d d d D ]}tj|j|j|gd}qd |_ tj|jtj|j|jd|d}|	| |S )Nr   r  rn   r   )
rE  r   rx  r<   rF  r   ry   rz   rQ   r  )r    r]   rp   r  rF  Zassmtr   r   r"   r    s    
z/AnalyseDeclarationsTransform._create_assignmentc                 C   s~   |   }|| |jrf| jt| jd  | ||j ||j | 	| | 
  | j  n|| | 	| |S r  )r  r  rd   r  rx   r   r  
expr_scopeZanalyse_scoped_declarationsr8   r  r  r  r   r   r"   visit_ScopedExprNode  s    



z1AnalyseDeclarationsTransform.visit_ScopedExprNodec                 C   s   |  | ||   |S r   )r8   r  r  r   r   r   r"   visit_TempResultFromStatNode  s    
z9AnalyseDeclarationsTransform.visit_TempResultFromStatNodec                 C   s   |j dkrd S | |S d S )Nr  )r   r  r   r   r   r"   rB    s    
z/AnalyseDeclarationsTransform.visit_CppClassNodec                 C   s4  d S ]}|	t j|j||j
d qg }t||D ]4\}}|	| jjt j|j|j
d|d|jd q2d|jjj
d	t| d d
 f }| jjtj|j|dt j|j|jjj dt j|j|dt j|jt|dt j|jt|dddd|jdjd }	|j
|	_d|	_|	jj}
t|
d jtjs0J |j
|
d j_
|
d }t|tjr`|j
dksdJ |jd }|jjjsd|_ |jd= t||D ]*\}}t!"|}|j
|j#_
|j	| qt||D ]R\}}|jj$r| j%}n| j&}|jd|i|jdjd }|j
|_
|	jj	| q|	'| (  | )|	S )Nr    r<   rQ   rP   r<   r   r^  rn   )ZVALUEATTRro  z%s(%s)z%s, r   rO   rv  z%sz%r)ZINIT_ASSIGNMENTSZIS_UNIONZMEMBER_TUPLEZ
STR_FORMATZREPR_FORMATr   Tr   r0   r   )*r   r(  r<   rz   r   r  r6  r   r  rx   rQ   r   init_assignmentr  r   struct_or_union_wrapperr   r>   r*  Z	is_structrz  r5  replacer=   r  ZshadowrU   rZ   r  ZCSimpleBaseTypeNoder\   rR   Zkw_onlyr   r   
declaratorr  basic_pyobject_propertybasic_propertyr  r  r   )r    r!   Z
self_valuer  
attributesr  Zinit_assignmentsattrZ
str_formatZwrapper_classZ
class_bodyZinit_methodZarg_templater   templater  r   r   r"   r(     s~           


"



z8AnalyseDeclarationsTransform.visit_CStructOrUnionDefNodec                 C   s   |  | |S r   r8   r   r   r   r"   r%     s    
z2AnalyseDeclarationsTransform.visit_CDeclaratorNodec                 C   s   |S r   r   r   r   r   r"   r#     s    z/AnalyseDeclarationsTransform.visit_CTypeDefNodec                 C   s   d S r   r   r   r   r   r"   r&     s    z0AnalyseDeclarationsTransform.visit_CBaseTypeNodec                 C   s   |j dkr|S d S d S )Npublic)r   r   r   r   r"   r'     s    
z/AnalyseDeclarationsTransform.visit_CEnumDefNodec                 C   s\   |j | jd v rN|  |j }|d u s:|jdkrN|jjsNt|jd|j  d | 	| |S )Nr   r  z,cdef variable '%s' declared after it is usedr   )
rQ   r  r  r  r   r   r  r   r<   r8   )r    r!   r  r   r   r"   visit_CNameDeclaratorNode!  s    
z6AnalyseDeclarationsTransform.visit_CNameDeclaratorNodec                 C   s   |  | d S r   r  r   r   r   r"   r$   *  s    
z.AnalyseDeclarationsTransform.visit_CVarDefNodec                 C   sF   |  |j}|sd S t|tu r<|d |_|g|dd   S ||_|S )Nr   r   )r  r!   r6  r   
child_node)r    r!   r  r   r   r"   visit_CnameDecoratorNode/  s    
z5AnalyseDeclarationsTransform.visit_CnameDecoratorNodec                 C   s|   |j dkr"|jjr| j}q2| j}n|j dkr2| j}|jdtj|j	tj
|j	dd|jdi|j	djd }|j|_|j|_|S )	Nr  readonlyr   r    r  r  ro  r   )r   r6  r  r  r  basic_property_ror  r   r(  r<   rz   rQ   r=   rV   )r    r  r
  r  r   r   r"   r  9  s&    


z,AnalyseDeclarationsTransform.create_Property))r)   r*   r+   r   r-   r  r  r  r  r  r  r  r   r  r   r_   r   r  r  r  r  r  r  r   r  r  r  r  r  r  rB  r(   r%   r#   r&   r'   r  r$   r  r  rH   r   r   r5   r"   r    s\   

	

 
$N	
r  c                       sb   e Zd ZdZ fddZdddZdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Z  ZS ) CalculateQualifiedNamesTransformz^
    Calculate and store the '__qualname__' and the global
    module name on some nodes.
    c                    s:   |   j| _g | _tt| }|j| _|j| _| 	| |S r   )
Zglobal_scoper  r   r/   r  r   r  r  _super_visit_ClassDefNoder8   )r    r!   Z_superr5   r   r"   r   P  s    

z1CalculateQualifiedNamesTransform.visit_ModuleNodeNc                 C   s@   |r| j d d  }|| n| j }td||_| j|_d S )Nr  )r  rx   r   rX  qualnamer   )r    r!   rQ   r  r   r   r"   _set_qualnameY  s    z.CalculateQualifiedNamesTransform._set_qualnamec                 C   s*   |j r|js|jg| _n| j|j d S r   )is_pyglobalZis_pyclass_attrrQ   r  rx   )r    r  r   r   r"   _append_entryb  s    z.CalculateQualifiedNamesTransform._append_entryc                 C   s   |  ||j | | |S r   )r  rQ   r8   r   r   r   r"   visit_ClassNodeh  s    
z0CalculateQualifiedNamesTransform.visit_ClassNodec                 C   s   |  | | | |S r   )r  r8   r   r   r   r"   visit_PyClassNamespaceNodem  s    

z;CalculateQualifiedNamesTransform.visit_PyClassNamespaceNodec                 C   sd   | j d d  }|jjr@| j r@| j d dkr@| j   | | n| ||jj | | || _ |S Nr   <locals>)r  r]   r  r  r  rQ   r8   r    r!   orig_qualified_namer   r   r"   visit_PyCFunctionNodes  s    

z6CalculateQualifiedNamesTransform.visit_PyCFunctionNodec                 C   st   |j rX| jrX| jd dks$J | j| jd d  }| j  | | | | || _n| ||j | | |S r  )r  r  r  r  r  rQ   r   r  r   r   r"   r  ~  s    



z.CalculateQualifiedNamesTransform.visit_DefNodec                 C   sX   | j d d  }t|dd dkr,| j d n| |j | j d | | || _ |S )NrQ   z<lambda>r  )r  r  rx   r  r  r  r  r   r   r"   r     s    
z2CalculateQualifiedNamesTransform.visit_FuncDefNodec                 C   sH   | j d d  }t|dd p(|  |j}| | | | || _ |S )Nr  )r  r  r  r  rQ   r  r  )r    r!   r  r  r   r   r"   r    s    

z3CalculateQualifiedNamesTransform.visit_ClassDefNode)N)r)   r*   r+   r,   r   r  r  r  r  r  r  r   r  rH   r   r   r5   r"   r  K  s   	
	r  c                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
AnalyseExpressionsTransformc                 C   s(   |j   |j|j |_| | |S r   )r   infer_typesrU   analyse_expressionsr8   r   r   r   r"   r     s    

z,AnalyseExpressionsTransform.visit_ModuleNodec                 C   s(   |j   |j|j |_| | |S r   )r  r   rU   r!  r8   r   r   r   r"   r     s    

z-AnalyseExpressionsTransform.visit_FuncDefNodec                 C   s*   |j r|j  ||j}| | |S r   )rd   r  r   Zanalyse_scoped_expressionsr8   r   r   r   r"   r    s
    

z0AnalyseExpressionsTransform.visit_ScopedExprNodec                 C   s"   |  | |jr|jjs|j}|S )a  
        Replace index nodes used to specialize cdef functions with fused
        argument types with the Attribute- or NameNode referring to the
        function. We then need to copy over the specialization properties to
        the attribute or name node.

        Because the indexing might be a Python indexing operation on a fused
        function, or (usually) a Cython indexing operation, we need to
        re-analyse the types.
        )r   Zis_fused_indexr6  Zis_errorrr   r   r   r   r"   visit_IndexNode  s    
z+AnalyseExpressionsTransform.visit_IndexNodeN)r)   r*   r+   r   r   r  r"  r   r   r   r"   r    s   r  c                   @   s   e Zd Zdd Zdd ZdS )FindInvalidUseOfFusedTypesc                 C   s0   |j s,|js"|jjr"t|jd n
| | |S )Nz-Return type is not specified as argument type)r  r  return_typer  r   r<   r8   r   r   r   r"   r     s
    
z,FindInvalidUseOfFusedTypes.visit_FuncDefNodec                 C   s*   |j r|j jrt|jd n
| | |S )Nz6Invalid use of fused types, type cannot be specialized)r6  r  r   r<   r8   r   r   r   r"   r:     s    
z)FindInvalidUseOfFusedTypes.visit_ExprNodeN)r)   r*   r+   r   r:   r   r   r   r"   r#    s   r#  c                   @   s   e Zd Zdd Zdd ZdS )ExpandInplaceOperatorsc           	         s   |j }|j}|jjr|S t|tjr(|S |  }d fdd	 z |dd\}}W n tyh   | Y S 0 |j	f i |j
}tj|j|j||dd}|| || || tj|j|||j|d}|  |D ]}t||}q|S )	NFc                    s   | j r| g fS | jjr,|s,t| } | | gfS | jrf | j\}}t| j}tj| j	||d||g fS | j
r | j\}}tj| j	|| jd|fS t| tjrtdnt| } | | gfS d S )N)rr   index)r   r^  z@Don't allow things like attributes of buffer indexing operations)r   r6  r  r
   Zis_subscriptrr   r&  r   Z	IndexNoder<   r  r   r(  r^  rZ   BufferIndexNode
ValueError)r!   settingrr   Ztempsr&  r   side_effect_free_referencer   r"   r+    s     


zVExpandInplaceOperators.visit_InPlaceAssignmentNode.<locals>.side_effect_free_referenceT)r)  )operatoroperand1operand2Zinplacer   )F)ro   rp   r6  Zis_cpp_classrZ   r   r'  r  r(  r6   r  
binop_noder<   r,  Zanalyse_target_typesZanalyse_typesZanalyse_operationr   ry   Z	coerce_toreverser	   )	r    r!   ro   rp   r  Zlet_ref_nodesdupbinoptr   r*  r"   visit_InPlaceAssignmentNode  s>    



z2ExpandInplaceOperators.visit_InPlaceAssignmentNodec                 C   s   |S r   r   r   r   r   r"   r:   	  s    z%ExpandInplaceOperators.visit_ExprNodeN)r)   r*   r+   r4  r:   r   r   r   r"   r%    s   5r%  c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )AdjustDefByDirectivesz
    Adjust function and class definitions by the decorator directives:

    @cython.cfunc
    @cython.cclass
    @cython.ccall
    @cython.inline
    @cython.nogil
    c                 C   s   |j | _ d| _| | |S r.   )r   in_py_classr8   r   r   r   r"   r   #	  s    
z&AdjustDefByDirectives.visit_ModuleNodec                 C   s"   | j }|j | _ | | || _ |S r   )r   r8   )r    r!   r9  r   r   r"   r  )	  s
    
z2AdjustDefByDirectives.visit_CompilerDirectivesNodec                 C   s  g }d| j v r|d | j d}| j d}| j d}|d u rj| j d rj|j}|d urv|d u rvd}n|d u rvd}d| j v r|jd	||||d
}| |S d| j v r| jrt|jd n|jd||||d
}| |S d|v rt|jd |rt|jd | 	| |S )Nr   rL  r/  returnsZannotation_typingr7   r.   ZccallT)overridabler   rL  r7  
except_valZcfuncz#cfunc directive is not allowed hereFz,Python functions cannot be declared 'inline'z+Python functions cannot be declared 'nogil')
r   rx   ru   return_type_annotationas_cfunctionr  r6  r   r<   r8   )r    r!   r   rL  r9  Zreturn_type_noder   r   r"   r  0	  s@    






z#AdjustDefByDirectives.visit_DefNodec                 C   s   |S r   r   r   r   r   r"   r_   T	  s    z&AdjustDefByDirectives.visit_LambdaNodec                 C   s@   d| j v r| }| |S | j}d| _| | || _|S d S )Nrj   T)r   	as_cclassr  r6  r8   r    r!   Zold_in_pyclassr   r   r"   rD  X	  s    


z*AdjustDefByDirectives.visit_PyClassDefNodec                 C   s    | j }d| _ | | || _ |S r.   )r6  r8   r=  r   r   r"   r   c	  s
    
z)AdjustDefByDirectives.visit_CClassDefNodeN)
r)   r*   r+   r,   r   r  r  r_   rD  r   r   r   r   r"   r5  	  s   
$r5  c                   @   sB   e Zd ZdZdd Zdd ZdddZd	d
 Zdd Zdd Z	dS )AlignFunctionDefinitionszq
    This class takes the signatures from a .pxd file and applies them to
    the def methods in a .py file.
    c                 C   s&   |j | _ |j| _t | _| | |S r   )r   r   r   r  r8   r   r   r   r"   r   q	  s
    
z)AlignFunctionDefinitions.visit_ModuleNodec                 C   sb   | j |j}|r^|jr(| | |S |j r6|j js^t|jd|j  |jrZt|jd d S |S )N'%s' redeclaredprevious declaration here)	r   r  rQ   Z	is_cclassr   r<  is_builtin_scoper   r<   r    r!   pxd_defr   r   r"   rD  x	  s    z-AlignFunctionDefinitions.visit_PyClassDefNodeNc                 C   sL   |d u r| j |j}|r4|js$|S | j }|jj | _ | | |rH|| _ |S r   )r   r  r  Zdefined_in_pxdr6  r8   )r    r!   rC  r  r   r   r"   r   	  s    

z,AlignFunctionDefinitions.visit_CClassDefNodec                 C   s   | j |j}|rZ|j r |j jsZ|jsNt|jd|j  |jrJt|jd d S ||}n4| j jr| j	d r|j| j
vr| r|j| j d}|S )Nr?  r@  Z
auto_cpdef)r   )r   r  rQ   rA  is_cfunctionr   r<   r;  is_module_scoper   r  Zis_cdef_func_compatiblerB  r   r   r"   r  	  s    
z&AlignFunctionDefinitions.visit_DefNodec                 C   s(   | j jr$|jD ]\}}| j| q|S r   )r   rE  r   r  r   )r    r!   rQ   r   r   r   r"   r  	  s    z1AlignFunctionDefinitions.visit_FromImportStatNodec                 C   s   |S r   r   r   r   r   r"   r:   	  s    z'AlignFunctionDefinitions.visit_ExprNode)N)
r)   r*   r+   r,   r   rD  r   r  r  r:   r   r   r   r"   r>  k	  s   
	r>  c                   @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )RemoveUnreachableCodec                 C   s   | j d s|S | | t|jD ]\\}}|d7 }|jr"|t|jk rt| j d rdt|j| jdd |jd | |_d|_ qq"|S )NZremove_unreachabler   warn.unreachableUnreachable coder   T)r  r8   r   r=   is_terminatorr   r   r<   )r    r!   idxr  r   r   r"   rA   	  s    


z(RemoveUnreachableCode.visit_StatListNodec                 C   s   |  | |jjrd|_|S r7   )r8   rU   rI  r   r   r   r"   visit_IfClauseNode	  s    
z(RemoveUnreachableCode.visit_IfClauseNodec                 C   s8   |  | |jr4|jjr4|jD ]}|js q4qd|_|S r7   )r8   ri  rI  rs  )r    r!   Zclauser   r   r"   visit_IfStatNode	  s    

z&RemoveUnreachableCode.visit_IfStatNodec                 C   s<   |  | |jjr8|jr8| jd r2t|jjdd d |_|S )NrG  rH  r   )r8   rU   rI  ri  r  r   r<   r   r   r   r"   visit_TryExceptStatNode	  s    

z-RemoveUnreachableCode.visit_TryExceptStatNodec                 C   s   |  | |jjrd|_|S r7   )r8   r   rI  r   r   r   r"   visit_TryFinallyStatNode	  s    
z.RemoveUnreachableCode.visit_TryFinallyStatNodeN)r)   r*   r+   rA   rK  rL  rM  rN  r   r   r   r"   rF  	  s
   
rF  c                       st   e Zd Z f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  ZS )rW   c                    s<   t t|   g | _g | _g | _g | _d| _d| _d| _	d S r.   )
r/   rW   r0   yieldsr7  finallysexceptshas_return_valuerX   rY   r   r5   r   r"   r0   	  s    zYieldNodeCollector.__init__c                 C   s   |  | d S r   r  r   r   r   r"   r   	  s    zYieldNodeCollector.visit_Nodec                 C   s    | j | d| _| | d S r7   )rO  rx   rX   r8   r   r   r   r"   visit_YieldExprNode	  s    z&YieldNodeCollector.visit_YieldExprNodec                 C   s    | j | d| _| | d S r7   )rO  rx   rY   r8   r   r   r   r"   visit_AwaitExprNode	  s    z&YieldNodeCollector.visit_AwaitExprNodec                 C   s&   |  | |jrd| _| j| d S r7   )r8   rP   rR  r7  rx   r   r   r   r"   visit_ReturnStatNode	  s    
z'YieldNodeCollector.visit_ReturnStatNodec                 C   s   |  | | j| d S r   )r8   rP  rx   r   r   r   r"   rN  	  s    
z+YieldNodeCollector.visit_TryFinallyStatNodec                 C   s   |  | | j| d S r   )r8   rQ  rx   r   r   r   r"   rM  
  s    
z*YieldNodeCollector.visit_TryExceptStatNodec                 C   s   d S r   r   r   r   r   r"   r  
  s    z%YieldNodeCollector.visit_ClassDefNodec                 C   s   d S r   r   r   r   r   r"   r   

  s    z$YieldNodeCollector.visit_FuncDefNodec                 C   s   d S r   r   r   r   r   r"   r_   
  s    z#YieldNodeCollector.visit_LambdaNodec                 C   s   d S r   r   r   r   r   r"   rc   
  s    z0YieldNodeCollector.visit_GeneratorExpressionNodec                 C   s   d S r   r   r   r   r   r"   visit_CArgDeclNode
  s    z%YieldNodeCollector.visit_CArgDeclNode)r)   r*   r+   r0   r   rS  rT  rU  rN  rM  r  r   r_   rc   rV  rH   r   r   r5   r"   rW   	  s   
rW   c                   @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )MarkClosureVisitorc                 C   s   d| _ | | |S r.   needs_closurer8   r   r   r   r"   r   
  s    
z#MarkClosureVisitor.visit_ModuleNodec           
      C   s<  d| _ | | | j |_ d| _ t }|| |jrrtj}|jr`tj}|j|j	 D ]
}d|_
qRq| jd rtj}n<|jrtdd |jD }t|jd |S |jrtj}n|S t|jdD ]\}}||_q|j	|j |j D ]
}d|_qtj|j|j|j|jo|jd}||j|j|j|j|j|j|j||j|j d	
}	|	S )
NFTZiterable_coroutinec                 s   s   | ]}|j r|V  qd S r   )Zis_await)r   yr   r   r"   r  2
  rJ   z7MarkClosureVisitor.visit_FuncDefNode.<locals>.<genexpr>z/'await' not allowed in generators (use 'yield')r   )r<   rQ   rU   Zis_async_gen_body)
r<   rQ   rR   rS   rT   rV   rE  r  lambda_namer:  )!rY  r8   rW   r`   r   ZAsyncDefNoderX   ZAsyncGenNoderO  r7  Zin_async_genr  ZIterableAsyncDefNoderY   nextr   r<   ZGeneratorDefNoder   Z	label_numrP  rQ  Zin_generatorZGeneratorBodyDefNoderQ   rU   rR   rS   rT   rV   rE  r[  r:  )
r    r!   r^   Zcoroutine_typeZ
yield_exprfoundr   Zretnoder  	coroutiner   r   r"   r    
  sJ    



z$MarkClosureVisitor.visit_FuncDefNodec                 C   s:   d| _ | | | j |_ d| _ |j r6|jr6t|jd |S )NFTz1closures inside cpdef functions not yet supported)rY  r8   r8  r   r<   r   r   r   r"   visit_CFuncDefNodeJ
  s    
z%MarkClosureVisitor.visit_CFuncDefNodec                 C   s"   d| _ | | | j |_ d| _ |S )NFTrX  r   r   r   r"   r_   S
  s
    
z#MarkClosureVisitor.visit_LambdaNodec                 C   s   |  | d| _|S r7   )r8   rY  r   r   r   r"   r  Z
  s    
z%MarkClosureVisitor.visit_ClassDefNodeN)r)   r*   r+   r   r   r_  r_   r  r   r   r   r"   rW  
  s
   *	rW  c                       sV   e Zd Z fddZdd Zdd Zddd	Zd
d Zdd Zdd Z	dd Z
  ZS )CreateClosureClassesc                    s    t t| | g | _d| _d S r.   )r/   r`  r0   pathr  r3   r5   r   r"   r0   d
  s    zCreateClosureClasses.__init__c                 C   s   |j | _| | |S r   )r   r   r8   r   r   r   r"   r   i
  s    
z%CreateClosureClasses.visit_ModuleNodec                 C   sd   g }g }|j  D ]H}|j D ]8\}}|s.q |jrD|||f q |jr |||f q q||fS r   )r  iter_local_scopesr  r   from_closurerx   
in_closure)r    r!   rc  rd  r   rQ   r  r   r   r"   find_entries_used_in_closuresn
  s    z2CreateClosureClasses.find_entries_used_in_closuresNc                 C   s  |j r>|j D ],}|j D ]}|js|js|jsd|_qq| 	|\}}|
  d|_d|_|j}|jj}	|	jsz|	jr|	j}	qn|s| js|r|s|jstd|j}d|_d|_|j rn(|s|sd S |sd|_|	j|_d|_d S d|tj|jjddf }
|j|
|jddd}d|j_ ||_|jj}d|_!d|_"|j#sJ|j rTd|j$d< t%j&rht%j&|j$d	< |r|	j'szJ |j(|jtj)tj)|	jjdd
 d|_|D ]@\}}|j(|j|j*s|j+nd |j|jdd
}|j,rd|_,qd|_|-|j d S )NTFz%DefNode does not have assignment nodez%s_%sr  __)rQ   r<   ZdefiningZimplementingZno_gc_clearZfreelist)r<   rQ   r  r6  Zis_cdefr   ).r  r  rb  r  valuesrc  r  Z
is_cglobalrd  re  r  rY  Zneeds_outer_scoper  r   r  r  r  ra  r  r   Zneeds_self_codeZis_passthroughZscope_classZnext_idr   Zclosure_class_prefixr  r  Zdeclare_c_classr<   r6  Zis_final_typeZis_internalZis_closure_class_scoper`   r   r   Zclosure_freelist_sizer  r  Zouter_scope_cnameZin_subscoperQ   Zis_declared_genericZcheck_c_class)r    r!   Ztarget_module_scopeZ
inner_noder   r  rc  rd  Z
func_scopeZcscoper   class_scoperQ   Zclosure_entryr   r   r"   create_class_from_scope{
  s    



z,CreateClosureClasses.create_class_from_scopec                 C   sD   t |jtjs|S | j}d| _| |j| j| | | || _|S r7   )rZ   r]   r   r\   r  ri  r   r8   )r    r!   Zwas_in_lambdar   r   r"   r_   
  s    
z%CreateClosureClasses.visit_LambdaNodec                 C   sR   | j r| | |S |js | jrN| || j | j| | | | j  |S r   )r  r8   rY  ra  ri  r   rx   r  r   r   r   r"   r   
  s    


z&CreateClosureClasses.visit_FuncDefNodec                 C   s   |  | |S r   r  r   r   r   r"   r  
  s    
z/CreateClosureClasses.visit_GeneratorBodyDefNodec                 C   s"   |j s| |S | | |S d S r   )r8  r   r8   r   r   r   r"   r_  
  s    

z'CreateClosureClasses.visit_CFuncDefNode)N)r)   r*   r+   r0   r   re  ri  r_   r   r  r_  rH   r   r   r5   r"   r`  `
  s   
Qr`  c                       sN   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	e
jZ  ZS )InjectGilHandlinga
  
    Allow certain Python operations inside of nogil blocks by implicitly acquiring the GIL.

    Must run before the AnalyseDeclarationsTransform to make sure the GILStatNodes get
    set up, parallel sections know that the GIL is acquired inside of them, etc.
    c                    s   d| _ tt| |S r.   )rL  r/   rj  r   r    r  r5   r   r"   r   
  s    zInjectGilHandling.__call__c                 C   s   | j rtj|jd|d}|S )zRAllow raising exceptions in nogil sections by wrapping them in a 'with gil' block.rM  rN  )rL  r   rQ  r<   r   r   r   r"   visit_RaiseStatNode
  s    z%InjectGilHandling.visit_RaiseStatNodec                 C   s&   | j }|jdk| _ | | || _ |S )NrL  )rL  rO  r8   r    r!   	was_nogilr   r   r"   visit_GILStatNode  s
    
z#InjectGilHandling.visit_GILStatNodec                 C   s<   | j }t|jtjr(|jj o$|jj | _ | | || _ |S r   )rL  rZ   r  r   ZCFuncDeclaratorNodeZwith_gilr8   rm  r   r   r"   r_    s    
z$InjectGilHandling.visit_CFuncDefNodec                 C   s"   | j }|j | _ | | || _ |S r   )rL  r8   rm  r   r   r"   visit_ParallelRangeNode  s
    
z)InjectGilHandling.visit_ParallelRangeNodec                 C   s   |S r   r   r   r   r   r"   r:     s    z InjectGilHandling.visit_ExprNode)r)   r*   r+   r,   r   rl  ro  r_  rp  r:   r   r   r   rH   r   r   r5   r"   rj  
  s   rj  c                       sX   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Z  ZS )GilChecka,  
    Call `node.gil_check(env)` on each node to make sure we hold the
    GIL when we need it.  Raise an error when on Python operations
    inside a `nogil` environment.

    Additionally, raise exceptions for closely nested with gil or with nogil
    statements. The latter would abort Python.
    c                    s&   |j g| _d| _d| _tt| |S r.   )r   	env_stackrL  nogil_declarator_onlyr/   rq  r   rk  r5   r   r"   r   /  s    
zGilCheck.__call__c                 C   sX   | j }|j}|r8t| jdkr8| jd j | _ | || || _ | j|d |d || _ d S )Nr   r  )attrsr_  )rL  outer_attrsr   rr  r8   )r    r!   Z	gil_statern  ru  r   r   r"   _visit_scoped_children8  s    zGilCheck._visit_scoped_childrenc                 C   sV   | j |j |jj}|r d| _|r6|jr6||j | || d| _| j   |S r@   )rr  rx   r  rL  rs  nogil_checkrv  r  )r    r!   Zinner_nogilr   r   r"   r   C  s    

zGilCheck.visit_FuncDefNodec                 C   sz   | j r|jr|  | j }|jdk}||krP| jsP|sDt|jd nt|jd t|jtj	rj|jj
\|_| || |S )NrL  z3Trying to acquire the GIL while it is already held.z;Trying to release the GIL while it was previously released.)rL  rw  rO  rs  r   r<   rZ   r   r   r>   r=   rv  )r    r!   rn  Zis_nogilr   r   r"   ro  U  s    
zGilCheck.visit_GILStatNodec                 C   s\   |j r(d|_ tj|jd|d}| |S | j s>t|jd d S || jd  | | |S )NFrL  rN  z)prange() can only be used without the GILr   )	rL  r   rQ  r<   ro  r   rw  rr  r8   r   r   r   r"   rp  l  s    

z GilCheck.visit_ParallelRangeNodec                 C   s:   | j st|jd d S |jr,|| jd  | | |S )Nz5The parallel section may only be used without the GILr   )rL  r   r<   rw  rr  r8   r   r   r   r"   visit_ParallelWithBlockNode{  s    
z$GilCheck.visit_ParallelWithBlockNodec                 C   s6   | j rt|tjr| |S d|_d|_| | |S )zM
        Take care of try/finally statements in nogil code sections.
        NT)rL  rZ   r   rQ  r   rw  Zis_try_finally_in_nogilr8   r   r   r   r"   rN    s    

z!GilCheck.visit_TryFinallyStatNodec                 C   sR   | j r"| jr"|jr"|| j d  |jr8| || j n
| | | jrNd|_|S )Nr   T)rr  rL  rw  ru  rv  r8   Zin_nogil_contextr   r   r   r"   r     s    
zGilCheck.visit_Node)r)   r*   r+   r,   r   rv  r   ro  rp  rx  rN  r   rH   r   r   r5   r"   rq  %  s   		rq  c                   @   sp   e Zd Z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S )TransformBuiltinMethodszQ
    Replace Cython's own cython.* builtins by the corresponding tree nodes.
    c                 C   s   |j r
d S | | |S d S r   )Zdeclaration_onlyr8   r   r   r   r"   r     s    
z2TransformBuiltinMethods.visit_SingleAssignmentNodec                 C   s   |  | | |S r   )r8   visit_cython_attributer   r   r   r"   r     s    
z+TransformBuiltinMethods.visit_AttributeNodec                 C   s
   |  |S r   )rz  r   r   r   r"   r    s    z&TransformBuiltinMethods.visit_NameNodec                 C   s   |  }|r|dkr&tj|jdd}n|dkrPddlm} tj|jt|d}np|dkrft|j}nZ|dv rtj	|jt|| 
  |d	}n,t|rn | jj|rnt|jd
|  |S )Nr   TrO   __version__r   )r{  r   )r   	frozensetr   rQ   r  z>'%s' not a valid cython attribute or is being used incorrectly)r#  r   r*  r<   r   r{  r5  r   ZNullNoderz   r  Zbuiltin_scoper  r   r  r4   cython_scopelookup_qualified_namer   )r    r!   r^  versionr   r   r"   rz    s&    
z.TransformBuiltinMethods.visit_cython_attributec                 C   sZ   |   }| | t|jdkrV|jt|j |jsV|jt	|j| 
 | |S r  )r  r8   r   rR   rx   r   GlobalsExprNoder<   rE  LocalsExprNodecurrent_scope_node)r    r!   r  r   r   r"   visit_ExecStatNode  s    
z*TransformBuiltinMethods.visit_ExecStatNodec           	         sZ  |   }||}|r|S |j |dv r|dkrXt|jdkrXt| jdt|j  |S |dkrt|jdkrt| jdt|j  t|jdkr|S t |  |S t|jdkrt| jdt|j  t|jdkr|S |j	s|j
r|j	r
|  }t|j}n
t }t|S td	d
 |j D } fdd|D }tj |dS d S )N)r?  varsr?  r   zGBuiltin 'locals()' called with wrong number of args, expected 0, got %dr  r   zGBuiltin 'vars()' called with wrong number of args, expected 0-1, got %dzFBuiltin 'dir()' called with wrong number of args, expected 0-1, got %dc                 s   s   | ]}|j r|j V  qd S r   rn   r   r  r   r   r"   r    rJ   z9TransformBuiltinMethods._inject_locals.<locals>.<genexpr>c                    s   g | ]}t j |d qS )rO   )r   ZIdentifierStringNoder  ro  r   r"   r     s   z:TransformBuiltinMethods._inject_locals.<locals>.<listcomp>rv  )r  r  r<   r   rR   r   r   r  r  r  rE  ry  r%  r  SortedDictKeysNoder   r  rg  r   )	r    r!   	func_namer  r  rk   Zlocals_dictZlocal_namesr   r   ro  r"   _inject_locals  sH    



z&TransformBuiltinMethods._inject_localsc                 C   sF   |  | |jdv rBt|jtjrB|jj}t|tjr<|j}||_|S )Nnot_in)r8   r,  rZ   r.  r   r  r   ZNoneCheckNode)r    r!   r   r   r   r"   visit_PrimaryCmpNode  s    

z,TransformBuiltinMethods.visit_PrimaryCmpNodec                 C   s
   |  |S r   )r  r   r   r   r"   visit_CascadedCmpNode  s    z-TransformBuiltinMethods.visit_CascadedCmpNodec                 C   sb   |   }||}|s$t|jdkr(|S |jt|j |js^|jt	|j| 
 | |S r  )r  r  r   rR   rx   r   r  r<   rE  r  r  )r    r!   r  r  r  r   r   r"   _inject_eval	  s    
z$TransformBuiltinMethods._inject_evalc                 C   s   |   }||}|s|jr |S |  }t|tjrH|jrHt| jdk rL|S | jd \}}|j	rd|_
d|j_tj|j|jdtj|j|jd jdg|_n8|jrtj|j|jj|jdtj|j|jd jdg|_|S )Nr   r  T)r  r   rn   r}  )r  r  rR   r  rZ   r   r\   r   rr  r  Zrequires_classobjZ
class_cell	is_activer   ZClassCellNoder<   r  rz   rQ   r  r   r  )r    r!   r  r  r  r]   Z
class_noderh  r   r   r"   _inject_super  s4    


z%TransformBuiltinMethods._inject_superc                 C   s  |j  }|r|tjv r\t|jdkr<t|j jd|  ntj| |j j|jd d}nJ|tjv rt|jdkrt|j jd|  n$tj| |j j|jd |jd d}n|dkr&t|jdkrt|j jd	 nJ|jd 	| 
 }|rtj|j j||jd d
d}nt|jd jd n|dkrt|jdkrPt|j jd nF|jd 	| 
 }|r~tj|j j|d}ntj|j j|jd d}n|dkrt|jdkrt|j jd n&t|j jd|jd |jd }d|_n|dkr>t|jdkrt|j jd n&t|j jd|jd |jd }d|_nh|dkr`tj|jtdd|_ nF|dkrtj|jtdd|_ n$| jj|rnt|j jd|  | | t|tjr|j jr|j j}|dv r| ||S |dkr| ||S |dkr| ||S |S )Nr   z%s() takes exactly one argumentr   rp  r   z %s() takes exactly two arguments)r-  r.  r   Dcast() takes exactly two arguments and an optional typecheck keywordFr6  rq  	typecheckr  r   z#sizeof() takes exactly one argument)Zarg_typeZcmodz"cmod() takes exactly two arguments%TZcdivz"cdiv() takes exactly two arguments/r   rn   r   z*'%s' not a valid cython language construct)dirr?  r  evalr/   )r"  r#  r   rS  r   rR   r   r<   rT  r  r  r   TypecastNodeZSizeofTypeNodeZSizeofVarNoder/  Z	cdivisionrz   r   r4   r~  r  r8   rZ   rx  r   rQ   r  r  r  )r    r!   r"  r6  r  r   r   r"   visit_SimpleCallNode2  sz    







 
 





z,TransformBuiltinMethods.visit_SimpleCallNodec                 C   s   |j  }|dkr|jj}|jd }t|dksRt|dksRt|dkrbd|vrbt|j jd nN|d 	| 
 }|r|dd}tj|j j||d |d}nt|d jd	 | | |S )
Nr   r   r   r  r  r   Fr  r  )r"  r#  ra  rR   rb  r  r   r   r<   r  r  ru   r   r  r8   )r    r!   r"  rR   r`  r6  r  r   r   r"   visit_GeneralCallNodex  s*    


z-TransformBuiltinMethods.visit_GeneralCallNodeN)r)   r*   r+   r,   r   r   r  rz  r  r  r  r  r  r  r  r  r   r   r   r"   ry    s   'Fry  c                       s@   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Z  Z	S )ReplaceFusedTypeChecksa0  
    This is not a transform in the pipeline. It is invoked on the specific
    versions of a cdef function with fused argument types. It filters out any
    type branches that don't match. e.g.

        if fused_t is mytype:
            ...
        elif fused_t in other_fused_type:
            ...
    c                    s0   t t|   || _ddlm} |dd| _d S )Nr   )ConstantFoldingT)Z
reevaluate)r/   r  r0   r  ZOptimizer  r  )r    r  r  r5   r   r"   r0     s    zReplaceFusedTypeChecks.__init__c                 C   s   |  | | |S )zc
        Filters out any if clauses with false compile time type check
        expression.
        )r8   r  r   r   r   r"   rL    s    
z'ReplaceFusedTypeChecks.visit_IfStatNodec                 C   sf  t jdd, |j| j}|j| j}W d    n1 s>0    Y  |rb|rbtj|jdd}tj|jdd}| 	||jj}|j
}|dv r| 	||jj}||}|dv }|r|s|s|s|S n|dv r^t|tjr|j}|jrt|jjd nb|jst|jjd	 nJt|}	|	D ],}
||
r"|d
krD|  S |  S q"|dkr^|S |S |S )NT)ignoreFrO   )isis_not==z!=)r  r  )inr  zType is fusedz-Can only use 'in' or 'not in' on a fused typer  r  )r   Zlocal_errorsr-  r  r  r.  r   r*  r<   specialize_typer,  Zsame_asrZ   r   ZCTypedefTypeZtypedef_base_typer  r   Zget_specialized_types)r    r!   Ztype1Ztype2Z
false_nodeZ	true_nodeopZis_sameeqtypesZspecialized_typer   r   r"   r    sB    ,




z+ReplaceFusedTypeChecks.visit_PrimaryCmpNodec                 C   s6   z| | jjW S  ty0   t|d | Y S 0 d S )NzType is not specific)Z
specializer  Zfused_to_specificKeyErrorr   )r    r6  r<   r   r   r"   r    s
    
z&ReplaceFusedTypeChecks.specialize_typec                 C   s   |  | |S r   r  r   r   r   r"   r     s    
z!ReplaceFusedTypeChecks.visit_Node)
r)   r*   r+   r,   r0   rL  r  r  r   rH   r   r   r5   r"   r    s   
2r  c                       sP   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	dd Z
  ZS )DebugTransformz9
    Write debug information for this Cython module.
    c                    s:   t t| | t | _| jj| _|j| _	g | _
d| _d S r.   )r/   r  r0   r   visitedr4   Zgdb_debug_outputwritertbZc_filec_output_filenested_funcdefsregister_stepinto)r    r4   optionsr   r5   r   r"   r0     s    
zDebugTransform.__init__c                 C   s   |j | j_t|j |jd j| jd}| jd| | jd | | | j	D ]}| 
| qNd| _| | d| _| jd | jd i }|jj D ]8\}}|j| jvr|jds|jjs|jjs|||< q| | | jd |S )	Nr   )r   filenameZ
c_filenameModuleZ	FunctionsTFZGlobalsZ__pyx_)full_module_namer  r   r%  r<   r  r  startr8   r  r   r   serialize_modulenode_as_functionendr   r  r   r  r  rQ   r	  r6  rD  r  serialize_local_variables)r    r!   rt  Znested_funcdefr  kr  r   r   r"   r     s:    







zDebugTransform.visit_ModuleNodec                 C   s:  | j |jj t|ddr |S | jr6| j| |S |jd u rFd}n
|jj	j
}t|j	jpdt|dd|j	j
||jjt|jd d}| jjd|d	 | jd
 | |jj | jd
 | jd |jjD ] }| j|j | j|j q| jd | jd d| _| | d| _| jd | jd |S )Nr  Fr   rQ   z	<unknown>r   )rQ   r  pf_cnamer  linenoFunctionrt  Locals	ArgumentsStepIntoFunctionsT)r  r   r  r  r  r  r  rx   r  r  
func_cnamer%  rQ   r1  r<   r  r  r  r  r  Zarg_entriesr8   )r    r!   r  rt  r   r   r   r"   r   $  s@    


z DebugTransform.visit_FuncDefNodec                 C   sh   | j rZ|jd urZ|jjrZt|ddrZ|jjd urZt|jjd}| jjd|d | j	d | 
| |S )NZ	is_calledFrn   ZStepIntoFunctionr  )r  r6  rD  r  r  r  r%  r  r  r  r8   r    r!   rt  r   r   r"   r  P  s    



zDebugTransform.visit_NameNodec                 C   s\   |j dd }d| }d| }t||ddddd}t||d	}| || | || d
S )z
        Serialize the module-level code as a function so the debugger will know
        it's a "relevant frame" and it will know where to set the breakpoint
        for 'break modulename'.
        r  r   initZPyInit_r   1True)rQ   r  r  r  r  Zis_initmodule_function)r  N)r  
rpartitionr%  !_serialize_modulenode_as_function)r    r!   rQ   Z	cname_py2Z	cname_py3Z	py2_attrsZ	py3_attrsr   r   r"   r  b  s    z/DebugTransform.serialize_modulenode_as_functionc                 C   s   | j jd|d | j d | |jj | j d | j d | j d | j d d| _| | d| _| j d | j d d S )Nr  r  r  r  r  TF)r  r  r  r   r  r  r  r8   r  r   r   r"   r  }  s    
z0DebugTransform._serialize_modulenode_as_functionc                 C   s   |  D ]}|jsq|jjr"d}nd}|jrZdtj|jjf }d|jj	j
|jj|jf }n*|jrxdtj|jf }|j
}n|j}|j
}|jsd}nt|jd }t|j||||d}| jd| | jd qd S )	NZPythonObjectZCObjectz%s->%sz%s.%s.%s0r   )rQ   r  r  r6  r  ZLocalVar)rg  r  r6  r  rc  r   Zcur_scope_cnameZouter_entryr   r  r  rQ   rd  r<   r1  r%  r  r  r  )r    r  r  vartyper  qnamer  rt  r   r   r"   r    sB    
z(DebugTransform.serialize_local_variables)r)   r*   r+   r,   r0   r   r   r  r  r  r  rH   r   r   r5   r"   r    s   (,r  )F
__future__r   r  r   rG  r   r  r   r   r   r   r   r   r   r   ZVisitorr   r   r   r   r   r   r	   r
   r   ZStringEncodingr   r   r   r   r   r   ZCoder   r   r-   rI   rw   rg   rv   rK   r   r   r   r   r   r   r   r   rU  rl  r{  r  r  r  r  r  r#  r%  r5  r>  rF  rW   rW  r`  rj  rq  ry  r  r  r   r   r   r"   <module>   s   L V.!E$9   G 0C /-    GU&<SF/9G 6| oX