U
    {h                    @   s  d dl Z e jee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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 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 ddlmZmZmZmZ G dd d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&G dd deZ'G dd  d eZ(d!d" Z)d#d$ Z*d%d& Z+e j,e-e-d'd(d)Z.e j,e-e-e-e-d*d+d,Z/G d-d. d.ee Z0G d/d0 d0ee Z1G d1d2 d2eZ2G d3d4 d4ee Z3G d5d6 d6ee Z4G d7d8 d8ee Z5G d9d: d:ee Z6G d;d< d<ee Z7G d=d> d>ee Z8G d?d@ d@eZ9G dAdB dBeZ:dCdD Z;G dEdF dFeZ<G dGdH dHeZ=G dIdJ dJeZ>G dKdL dLeZ?G dMdN dNee Z@G dOdP dPeZAG dQdR dReZBG dSdT dTeZCG dUdV dVeZDG dWdX dXeZEG dYdZ dZeZFG d[d\ d\ee ZGG d]d^ d^eZHG d_d` d`ee ZIG dadb dbeZJG dcdd ddeZKG dedf dfeZLdS )g    N)
PyrexTypesNaming	ExprNodesNodesOptions	UtilNodesLetNode
LetRefNodeTreeFragmentEncodedStringerrorwarningcopyhashlibsys
itemgetter)r      )r   )r   )r   )r   )r   )Builtin)Errors)VisitorTransformTreeVisitor)CythonTransformEnvTransformScopeTrackingTransform)r   r	   )r
   )r   )r   r   CompileErrorInternalErrorc                   @   sH   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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   G/tmp/pip-unpacked-wheel-fhl22ezh/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_CStructOrUnionDefNodec                 C   s   |j dkr| | |S Nextern)
visibilityvisitchildrenr   r   r   r"   visit_CppClassNode7   s    

z#SkipDeclarations.visit_CppClassNodeN)__name__
__module____qualname____doc__r#   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 Zd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  | d| _d| _d S NF)super__init__is_in_statlist
is_in_exprr    context	__class__r   r"   r5   S   s    zNormalizeTree.__init__c                 C   s2   |  | t|jtjs.tj|j|jgd|_|S Nposstats)r,   
isinstancebodyr   StatListNoder>   r   r   r   r"   visit_ModuleNodeX   s    
zNormalizeTree.visit_ModuleNodec                 C   s    | j }d| _ | | || _ |S NT)r7   r,   )r    r!   stacktmpr   r   r"   visit_ExprNode_   s
    
zNormalizeTree.visit_ExprNodeFc                 C   sB   | j }|| _ | | || _ | j s:| js:tj|j|gdS |S d S r<   )r6   r,   r7   r   rB   r>   )r    r!   Zis_listcontainerrE   r   r   r"   visit_StatNodef   s    
zNormalizeTree.visit_StatNodec                 C   s   d| _ | | d| _ |S NTF)r6   r,   r   r   r   r"   visit_StatListNodep   s    
z NormalizeTree.visit_StatListNodec                 C   s   |  |dS rD   rG   r   r   r   r"   visit_ParallelAssignmentNodev   s    z*NormalizeTree.visit_ParallelAssignmentNodec                 C   s   |  |dS rD   rJ   r   r   r   r"   r'   y   s    z NormalizeTree.visit_CEnumDefNodec                 C   s   |  |dS rD   rJ   r   r   r   r"   r(   |   s    z)NormalizeTree.visit_CStructOrUnionDefNodec                 C   s$   |j jrt|j jS | |S dS )z!Eliminate useless string literalsN)expris_string_literalr   PassStatNoder>   rG   r   r   r   r"   visit_ExprStatNode   s    z NormalizeTree.visit_ExprStatNodec                 C   s   |S r   r   r   r   r   r"   r%      s    z#NormalizeTree.visit_CDeclaratorNode)F)r.   r/   r0   r1   r5   rC   rF   rG   rI   rK   r'   r(   rO   r%   __classcell__r   r   r:   r"   r2   >   s   

r2   c                   @   s   e Zd ZdS )PostParseErrorN)r.   r/   r0   r   r   r   r"   rQ      s    rQ   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                       s   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dd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Z  ZS )(	PostParsea  
    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.

    - Some invalid uses of := assignment expressions are detected
    c                    s"   t  | d| ji| _d| _d S )NZ__cythonbufferdefaults__F)r4   r5   handle_bufferdefaultsspecialattribute_handlersin_pattern_noder8   r:   r   r"   r5      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rL   value)nameargsstar_argstarstar_argrA   doc)YieldNodeCollectorr,   result_expr	has_yield	has_awaitr@   r   ZYieldExprNoder   ExprStatNoder>   ZReturnStatNodeDefNoderY   rZ   r[   r\   def_node)r    r!   	collectorrA   r   r   r"   visit_LambdaNode   s,         
zPostParse.visit_LambdaNodec                 C   sd   t  }|j|jd dgd tj|j|jd g d d |j|jdd	|_t	j
|j| jdkd | | |S )NiteratorattrsexcludeT)rY   r]   rZ   r[   r\   rA   is_async_defis_generator_expressionpyclasscclassscope_is_class)r^   r,   loopr   rc   r>   rY   ra   rd   _AssignmentExpressionChecker	do_checks
scope_typer    r!   re   r   r   r"   visit_GeneratorExpressionNode   s          
z'PostParse.visit_GeneratorExpressionNodec                 C   sH   |j s$t }||j |jr$d|_ tj|j| jdkd | | |S )NTrm   rp   )has_local_scoper^   r,   rr   ra   rs   rt   ru   rv   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   )
r@   defaultr   ZDictNoderQ   r>   ERR_BUF_DEFAULTS
scope_nodeZbuffer_defaults_nodeZbuffer_defaults_pos)r    declr   r   r"   rS      s    
zPostParse.handle_bufferdefaultsc           	   
   C   s4  z|  | |g}g }|jD ]}|}t|tjtjfr>|j}q$t|tjr|jd k	r| j	dkrt| j
tjr| j|j}|r||k	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k
r. } z| j| W Y d S d }~X Y nX d S )N)ro   rn   structmodulerY   )lhsrhsfirst)r,   Zdeclaratorsr@   r   ZCPtrDeclaratorNodeZCConstDeclaratorNodebaseCNameDeclaratorNoderz   ru   r|   ZCClassDefNoderT   getrY   rQ   r>   ERR_INVALID_SPECIALATTR_TYPEERR_CDEF_INCLASSappendSingleAssignmentNoder   NameNoder9   nonfatal_error)	r    r!   r?   Znewdeclsr}   ZdeclbasehandlerZfirst_assignmenter   r   r"   r$      s@    




 zPostParse.visit_CVarDefNodec                 C   s   |  | | ||j|jgS r   )r,   _visit_assignment_noder   r   r   r   r   r"   visit_SingleAssignmentNode  s    
z$PostParse.visit_SingleAssignmentNodec                 C   s    |  | | ||j|jg S r   )r,   r   lhs_listr   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_constructorrM   ).0rL   r   r   r"   
<listcomp>%  s     z4PostParse._visit_assignment_node.<locals>.<listcomp>   Nr   r   r   r   )r   r   r?   c                 S   s   g | ]}|j |fqS r   )Z
expression)r   tempr   r   r"   r   A  s   )sumflatten_parallel_assignmentseliminate_rhs_duplicateslenr   r   r>   ZCascadedAssignmentNoder   ZParallelAssignmentNodesort_common_subsequencesr   )r    r!   	expr_listexpr_list_listZ	temp_refsZnodesr   r   assign_nodeZduplicates_and_temps_Ztemp_refr   r   r"   r   !  sB    

  
z PostParse._visit_assignment_nodec                 C   s.   |j D ]"}|jr| || q|| q|S r   )rZ   r   _flatten_sequencer   )r    seqresultargr   r   r"   r   I  s
    
zPostParse._flatten_sequencec                 C   s   |  | | |g |_|S r   )r,   r   rZ   r   r   r   r"   visit_DelStatNodeQ  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 )Nr   T)rZ   Zignore_nonexistingr   )rA   finally_clause)Zis_except_asr   ZDelStatNoder>   r   r   targetrY   rB   TryFinallyStatNoderA   r,   )r    r!   Z
del_targetr   r   r"   visit_ExceptClauseNodeV  s,     
z PostParse.visit_ExceptClauseNodec              	   C   sL   |j dkr>tj|jtj|jtdd|jddddd|_ d|_| | |S )zUExtract the exception raising into a RaiseStatNode to simplify GIL handling.
        NAssertionErrorr   T)exc_type	exc_valueexc_tbcauseZbuiltin_exc_nameZwrap_tuple_value)		exceptionr   ZRaiseStatNoder>   r   r   r   rX   r,   r   r   r   r"   visit_AssertStatNodei  s    
	
zPostParse.visit_AssertStatNodec                 C   s   t |j|j d S r   )r   r>   whatr   r   r   r"   visit_ErrorNodez  s    zPostParse.visit_ErrorNodec                 C   s   |   | | |S r   )Zvalidate_targetsr,   r   r   r   r"   visit_MatchCaseNode~  s    
zPostParse.visit_MatchCaseNodec                 C   s   |   | | |S r   )Zvalidate_irrefutabler,   r   r   r   r"   visit_MatchNode  s    
zPostParse.visit_MatchNodec                 C   s"   | j d }| _ | | || _ |S rD   )rU   r,   )r    r!   rU   r   r   r"   visit_PatternNode  s    
zPostParse.visit_PatternNodec                 C   s    | j rt|jd | | |S )Nz/f-strings are not accepted for pattern matching)rU   r   r>   r,   r   r   r   r"   visit_JoinedStrNode  s    
zPostParse.visit_JoinedStrNodec                 C   s:   | j dkr0|jdkr0t|jd|j dd d S | |S )Nro   )Z__getreadbuffer__Z__getwritebuffer__Z__getsegcount__Z__getcharbuffer__'zD' relates to the old Python 2 buffer protocol and is no longer used.r   )ru   rY   r   r>   visit_FuncDefNoder   r   r   r"   visit_DefNode  s    
zPostParse.visit_DefNode)r.   r/   r0   r1   r5   rf   rw   ry   rS   r$   r   r   r   r   r   r   r   r   r   r   r   r   r   rP   r   r   r:   r"   rR      s(   #-(rR   c                       sD   e Zd Z fddZdd Zdd Zdd Zd	d
 Zdd Z  Z	S )%_AssignmentExpressionTargetNameFinderc                    s   t    i | _d S r   )r4   r5   target_namesr    r:   r   r"   r5     s    
z._AssignmentExpressionTargetNameFinder.__init__c                 C   s<   |j r|jgS |jr8g }|jD ]}|| | q|S g S r   )is_namerY   r   rZ   extendfind_target_names)r    r   namesr   r   r   r"   r     s    
z7_AssignmentExpressionTargetNameFinder.find_target_namesc                 C   s$   t | |j| j|< | | d S r   )tupler   r   r   r,   r   r   r   r"   visit_ForInStatNode  s    z9_AssignmentExpressionTargetNameFinder.visit_ForInStatNodec                 C   s   d S r   r   r   r   r   r"   ry     s    z=_AssignmentExpressionTargetNameFinder.visit_ComprehensionNodec                 C   s   d S r   r   r   r   r   r"   rf     s    z6_AssignmentExpressionTargetNameFinder.visit_LambdaNodec                 C   s   |  | d S r   r,   r   r   r   r"   
visit_Node  s    z0_AssignmentExpressionTargetNameFinder.visit_Node)
r.   r/   r0   r5   r   r   ry   rf   r   rP   r   r   r:   r"   r     s   r   c                       sl   e Zd ZdZ fddZdd Zdd Zedd	 Zd
d Z	dd Z
dd Zdd Zdd Zdd Z  ZS )rs   za
    Enforces rules on AssignmentExpressions within generator expressions and comprehensions
    c                    sb   t    t }|| |j| _d| _d| _|| _d| _	t
 | _| j D ]}| j| qLd S NFr   )r4   r5   r   visitr   target_names_dictin_iteratorin_nested_generatorrq   current_target_namessetall_target_namesvaluesupdate)r    	loop_noderq   Ztarget_name_finderr   r:   r   r"   r5     s    

z%_AssignmentExpressionChecker.__init__c                 C   s6   | j | j| j| j| jf}d| _d| _d| _t | _|S r   )r   r   rq   r   r   r   r    	old_stater   r   r"   _reset_state  s    z)_AssignmentExpressionChecker._reset_statec                 C   s   |\| _ | _| _| _| _d S r   )r   r   rq   r   r   r   r   r   r"   
_set_state  s    z'_AssignmentExpressionChecker._set_statec                 C   s   | ||}| | d S r   )r   )clsr   rq   checkerr   r   r"   rt     s    
z&_AssignmentExpressionChecker.do_checksc                 C   sj   | j r| | d S | j}| j|d }|r:|  j|7  _d| _| |j d| _| j|dd || _d S )NTF)rg   rj   )r   r,   r   r   r   r   r   rg   )r    r!   r   target_namer   r   r"   r     s    
z0_AssignmentExpressionChecker.visit_ForInStatNodec                 C   sf   | j rt|jd | jr$t|jd |j| jkrDt|jd|j  n|j| jkrbt|jd|j  d S )NzKassignment expression cannot be used in a comprehension iterable expressionzKassignment expression within a comprehension cannot be used in a class bodyzIassignment expression cannot rebind comprehension iteration variable '%s'zHcomprehension inner loop cannot rebind assignment expression target '%s')r   r   r>   rq   r   r   r   r   r   r   r"   visit_AssignmentExpressionNode  s    z;_AssignmentExpressionChecker.visit_AssignmentExpressionNodec                 C   s"   |   }| |j | | d S r   )r   r   r_   r   )r    r!   r   r   r   r"   rf     s    z-_AssignmentExpressionChecker.visit_LambdaNodec                 C   s    | j }d| _ | | || _ d S rD   )r   r,   r    r!   r   r   r   r"   ry     s    
z4_AssignmentExpressionChecker.visit_ComprehensionNodec                 C   s"   | j }d| _ | |j || _ d S rD   )r   r   rr   r   r   r   r"   rw   	  s    z:_AssignmentExpressionChecker.visit_GeneratorExpressionNodec                 C   s   |  | d S r   r   r   r   r   r"   r     s    z'_AssignmentExpressionChecker.visit_Node)r.   r/   r0   r1   r5   r   r   classmethodrt   r   r   rf   ry   rw   r   rP   r   r   r:   r"   rs     s   	
rs   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 | kr<| kr`t| }|| < | n$|  | jr`| jD ]} | qRd S r   )
is_literalr   r	   r   addr   rZ   )r!   Zref_nodeitem)find_duplicatesref_node_sequence	ref_nodes
seen_nodesr   r"   r     s    

z1eliminate_rhs_duplicates.<locals>.find_duplicatesr   Nc                    s,   |  kr |  S | j r(tt| j| _| S r   )r   listmaprZ   )r!   )r   substitute_nodesr   r"   r   2  s
    z2eliminate_rhs_duplicates.<locals>.substitute_nodes)r   r   r   r   rZ   )r   r   r   r   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 ]*}||kr dS |j r |j|r dS qdS rH   r   rZ   )r   xr   containsr   r"   r   N  s    z*sort_common_subsequences.<locals>.containsc                    s   |j o |j| S r   r   )abr   r   r"   
lower_thanU  s    z,sort_common_subsequences.<locals>.lower_thanr   r   r   N)	enumeraterange)itemsr   r>   r   keynew_posir   r   r"   r   B  s    r   c                 C   sD   g }| j }| j}| j}|j}|D ]}||}||||d q |S )NrW   )r>   r;   rX   r   )literalcharsr>   stypeZsvalZ	sval_typecharcvalr   r   r"   #unpack_string_to_character_literalsd  s    r   )inputoutputc                 C   s2  | 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}	d}
|jD ]}|
t|j7 }
q|
dkrt|jd |||g qq|	|
 |krJt|jd	||dkr.d
p0df  |||g qq|
rbt|||j| q|	|k rt|jd|	|f  |||g qqt||jD ]\}}|| qq|r|| || t||D ]$\}}|r|| t|| q|D ](}|d j r t|| n
|| qd S )Nr   c                 S   s   g | ]
}|j qS r   )r   )r   r   r   r   r"   r   z  s     z0flatten_parallel_assignments.<locals>.<listcomp>c                 S   s   g | ]}g qS r   r   r   r   r   r   r"   r     s     z4starred assignment target must be in a list or tupler   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@   r   UnicodeNoder   r   rZ   rM   r   r   r   
is_starredr   r>   boolmap_starred_assignmentzipr   )r   r   r   Zcomplete_assignmentsrhs_argsZrhs_sizelhs_targetsstarred_assignmentsr   Zlhs_sizeZstarred_targetsrL   targetsZcascader   r   r"   r   p  st    




 



r   )r  r  lhs_argsr  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>   rZ   )
r   r  r  r   r   r   r   r>   r   ListNode)r  r  r	  r  r   r  rL   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 |S )Npxd)ru   r4   __call__r   r:   r   r"   r    s    zPxdPostParse.__call__c                 C   s    | j }d| _ | | || _ |S Nro   )ru   r,   )r    r!   oldr   r   r"   visit_CClassDefNode  s
    
z PxdPostParse.visit_CClassDefNodec                 C   s   | j }t|tjr*| jdkr*|jdkr*d }t|tjrd|jkr| jdkrd|_|j	dkrh| j
|j	 }q|jrz| j
d }qd }n| j }|r| jt|j| d S |S d S )Nro   )Z__getbuffer__Z__releasebuffer__inline)r  ro   Tprivateapi)ERR_INLINE_ONLYr@   r   rc   ru   rY   CFuncDefNode	modifiersZinline_in_pxdr+   ERR_NOGO_WITH_INLINEr  r9   r   rQ   r>   )r    r!   errr   r   r"   r      s(    

zPxdPostParse.visit_FuncDefNode)
r.   r/   r0   r1   r  r  r  r  r   rP   r   r   r:   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 | _d S r   )r4   r5   r   numpy_module_namesr   r:   r   r"   r5     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_CImportStatNode#  s    
z*TrackNumpyAttributes.visit_CImportStatNodec                 C   s2   |  | |j}|jr"|j| jks(|jr.d|_|S rD   )r,   objr   rY   r  Zis_numpy_attribute)r    r!   r  r   r   r"   visit_AttributeNode(  s
    
z(TrackNumpyAttributes.visit_AttributeNode)
r.   r/   r0   r5   r  r  r   recurse_to_childrenr   rP   r   r   r:   r"   r    s   r  c                       s  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d	d
dddddddddhZee
 dddddhZdddh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d0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Z d:d; Z!d<d= Z"d>d? Z#d@dA Z$dBdC Z%dDdE Z&dFdG Z'dHdI Z(dJdK Z)dLdM Z*dNdO Z+dPdQ Z,  Z-S )RInterpretCompilerDirectivesa+  
    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
    - replaces "cython.compiled" with BoolNode(value=True)
      allowing unreachable blocks to be removed at a fairly early stage
      before cython typing rules are forced on applied

    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unionr~   ZtypedefsizeofcastpointercompiledNULLZ
fused_typeparallelZcimportsdataclassesoperatorviewprangeZthreadidc                    s`   t  | t | _ddi| _i | _tt	 }|
 D ]\}}t||t|< q:|| _d S )Nstaticmethod)r4   r5   r   cython_module_namesdirective_namesparallel_directivesr   deepcopyr   get_directive_defaultsr   str
directives)r    r9   Zcompilation_directive_defaultsr7  r   rX   r:   r   r"   r5   x  s    
z$InterpretCompilerDirectives.__init__c                 C   sZ   t j|d }|r8||kr8| jt|d||f  dS |t jkrRt|d|f  dS d S )Nz4The %s compiler directive is not allowed in %s scopeFzInvalid directive: '%s'.T)r   Zdirective_scopesr   r9   r   rQ   directive_typesr   )r    r>   	directivescopeZlegal_scopesr   r   r"   check_directive_scope  s    
z1InterpretCompilerDirectives.check_directive_scopec           
      C   s   | dsd S |ddd }|| jkr,d S d}dd d d d	 D }|D ]"\}}| d| rNd
| } qrqN|s|tjk}|s| dsddlm}	 t|	|}|rd| }t	|d||rdnd|f  d S )Ncython..r   r   r   c                 S   s   g | ]}|  qS r   )split)r   liner   r   r"   r     s    zJInterpretCompilerDirectives._check_valid_cython_module.<locals>.<listcomp>z                imp                  cimports
                cimp                 cimports
                para                 parallel
                parra                parallel
                dataclass            dataclasses
            r   zDid you mean 'cython.%s' ?r   )Shadowz2Instead, use 'import cython' and then 'cython.%s'.z''%s' is not a valid cython.* module%s%sz. )

startswithr>  valid_cython_submodules
splitlinesr   r8  r   r@  hasattrr   )
r    r>   r  	submoduleextrahintsZwrongcorrectZis_simple_cython_namer@  r   r   r"   _check_valid_cython_module  s6    

	


z6InterpretCompilerDirectives._check_valid_cython_modulec                 C   st   t |jD ],}| |j|ds
| |j|d |j|= q
|j| _| j|j | j|_| j	|_	| 
| | j|_|S )Nr   )sortedZdirective_commentsr;  r>   Zwrong_scope_errorr:  module_scoper7  r   r3  r,   r1  )r    r!   r   r   r   r"   rC     s    

z,InterpretCompilerDirectives.visit_ModuleNodec                 C   s$   | j |j  }| _ | | || _ |S r   r7  r,   r    r!   old_directivesr   r   r"   visit_CompilerDirectivesNode  s    
z8InterpretCompilerDirectives.visit_CompilerDirectivesNodec                 C   s   |t jkp|| jkpt|S r   )r   r8  special_methodsr   parse_basic_type)r    rY   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kr|t|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.
        r=  cython.parallel.cython.parallelr+  zcython.parallel.*zcython.parallel.%s   r   zNo such directive: %s)rA  r>  r3  valid_parallel_directivesr   r   )r    	full_namer>   r   r9  rY   r   r   r"   is_parallel_directive  s    

z1InterpretCompilerDirectives.is_parallel_directivec                 C   s  |j }|dkrt|jd |drV|jrJ|jdkrJ|tdd  |_ |S t|jd |dkrr| j|jpld n|dr|drt|j|j d  n| |j| |d	kr|jr|jdkr|| j	|j< n| jd || j	d	< n*|jr|d
d  | j
|j< n| jd d S |S )Ncython.cimportszGCannot cimport the 'cython.cimports' package directly, only submodules.cython.cimports.cythonzkPython cimports must use 'from cython.cimports... import ...' or 'import ... as ...', not just 'import ...'r<  rS  z is not a modulerT     )r  r   r>   rA  r  r   r1  r   rI  r3  r2  r    r!   r  r   r   r"   r    s:    

z1InterpretCompilerDirectives.visit_CImportStatNodec           
      C   s  |j }|dks|dr.| |j||j|jS |js|dksJ|dr| |j| |d dd  }g }|jD ]\}}}|| }d| }	| |	|jr|	| j|p|< qr| 	|r|| j
|p|< qr|dkr|| j
|p|< ||||f qr||||f qr|sd S ||_|S )NrY  rZ  r[  r<  r=  r\  )r,  typing)r  rA  _create_cimport_from_importr>   relative_levelimported_namesrI  rX  r3  rR  r2  r   )
r    r!   r  rE  newimpr>   rY   r  rW  qualified_namer   r   r"   visit_FromCImportStatNode	  s>       
z5InterpretCompilerDirectives.visit_FromCImportStatNodec                 C   s  |j }|jj}|dks |drjg }|jD ]*\}}||j|||jkrJd n|jf q*| |j||j	|S |dks~|dr| 
|jj| |d dd  }g }|jD ]Z\}}|| }	d|	 }
| |
|jr|
| j|j< q| |	r|	| j|j< q|||f q|sd S ||_|S )NrY  rZ  r[  r<  r=  r\  )r   r  rX   rA  r   r   r>   rY   r_  levelrI  rX  r3  rR  r2  )r    r!   Zimport_noder  ra  rY   	name_noderE  rb  rW  rc  r   r   r"   visit_FromImportStatNode*  s<       
z4InterpretCompilerDirectives.visit_FromImportStatNodec                    sR   |dks| dr&t|tdd  }|r<tj|| |dS  fdd|D S d S )NrY  rZ  )r  r`  ra  c                    s(   g | ] \}}}t j||| d kdqS )r   )r  r  is_absolute)r   CImportStatNode)r   r>   Zdotted_namer  re  r   r"   r   R  s   zKInterpretCompilerDirectives._create_cimport_from_import.<locals>.<listcomp>)rA  r   r   r   ZFromCImportStatNode)r    Znode_posr  re  ra  r   rj  r"   r_  F  s     
z7InterpretCompilerDirectives._create_cimport_from_importc                 C   s^   t |jtjrP|jjj}|dkr.|ds.|S tj|j	||j
jd}| |}n
| | |S )Nr[  r<  )r  r  )r@   r   r   Z
ImportNoder  rX   rA  r   ri  r>   r   rY   r  r,   r]  r   r   r"   r   [  s    

z6InterpretCompilerDirectives.visit_SingleAssignmentNodec                 C   sb   |j r| |d |j| jkr&d|_n| j|j}|d k	rB||_| dkr^t	j
|jddS |S )N
annotationTr)  rW   )rk  
visitchildrY   r1  is_cython_moduler2  r   Zcython_attributeas_cython_attributer   BoolNoder>   )r    r!   r9  r   r   r"   visit_NameNodeh  s    z*InterpretCompilerDirectives.visit_NameNodec                 C   s*   |  | | dkr&tj|jddS |S )Nr)  TrW   )r,   rn  r   ro  r>   r   r   r   r"   r  v  s    
z/InterpretCompilerDirectives.visit_AttributeNodec                 C   s   |j r| |j  |S r   )rL   r   r   r   r   r"   visit_AnnotationNode}  s    z0InterpretCompilerDirectives.visit_AnnotationNodec                 C   s   |  |d | | |S NZcppclass)rl  r,   r   r   r   r"   visit_NewExprNode  s    
z-InterpretCompilerDirectives.visit_NewExprNodec              	   C   s  t |tjr| |d |j }|rtj|}|r|	 \}}g }g }|d k	r|t
k	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r| | | }|rtj|}|tkrVtj|jdd}| ||gd |jgS |d ksl|tjkrv|d fgS t|jd| d S )Nfunction%s.%sTrW   z5The '%s' directive should be used as a function call.)r@   r   CallNoderl  rt  rn  r   r8  r   explicit_args_kwdsdictkey_value_pairsrX   r   try_to_parse_directiver>   AttributeNoder   r   r  ro  DEFER_ANALYSIS_OF_ARGUMENTSrQ   )r    r!   optnamedirectivetyperZ   kwdsr7  ry  Zkeyvaluer   rX   Zsub_optnamer   r   r   r"   try_to_parse_directives  sL    




 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kr8|d k	st|dkst|d t	j
s*t|d	| ||d jfS |tkr|d k	slt|dkslt|d t	jszt|d
| |t|d jfS |tkr|d k	st|dkst|d t	jst|d| |t|d jfS |tkr|d k	st|dkrt|d| ||d fS |tkrNt|dkrBt|d| || fS |tkr|r|t|jdkr|t|d| |dd |D fS t|r|d k	st|dkst|d t	jst|d| |||t|d jfS |tjkr|||r| ni ffS dst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"8The %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 argumentsz+The %s directive takes no keyword argumentsc                 S   s   g | ]}t |jqS r   )r6  rX   )r   r   r   r   r"   r     s     zFInterpretCompilerDirectives.try_to_parse_directive.<locals>.<listcomp>F)r9   cpprQ   r   ry  r   rM   rX   r@   r   ro  r   r8  r   NoneNoder5  r  intZIntNoder6  r   typerx  Zas_python_dictr   callabler|  r   )	r    r}  rZ   r  r>   Z	arg_errorr  kwr~  r   r   r"   rz    s    



 
*
*
*



*z2InterpretCompilerDirectives.try_to_parse_directivec                 C   s   |s|rt | |S | j}tj|f|}|d k	rBtj|f|}n|}||krX| |S || _|d k	r||krtj|jjtj	|jj||jdgd|_| |}|| _t
|tj	r||j |j}t
|tjstj|j|gd}tj	|j|||jdS )N)r7  rA   r   )rA   r7  is_terminator)r   r   r7  r   Zcopy_inherited_directivesr   rB   rA   r>   ZCompilerDirectivesNoder@   r   r  )r    r!   r7  contents_directivesrN  new_directivesZnew_contents_directivesZretbodyr   r   r"   visit_with_directives  sP    

	
   z1InterpretCompilerDirectives.visit_with_directivesc                 C   s   |  |d\}}| |||S )Nrt  _extract_directivesr  r    r!   r7  r  r   r   r"   r     s    z-InterpretCompilerDirectives.visit_FuncDefNodec                 C   sb   |  |d\}}| D ]8\}}|dkr0||_q|dkr| jt|jd|  q| j||d dS )Nrt  locals)finalr0  zXCdef functions can only take cython.locals(), staticmethod, or final decorators, got %s.r  )r  r   directive_localsr9   r   rQ   r>   r  )r    r!   r7  r   rY   rX   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 rr  r  r  r   r   r"   r-   3  s    z.InterpretCompilerDirectives.visit_CppClassNodec                 C   s   |  |d\}}| |||S )Nclassr  r  r   r   r"   visit_PyClassDefNode7  s    z0InterpretCompilerDirectives.visit_PyClassDefNodec                 C   s0  |j si i fS g }g }g }t| j}t }|j ddd D ]L}| |j}	|	dk	r~|	D ]}
| |j|
d |rb|
\}}|dkr|dkrd}nB|\}}|st|dkst	|d t
jst|jd| |d j}||f}
||||kr$|dkrd	|krt|jd
 ||
 |||< n&t|jd||dk	r@d| ndf  |
d dkrb|| |
d dkrZ|dkrZd}qZq:|| q:|ddd |ddd  |_ i }i }|D ]r\}}||kr|| }t	|tr|| n t	|tr|| n|||< n|||< |tjkr|||< q||fS )z
        Returns two dicts - directives applied to this function/class
        and directives applied to its contents. They aren't always the
        same (since e.g. cfunc should not be applied to inner functions)
        Nr   r   )nogilwith_gilTr   r  cfuncufuncz=Cannot apply @cfunc to @ufunc, please reverse the decorators.z/Directive does not change previous value (%s%s)z=%rr   r0  ro   r  )
decoratorsrx  r7  objectr  	decoratorr;  r>   r   r@   r   ro  rQ   rX   r   r   r   r   r   r   r   r   Zimmediate_decorator_directives)r    r!   Z
scope_namer7  ZrealdecsZbothZcurrent_opt_dictmissingdecr  r9  rY   rX   rZ   r  optdictZcontents_optdict	old_valuer   r   r"   r  ;  sd    


 


 


z/InterpretCompilerDirectives._extract_directivesc                 C   s   i }|  |jpg D ]}|d kr"q|jd k	rB| jt|jd q|\}}|dkrb| ||  S |dkr|\}}| |||  S | 	|j|dr|||< q|r| j
|j|d dS | |S )Nz6Compiler directive with statements cannot contain 'as')r  gilcritical_sectionzwith statementr  )r  managerr   r9   r   rQ   r>   _transform_with_gil_transform_critical_sectionr;  r  rA   r   )r    r!   Zdirective_dictr9  rY   rX   rZ   r  r   r   r"   visit_WithStatNode~  s(    


z.InterpretCompilerDirectives.visit_WithStatNodec                 C   s   |dkst |j}d }t|tjrZ|jrZt|jdkrN| jt	|j
d|  |jd }n$t|tjr~| jt	|j
d|  tj|j
||j|d}| |S )N)r  r  r   z6Compiler directive %s accepts one positional argument.r   )staterA   	condition)r   r  r@   r   SimpleCallNoderZ   r   r9   r   rQ   r>   GeneralCallNoder   GILStatNoderA   r   )r    r!   r  r  r  r   r   r"   r    s    z/InterpretCompilerDirectives._transform_with_gilc                 C   sN   t |dk st |dks|r0| jt|jd tj|j||jd}| |S )Nr   r   zBcritical_section directive accepts one or two positional argumentsrZ   rA   )	r   r9   r   rQ   r>   r   CriticalSectionStatNoderA   r   )r    r!   rZ   r  r   r   r"   r    s    
  z7InterpretCompilerDirectives._transform_critical_section).r.   r/   r0   r1   r   Z
TypeofNodeZAmpersandNodeZDereferenceNodeZinc_dec_constructorZ
TypeidNodeunop_method_nodesZc_binop_constructorbinop_method_nodesrP  r   rB  rV  r5   r;  rI  rC   rO  rR  rX  r  rd  rg  r_  r   rp  r  rq  rs  r  rz  r  r   r$   r  r-   r  r  r  r  r  rP   r   r   r:   r"   r!  2  s   



         
	
'$!,@*C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kp|jS r   )rY   r3  rm  r   r   r   r"   node_is_parallel_directive  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k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   ru  r   Nr+  zInvalid directive: %sF)	namenode_is_cython_modulejoinparallel_directiver3  rstripdirective_to_noder   r   r>   )r    r!   r9  r   r   r   r"   get_directive_class_node  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
        )r3  r   r   r   r   r"   rC     s    
z'ParallelRangeTransform.visit_ModuleNodec                 C   s    |  |r|jg| _|j| _|S r   )r  rY   r  rm  r  r   r   r   r"   rp    s    

z%ParallelRangeTransform.visit_NameNodec                 C   s"   |  | | jr| j|j |S r   )r,   r  r   	attributer   r   r   r"   r    s    
z*ParallelRangeTransform.visit_AttributeNodec                 C   sl   |  |d | js$| j|dd |S t|tjr@|jj}|j}n
|j}i }| 	|}|rh||j
||d}|S )Nrt  )rt  r   )rZ   kwargs)rl  r  r,   r@   r   r  positional_argsrZ   keyword_argsr  r>   )r    r!   rZ   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| _| |d}d| _||_	|S | j
r| |}|sjdS |tjkrt|jd dS | |d |S )z.Rewrite with cython.parallel.parallel() blockszparallel withz*Nested parallel with blocks are disallowedrA   Nz%The parallel directive must be called)r   r  r@   r   ParallelWithBlockNoder  r   r>   rl  rA   r  r  )r    r!   ZnewnoderA   r  r   r   r"   r    s(    


z)ParallelRangeTransform.visit_WithStatNodec                 C   s   |  |d |  |d t|jjtj}| j}|rx|jj}|j|_|j|_|j	|_	|}t|jt
jsrt|jjd d| _|  |d || _|  |d |S )z/Rewrite 'for i in cython.parallel.prange(...):'rg   r   z+Can only iterate over an iteration variabler/  rA   else_clause)rl  r@   rg   sequencer   ParallelRangeNoder  r   rA   r  r   r   r   r>   )r    r!   Z	in_prangeprevious_stateZparallel_range_noder   r   r"   r   8  s*    z*ParallelRangeTransform.visit_ForInStatNodec                    s   |dk	rt  |S dS )zVisit a node that may be NoneN)r4   r   r   r:   r   r"   r   W  s    zParallelRangeTransform.visit)r.   r/   r0   r1   r  r  Zin_context_manager_sectionr  r   r  r   ZParallelThreadIdNoder  r  r  r  rC   rp  r  r  r  r   r   rP   r   r   r:   r"   r    s$   r  c                   @   s"   e Zd Zdd Zdd ZejZdS )WithTransformc                    s  |  |dg |j |j}|j|j|j  }}}t| }|_tj tj	 t
|t|r^dndddg dd|_|rtj |jd|_|d k	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||r
t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|rtj d dnd dddd|_|S )NrA   
__aenter__	__enter__T)r  r  Zis_special_lookup)rt  rZ   Zis_temp)r   )r   Z	with_noder   c                    s   g | ]}t  qS r   )r   ZExcValueNoder   r>   r   r"   r   v  s    z4WithTransform.visit_WithStatNode.<locals>.<listcomp>rU  )ZslowrZ   F)Z	with_statZtest_if_runrZ   Z
await_exproperand)r  rA   )
if_clausesr  )rA   patternr   excinfo_target)rA   Zexcept_clausesr  c                    s   g | ]}t  qS r   )r   r  r   r  r   r"   r     s     rZ   rV   )rA   r   Zhandle_error_case)r,   r>   is_asyncrA   r   r  r   	ProxyNoder  r{  	CloneNoder   Z
enter_callZAwaitExprNoder   rB   ZWithTargetAssignmentStatNode	TupleNoder   ZExceptClauseNodeZ
IfStatNodeZIfClauseNodeZNotNodeZWithExitCallNodeZReraiseStatNoder   ZTryExceptStatNoderb   )r    r!   r  rA   r   r  r  Zexcept_clauser   r  r"   r  ^  s        
         z WithTransform.visit_WithStatNodec                 C   s   |S r   r   r   r   r   r"   rF     s    zWithTransform.visit_ExprNodeN)r.   r/   r0   r  rF   r   r   r   r   r   r   r"   r  ]  s   >r  c                       s4   e Zd Z fddZdd Zdd Zdd Z  ZS )	#_GeneratorExpressionArgumentsMarkerc                    s   t    || _d S r   )r4   r5   gen_expr)r    r  r:   r   r"   r5     s    
z,_GeneratorExpressionArgumentsMarker.__init__c                 C   s&   |j s|jrt| j|_| | d S r   )r   generator_arg_tagr   r  r,   r   r   r   r"   rF     s    
z2_GeneratorExpressionArgumentsMarker.visit_ExprNodec                 C   s   d S r   r   r   r   r   r"   r     s    z._GeneratorExpressionArgumentsMarker.visit_Nodec                 C   s   | j |_d S r   )r  r  r   r   r   r"   rw     s    zA_GeneratorExpressionArgumentsMarker.visit_GeneratorExpressionNode)r.   r/   r0   r5   rF   r   rw   rP   r   r   r:   r"   r    s   r  c                   @   s2   e Zd Zdd Zdd Zdd Zdd ZejZ	d	S )
_HandleGeneratorArgumentsc                 C   s   ddl m} t|tjst|| _t|jj	| _	t|j
| _
d| _i | _| | | j D ]\}}|||| q\| j	|j_	| j
|_
|S )Nr   )Visitorr   )r   r  r@   r   ZGeneratorExpressionNoder   gen_noder   rd   rZ   call_parameters	tag_countsubstitutionsr,   r   Zrecursively_replace_node)r    r!   r  kvr   r   r"   r    s    

z"_HandleGeneratorArguments.__call__c                 C   s   | j |dd}|S )NF)do_visit_children_handle_ExprNode)r    r!   Znew_noder   r   r"   rw     s    z7_HandleGeneratorArguments.visit_GeneratorExpressionNodec                 C   s  |j d k	rr| jd k	rr| j|j krr|j}| j}|  jd7  _td|}| jj}|j|sddl	m
} ttj|t| }tj||d}	|j}
tj|
dd}
|
|	_tj||	d d d d}|	j|_|
|_| j| d |_ | j| ||j||_||j_d|j_|r4| jd  }| _| | || _tj||dd	}| jjj j!|j|_|jj|_|| j"|< |S |r| | |S )
Nr   z.{})Symtabr>   rY   F)Zremove_fakeref)r>   
declarator	base_typerz   rk  T)rY   Zinitialized_check)#r  r  r>   r  r   formatrd   local_scopelookup_herer   r  r   Zgenexpr_arg_prefixZpunycodify_namer6  r   r   r  r   Zremove_cv_refZCArgDeclNoderY   rZ   r   r  Zdeclare_argumententrycname
in_closurer,   r   r   gbodylookupr  )r    r!   r  r>   Zname_sourcerY   rd   r  r  Z	name_declr  Znew_argr  rf  r   r   r"   r    sP    

  



z*_HandleGeneratorArguments._handle_ExprNodec                 C   s   |  |dS rD   r  r   r   r   r"   rF     s    z(_HandleGeneratorArguments.visit_ExprNodeN)
r.   r/   r0   r  rw   r  rF   r   r   r   r   r   r   r"   r    s
   =r  c                       s   e Zd ZdZdZedededdjZ fddZd	d
 Z	dd Z
dd Zdd Zedd Zdd Z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                    s6   | j d krg | _ | j i  t |}| j   |S r   )_propertiesr   r4   r  popr   r:   r   r"   r  /  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')r@   r>   r6  r   rY   )r    r!   re  r   r   r"   visit_PropertyNode7  s    z%DecoratorTransform.visit_PropertyNodec                 C   s   |  |}|js|S | jdks*| jjdkrnt|jdkrX|jd jjrX|jd jjdksjt	|jd j
d |S |}| |}|r|jjr| }|r| |||}nt	|j
d |jr| ||jd S |S )Nro   r*   r   r   r0  z0Cdef functions cannot take arbitrary decorators.z*C property decorator can only be @property)r   r  ru   r|   r+   r   r  r   rY   r   r>   _find_property_decoratorZdeclared_name_add_property_reject_decorated_property)r    r!   Zret_nodedecorator_noderY   r   r   r"   visit_CFuncDefNode=  s(    

z%DecoratorTransform.visit_CFuncDefNodec                 C   s  | j }| |}|dks|js"|S | |}|d k	r|j}|jrP| ||j|S | |j	}|r|j
j|jkrt|jd|j
j|jf  n(t|jdkr| ||S | |||S |jD ]8}|j}|jr| j|jdkO  _| j|jdkO  _q|j}d |_| |||jS )Nro   z3Mismatching property names, expected '%s', got '%s'r   r   r0  )ru   r   r  r  r  r   r  rY   _map_property_attributer  r  r   r>   r   r  _add_to_propertyZis_classmethodZis_staticmethodchain_decorators)r    r!   ru   r  r  Zhandler_namefuncZdecsr   r   r"   r   W  s:    

 
z DecoratorTransform.visit_DefNodec                 C   s\   | j d }|jd d d D ]<}|j}|jr<|jdkr<|  S |jr|jj|kr|  S qd S )Nr   property)r  r  r  r   rY   is_attributer  )r    r!   
propertiesr  r  r   r   r"   r  }  s    

z+DecoratorTransform._find_property_decoratorc                 C   s$   | j D ]}||krt|jd q| S )Nz=Property methods with additional decorators are not supported)r  r   r>   )r!   r  decor   r   r"   r    s    
z-DecoratorTransform._reject_decorated_propertyc                 C   s  t |jdkr| ||S |j| | jd }t|tj}tj|j	|gd}|r||krft
|j	d d|jkr|t
|j	d tj|j	|j||d}nl||kr|| }|jrt
|j	d n$td|_|j	|_	|j|_|g|j_d S td|_tj|j	||j|d	}|||< |S )
Nr   r   r   C property redeclaredr  z+C property method must be declared 'inline')r]   rY   rA   r  )rY   r]   rA   )r   r  r  remover  r@   r   r  rB   r>   r   r  ZCPropertyNoder]   is_cpropertyr   rY   rA   r?   ZPropertyNode)r    r!   rY   r  r  r  rA   propr   r   r"   r    s<    




   z DecoratorTransform._add_propertyc           	      C   sz   | j d }||j }|jr*t|jd d S ||_|j| |jj}t	|D ]\}}|j|krL|||<  qvqL|
| d S )Nr   r  )r  rY   r  r   r>   r  r  rA   r?   r   r   )	r    r!   rY   r  r  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.
        r   Nr   rt  rZ   r   )	r   r   r>   r  r  r   r   ZIndirectionNodeZdecorator_indirection)r!   r  rY   Zdecorator_resultr  rf  Zreassignmentr   r   r"   r    s     
z#DecoratorTransform.chain_decorators)r.   r/   r0   r1   r  r   r   r  r  r  r  r   r  r0  r  r  r  r  rP   r   r   r:   r"   r    s"   &
r  c                   @   s,   e Zd ZdZdd Ze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 )	Nr  r  z/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   r  r  r@   r   rv  rt  r   rY   rw  r   r   r   r  r   Zunicode_typecompile_time_valuer   ZCnameDecoratorNoder>   )r    r!   r   r  rZ   r  r  r   r   r"   handle_function  s:    


z(CnameDirectivesTransform.handle_functionN)
r.   r/   r0   r1   r  r   r  r'   r(   r$   r   r   r   r"   r	    s    r	  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S )ForwardDeclareTypesz
    Declare all global cdef names that we allow referencing in other places,
    before declaring everything (else) in source code order.
    c                 C   s(   | j }|j}|j|_| | ||_|S r   )rK  r7  r,   )r    r!   envr  r   r   r"   rO    s    
z0ForwardDeclareTypes.visit_CompilerDirectivesNodec                 C   s    |j | _|j| j_| | |S r   )r:  rK  r7  r,   r   r   r   r"   rC     s    

z$ForwardDeclareTypes.visit_ModuleNodec                 C   s&   | j j}d| j _| | || j _|S Nr   )rK  Zin_cincluder,   )r    r!   Zold_cinclude_flagr   r   r"   visit_CDefExternNode  s
    
z(ForwardDeclareTypes.visit_CDefExternNodec                 C   s   | | j |S r   )r$  rK  r   r   r   r"   r'   &  s    z&ForwardDeclareTypes.visit_CEnumDefNodec                 C   s   |j | jjkr|| j |S r   )rY   rK  entriesr$  r   r   r   r"   r(   *  s    z/ForwardDeclareTypes.visit_CStructOrUnionDefNodec                 C   sr   |j | jjkr|| j | jj|j  j}|d k	rn|jrn|jsn|jrn|j}|jD ]}|jrP|jj	rP|j
  qP|S r   )
class_namerK  r  r$  r  is_extension_typeZis_builtin_typer:  Zcfunc_entriesis_fusedZ"get_all_specialized_function_types)r    r!   r  r:  r  r   r   r"   r  /  s    
z'ForwardDeclareTypes.visit_CClassDefNodec                 C   s   |S r   r   r   r   r   r"   r   ;  s    z%ForwardDeclareTypes.visit_FuncDefNodec                 C   s   |S r   r   r   r   r   r"   r  ?  s    z(ForwardDeclareTypes.visit_PyClassDefNodeN)r.   r/   r0   r1   rO  rC   r  r'   r(   r  r   r  r   r   r   r"   r    s   r  c                       sx  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 f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'dCdD Z(dEdF Z)dGdH Z*  Z+S )IAnalyseDeclarationsTransformzr
property NAME:
    def __get__(self):
        return ATTR
    def __set__(self, value):
        ATTR = value
    c_classNre  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 }|j| _||S r   )seen_vars_stackr   fused_error_funcsr4   r   _super_visit_FuncDefNoder  )r    rootZsuper_classr:   r   r"   r  t  s
    z%AnalyseDeclarationsTransform.__call__c                 C   s   | j d |j |S Nr   )r  r   rY   r   r   r   r"   rp  |  s    z+AnalyseDeclarationsTransform.visit_NameNodec                 C   sJ   g | _ | jt  ||   | | | j  |jj	
| j  |S r   )extra_module_declarationsr  r   r   analyse_declarationscurrent_envr,   r  rA   r?   r   r   r   r   r"   rC     s    

z-AnalyseDeclarationsTransform.visit_ModuleNodec                 C   s8   |  j d7  _ ||   | | |  j d8  _ |S r  )	in_lambdar  r   r,   r   r   r   r"   rf     s
    
z-AnalyseDeclarationsTransform.visit_LambdaNodec                 C   s   |  |}|jr<d|jjkr<ddlm} |||jjd |  |jr|jjr|jrg }|jjD ]4}|jr\| 	|}|
|j | | || q\|r|j j|7  _|jdkr|jds|jds| | |S )Ndataclasses.dataclassr   )handle_cclass_dataclassr*   
__reduce____reduce_ex__)visit_ClassDefNoder:  r7  Z	Dataclassr#  ZimplementedrA   var_entriesZneeds_propertycreate_Propertyr  r   r   r?   r+   r  _inject_pickle_methods)r    r!   r#  r?   r  r  r   r   r"   r    s*    






z0AnalyseDeclarationsTransform.visit_CClassDefNodec                    s  |    |jjd dkrd S |jjd dk}g }|jj}d }d }|d k	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|
 nl|D ](}|jjs|j  |j  qdd |D }t|}d|j }td|d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 |D t|d%krvd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 kr|V  qdS ))__weakref____dict__Nr   r   r   r   r   r"   	<genexpr>  s     
 zFAnalyseDeclarationsTransform._inject_pickle_methods.<locals>.<genexpr>Z	__cinit__r$  r%  c                 S   s   | j S r   r   )r   r   r   r"   <lambda>      zEAnalyseDeclarationsTransform._inject_pickle_methods.<locals>.<lambda>)r   c                    s0   g | ](}|j js|j  r(|j  s|qS r   )r  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   )r  Zis_struct_or_unionr,  r   r   r"   r     s      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.%sNr   r,  r   r   r"   r-    s     zZPickling of struct members such as %s must be explicitly requested with @auto_pickle(True)c                 s   s   | ]}d |j  V  qdS r2  r   r,  r   r   r"   r-    s     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   r   r,  r   r   r"   r     s     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 not in %(checksums)s:
                        from pickle import PickleError as __pyx_PickleError
                        raise __pyx_PickleError, "Incompatible checksums (0x%%x vs %(checksums)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(%s)z, z; c                 s   s   | ]\}}d ||f V  qdS )z!__pyx_result.%s = __pyx_state[%s]Nr   )r   ixr  r   r   r"   r-  	  s   )unpickle_func_name	checksumsmembersr  ZassignmentsZnum_membersr   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)
                r   c                 s   s   | ]}d | V  qdS r2  r   )r   r  r   r   r"   r-  "	  s     r   r   z or c                 S   s   g | ]}|j jrd |j qS )zself.%s is not None)r  r0  rY   r,  r   r   r"   r   $	  s      False)r5  checksumr7  Zany_notnone_members) r   r:  r7  r  r  r   r'  r  r  sortr  r   r>   r
   r2   
substituter  r   rA   r?   r   r0  Zcreate_to_py_utility_codeZcreate_from_py_utility_code_calculate_pickle_checksumsZpunycode_class_namer  r   r   r  enter_scope
exit_scope)r    r!   Zauto_pickle_forcedZall_membersr   ZcinitZinherited_reduceZnon_pystructsr3  Zpickle_funcr   Zall_members_namesr6  r5  Zunpickle_funcr   r1  r"   r)    s    
 



 
( 
z3AnalyseDeclarationsTransform._inject_pickle_methodsc                 C   sx   g }|D ]0}|j }|jr.|jdks.||jr|| q|rtt| j}|j}||||j\}	}
|
	| ||
g}|S )zd
        Create function calls to the decorators and reassignments to
        the function.
        )r0  r   )
r  r   rY   r  r   r  r9   r!   r  r  )r    Zold_decoratorsr  r!   r  r  r  	transformrd   r   Zreassignmentsr   r   r"   _handle_fused_def_decorators-	  s(    

  
z9AnalyseDeclarationsTransform._handle_fused_def_decoratorsc                 C   s   |j d|j | |d || d|jjj_tj	j
|jdd}t||}||_| |jt|||_|r| |||}|S )z#Handle def or cpdef fused functionsr   py_funcFT)binding)r?   insertrB  rl  Zupdate_fused_defnode_entryr  	signatureZuse_fastcallr   PyCFunctionNodefrom_defnoder  Zcoerce_to_tempZresulting_fused_function_create_assignmentr  Zfused_func_assignmentrA  )r    r  r  r!   Zpycfuncr   r   r"   _handle_defG	  s    
  z(AnalyseDeclarationsTransform._handle_defc                 C   s   ddl m} | js| jr| j| jk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   r  N)r   rJ  fused_functionr!  r  r   r>   r   r   rN   rA   rZ   r  r  Zget_fused_typesr
  ZFusedCFuncDefNoder,   rB  rI  )r    r  r!   rJ  r   r  r   r   r"   _create_fused_function[	  s(    

z3AnalyseDeclarationsTransform._create_fused_functionc                 C   s8   |j r2|jr2t|jd d|_tj|jg d|j_|jS )NzFused generators not supportedFr   )is_generatorhas_fused_argumentsr   r>   r   rB   r  rA   r   r   r   r"   _handle_fusedy	  s
    z*AnalyseDeclarationsTransform._handle_fusedc                 C   s   |   }| jt  |j}|| |j D ]Z\}}||s0|	|}|rh|j
rh|jrh||j}|r~||||j q0t|jd q0| |r| ||}n|j| | |}| j  d|jkrddlm} ||S |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 typer  r   )UFuncs)r   r  r   r   r  Zdeclare_argumentsr  r   r  analyse_as_typer  fused_to_specific
specializedeclare_varr>   r   rO  rL  rA   r  r  r  r7  r   rQ  Zconvert_to_ufunc)r    r!   r  lenvvarZ	type_noder  rQ  r   r   r"   r   	  s*    







z.AnalyseDeclarationsTransform.visit_FuncDefNodec                 C   sr   |  |}t|tjs|S |  }|jd krDt||_|j| |j	sP|j
rT|S ||sb|S || ||gS r   )r   r@   r   rc   r   code_objectr   CodeObjectNoder  Zfused_py_funcis_generator_bodyZneeds_assignment_synthesis_synthesize_assignmentr    r!   r  r   r   r"   r   	  s    


z*AnalyseDeclarationsTransform.visit_DefNodec                 C   s<   |j d kr2|jd kr2tj||_ |j |   | |S r   )rX  rB  r   rY  Z	for_cfuncr  r   r   r   r   r   r"   r  	  s    z/AnalyseDeclarationsTransform.visit_CFuncDefNodec                 C   s
   |  |S r   )r   r   r   r   r"   visit_GeneratorBodyDefNode	  s    z7AnalyseDeclarationsTransform.visit_GeneratorBodyDefNodec                 C   s   |  |}|j|j_|S r   )r   rX  r  )r    r!   r   r   r   r"   visit_GeneratorDefNode	  s    

z3AnalyseDeclarationsTransform.visit_GeneratorDefNodec                 C   sj   |}|j s|jr|j}q|j p(| jd}|jrFtj|| }|_	ntj
||}|j|_| |||S )NrC  )is_py_class_scopeis_c_class_scopeouter_scopecurrent_directivesr   is_closure_scoper   ZInnerFunctionNoderG  py_cfunc_noderF  rC  Zis_cyfunctionrH  )r    r!   r  ZgenvrC  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  r   r   )
r  r   r  r>   r  r   r   r   rY   r  )r    rd   r   r  r  Zassmtr   r   r"   rH  	  s    
z/AnalyseDeclarationsTransform._create_assignmentc                    s&   | j  }t | | j | d S r   )r  r  r4   visit_func_outer_attrsr   )r    r!   stackr:   r   r"   re  	  s    
z3AnalyseDeclarationsTransform.visit_func_outer_attrsc                 C   s~   |   }|| |jrf| jt| jd  | ||j ||j | | | 	  | j
  n|| | | |S r  )r   r  
expr_scoper  r   r   r=  Zanalyse_scoped_declarationsr,   r>  r  r\  r   r   r"   visit_ScopedExprNode	  s    



z1AnalyseDeclarationsTransform.visit_ScopedExprNodec                 C   s   |  | ||   |S r   r,   r  r   r   r   r   r"   visit_TempResultFromStatNode	  s    
z9AnalyseDeclarationsTransform.visit_TempResultFromStatNodec                 C   s   |j dkrd S | |S d S r)   )r+   r&  r   r   r   r"   r-   
  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s0t|j
|
d j_
|
d }t|tjr`|j
dksdt|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  rX   r>   r  r  r   )ZVALUEATTRr  z%s(%s)z%s, r   rW   r  z%sz%r)ZINIT_ASSIGNMENTSZIS_UNIONZMEMBER_TUPLEZ
STR_FORMATZREPR_FORMATr   Tr   r5   rl  )+r   r{  r>   r   r   r  r  r:  r'  r   rY   r  init_assignmentr;  r   struct_or_union_wrapperr   rB   ro  Z	is_structr  r   replacer?   r  ZshadowrA   r@   r  ZCSimpleBaseTypeNoder   rc   rZ   Zkw_onlyr   r4  r  r0  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   r   r   r   r   r"   r%   W
  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'   b
  s    
z/AnalyseDeclarationsTransform.visit_CEnumDefNodec                 C   sZ   |j | jd krL|  |j }|d ks:|jdkrL|jjsLt|jd|j   | 	| |S )Nr   r*   z,cdef variable '%s' declared after it is used)
rY   r  r   r  r+   r:  r`  r   r>   r,   )r    r!   r  r   r   r"   visit_CNameDeclaratorNodeh
  s    
z6AnalyseDeclarationsTransform.visit_CNameDeclaratorNodec                 C   s   |  | d S r   r   r   r   r   r"   r$   q
  s    
z.AnalyseDeclarationsTransform.visit_CVarDefNodec                 C   s@   |  |d}|sd S t|tkr<|d |_|g|dd   S |S )Nr!   r   r   )rl  r  r   r!   )r    r!   Z
child_noder   r   r"   visit_CnameDecoratorNodev
  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 )	Nrv  readonlyrl  r    r  rk  r  r   )r+   r  r0  rq  rr  basic_property_ror;  r   r{  r>   r   rY   r?   r]   )r    r  ru  r  r   r   r"   r(  
  s(    

 z,AnalyseDeclarationsTransform.create_Propertyc                 C   s   |  | ||   |S r   ri  r   r   r   r"   r   
  s    
z;AnalyseDeclarationsTransform.visit_AssignmentExpressionNode),r.   r/   r0   r
   r2   rr  rq  rz  ro  rn  rK  r!  r  rp  rC   rf   r  r)  rA  rI  rL  rO  r   r   r  r]  r^  r[  rH  re  rh  rj  r-   r(   r%   r#   r&   r'   rw  r$   rx  r(  r   rP   r   r   r:   r"   r  D  sh     	 
 )N		r  c              
   C   s   d | d}tjdkr"ddini }g }dD ]V}ztt|}||f| }W n ttfk
rl   Y q.Y nX |	d|d d   q.|S )	N zutf-8)rU  	   ZusedforsecurityF)sha256sha1md50xr\  )
r  encoder   version_infor
  r   	hexdigestAttributeError
ValueErrorr   )Zmember_namesZmember_names_stringZhash_kwargsr6  Z	algo_nameZ
mkchecksumr9  r   r   r"   r<  
  s    

r<  c                       sz   e Zd Zd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dd Zdd Z  ZS ) CalculateQualifiedNamesTransformz^
    Calculate and store the '__qualname__' and the global
    module name on some nodes.
    Fc                    s6   |   j| _g | _t }|j| _|j| _| | |S r   )	Zglobal_scoperc  r  r4   r   r  r&  _super_visit_ClassDefNoder,   )r    r!   Z_superr:   r   r"   rC   
  s    
z1CalculateQualifiedNamesTransform.visit_ModuleNodeNc                 C   s@   |r| j d d  }|| n| j }td||_| j|_d S )Nr=  )rc  r   r   r  qualnamer  )r    r!   rY   r  r   r   r"   _set_qualname
  s    z.CalculateQualifiedNamesTransform._set_qualnamec                 C   s*   |j r|js|jg| _n| j|j d S r   )is_pyglobalZis_pyclass_attrrY   rc  r   )r    r  r   r   r"   _append_entry
  s    z.CalculateQualifiedNamesTransform._append_entryc                 C   s   |  ||j | | |S r   )r  rY   r,   r   r   r   r"   visit_ClassNode
  s    
z0CalculateQualifiedNamesTransform.visit_ClassNodec                 C   s   |  | | | |S r   )r  r,   r   r   r   r"   visit_PyClassNamespaceNode
  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>)rc  rd   
is_wrapperr  r  rY   r,   r    r!   orig_qualified_namer   r   r"   visit_PyCFunctionNode
  s    

z6CalculateQualifiedNamesTransform.visit_PyCFunctionNodec                 C   st   |j rX| jrX| jd dks$t| j| jd d  }| j  | | | | || _n| ||j | | |S r  )r  rc  r   r  r  r  rY   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 )NrY   z<lambda>r  )rc  r
  r   r  r  r  r  r   r   r"   r   
  s    
z2CalculateQualifiedNamesTransform.visit_FuncDefNodec                 C   s`   |j |}tj|jt||dd}tj|j|d}|jj	dt
j|j||d|   d S )NT)rY   r  	is_targetrW   r   r   )r:  r  r   r   r>   r   r   rA   r?   rD  r   r   analyse_expressionsr   )r    r!   rY   rX   r  r   r   r   r   r"   generate_assignment
  s    z4CalculateQualifiedNamesTransform.generate_assignmentc                 C   s   | j }d| _ | j}d| _| jd d  }t|dd pB|  |jj}| | | 	| | j rx| 
|dtd| j | jr| 
|dt| j || _|| _ || _|S )NFr  r0   r=  r/   )needs_qualname_assignmentneeds_module_assignmentrc  r
  r   r  r   rY   r  r  r  r   r  r  )r    r!   Zorig_needs_qualname_assignmentZorig_needs_module_assignmentr  r  r   r   r"   r&    s,    

z3CalculateQualifiedNamesTransform.visit_ClassDefNodec                 C   s4   |   }|jr0|jdkr d| _n|jdkr0d| _|S )Nr0   Tr/   )r   r`  rY   r  r  )r    r!   r:  r   r   r"   rp    s    

z/CalculateQualifiedNamesTransform.visit_NameNode)N)r.   r/   r0   r1   r  r  rC   r  r  r  r  r  r   r   r  r&  rp  rP   r   r   r:   r"   r  
  s   	
	r  c                   @   sD   e 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S )AnalyseExpressionsTransformc                 C   s>   |j   |j|j |_|jhg| _| | | | |S r   )r:  infer_typesrA   r  r>   	positionsr,   _build_positionsr   r   r   r"   rC   *  s    


z,AnalyseExpressionsTransform.visit_ModuleNodec                 C   sj   |j   |j|j |_| jd |j |jr>| jd }n|jh}| j| | 	| | 
| |S r  )r  r  rA   r  r  r   r>   r  r   r,   r  )r    r!   Zlocal_positionsr   r   r"   r   2  s    


z-AnalyseExpressionsTransform.visit_FuncDefNodec                 C   s*   |j r|j  ||j}| | |S r   )rx   rg  r  Zanalyse_scoped_expressionsrF   r   r   r   r"   rh  B  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.
        )rF   Zis_fused_indexr  Zis_errorr   r   r   r   r"   visit_IndexNodeI  s    
z+AnalyseExpressionsTransform.visit_IndexNodec                 C   s    | j d |j | | |S r  r  r   r>   r,   r   r   r   r"   rF   \  s    
z*AnalyseExpressionsTransform.visit_ExprNodec                 C   s    | j d |j | | |S r  r  r   r   r   r"   rG   a  s    
z*AnalyseExpressionsTransform.visit_StatNodec           	      C   s   t | j tdddd}d}d}g }|D ]6\}}}||||||krJ|n|d f || }}q*|  ||_|  dd t|D |j_	d	S )
zg
        Build the PEP-626 line table and "bytecode-to-position" mapping used for CodeObjects.
        r   r   T)r   reverser   r   c                 S   s   i | ]\}}||qS r   r   )r   r   positionr   r   r"   
<dictcomp>  s    z@AnalyseExpressionsTransform._build_positions.<locals>.<dictcomp>N)
rJ  r  r  r   r   r  Znode_positionsr   r  Znode_positions_to_offset)	r    	func_noder  Z	next_lineZnext_column_in_linerangesr   r?  Zstart_columnr   r   r"   r  f  s"    "z,AnalyseExpressionsTransform._build_positionsN)
r.   r/   r0   rC   r   rh  r  rF   rG   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	S )
FindInvalidUseOfFusedTypesc                 C   s   d| _ | | |S r3   )_in_fused_functionr   )r    treer   r   r"   r    s    
z#FindInvalidUseOfFusedTypes.__call__c                 C   s   |  | d S r   r   r   r   r   r"   r     s    z%FindInvalidUseOfFusedTypes.visit_Nodec                 C   sB   | j }|j| _ | j s.|js.|jjr.t|jd | | || _ d S )Nz-Return type is not specified as argument type)r  rN  rZ  return_typer  r   r>   r,   )r    r!   Zouter_statusr   r   r"   r     s    
z,FindInvalidUseOfFusedTypes.visit_FuncDefNodec                 C   s0   | j s"|jr"|jjr"t|jd n
| | d S )Nz6Invalid use of fused types, type cannot be specialized)r  r  r  r   r>   r,   r   r   r   r"   rF     s    z)FindInvalidUseOfFusedTypes.visit_ExprNodeN)r.   r/   r0   r  r   r   rF   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k
rj   | Y S X |j	f |j
}tj|j|j||d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|d\}}tj| j	|| jd|fS t| tjrtdnt| } | | gfS d S )N)r   indexsetting)r  r  z@Don't allow things like attributes of buffer indexing operations)r   r  r0  r	   Zis_subscriptr   r  r   Z	IndexNoder>   r   r  r{  r  r@   BufferIndexNoder  )r!   r  r   Ztempsr  r  side_effect_free_referencer   r"   r    s     


zVExpandInplaceOperators.visit_InPlaceAssignmentNode.<locals>.side_effect_free_referenceTr  )r-  operand1operand2Zinplacer   )F)r   r   r  is_cpp_classr@   r   r  r   r  r;   r+  
binop_noder>   r-  r  Zanalyse_target_typesZanalyse_typesZanalyse_operationr   r   Z	coerce_tor  r   )	r    r!   r   r   r  Zlet_ref_nodesdupZbinoptr   r  r"   visit_InPlaceAssignmentNode  s@    



z2ExpandInplaceOperators.visit_InPlaceAssignmentNodec                 C   s   |S r   r   r   r   r   r"   rF     s    z%ExpandInplaceOperators.visit_ExprNodeN)r.   r/   r0   r  rF   r   r   r   r"   r    s   6r  c                   @   sL   e Zd 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S )AdjustDefByDirectivesz
    Adjust function and class definitions by the decorator directives:

    @cython.cfunc
    @cython.cclass
    @cython.ccall
    @cython.inline
    @cython.nogil
    @cython.critical_section
    )ro   total_orderingr"  c                 C   s   |j | _ d| _| | |S r3   )r7  in_py_classr,   r   r   r   r"   rC     s    
z&AdjustDefByDirectives.visit_ModuleNodec                 C   s"   | j }|j | _ | | || _ |S r   rL  rM  r   r   r"   rO    s
    
z2AdjustDefByDirectives.visit_CompilerDirectivesNodec              	   C   s  g }d| j kr|d | j d}| j d}| j d}|d krHdnd}| j d}|d kr| j d r|j}|d k	r|d krd	}n|d krd |rdndf}| j d
rd| j krt|jd d| j krd| j krt|jd |rt|jd |jd|||||d}| |S d| j krV| jr4t|jd n"|jd||||||d}| |S d|krlt|jd |r~t|jd |rt|jd | 	| |S )Nr  r  r  r  FTreturnsZannotation_typingrD   Zc_compile_guardr  z+c_compile_guard only allowed on C functionsZccallz-cfunc and ccall directives cannot be combinedz-ccall functions cannot be declared 'with_gil')overridabler  r  r  
except_valhas_explicit_exc_clausez#cfunc directive is not allowed here)r  r  r  r  r  r  r  z,Python functions cannot be declared 'inline'z+Python functions cannot be declared 'nogil'z.Python functions cannot be declared 'with_gil')
r7  r   r   return_type_annotationr   r>   as_cfunctionr   r  r   )r    r!   r  r  r  r  r  Zreturn_type_noder   r   r"   r     sf    


    
     


z#AdjustDefByDirectives.visit_DefNodec                 C   s^   d| j krP| j d }|d k	r(t|jd tj|jtj|j|dg|jd}||_| | |S )Nr  z2critical_section decorator does not take arguments)r  r  )	r7  r   r>   r   r  r   Z#FirstArgumentForCriticalSectionNoderA   r,   )r    r!   rX   Znew_bodyr   r   r"   r   -  s    


z'AdjustDefByDirectives.visit_FuncDefNodec                 C   s   |S r   r   r   r   r   r"   rf   ;  s    z&AdjustDefByDirectives.visit_LambdaNodec                    sN   t  fdd jD r*| } |S  j}d _ | | _|S d S )Nc                 3   s   | ]}| j kV  qd S r   )r7  )r   r9  r   r   r"   r-  @  s     z=AdjustDefByDirectives.visit_PyClassDefNode.<locals>.<genexpr>T)anyconverts_to_cclass	as_cclassr   r  r,   r    r!   Zold_in_pyclassr   r   r"   r  ?  s    

z*AdjustDefByDirectives.visit_PyClassDefNodec                 C   s    | j }d| _ | | || _ |S r3   )r  r,   r  r   r   r"   r  J  s
    
z)AdjustDefByDirectives.visit_CClassDefNodeN)r.   r/   r0   r1   r  rC   rO  r   r   rf   r  r  r   r   r   r"   r    s   .r  c                   @   s:   e Zd ZdZdd Zdd Zd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 | _ | | |S r   )r:  r,   r   r   r   r"   rC   X  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 Nz'%s' redeclaredzprevious declaration here)	r:  r  rY   Z	is_cclassr  r  is_builtin_scoper   r>   r    r!   pxd_defr   r   r"   r  ]  s    z-AlignFunctionDefinitions.visit_PyClassDefNodeNc                 C   sL   |d kr| j |j}|r4|js$|S | j }|jj | _ | | |rH|| _ |S r   r:  r  r  Zdefined_in_pxdr  r,   r    r!   r  ra  r   r   r"   r  i  s    

z,AlignFunctionDefinitions.visit_CClassDefNodec                 C   s\   | j |j}|rX|j r |j jsX|jsNt|jd|j  |jrJt|jd d S ||}|S r  )r:  r  rY   r  is_cfunctionr   r>   r  r  r   r   r"   r   v  s    
z&AlignFunctionDefinitions.visit_DefNodec                 C   s   |S r   r   r   r   r   r"   rF     s    z'AlignFunctionDefinitions.visit_ExprNode)N)	r.   r/   r0   r1   rC   r  r  r   rF   r   r   r   r"   r  R  s   
r  c                   @   s6   e Zd Zdd Zdd ZdddZdd	 Zd
d ZdS )AutoCpdefFunctionDefinitionsc                 C   s&   |j | _ t | _|j| _| | |S r   )r7  r   ra  r:  r,   r   r   r   r"   rC     s
    
z-AutoCpdefFunctionDefinitions.visit_ModuleNodec                 C   s8   | j jr4| jd r4|j| jkr4| r4|j| j d}|S )NZ
auto_cpdef)r:  )r:  is_module_scoper7  rY   ra  Zis_cdef_func_compatibler  r   r   r   r"   r     s    
z*AutoCpdefFunctionDefinitions.visit_DefNodeNc                 C   sL   |d kr| j |j}|r4|js$|S | j }|jj | _ | | |rH|| _ |S r   r  r  r   r   r"   r    s    

z0AutoCpdefFunctionDefinitions.visit_CClassDefNodec                 C   s(   | j jr$|jD ]\}}| j| q|S r   )r:  r  r   ra  r   )r    r!   rY   r   r   r   r"   rg    s    z5AutoCpdefFunctionDefinitions.visit_FromImportStatNodec                 C   s   |S r   r   r   r   r   r"   rF     s    z+AutoCpdefFunctionDefinitions.visit_ExprNode)N)r.   r/   r0   rC   r   r  rg  rF   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 )RemoveUnreachableCodec                 C   s   | j d s|S | | t|jdkrPt|jd tjrP|jd jsP|jd d = t|jdD ]T\}}|jr\|t|jk r| j d rt	|j| j
dd |jd | |_d|_ qq\|S )NZremove_unreachabler   r   warn.unreachableUnreachable coder   T)rb  r,   r   r?   r@   r   rB   r   r  r   r>   )r    r!   idxr  r   r   r"   rI     s    

,
z(RemoveUnreachableCode.visit_StatListNodec                 C   s   |  | |jjrd|_|S rD   )r,   rA   r  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 rD   )r,   r  r  r  )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 )Nr  r  r   )r,   rA   r  r  rb  r   r>   r   r   r   r"   visit_TryExceptStatNode  s    

z-RemoveUnreachableCode.visit_TryExceptStatNodec                 C   s   |  | |jjrd|_|S rD   )r,   r   r  r   r   r   r"   visit_TryFinallyStatNode  s    
z.RemoveUnreachableCode.visit_TryFinallyStatNodec                 C   s   | j d stj|jg d}|S )zEliminate useless PassStatNodeZ	linetracer=   )rb  r   rB   r>   r   r   r   r"   visit_PassStatNode  s    
z(RemoveUnreachableCode.visit_PassStatNodeN)	r.   r/   r0   rI   r  r  r  r  r  r   r   r   r"   r    s   
r  c                       sx   e Zd Zg f 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 )r^   c                    s>   t    g | _g | _g | _g | _d| _d| _d| _|| _	d S r3   )
r4   r5   yieldsr  finallysexceptshas_return_valuer`   ra   excludes)r    r  r:   r   r"   r5     s    
zYieldNodeCollector.__init__c                 C   s   || j kr| | d S r   )r  r,   r   r   r   r"   r     s    
zYieldNodeCollector.visit_Nodec                 C   s    | j | d| _| | d S rD   )r  r   r`   r,   r   r   r   r"   visit_YieldExprNode  s    z&YieldNodeCollector.visit_YieldExprNodec                 C   s    | j | d| _| | d S rD   )r  r   ra   r,   r   r   r   r"   visit_AwaitExprNode  s    z&YieldNodeCollector.visit_AwaitExprNodec                 C   s&   |  | |jrd| _| j| d S rD   )r,   rX   r  r  r   r   r   r   r"   visit_ReturnStatNode  s    
z'YieldNodeCollector.visit_ReturnStatNodec                 C   s   |  | | j| d S r   )r,   r  r   r   r   r   r"   r    s    
z+YieldNodeCollector.visit_TryFinallyStatNodec                 C   s   |  | | j| d S r   )r,   r  r   r   r   r   r"   r    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"   rf     s    z#YieldNodeCollector.visit_LambdaNodec                 C   s    t |jtjr| |jj d S r   )r@   rr   r   _ForInStatNoder   rg   r   r   r   r"   rw     s    z0YieldNodeCollector.visit_GeneratorExpressionNodec                 C   s   d S r   r   r   r   r   r"   visit_CArgDeclNode%  s    z%YieldNodeCollector.visit_CArgDeclNode)r.   r/   r0   r5   r   r  r  r  r  r  r&  r   rf   rw   r  rP   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 )MarkClosureVisitorc                 C   s   d| _ g | _| | |S r3   )needs_closurer  r,   r   r   r   r"   rC   /  s    
z#MarkClosureVisitor.visit_ModuleNodec           
      C   sH  d| _ | | | j |_ d| _ t| j}|| |jrvtj}|jrdtj}|j	|j
 D ]
}d|_qVq| 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|jo|jd}||j|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-  G  s      z7MarkClosureVisitor.visit_FuncDefNode.<locals>.<genexpr>z/'await' not allowed in generators (use 'yield')r   )r>   rY   rA   Zis_coroutine_bodyZis_async_gen_body)r>   rY   rZ   r[   r\   r]   r  r  lambda_namer  rl   )#r  r,   r^   r  rk   r   ZAsyncDefNoder`   ZAsyncGenNoder  r  Zin_async_genrb  ZIterableAsyncDefNodera   nextr   r>   GeneratorDefNoder   Z	label_numr  r  Zin_generatorZGeneratorBodyDefNoderY   rA   rZ   r[   r\   r]   r  r  r  rl   )
r    r!   re   Zcoroutine_typeZ
yield_exprfoundr   Zretnoder  	coroutiner   r   r"   r   5  s\    




       z$MarkClosureVisitor.visit_FuncDefNodec                 C   s:   d| _ | | | j |_ d| _ |j r6|jr6t|jd |S )NFTz1closures inside cpdef functions not yet supported)r  r,   r  r   r>   r   r   r   r"   r  a  s    
z%MarkClosureVisitor.visit_CFuncDefNodec                 C   s"   d| _ | | | j |_ d| _ |S )NFT)r  r,   r   r   r   r"   rf   j  s
    
z#MarkClosureVisitor.visit_LambdaNodec                 C   s   |  | d| _|S rD   )r,   r  r   r   r   r"   r&  q  s    
z%MarkClosureVisitor.visit_ClassDefNodec                 C   sh   | j }t|jtjr |jjg| _ | |}|| _ t|jtjsB|S |jjj}|jrV|S t	|
| |S r   )r  r@   rr   r   r  rg   rf   r  r   r  r   )r    r!   r  Zitseqr   r   r"   rw   v  s    

z0MarkClosureVisitor.visit_GeneratorExpressionNodeN)	r.   r/   r0   rC   r   r  rf   r&  rw   r   r   r   r"   r  +  s   ,	r  c                       s^   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
dd Z  ZS )CreateClosureClassesc                    s   t  | g | _d| _d S r3   )r4   r5   pathr!  r8   r:   r   r"   r5     s    zCreateClosureClasses.__init__c                 C   s   |j | _| | |S r   )r:  rK  r,   r   r   r   r"   rC     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_closurer   r  )r    r!   r  r  r:  rY   r  r   r   r"   find_entries_used_in_closures  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 }
t|
}
|j|
|jddd}d|j _!||_|j j}d|_"d|_#|j$sR|j r\d|j%d< t&j'rpt&j'|j%d	< |r|	j(st)|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=  __)rY   r>   ZdefiningZimplementingZno_gc_clearZfreelist)r>   rY   r  r  Zis_cdefr   )0rM  r  r  r  r   r  r  Z
is_cglobalr  r  r:  r  Zneeds_outer_scoper  r:  r_  r`  ra  r  rd  r   Zneeds_closure_codeZis_passthroughZscope_classZnext_idr   Zclosure_class_prefixr  rp  r   Zdeclare_c_classr>   r  Zis_final_typeZis_internalZis_closure_class_scoperk   r7  r   Zclosure_freelist_sizerc  r   rU  Zouter_scope_cnameZin_subscoperY   Zis_declared_genericZcheck_c_class)r    r!   Ztarget_module_scopeZ
inner_noder:  r  r  r  Z
func_scopeZcscoper  class_scoperY   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 rD   )r@   rd   r   rc   r!  r  rK  r,   )r    r!   Zwas_in_lambdar   r   r"   rf     s    
z%CreateClosureClasses.visit_LambdaNodec                 C   sR   | j r| | |S |js | jrN| || j | j| | | | j  |S r   )r!  r,   r  r  r  rK  r   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   )r  r   r,   r   r   r   r"   r    s    

z'CreateClosureClasses.visit_CFuncDefNodec                 C   s   t  |}| |S r   )r  rf   r   r   r   r"   rw     s    
z2CreateClosureClasses.visit_GeneratorExpressionNode)N)r.   r/   r0   r5   rC   r  r  rf   r   r]  r  rw   rP   r   r   r:   r"   r    s   
Rr  c                   @   sJ   e Zd ZdZdZdd ZeZeZdd Zdd Z	d	d
 Z
dd ZejZd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.
    Fc                 C   s   | j rtj|jd|d}|S )zYAllow the (Python statement) node in nogil sections by wrapping it in a 'with gil' block.r  r  rA   )r  r   r  r>   r   r   r   r"   _inject_gil_in_nogil'  s    z&InjectGilHandling._inject_gil_in_nogilc                 C   s&   | j }|jdk| _ | | || _ |S )Nr  )r  r  r,   r    r!   	was_nogilr   r   r"   visit_GILStatNode5  s
    
z#InjectGilHandling.visit_GILStatNodec                 C   s<   | j }t|jtjr(|jj o$|jj | _ | | || _ |S r   )r  r@   r  r   ZCFuncDeclaratorNoder  r,   r  r   r   r"   r  <  s    
z$InjectGilHandling.visit_CFuncDefNodec                 C   s"   | j }|j | _ | | || _ |S r   )r  r,   r  r   r   r"   visit_ParallelRangeNodeD  s
    
z)InjectGilHandling.visit_ParallelRangeNodec                 C   s   |S r   r   r   r   r   r"   rF   K  s    z InjectGilHandling.visit_ExprNodeN)r.   r/   r0   r1   r  r  Zvisit_RaiseStatNodeZvisit_PrintStatNoder  r  r  rF   r   r   r   r   r   r   r"   r    s   r  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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                    s0   |j g| _tjj| _d | _tjj| _t 	|S r   )
r:  	env_stackr   
NoGilStateHasGilnogil_statein_lock_block"nogil_state_at_current_gilstatnoder4   r  )r    r  r:   r   r"   r  \  s
    


zGilCheck.__call__c                 C   sh   | j }|j}|rHt| jdkrH| jd jr2tjjntjj| _ | 	|| || _ | j	|d |d || _ d S )Nr   rm  rh   )
r  outer_attrsr   r  r  r   r  NoGilr  r,   )r    r!   r  r  r  r   r   r"   _visit_scoped_childrend  s    zGilCheck._visit_scoped_childrenc                 C   sv   | j |j |jj}| jd  }| _| j}|r8tjj| _|rN|j	rN|	|j | 
|| j || _|| _| j   |S r   )r  r   r  r  r  r  r   r  
NoGilScopenogil_checkr   r  )r    r!   Zinner_nogilr  r  r   r   r"   r   p  s    


zGilCheck.visit_FuncDefNodec                 C   s  |j d k	r"t|j jd|j  |S | jr6|jr6|  | j}|jdk}|s|| jr|| jjjj	dd
 }t|jd| dd ||kr| jtjjks|st|jd nt|jd	 | jtjjkrd
|_t|jtjr|jj\|_| j}| j| _|rtjjntjj}| || || _|S )Nz<Non-constant condition in a `with %s(<condition>)` statementr  T)ZpyrexzAcquiring the GIL inside a z: lock. To avoid potential deadlocks acquire the GIL first.r   z3Trying to acquire the GIL while it is already held.z;Trying to release the GIL while it was previously released.F)r  r   r>   r  r  r  r  r   r  Zempty_declaration_codestripr   r   r  r  scope_gil_state_knownr@   r   rB   r?   r  r  r  r   )r    r!   r  Zis_nogil	type_namer  r  r   r   r"   r    s@    



zGilCheck.visit_GILStatNodec                 C   s   |j s| jtjjkrV|j d }|_ tj|jd|d}|sL| jtjjkrLd|_| |S | jslt	|jd d S |
| jd  | | |S )NFr  r  z)prange() can only be used without the GILr   )r  r  r   r  r  r  r>   r  r  r   r  r  r,   )r    r!   Znode_was_nogilr   r   r"   r    s    

z GilCheck.visit_ParallelRangeNodec                 C   sj   | j st|jd d S | j tjjkrFtj|jd|d}d|_| |S |j	r\|	| j
d  | | |S )Nz5The parallel section may only be used without the GILr  r  Fr   )r  r   r>   r   r  r  r  r  r  r  r  r,   r   r   r   r"   visit_ParallelWithBlockNode  s    

z$GilCheck.visit_ParallelWithBlockNodec                 C   s*   | j s| |S d|_d|_| | |S )zM
        Take care of try/finally statements in nogil code sections.
        NT)r  r   r  Zis_try_finally_in_nogilr,   r   r   r   r"   r    s    

z!GilCheck.visit_TryFinallyStatNodec                 C   s
   |  |S r   )r   r   r   r   r"   visit_CriticalSectionStatNode  s    z&GilCheck.visit_CriticalSectionStatNodec                 C   s"   | j | }| _ | |}|| _ |S r   )r  r   )r    r!   r  r   r   r   r"   visit_CythonLockStatNode  s    
z!GilCheck.visit_CythonLockStatNodec                 C   s"   | j tjjkrd|_| | |S r3   )r  r   r  r  r  r,   r   r   r   r"   visit_GILExitNode  s    
zGilCheck.visit_GILExitNodec                 C   sT   | j r"| jr"|jr"|| j d  |jr8| || j n
| | | jrP| j|_|S r  )r  r  r  r  r   r,   Zin_nogil_contextr   r   r   r"   r     s    
zGilCheck.visit_Nodec                 C   s   |j r|j jjr|jjr|jjdkrt|jdkrd }| jt	j
jkrJd}n| jt	j
jkr\d}|rtj|j|jjj| |jj|j gd}| |S )Nacquirer   ZNogilZGilr  )r    r  Zis_cython_lock_typert  r   r  r   rZ   r  r   r  r  r  r   ZPythonCapiCallNoder>   r  r  r   )r    r!   suffixr   r   r"   visit_SimpleCallNode   s(    
zGilCheck.visit_SimpleCallNode)r.   r/   r0   r1   r  r   r   r  r  r  r  r  r  r	  r   r  rP   r   r   r:   r"   r  R  s   	+r  c                   @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )CoerceCppTempsa  
    For temporary expression that are implemented using std::optional it's necessary the temps are
    assigned using `__pyx_t_x = value;` but accessed using `something = (*__pyx_t_x)`. This transform
    inserts a coercion node to take care of this, and runs absolutely last (once nothing else can be
    inserted into the tree)

    TODO: a possible alternative would be to split ExprNode.result() into ExprNode.rhs_result() and ExprNode.lhs_result()???
    c                 C   s   |   jr| | |S r   )r   r  r,   r   r   r   r"   rC     s    

zCoerceCppTemps.visit_ModuleNodec                 C   s>   |  | |  jd r:| r:|jjr:|jjs:t|}|S )NZ
cpp_locals)	r,   r   r7  Zresult_in_tempr  r  Zis_fake_referencer   ZCppOptionalTempCoercionr   r   r   r"   rF   %  s    

zCoerceCppTemps.visit_ExprNodec                 C   s   |S r   r   r   r   r   r"   visit_CppOptionalTempCoercion/  s    z,CoerceCppTemps.visit_CppOptionalTempCoercionc                 C   s   |S r   r   r   r   r   r"   visit_CppIteratorNode2  s    z$CoerceCppTemps.visit_CppIteratorNodec                 C   s   |  |j |S r   )r,   rL   r   r   r   r"   rO   5  s    z!CoerceCppTemps.visit_ExprStatNodeN)	r.   r/   r0   r1   rC   rF   r  r  rO   r   r   r   r"   r    s   
r  c                       s   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dd Z fddZ fddZd d! Zd"d# Z  ZS )$TransformBuiltinMethodsz
    Replace Cython's own cython.* builtins by the corresponding tree nodes.
    Also handle some Python special builtin functions (e.g. super()/locals())
    that require introspection by the compiler.
    c                    s   t  j|| i | _d S r   )r4   r5   def_node_body_insertions)r    rZ   r  r:   r   r"   r5   A  s    z TransformBuiltinMethods.__init__c                 C   s   |j r
d S | | |S d S r   )Zdeclaration_onlyr,   r   r   r   r"   r   E  s    
z2TransformBuiltinMethods.visit_SingleAssignmentNodec                 C   s   |  | | |S r   )r,   visit_cython_attributer   r   r   r"   r  L  s    
z+TransformBuiltinMethods.visit_AttributeNodec                 C   s4   |j dkr*|  }|d}|s*| |}| |S )Nr;   )rY   r   r  _inject_classr  )r    r!   rV  r  r   r   r"   rp  P  s    


z&TransformBuiltinMethods.visit_NameNodec                 C   s   |  }|r|dkr6ddlm} tj|jt|d}np|dkrLt|j}nZ|dkrztj|jt|| 	 
 |d}n,t|rn | jj|rnt|jd|  |S )	N__version__r   )r  rW   r*  )r   	frozensetr0  rY   r  z>'%s' not a valid cython attribute or is being used incorrectly)rn  r   r  r   r   r>   r   ZNullNoder   r   Zbuiltin_scoper  r   rQ  r9   cython_scopelookup_qualified_namer   )r    r!   r  versionr   r   r"   r  X  s"    
z.TransformBuiltinMethods.visit_cython_attributec                 C   sZ   |   }| | t|jdkrV|jt|j |jsV|jt	|j| 
 | |S r  )r   r,   r   rZ   r   r   GlobalsExprNoder>   r  LocalsExprNodecurrent_scope_node)r    r!   rV  r   r   r"   visit_ExecStatNodek  s    
  z*TransformBuiltinMethods.visit_ExecStatNodec           	         sZ  |   }||}|r|S |j |dk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   r   r   rW  r   r   r"   r-    s      z9TransformBuiltinMethods._inject_locals.<locals>.<genexpr>c                    s   g | ]}t j |d qS )rW   )r   ZIdentifierStringNoder  r  r   r"   r     s   z:TransformBuiltinMethods._inject_locals.<locals>.<listcomp>r  )r   r  r>   r   rZ   r   r   r  r  r_  r  r  rx  r  SortedDictKeysNoderJ  r  r   r
  )	r    r!   	func_namerV  r  rn   Zlocals_dictZlocal_namesr   r   r  r"   _inject_localsv  sH    



z&TransformBuiltinMethods._inject_localsc                 C   sF   |  | |jdkrBt|jtjrB|jj}t|tjr<|j}||_|S )Nnot_in)r,   r-  r@   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   sh   |   }||}t|jdks*|r.|js.|S |jt|j |j	sd|jt
|j|  | |S r  )r   r  r   rZ   
is_builtinr   r   r  r>   r  r  r  )r    r!   r!  rV  r  r   r   r"   _inject_eval  s    
  z$TransformBuiltinMethods._inject_evalc                 C   s>  |   }t|tjs|S d  } }}t| jD ]R\}}t|tjrP|}|} qq.t|tjrl|}|j}|}	q.t|tjr.|}|}	q.|r|s|S || j	kr:|j
j}
|jrtj|
|jj|jd}n8|jrtj|
|d k	d}|rd|_nd|_d|j_n|S tj|
tj|
tdd|d}||	 || j	ks0t|| j	|< |S )Nr  rM  Tr;   r   r   )r  r@   r   ZFuncDefNodereversedr  ZClassDefNoder  r  r  rA   r>   r`  r   r   r:  rY   r  r_  ClassCellNoderequires_classobj
class_cell	is_activer   r   r  r   )r    r!   Zcurrent_def_nodeZ	fdef_node
class_nodeZgenerator_nodeZ
stack_nodeZstack_scoper  Z
fdef_scoper>   r   r   r   r   r"   r    sR     


z%TransformBuiltinMethods._inject_classc                 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   rm  Tr(  r   r   r  )r   r  rZ   r  r@   r   rc   r   r  r_  r+  r,  r-  r   r*  r>   rM  r   rY   r`  r:  r  )r    r!   r!  rV  r  rd   r.  r  r   r   r"   _inject_super  s4    

   z%TransformBuiltinMethods._inject_superc                 C   sP   | j |d }|rLt|jtjr2|jjd| ntj|jj||jgd|_d S )Nr   r   )	r  r  r@   rA   r   rB   r?   rD  r>   )r    r!   Zbody_insertionr   r   r"   _do_body_insertion  s    
z*TransformBuiltinMethods._do_body_insertionc                    s   t  |}| | |S r   )r4   r   r0  r   r:   r   r"   r     s    
z)TransformBuiltinMethods.visit_FuncDefNodec                    s   t  |}| | |S r   )r4   r]  r0  r   r:   r   r"   r]    s    
z2TransformBuiltinMethods.visit_GeneratorBodyDefNodec                 C   s  |j  }|r|tjkr\t|jdkr<t|j jd|  ntj| |j j|jd d}nJ|tjk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kr| ||S |dkr| ||S |dkr| ||S |S )Nr   z%s() takes exactly one argumentr   r  r   z %s() takes exactly two arguments)r  r  r'  Dcast() takes exactly two arguments and an optional typecheck keywordFr  r  	typecheckrP  r&  z#sizeof() takes exactly one argument)Zarg_typeZcmodz"cmod() takes exactly two arguments%TZcdivz"cdiv() takes exactly two arguments/r   r   r0  z*'%s' not a valid cython language construct)dirr  r  evalr4   )rt  rn  r!  r  r   rZ   r   r>   r  rR  r   r   TypecastNodeZSizeofTypeNodeZSizeofVarNoder  Z	cdivisionr   r   r9   r  r  r,   r@   r  r   rY   r"  r'  r/  )r    r!   rt  r  r!  r   r   r"   r  !  s    

 

  

   

 
 





z,TransformBuiltinMethods.visit_SimpleCallNodec                 C   s   |j  }|dkr|jj}|jd }t|dksRt|dksRt|dkrbd|krbt|j jd nN|d 	| 
 }|r|dd}tj|j j||d |d}nt|d jd	 | | |S )
Nr'  r   r   r3  r1  r   Fr2  rP  )rt  rn  r  rZ   r  r  r   r   r>   rR  r   r   r   r8  r,   )r    r!   rt  rZ   r  r  r3  r   r   r"   visit_GeneralCallNodeg  s0    

   
z-TransformBuiltinMethods.visit_GeneralCallNode)r.   r/   r0   r1   r5   r   r  rp  r  r  r"  r$  r%  r'  r  r/  r0  r   r]  r  r9  rP   r   r   r:   r"   r  ;  s$   ';	Fr  c                       sH   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	  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                    s,   t    || _ddlm} |dd| _d S )Nr   )ConstantFoldingT)Z
reevaluate)r4   r5   r  ZOptimizer;  r@  )r    r  r;  r:   r   r"   r5     s    
zReplaceFusedTypeChecks.__init__c                 C   s   |  | | |S )zc
        Filters out any if clauses with false compile time type check
        expression.
        r,   r@  r   r   r   r"   r    s    
z'ReplaceFusedTypeChecks.visit_IfStatNodec                 C   s   |  | | |S )z9
        Fold constant condition of GILStatNode.
        r<  r   r   r   r"   r    s    
z(ReplaceFusedTypeChecks.visit_GILStatNodec              	   C   sP  t jdd" |j| j}|j| j}W 5 Q R X |rL|rLtj|jdd}tj|jdd}| 	||jj}|j
}|dkr| 	||jj}||}|dk}|r|s|s|s|S n|dkrHt|tjr|j}|jrt|jjd n`|jst|jjd	 nJt|}	|	D ],}
||
r|d
kr.|  S |  S q|dkrH|S |S |S )NT)ignoreFrW   )isis_not==z!=)r>  r@  )inr#  zType is fusedz-Can only use 'in' or 'not in' on a fused typerA  r#  )r   Zlocal_errorsr  rR  r  r  r   ro  r>   specialize_typer-  Zsame_asr@   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   s8   z| | jjW S  tk
r2   t|d | Y S X d S )NzType is not specific)rT  r  rS  KeyErrorr   )r    r  r>   r   r   r"   rB    s
    
z&ReplaceFusedTypeChecks.specialize_typec                 C   s   |  | |S r   r   r   r   r   r"   r     s    
z!ReplaceFusedTypeChecks.visit_Node)r.   r/   r0   r1   r5   r  r  r$  rB  r   rP   r   r   r:   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                    s6   t  | t | _| jj| _|j| _g | _	d| _
d S r3   )r4   r5   r   visitedr9   Zgdb_debug_outputwritertbZc_filec_output_filenested_funcdefsregister_stepinto)r    r9   optionsr   r:   r   r"   r5     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k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_namerI  r  rx  r>   rN  rJ  startr,   rK  r   rL   serialize_modulenode_as_functionendr:  r  r   rc  rH  rY   rA  r  r  r  serialize_local_variables)r    r!   ri   Znested_funcdefr  r  r  r   r   r"   rC     s:    







zDebugTransform.visit_ModuleNodec                 C   sF  | j |jj t|ddr |S | jr6| j| |S |jd krFd}n
|jj	j
}|j	jp^|j	j
}t|j	jptt|dd|||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   rY   z	<unknown>r   )rY   r  pf_cnamerc  linenoFunctionri   Locals	ArgumentsStepIntoFunctionsT)rH  r   r  rc  r
  rL  rK  r   rB  r  
func_cnameZpyfunc_cnamerx  rY   r6  r>   rI  rQ  rT  r  rS  Zarg_entriesr,   )r    r!   rU  r  ri   r   r   r   r"   r     sB    


z DebugTransform.visit_FuncDefNodec                 C   sh   | j rZ|jd k	rZ|jjrZt|ddrZ|jjd k	rZt|jjd}| jjd|d | j	d | 
| |S )NZ	is_calledFr   ZStepIntoFunctionrX  )rL  r  r  r
  r  r\  rx  rI  rQ  rS  r,   r    r!   ri   r   r   r"   rp  K  s    



zDebugTransform.visit_NameNodec                 C   s0   |  |t|jdd | dddd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   r   1True)rY   r  rU  rc  rV  Zis_initmodule_functionN)!_serialize_modulenode_as_functionrx  rP  
rpartitionZmodule_init_func_cnamer   r   r   r"   rR  ]  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 )NrW  rX  rY  rZ  r[  TF)rI  rQ  rT  r:  r  rS  rL  r,   r]  r   r   r"   r`  n  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   )rY   r  rc  r  rV  ZLocalVar)r   r  r  r0  r  r   Zcur_scope_cnameZouter_entryr:  ra  rc  rY   r  r>   r6  rx  rI  rQ  rS  )r    r  r  vartyper  qnamerV  ri   r   r   r"   rT    sB    
z(DebugTransform.serialize_local_variables)r.   r/   r0   r1   r5   rC   r   rp  rR  r`  rT  rP   r   r   r:   r"   rG    s   (1rG  )Mr[  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
   ZStringEncodingr   r   r   r   r   r   r2   rQ   r   r{   r   rR   r   rs   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  r  r  r  r  r:  rG  r   r   r   r"   <module>   s           !L  Y."K'9      0Fc >/9    V `=n6,8?] 6 E%  E_