U
    {h|                    @   sj  d dl Z e j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Zd dlmZ ddl	m
Z
 ddlmZmZ eef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% dd Z&ej'ej(ffddZ)dd Z*dd Z+dd Z,G dd  d ej-Z.d!d" Z/d#d$ Z0G d%d& d&ej1Z2G d'd( d(ej1Z3G d)d* d*ej4e"Z5G d+d, d,ej4Z6G d-d. d.ej1Z7G d/d0 d0ej8ej1Z9G d1d2 d2ej8ej:Z;d3d4 Z<e=d5d6Z>e=d7d6Z?G d8d9 d9ej4e"Z@G d:d; d;ej1ej8ZAG d<d= d=ejBZCdS )>    N)UtilityCodeEncodedStringbytes_literalencoded_stringNodes	ExprNodes
PyrexTypesBuiltin	UtilNodesZ_py_int_typesrecopycodecs	itertools
attrgetter)r      )	TypeSlots)UnicodeNodenot_a_constant)r   )r   )r   )Visitor)r	   )r
   )Options)r   TempitaUtilityCode)r   r   r   )errorwarning)SkipDeclarations   )Utils)reducec                 C   s   t | dS )N
Optimize.c)r   load_cached)name r    </tmp/pip-unpacked-wheel-fhl22ezh/Cython/Compiler/Optimize.pyload_c_utility%   s    r"   c                 C   s   t | |r| jS | S N)
isinstancearg)nodeZcoercion_nodesr    r    r!   unwrap_coerced_node)   s    
r'   c                 C   s   t | tjr| j} q | S r#   )r$   r
   ResultRefNode
expressionr&   r    r    r!   unwrap_node/   s    r+   c                 C   sr   t | } t |}t| tjr4t|tjr4| j|jkS t| tjrnt|tjrn| j olt| j|jol| j	|j	kS dS NF)
r+   r$   r   NameNoder   AttributeNode
is_py_attris_common_valueobj	attribute)abr    r    r!   r0   5   s    "r0   c                 C   s   | d k	r| j d krd S | S r#   )constant_resultr*   r    r    r!   filter_none_node?   s    r6   c                   @   sH   e Zd ZdZdd ZejjZdd Z	dd Z
dd	 Zd
d Zdd ZdS )_YieldNodeCollectorz9
    YieldExprNode finder for generator expressions.
    c                 C   s   t j|  i | _g | _d S r#   )r   TreeVisitor__init__yield_stat_nodesyield_nodes)selfr    r    r!   r9   I   s    z_YieldNodeCollector.__init__c                 C   s   | j | | | d S r#   )r;   appendvisitchildrenr<   r&   r    r    r!   visit_YieldExprNodeP   s    z'_YieldNodeCollector.visit_YieldExprNodec                 C   s&   |  | |j| jkr"|| j|j< d S r#   )r>   exprr;   r:   r?   r    r    r!   visit_ExprStatNodeT   s    
z&_YieldNodeCollector.visit_ExprStatNodec                 C   s   d S r#   r    r?   r    r    r!   visit_GeneratorExpressionNode[   s    z1_YieldNodeCollector.visit_GeneratorExpressionNodec                 C   s   d S r#   r    r?   r    r    r!   visit_LambdaNode^   s    z$_YieldNodeCollector.visit_LambdaNodec                 C   s   d S r#   r    r?   r    r    r!   visit_FuncDefNodea   s    z%_YieldNodeCollector.visit_FuncDefNodeN)__name__
__module____qualname____doc__r9   r   r8   r>   
visit_Noder@   rB   rC   rD   rE   r    r    r    r!   r7   E   s   r7   c                 C   s    t | }t|dkrdS |d S )Nr   )NNr   )_find_yield_statementslenr&   yield_statementsr    r    r!   _find_single_yield_expressione   s    rO   c                    sF   t    |  z fdd jD }W n tk
r@   g }Y nX |S )Nc                    s   g | ]}|j  j| fqS r    )r%   r:   ).0Z
yield_node	collectorr    r!   
<listcomp>p   s   z*_find_yield_statements.<locals>.<listcomp>)r7   r>   r;   KeyErrorrM   r    rQ   r!   rK   l   s    



rK   c                   @   s  e Zd ZdZdd Zdd Zd0ddZd	d
 Zd1ddZe	j
e	je	dejdgddZe	j
e	je	dejdgddZd2ddZe	
e	je	de	jde	de	jde	de	jdgZe	j
e	je	de	jde	de	jde	de	jde	de	jdgddZd3ddZd4ddZdd Zdd Zd5d d!Z d"d# Z!d$d% Z"e	
e	je	d&e	jde	d'e	jde	d(e	jde	d)e	jde	d*e	jdgZ#e	
e	je	d+e	jde	d,e	jde	d)e	jde	d-e	jdgZ$d.d/ Z%dS )6IterationTransforma   Transform some common for-in loop patterns into efficient C loops:

    - for-in-dict loop becomes a while loop calling PyDict_Next()
    - for-in-enumerate is replaced by an external counter variable
    - for-in-range loop becomes a plain C for loop
    c                 C   sJ  |  r8|j}t|}|jjr0|jjjj}n
|jjj}t	|}|
|}tj|d|j|d}tj|tj||tj|dddt|gd}tj|tj|||dgd d}	tj||gtj||tj|jj|jd	|	tj||tj|d
dddd}
|
|  }
| |
}
t||
}|jdkr4tj||d}|S | | |S d S )N==)operatoroperand1operand2r   valuelhsrhsstats	conditionbody)
if_clauseselse_clause)sequencer   )targetiteratorrc   re   tempsrc   not_inoperand)Zis_ptr_containsposr
   r(   rY   is_subscriptbasetype	base_type
TempHandlerefr   PrimaryCmpNoderX   r   StatListNodeSingleAssignmentNodeBoolNodeZBreakStatNode
IfStatNodeIfClauseNodeTempsBlockNodeZForInStatNodeZIteratorNodeanalyse_expressionscurrent_envvisitTempResultFromStatNoderW   NotNoder>   )r<   r&   rn   
result_refrr   Ztarget_handlerg   cmp_nodeZif_bodyZif_nodeZfor_loopnew_noder    r    r!   visit_PrimaryCmpNode   sX    
	



   	

z'IterationTransform.visit_PrimaryCmpNodec                 C   s   |  | | ||jjS r#   )r>   _optimise_for_looprh   rf   r?   r    r    r!   visit_ForInStatNode   s    
z&IterationTransform.visit_ForInStatNodeFc                 C   s  d }|j s|jr4|jr4|jjr4|jjj}|jr4|j}tj|j	|fkr`|rL|S | j
||d dddS tj|j	|fkstj|j	|fkr|r|S | ||S |j	js|j	jr| j|||dS |j	tjkr| j|||dS |j	tjkr| j|||dS |j	tjkr| j||d|dS t|tjr:|jj	jr:| j||jd|dS t|tjsL|S |jd krt|jrnt|jjppd}n$t|j}|r|j d k	r|d8 }|j!}|jr|s|s|j p|j"}|j#}	| $ j%j&dk}
|
s$|	d	kr$t|tj'r$|j!}|j r$|j(d
kr$|jr$|jj)r$d}
d }}|	dksF|
rL|	dkrLd}nB|	dksf|
rl|	dkrld}n"|	dks|
r|	dkrd }}|s|r| 
|||	||S |j d kr|j r|jr|jj)r|j(dkr|r|S | *||S |j(dkr|r
|S | +||S t,j-rd|  kr6dkrn n|j d kr|j r|j(dkr|jr|jj)r|j.j	j/s|j.j	j0r| j1|||dS |j.j	j2r|jd kr|jjn|jD ]F}t|tj3r|4 rd|j5  krdk rn nq qq| j1|||dS |S )NTF)dict_objmethodkeysvaluesreversed)
is_mutabler   r   r      )r   r   itemsdictiterkeysr   
itervaluesr   	iteritemsr   	enumerater   )rangexrange      @)6is_nameis_attributeentry
annotationrA   ro   rp   r	   	dict_typerq   _transform_dict_iterationset_typefrozenset_type_transform_set_iterationis_ptris_array_transform_carray_iteration
bytes_type_transform_bytes_iterationunicode_type_transform_unicode_iterationbytearray_type_transform_indexable_iterationr$   r   CoerceToPyTypeNoder%   is_memoryviewsliceSimpleCallNodeargs	arg_tuplerL   r<   functionr1   r2   global_scopecontextZlanguage_levelZCallNoder   
is_builtin_transform_enumerate_iteration_transform_reversed_iterationr   Zconvert_rangerg   is_intis_enum_transform_range_iterationis_pyobjectIntNodehas_constant_resultr5   )r<   r&   iterabler   Zannotation_typer   	arg_countr   Zbase_objr   Zis_safe_iterZinner_functionr   r   r%   r    r    r!   r      s    
    
    $(
z%IterationTransform._optimise_for_loopc                 C   s   |j j}t|dkr$t|jd |S t|dkr@t|jd |S |d }|jtjtjfkrt|	d|j
_d|j
_|S | j||ddS )Nr   z(reversed() requires an iterable argumentr   z#reversed() takes exactly 1 argument!'NoneType' object is not iterableTr   )r   r   rL   r   rn   rq   r	   
tuple_type	list_typeas_none_safe_noderh   rf   r   r   )r<   r&   Zreversed_functionr   r%   r    r    r!   r   $  s"    z0IterationTransform._transform_reversed_iterationc                    st  t j|ddddtj jddtjd} fdd	}t j| tjdd
}|}|rjd\}	}
|| }}nd\}	}
t j jtjd}tj|j|d}t	j
 jj j|d}|  }tj|jddd}t	j|j||d}t	j j|gd}|rt	j
 j|| d}|j| t	j j||	||
|d| jdd
}t t |t	j jt ||d|}|jd j |S )zWIn principle can handle any iterable that Cython has a len() for and knows how to index'NoneType' is not iterableFT)Zmay_hold_noneis_temp0r   r[   r5   rq   c                     s.   t j jdtjdd} t j j| gdS )NrL   )r   r   r   r   )r   r-   rn   r	   builtin_scopelookupr   )Zbuiltin_lenr&   unpack_temp_noder    r!   make_length_callA  s    

zKIterationTransform._transform_indexable_iteration.<locals>.make_length_call)rq   r   >>=<=<rn   rq   )rp   indexrn   r]   r^   )boundscheckZ
wraparound)
directivesrc   r_   r\   N	bound1	relation1rg   	relation2bound2steprc   re   
from_rangerA   r   )r
   
LetRefNoder   r   r   rn   r   c_py_ssize_t_type	IndexNoder   rw   rg   r}   r   Zcopy_inherited_directivesr   ZCompilerDirectivesNoderv   r`   r=   ForFromStatNodere   LetNodeExprStatNoder   r|   insertrc   )r<   r&   
slice_noder   r   
start_noder   length_tempend_noder   r   Zcounter_reftarget_valuetarget_assignenvZnew_directivesrc   Zloop_length_reassign	loop_noderetr    r   r!   r   8  s        
   	z1IterationTransform._transform_indexable_iterationsNZNULLexception_valuec                 C   s   |j j}|js|tjk	r|S t|d}tj	|j
d| j|gdd}tj	|j
d| j|gdd}t|| j|tj|j
|d d ||jdd|dS )Nr   Z__Pyx_PyBytes_AsWritableStringr   r   r   __Pyx_PyBytes_GET_SIZE)rp   startr   stoprq   r   r   )rg   rq   r   r	   r   r
   r   r   r   PythonCapiCallNodern   PyBytes_AS_STRING_func_typePyBytes_GET_SIZE_func_typer   r   SliceIndexNode)r<   r&   r   r   target_typer   Zslice_base_nodeZlen_noder    r    r!   r     sH      	z-IterationTransform._transform_bytes_iterationkinddatar   lengthc                 C   s~  |j rzt|jdd}W n tk
r0   Y nfX tj|jtj|j||t	j
dt	j|  d tj|jtt|t|t	jdtjd}| |||S t|d}tj|jddt	jd}tt	j}||j}	|rd\}
}|	| }}	nd	\}
}tt	j}tt	j}tt	j}tj|jd
| j||j||j||jjgdd}|j|jjkrt||jj|  }t j!|jj|j|d}t j"|j||j#gd}t j$|j||
||jj||	d ||j%dd
}t j&|jtj|jd| j'|tj(|j||jt	j)dtj(|j||jt	j*dtj(|j||jt	j+dgddt,-dddd}t.|tj/|j||||gt j"|j||gddS )Nlatin1z	iso8859-1r   )rp   r   r   rq   r   r   r   r   r   Z__Pyx_PyUnicode_READFr   r   r_   Tr   Z__Pyx_init_unicode_iterationrm   rq   Zunicode_iterr   )r   r   result_is_usedutility_coder   ri   )0
is_literalr   r[   encodeUnicodeEncodeErrorr   r   rn   	BytesNoder   c_const_char_ptr_type	coerce_toZc_const_uchar_ptr_typer}   r   strrL   r   r	   r   r   r
   r   r   rs   rt   
c_int_typec_void_ptr_typer   PyUnicode_READ_func_typerg   rq   r   rw   rv   rc   r   re   r    init_unicode_iteration_func_typeAmpersandNodec_py_ssize_t_ptr_typec_void_ptr_ptr_typec_int_ptr_typer   r   r   r{   )r<   r&   r   r   bytes_valueZbytes_slicer   r   r   r   r   r   Z	kind_tempZ	data_tempcounter_tempr   r   rc   r   Z
setup_noder    r    r!   r     s       
    


   	 
 
z/IterationTransform._transform_unicode_iterationc                 C   sT  d}t |tjrN|j}t|j}t|j}d }|sJ|jjsFt	|j
d |S nB|jrt |jtjsht|j}|j}	t|	j}t|	j}t|	j}|rt |jtr|jdks|jdkr|r|jdk r|s|jjst	|j
d |S |j}
|r|
 }
|
dk }tj|j
tjtt|
t|
d}nr|jjrv|jjd krFt	|j
d |S |}d }tj|j
t|jjtj|jjd}d }n|jjst	|j
d |S |r|tj|  }|r|tj|  }|d kr|rtj|j
dtjdd}nt	|j
d |S |r$|stj|j
d	dtjd
}|| }}|j}|jr:| }||  }|rr|jdkrrtj|j
|d||d}n|}|r|jdkrtj|j
t|d||d|  }n
t|}t |}|!|j"j
}|jj#rn|j"jjrn|jt$j%kr(t&tj'|j"j
||j(dtj)|j"j|  }nDtj|j"j
tj|j"j
d	dtj*d
tj|j"j
ddtj*d
|t$j+dd}nP|j"jj,r|j"j-|j(s|}n,tj.|j"j
tj|j"j
d	dtj*d
||j(d}|j|j"jkr||j"j|  }t/j0|j"j
|j"|d}t/j1|j
||j2gd}| 3||\}}t/j4|j
||||||||j5dd
}tj6|j
|g|dS )NFz*C array iteration requires known end indexr   z8C array iteration requires known step size and end indexrq   r[   r5   r[   rq   r5   -1r   r   r   +rX   rW   rY   rq   r   1r   )r   r   rp   rq   r   )r   rp   rq   r   r_   Tr   ri   )7r$   r   r   rp   r6   r   r   rq   r   r   rn   ro   r   	SliceNodeAssertionErrorr   r5   intr   r   r   r	  absr   sizer  r}   Zelement_ptr_typecoerce_to_simpleAddNode	CloneNoder
   rs   rt   rg   	is_stringr	   r   CastNodeZDereferenceNoderr   c_py_ucs4_typer
  r   r   assignable_fromr   r   rw   rv   rc   _find_for_from_node_relationsr   re   r{   )r<   r&   r   r   Zneg_stepZ
slice_baser   r   r   r   
step_valueZptr_typeZ
carray_ptrZstart_ptr_nodeZstop_ptr_nodecounterr  r   r   rc   r   r   for_noder    r    r!   r   ,  sV   






 
 

   


  
   	 z.IterationTransform._transform_carray_iterationc              	   C   s  |j j}t|dkr$t|jd |S t|dkr@t|jd |S |jjsL|S |jj}t|dkrd|S |\}}|j}|js|j	s|S t|dkrt
|d ||  }ntj|jd|dd}t|}	tj|j|	tj|jd|ddd	||jd
}
tj|j||	dtj|j|	|
dg}t|jtjr6||jj |j_n ||j tj|jj|d|_||_|j|j|  |_|d |j_t|	| ||jjS )Nr   z)enumerate() requires an iterable argumentr   z%enumerate() takes at most 2 argumentsr   r   r  r  r  )rX   rY   rW   rq   r   r   r_   )r   r   rL   r   rn   rg   is_sequence_constructorrq   r   r   r'   r  r}   r   r   r
   r   r   r   rw   r$   rc   rv   r`   r=   itemrh   rf   r   r   )r<   r&   Zenumerate_functionr   targetsZenumerate_targetZiterable_targetZcounter_typer   tempZinc_expressionZ	loop_bodyr    r    r!   r     sz    

z1IterationTransform._transform_enumerate_iterationc                 C   s"   |r|rdS dS n|rdS dS d S )N)r   r   r   )r   r   r   r    )r<   Zneg_step_valuer   r    r    r!   r&    s    z0IterationTransform._find_for_from_node_relationsc                 C   sV  |j j}t|dk r0|j}d}tj|ddd}nD|d }|j}t|jtsN|S |j}|dkr`|S tj|t	||d}t|dkrtj|jddd}|d 
|  }	n$|d 
|  }|d 
|  }	| |dk |\}
}d }|r|	| }}	t|}|dkrt|jtrt|	jtr|dk rT|	j}|j}|||| d |   d }n(|j}|	j}|||| d |   d }tj|jt	||t|j|	jd}nt|	}| ||||}|dk r| }t	||_||_|
|  }|	jsd	}|pt|	}	nd
}tj|j|j||
||	||j|jd	d
}||   |rRt|	|}|S )Nr   r   r  r[   r5   r   r   r   r   TF)	rg   r   r   r   r   r   rc   re   r   )r   r   rL   rn   r   r   r$   r5   r  r	  Zcoerce_to_indexr}   r&  r  r   spanning_typerq   r
   r   _build_range_step_calculationr[   r  r   r   rg   rc   re   Zset_up_loopr   )r<   r&   Zrange_functionr   r   Zstep_posr'  r   r   r   r   r   bound2_ref_nodeabs_stepbegin_value	end_valueZbound1_valueZbound2_is_tempr)  r    r    r!   r   %  s    




  
   

   z-IterationTransform._transform_range_iterationc                 C   s   t |}t|j|j}|jjr8|dk r8t|tj}nt||j}|dk r\|}|}	d}
n|}|}	d}
tj|jtj|j||
tj	|jtj
|jt|||ddtj|jtj|jtj|j|d|	|ddtj
|jdd	d
|ddtj
|jt|||d|d|d|d|
tj
|jdd	d
|d}|S )Ni  r   -r  r   *r  r  r   r.  z//)r  r   r/  rq   r   r
  r   
binop_nodern   ZMulNoder   r	  DivNodeZSubNode)r<   r   r1  r   r'  r2  r/  Zspanning_step_typer3  r4  Zfinal_opZstep_calculation_noder    r    r!   r0  x  s     %-z0IterationTransform._build_range_step_calculationc                    sz  g }t tj}|| ||j}t tj}|| | j}	d  }
 }}|r|r jj	rt
 jjdkr jj\}
}q S q j}n|r j}
n j}t jtjr j}ntj jj jgd}t tj}|| tj j||jt|jd}t tj}|| | j}tj j|t|jd}t|||j|	|
|||}||  }|g|jdd< |rtj|j|d}|jdt
|dkrdnd	d
|gd}nt|j}|d} fdd}tj j|	tj jddddtj|j|tj|jd| j t!"dd|||jt#j$k|||gdddtj% jd | j&dg}t j' j|tj j|ddS )Nr   rn   r`   r   r   rZ   )'NoneType' object has no attribute '%{}s'   .30 PyExc_AttributeErrorr   format_argsr   c                    s"   | rdp
d} t j jt| | dS Nr   r   r.  r   r   rn   r	  rZ   r*   r    r!   	flag_node  s    z?IterationTransform._transform_dict_iteration.<locals>.flag_noder   r.  r\   Z__Pyx_dict_iteratorZ	dict_iterr   Tr  r   r   rb   rc   re   r_   ri   )(r
   rs   r   py_object_typer=   rt   rn   r   rg   r*  rL   r   r$   rc   r   rv   r   r  
c_ptr_typerq   r
  ZDictIterationNextNoder|   r}   r`   ZIdentifierStringNoder   formatNullNoderw   r   r   PyDict_Iterator_func_typer   r   r	   r   WhileStatNodere   r{   )r<   r&   r   r   r   r   rj   r-  Z	dict_temppos_tempZ
key_targetvalue_targetZtuple_targetrc   Zdict_len_tempZdict_len_temp_addrZis_dict_tempZis_dict_temp_addriter_next_nodeZmethod_noderC  result_coder    r*   r!   r     s    



 


 
 
   


   z,IterationTransform._transform_dict_iterationr   Zis_dictmethod_nameZp_orig_lengthZ	p_is_dictsetis_setZp_is_setc                    s  g }t tj}|| ||j}t tj}|| | j}t j	t
jr^ j	}nt
j j	j j	gd}t tj}|| tj j||jt|jd}	t tj}|| | j}
tj j|
t|jd} j}t
|||j|||
}||  }|g|jdd<  fdd}t
j j|tj jddddt
j|j|tj|jd	| jtd
d|||jtjk|	|gdddt
j jd | jdg}t j  j|t
j j|ddS )Nr9  r   r   c                    s"   | rdp
d} t j jt| | dS rA  rB  rZ   r*   r    r!   rC  M  s    z>IterationTransform._transform_set_iteration.<locals>.flag_noder   r.  r\   Z__Pyx_set_iteratorZset_iterr   TrD  rE  r_   ri   )!r
   rs   r   rF  r=   rt   rn   r   r$   rc   r   rv   r   r  rG  rq   r
  rg   ZSetIterationNextNoder|   r}   r`   rw   r   r   PySet_Iterator_func_typer   r   r	   r   rK  re   r{   )r<   r&   set_objrj   r-  Zset_temprL  rc   Zset_len_tempZset_len_temp_addrZis_set_tempZis_set_temp_addrrM  rN  rC  rO  r    r*   r!   r   +  s    



 


 
 
   
  z+IterationTransform._transform_set_iteration)F)F)F)F)F)F)&rF   rG   rH   rI   r   r   r   r   r   r   	CFuncTypeZc_char_ptr_typeCFuncTypeArgr	   r   r   r   r   r   r$  r
  r  r  rF  r  r  r  r  r   r   r   r&  r   r0  r   rJ  rS  r   r    r    r    r!   rU   z   sz   1
n
V
'	
\
 %I
S@b	rU   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d Zdd Zdd ZejjZdS )SwitchTransformz
    This transformation tries to turn long if statements into C switch statements.
    The requirement is that every clause be an (or of) var == value, where the var
    is common among all clauses and both var and value are ints.
    )NNNc           
      C   sf  t |tjtjfr|j}q t |tjr0|jj}q t |tjrD|j}q t |tj	r\|j
}q q\q t |tjr|jd k	rz| jS | rt |jtjtjfr|jdk}|r|s| jS t |jtjr|j r| jS ||j| |jfS | s`|jdk rd}n|r|jdkrd}n| jS t|j|jrp|jjrD||j|jgfS t|jdd rp|jjjrp||j|jgfS t|j|jr`|jjr||j|jgfS t|jdd r`|jjjr`||j|jgfS nt |tjr`|jdks|r`|jdkr`|jdk}| |j|\}}}| |j|\}}}	|d k	r`||kr`t||r`|rR|r`||||	 fS | jS )	Nrk   rV   F!=Tr   orand)r$   r   CoerceToTempNodeZCoerceToBooleanNoder%   ZBoolBinopResultNoder
   EvalWithTempExprNodesubexpressionTypecastNoderm   ru   cascadeNO_MATCHZis_c_string_containsrY   r   r  rW   Zcontains_surrogatesrX   extract_in_string_conditionsZis_python_comparisonr0   r  getattrr   Zis_constBoolBinopNodeextract_conditions)
r<   condallow_not_inrk   Znot_in_1t1Zc1Znot_in_2t2c2r    r    r!   rd  {  sl    






 z"SwitchTransform.extract_conditionsc                    s|   t tjr:ttttj}|  fdd|D S j t fddt	t
 D     fdd D S d S )Nc                    s"   g | ]}t j jt||d qS r.  rB  rP   Zcharvalstring_literalr    r!   rS     s   z@SwitchTransform.extract_in_string_conditions.<locals>.<listcomp>c                    s   h | ]} ||d   qS )r   r    )rP   i)
charactersr    r!   	<setcomp>  s     z?SwitchTransform.extract_in_string_conditions.<locals>.<setcomp>c                    s   g | ]}t j j||d qS rj  )r   CharNodern   rk  rl  r    r!   rS     s   
)r$   r   r   listmapordrQ  r[   sortr   rL   )r<   rm  Zcharvalsr    )ro  rm  r!   ra    s    

z,SwitchTransform.extract_in_string_conditionsc                 C   sj   |  ||\}}}|d kr | jS |d k	r8t||s8| jS |jjsH|jjrZtdd |D r`| jS |||fS )Nc                 S   s   g | ]}|j jp|j j qS r    )rq   r   r   )rP   re  r    r    r!   rS     s     z=SwitchTransform.extract_common_conditions.<locals>.<listcomp>)rd  r`  r0   rq   r   r   any)r<   
common_varrb   rf  rk   var
conditionsr    r    r!   extract_common_conditions  s    z)SwitchTransform.extract_common_conditionsc              	   C   s   t  }|D ]}| r4|j|kr& dS ||j q
z2|j}|jjsL|jjr^|jd k	r^|j}n|j	}W n t
k
r~   Y  dS X ||kr dS || q
dS )NTF)rQ  r   r5   addr   rq   r   Zis_cpp_enumZenum_int_valuecnameAttributeError)r<   condition_valuesseenr[   Zvalue_entryZvalue_for_seenr    r    r!   has_duplicate_values  s&    


z$SwitchTransform.has_duplicate_valuesc           
      C   s   | j ds| | |S d }g }|jD ]N}| ||jd\}}}|d kr\| | |  S |tj|j	||j
d q(dd |D }t|dk r| | |S | |r| | |S | |d |D ]}| |d qt|}tj|j	|||jd	}	|	S )
Noptimize.use_switchFrn   ry  rc   c                 S   s   g | ]}|j D ]}|qqS r    )ry  )rP   casere  r    r    r!   rS     s      z4SwitchTransform.visit_IfStatNode.<locals>.<listcomp>r   re   rc   rn   testcasesre   )current_directivesgetr>   rd   rz  rb   r=   r   SwitchCaseNodern   rc   rL   r  r+   SwitchStatNodere   )
r<   r&   rw  r  	if_clause_ry  r~  r  switch_noder    r    r!   visit_IfStatNode  sJ    

  





z SwitchTransform.visit_IfStatNodec                 C   st   | j ds| | |S | d |jd\}}}|d ksNt|dk sN| |r\| | |S | |||||j|j	S )Nr  Tr   )
r  r  r>   rz  r  rL   r  build_simple_switch_statementtrue_val	false_valr<   r&   rk   rw  ry  r    r    r!   visit_CondExprNode  s.    
  


    z"SwitchTransform.visit_CondExprNodec                 C   s   | j ds| | |S | d |d\}}}|d ksLt|dk sL| |rh| | ||   |S | ||||t	j
|jdddt	j
|jdddS Nr  Tr   r.  F)r  r  r>   rz  rL   r  wrap_operandsr}   r  r   rx   rn   r  r    r    r!   visit_BoolBinopNode%  s0    
  


   z#SwitchTransform.visit_BoolBinopNodec                 C   s   | j ds| | |S | d |d\}}}|d ksLt|dk sL| |rZ| | |S | ||||tj|j	dddtj|j	dddS r  )
r  r  r>   rz  rL   r  r  r   rx   rn   r  r    r    r!   r   8  s.    
  


   z$SwitchTransform.visit_PrimaryCmpNodec                 C   s   t |}tj|j|||j|  dd}tj|j|||j|  dd}	|r\|	| }}	tj|j||dg}
t	|}tj
|j||
|	d}t ||}|S )NTr]   r^   firstr  r  )r
   r(   r   rw   rn   r  rq   r}   r  r+   r  r   )r<   r&   rw  ry  rk   r  r  r   Z	true_bodyZ
false_bodyr  r  replacementr    r    r!   r  J  s6    

z-SwitchTransform.build_simple_switch_statementc                 C   sR   | j ds| | |S |j}|j}| | |j|k	rNt|j|sN|jS |S )Nr  )r  r  r>   r]  Z	lazy_tempr   Ztree_contains)r<   r&   Z	orig_exprZtemp_refr    r    r!   visit_EvalWithTempExprNodeg  s    


z*SwitchTransform.visit_EvalWithTempExprNodeN)rF   rG   rH   rI   r`  rd  ra  rz  r  r  r  r  r   r  r  r   VisitorTransformrecurse_to_childrenrJ   r    r    r    r!   rW  s  s   =&rW  c                   @   s    e Zd ZdZdd ZejjZdS )FlattenInListTransformzj
    This transformation flattens "x in [val1, ..., valn]" into a sequential list
    of comparisons.
    c                    sj  |   jd k	rS jdkr,d d}njdkr@d d}nS tjtjtjtjfs`S j	}jj
}t|dkr| rjdk}tjj||dS S td	d
 |D rS t|}g }g }|D ]P}| st|}|| tjj|||d d}	|tjj|	tjd q· fdd}
t|
|}t||}|d d d D ]}t||}qR|S )NinrY  rV   rk   rZ  rX  r   r.  c                 S   s   g | ]
}|j qS r    )
is_starredrP   r%   r    r    r!   rS     s     z?FlattenInListTransform.visit_PrimaryCmpNode.<locals>.<listcomp>)rn   rX   rW   rY   r_  )rn   rm   rq   c                    s   t jj | |dS )N)rn   rW   rX   rY   )r   rc  rn   )leftrightZconjunctionr&   r    r!   concat  s    z;FlattenInListTransform.visit_PrimaryCmpNode.<locals>.concatr   )r>   r_  rW   r$   rY   r   	TupleNodeListNodeSetNoderX   r   rL   Ztry_is_simplerx   rn   rv  r
   r(   r   r=   ru   r^  r   c_bint_typer   r\  )r<   r&   Z	eq_or_neqr]   r   r5   Zcondsrj   r%   re  r  rb   r   r-  r    r  r!   r     sb    










z+FlattenInListTransform.visit_PrimaryCmpNodeN)	rF   rG   rH   rI   r   r   r  r  rJ   r    r    r    r!   r  y  s   @r  c                   @   s0   e Zd ZdZejjZdd Zdd Z	dd Z
dS )	DropRefcountingTransformz&Drop ref-counting in safe places.
    c                 C   s  g g  }}g g  }}g }|j D ]b}t|tjrd| |j|||sH|  S | |j|||s|  S qt|tjrx|  S |  S q|s|rdd |D }dd |D }	t|t|	kr|S t	t|t	|kr|S |s|rrg }
|D ]&}| 
|}|s |  S |
| qg }|D ](}| 
|}|s0|  S || qt|
t|krT|S t	t|
t	|krn|S |S dd |D }|D ]}d|_q|| D ]\}}||krd|_q|| D ]}d|_q|S )zF
        Parallel swap assignments like 'a,b = b,a' are safe.
        c                 S   s   g | ]\}}|qS r    r    rP   pathnr    r    r!   rS     s     zIDropRefcountingTransform.visit_ParallelAssignmentNode.<locals>.<listcomp>c                 S   s   g | ]\}}|qS r    r    r  r    r    r!   rS     s     c                 S   s   g | ]
}|j qS r    r%   )rP   tr    r    r!   rS     s     F)r`   r$   r   rw   _extract_operandr]   r^   ZCascadedAssignmentNoderQ  rL   _extract_index_idr=   Zuse_managed_ref)r<   r&   Z
left_namesZright_namesZleft_indicesZright_indicesrj   statZlnamesZrnamesZlindicesZlhs_nodeZindex_idZrindicesZrhs_nodeZ	temp_argsr-  r  	name_node
index_noder    r    r!   visit_ParallelAssignmentNode  sh    



 
 








z5DropRefcountingTransform.visit_ParallelAssignmentNodec                 C   s   t |}|jjsdS t|tjr0|| |j}g }|}|jr\|j	rHdS ||j
 |j}q8|jr||j |d|d d d |f nB|jr|jjtjkrdS |jjjsdS |jjsdS || ndS dS )NF.r   T)r+   rq   r   r$   r   r[  r=   r%   r   r/   memberr1   r   r   joinro   rp   r	   r   r   r   )r<   r&   namesindicesrj   Z	name_pathZobj_noder    r    r!   r    s4    
 
z)DropRefcountingTransform._extract_operandc                 C   s>   |j }|j}t|tjr |j}nt|tjr0d S d S |j|fS r#   )rp   r   r$   r   r-   r   Z	ConstNode)r<   r  rp   r   Z	index_valr    r    r!   r  )  s    z*DropRefcountingTransform._extract_index_idN)rF   rG   rH   rI   r   r  r  rJ   r  r  r  r    r    r    r!   r    s
   Er  c                   @   s   e Zd ZdZejjZdd Zdd Z	dd Z
d4d	d
Zd5ddZd6ddZdd Zdd Zdd Zdd Zdd Zdd Zeejedejdg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&dS )7EarlyReplaceBuiltinCallsa  Optimize some common calls to builtin types *before* the type
    analysis phase and *after* the declarations analysis phase.

    This transform cannot make use of any argument types, but it can
    restructure the tree in a way that the type analysis phase can
    respond to.

    Introducing C function calls here may not be a good idea.  Move
    them to the OptimizeBuiltinCalls transform instead, which runs
    after type analysis.
    c                 C   s.   |  | |j}| |s|S | |||jS r#   )r>   r   _function_is_builtin_name_dispatch_to_handlerr   )r<   r&   r   r    r    r!   visit_SimpleCallNodeE  s
    

z-EarlyReplaceBuiltinCalls.visit_SimpleCallNodec                 C   sL   |  | |j}| |s|S |j}t|tjs4|S |j}| ||||j	S r#   )
r>   r   r  positional_argsr$   r   r  r   r  keyword_args)r<   r&   r   r   r   r    r    r!   visit_GeneralCallNodeL  s    

   z.EarlyReplaceBuiltinCalls.visit_GeneralCallNodec                 C   s:   |j s
dS |  }||j}|| |jk	r6dS dS )NFT)r   r}   r   r   r   Zlookup_here)r<   r   r   r   r    r    r!   r  X  s    z2EarlyReplaceBuiltinCalls._function_is_builtin_nameNc                 C   sT   |d krd|j  }n
d|j  }t| |d }|d k	rP|d krD|||S ||||S |S )Nz_handle_simple_function_%sz_handle_general_function_%s)r   rb  )r<   r&   r   r   kwargsZhandler_nameZhandle_callr    r    r!   r  b  s    

z-EarlyReplaceBuiltinCalls._dispatch_to_handlerc                 C   s"   t j|jj|jj|||d|_d S )Nr  )r   ZPythonCapiFunctionNoder   rn   r   )r<   r&   r|  	func_typer  r    r    r!   _inject_capi_functiono  s       z.EarlyReplaceBuiltinCalls._inject_capi_functionc                 C   sj   |s
d}n*t |ts|dkr"d}n|dkr0d}nd}|d k	rFd| }nd}t|jd|||t|f  d S Nr=  r   z...xzexpected %s, z3%s(%s) called with wrong number of args, %sfound %dr$   r	  r   rn   rL   r<   function_namer&   r   expectedZarg_strZexpected_strr    r    r!   _error_wrong_arg_countt  s     
   z/EarlyReplaceBuiltinCalls._error_wrong_arg_countc                 C   s\   |st j|jddS t|dkr0| d||d t|d dd }|tjtj	fkrX|d S |S )N0.0rZ   r   floatr   rq   )
r   	FloatNodern   rL   r  rb  r   c_double_typer	   
float_type)r<   r&   pos_argsarg_typer    r    r!   _handle_simple_function_float  s    z6EarlyReplaceBuiltinCalls._handle_simple_function_floatc                 C   s   t |}d  }}|dkr |\}n8|dkr2|\}}n&|dkrF|\}}}n| d|| |S tj|j|pnt|j||p~t|jdS )Nr   r   r   slice)r   r   r   )rL   r  r   r  rn   NoneNode)r<   r&   r  r   r   r   r   r    r    r!   _handle_simple_function_slice  s     
z6EarlyReplaceBuiltinCalls._handle_simple_function_slicec                 C   sb   t |dkr|S |d }t|tjtjfr^t |jdkr^tj|jtj	t
t|jt|jdS |S )zUnpack ord('X').
        r   r   r  )rL   r$   r   r   r  r[   r   rn   r   c_long_typer	  rt  )r<   r&   r  r%   r    r    r!   _handle_simple_function_ord  s     z4EarlyReplaceBuiltinCalls._handle_simple_function_ordc                 C   s   |  ||dS )zTransform

        _result = all(p(x) for L in LL for x in L)

        into

        for L in LL:
            for x in L:
                if not p(x):
                    return False
        else:
            return True
        F_transform_any_allr<   r&   r  r    r    r!   _handle_simple_function_all  s    z4EarlyReplaceBuiltinCalls._handle_simple_function_allc                 C   s   |  ||dS )zTransform

        _result = any(p(x) for L in LL for x in L)

        into

        for L in LL:
            for x in L:
                if p(x):
                    return True
        else:
            return False
        Tr  r  r    r    r!   _handle_simple_function_any  s    z4EarlyReplaceBuiltinCalls._handle_simple_function_anyc                 C   s   t |dkr|S t|d tjs$|S |d }|jj}|j}t|\}}|d krR|S |r\|}	ntj|j	|d}	t
j|j	d t
j|j	|	t
j|j	tj|j	||dddgd}
t
j|j	tj|j	| | dd|_t|||
 tj|j	||rdnd	d
S )Nr   r   rl   r.  rZ   ra   )re   rd   rv  all)gen	orig_func)rL   r$   r   GeneratorExpressionNodeZdef_nodeZgbodyrc   rO   r   rn   r   ry   rz   ZReturnStatNoderx   re   r   recursively_replace_nodeInlinedGeneratorExpressionNode)r<   r&   r  Zis_anygen_expr_nodeZgenerator_bodyr   yield_expressionyield_stat_noderb   	test_noder    r    r!   r    sH     
  
z+EarlyReplaceBuiltinCalls._transform_any_allitc           
      C   s   t |dkr|S |d }t|tjr6|jtjkr6|}nt|tjr|}t|j	}|sX|S tj
|j|dtjd}|D ]*\}}tj|j||jd}	t|||	 qrnF|jr| }n6tj|j| r|jtjtjfkrdnd| j|dd	}t|j|S )
a  Transform sorted(genexpr) and sorted([listcomp]) into
        [listcomp].sort().  CPython just reads the iterable into a
        list and calls .sort() on it.  Expanding the iterable in a
        listcomp is still faster and the result can be sorted in
        place.
        r   r   sortedr  Zcomprehension_typerA   rg   __Pyx_PySequence_ListKeepNewPySequence_ListTr   )rL   r$   r   ComprehensionNoderq   r	   r   r  rK   loopr  rn   ComprehensionAppendNoderg   r   r  r*  Zas_listr   result_in_tempr   rF  PySequence_List_func_typeZSortedListNode)
r<   r&   r  r%   Z	list_noder  rN   r  r  append_noder    r    r!   _handle_simple_function_sorted  sJ    
  
 z7EarlyReplaceBuiltinCalls._handle_simple_function_sortedc              	   C   sT  t |dkr|S t|d tjtjfs*|S |d }|j}t|tjrbt|\}}d}|dkr|S n>|j}|j}z|j	r~|j
js|W S W n tk
r   | Y S X t |dkrtj|jddd}n|d }tj|jtjd}tj|j|t|jd||d	}	t|||	 tj|jtj|jtj|j|d
|dd|gd}
tj|j|
||jd|jdS )zLTransform sum(genexpr) into an equivalent inlined aggregation loop.
        r   r   r   Nr   r   r.  r   r  r\   )rn   r)   Tr  r_   sum)r  result_node
expr_scoper  has_local_scope)rL   r$   r   r  r  r  rO   r=   rA   r  rq   r   r}  r   rn   r
   r(   r   rF  r   rw   r7  r   r  rv   r  r  r  )r<   r&   r  r  r   r  r  r   r   add_nodeZ	exec_coder    r    r!   Z__handle_simple_function_sum,  sb    

   z5EarlyReplaceBuiltinCalls.__handle_simple_function_sumc                 C   s   |  ||dS )Nr   _optimise_min_maxr  r    r    r!   _handle_simple_function_minf  s    z4EarlyReplaceBuiltinCalls._handle_simple_function_minc                 C   s   |  ||dS )Nr   r  r  r    r    r!   _handle_simple_function_maxi  s    z4EarlyReplaceBuiltinCalls._handle_simple_function_maxc           	      C   s   t |dkr<t |dkr,|d jr,|d j}t |dkr<|S tttj|dd }|d }|D ]>}t|}tj|j	||tj
|j	|||dd}t||}q`|ddd D ]}t||}q|S )zKReplace min(a,b,...) and max(a,b,...) by explicit comparison code.
        r   r   N)rX   rW   rY   )r  r  r  r   )rL   r*  r   rr  rs  r
   r(   r   ZCondExprNodern   ru   r\  )	r<   r&   r   rW   Zcascaded_nodesZlast_resultZarg_noder   Zref_noder    r    r!   r  l  s0    

z*EarlyReplaceBuiltinCalls._optimise_min_maxc                 C   sB   |st j|jg ddS | ||tj}||k	r>t j|j|dS |S )Nr    r   r5   r  )r   r  rn   _transform_list_set_genexprr	   r   AsTupleNode)r<   r&   r  resultr    r    r!   &_DISABLED_handle_simple_function_tuple  s    z?EarlyReplaceBuiltinCalls._DISABLED_handle_simple_function_tuplec                 C   sP   t |dkr|S |d jr,|d js,|d= n t|d tjrL|d  |d< |S )zSReplace frozenset([...]) by frozenset((...)) as tuples are more efficient.
        r   r   )rL   r*  r   r$   r   r  as_tupler  r    r    r!   !_handle_simple_function_frozenset  s    z:EarlyReplaceBuiltinCalls._handle_simple_function_frozensetc                 C   s&   |st j|jg g dS | ||tjS Nr  )r   r  rn   r   r	   r   r  r    r    r!   _handle_simple_function_list  s    z5EarlyReplaceBuiltinCalls._handle_simple_function_listc                 C   s(   |st j|jg t dS | ||tjS r  )r   r  rn   rQ  r   r	   r   r  r    r    r!   _handle_simple_function_set  s    z4EarlyReplaceBuiltinCalls._handle_simple_function_setc                 C   s   t |dkr|S t|d tjs$|S |d }|j}t|}|sB|S tj|j||tj	krZdnd|d}|D ]*\}}	tj
|j||jd}
t||	|
 qh|S )zLReplace set(genexpr) and list(genexpr) by an inlined comprehension.
        r   r   rQ  rr  r  r  )rL   r$   r   r  r  rK   r  rn   r	   r   r  rg   r   r  )r<   r&   r  r   r  r   rN   r  r  r  r  r    r    r!   r     s.     z4EarlyReplaceBuiltinCalls._transform_list_set_genexprc                 C   s   t |dkrtj|jg i dS t |dkr.|S t|d tjsB|S |d }|j}t|}|s`|S |D ]2\}}t|tjs|  S t |j	dkrd|  S qdtj
|j|dtjd}|D ]8\}}	tj|j|j	d |j	d |jd}
t||	|
 q|S )zDReplace dict( (a,b) for ... ) by an inlined { a:b for ... }
        r   key_value_pairsr5   r   r   r   r  )Zkey_exprZ
value_exprrg   )rL   r   DictNodern   r$   r  r  rK   r  r   r  r	   r   ZDictComprehensionAppendNoderg   r   r  )r<   r&   r  r  r   rN   r  r  r  r  r  r    r    r!   _handle_simple_function_dict  s>    
  z5EarlyReplaceBuiltinCalls._handle_simple_function_dictc                 C   s$   t |dkr|S t|tjs |S |S )zlReplace dict(a=b,c=d,...) by the underlying keyword dict
        construction which is done anyway.
        r   )rL   r$   r   r  )r<   r&   r  r  r    r    r!   _handle_general_function_dict  s
    z6EarlyReplaceBuiltinCalls._handle_general_function_dict)N)N)N)'rF   rG   rH   rI   r   r  r  rJ   r  r  r  r  r  r  r  r  r  r  r  r  r   rU  r	   r   rV  rF  r  r  Z5_EarlyReplaceBuiltinCalls__handle_simple_function_sumr  r  r  r  r  r  r  r   r  r  r    r    r    r!   r  6  s<   




$1:#&r  c                   @   s$   e Zd ZejjZdd Zdd ZdS )InlineDefNodeCallsc                 C   sR   |j d krd S |j jrd S |  |j}|rB|jrBt|jdkrFd S |jd jS )Nr   r   )Zcf_stateZ
cf_is_nullr}   r   r   Zcf_assignmentsrL   r^   )r<   r  r   r    r    r!   get_constant_value_node  s    

z*InlineDefNodeCalls.get_constant_value_nodec                 C   sv   |  | | jds|S |j}|js*|S | |}t|tjsD|S tj	|j
|||j|jd}| rr| ||S |S )Nzoptimize.inline_defnode_calls)r  r   r   generator_arg_tag)r>   r  r  r   r   r  r$   r   ZPyCFunctionNodeZInlinedDefNodeCallNodern   r   r  Zcan_be_inlinedreplace)r<   r&   r  r   Zinlinedr    r    r!   r    s&    

  z'InlineDefNodeCalls.visit_SimpleCallNodeN)	rF   rG   rH   r   r  r  rJ   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 Zdd	 Ze	ej
ed
ej
dgZdd Zdd Zej	ejedejdedejdedejdgdddZdd Zdd ejejejfD Zdd Zej	ejedejdgddZej	ejedejdgddZd d! Zdd"d#Zd$d% Z d&d' Z!d(d) Z"e	ej#ed*ej
dgZ$d+d, Z%e%Z&d-d. Z'e	ej(ed/ej(dgZ)d0d1 Z*e	ej+ed2ej
dgZ,d3d4 Z-e	ej.ed5ej+dgZ/d6d7 Z0e	ej1ed2ej
dgZ2d8d9 Z3e	ej4ed2ej
dgZ5d:d; Z6ej	ejed*ej
dgd<ddZ7d=d> Z8e	ej9ed
ej
dgZ:e	ej9ed?ejdgZ;d@dA Z<dBdC Z=e	ej>ed?ej
dgZ?e	ej>ed?ej@dgZAdDdE ZBej	ejedejCdgddZDej	ejedFejEdgddZFej	ejed*ej
dgddZGej#dGejdHejHdIej+dJej.dKej1dLej4dLej(dMijIZJdNhZKdOdP ZLe	ejMedQej
dgZNdRdS ZOe	ejPedej
dgZQdTdU ZRdVdW ZSe	ej
edXej
dedYej.dgZTe	ej
edXej
dedYej.dedZej(dgZUdd[d\ZVdd]d^ZWej	ejXed5ej
ded_ej
dgddZYd`da ZZdbdc Z[ej	ejXeddej
ded?ejdgddZ\ej	ejXeddej
ded?ej
dgddZ]dedf Z^e	ej
ed5ej
dgZ_ej	ej
ed5ej
dedgej
dedhejdediejdgddjZ`dkdl ZaddndoZbej	ejXed*ej
dgddZcdpdq Zde	ej
ed/ej
dedrej
dedsej
dgZedtdu Zfe	ej
ed/ej
dedrej
dedsej
dedvejdgZgdwdx Zhe	ej
ed/ej
dedrej
dedsej
dgZiej	ejed/ej
dedrej
dedsej
dgejjjdZkdydz Zld{d ejmejfD Znd|d} Zod~d Zpdd Zqdd Zrdd Zsdd Ztdd Zudd Zvdd Zwdd Zxdd Zydd Zzdd Z{dd Z|eoZ}epZ~eqZerZesZetZeuZevZewZexZeyZezZe{Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Ze	ejPedejdgZdd ZeZeZeZeZeZeZeZeZeZeZe	ejedejdgZe	ej+edej#dedejPdgZdd Ze	ej+edej#dedej
dedejdgZdd Ze	ej#edej#dedej
dgZdd Zej	ejPedej
dedej
dedejdedejdedejdgddZdd Zdd Zdd Zej	ejedej#dedej
dedejdedejdedejdgddZddĄ ZddƄ ZddȄ Zej	ejedej#dedej
dedejdedejdgddZddʄ Ze	ej#edej#dedej
dedej
dedejdgZdd΄ Ze	ejed*ej#dedejCdedejCdgZe	ejed*ej#dgZddddddddgZddڄ eD Zdd܄ Zee	ej#edejCdedejdedejCdgZe	ej#edejCdedejdedejdedejCdedejCdededgZe	ej#edej
dedejdedejdedejCdedejCdededgZdZdd ZeZdd Zdd Zdd Zdd Zdd ZdddejjdfddZdd Ze	ej
ed*ej
dgZdd Zdd Zdd ZdS )OptimizeBuiltinCallsa<  Optimize some common methods calls and instantiation patterns
    for builtin types *after* the type analysis phase.

    Running after type analysis, this transform can only perform
    function replacements that do not alter the function return type
    in a way that was not anticipated by the type analysis.
    c                 C   s   |  | | S )z:Flatten redundant type checks after tree changes.
        )r>   Z	reanalyser?   r    r    r!   visit_PyTypeTestNode-  s    
z)OptimizeBuiltinCalls.visit_PyTypeTestNodec                 C   s"   |  | |j|jjkr|jS |S )z,
        Drop redundant type casts.
        )r>   rq   rm   r?   r    r    r!   _visit_TypecastNode3  s    
z(OptimizeBuiltinCalls._visit_TypecastNodec                 C   sd   |  | t|jtjr"|jj|_|j}|dks<|js<|jr@dS |jr`|j	r`|j	j
s\|j	jr`dS |S )z7
        Drop dead code and useless coercions.
        N)r>   r$   rA   r   r   r%   is_noner  r   r   is_localZis_arg)r<   r&   rA   r    r    r!   rB   >  s    

z'OptimizeBuiltinCalls.visit_ExprStatNodec                 C   sT   |  | |j}t|tjr"|j}t|tjrP|jtjt	j
fkrP|j|  S |S )z<Drop redundant conversion nodes after tree changes.
        )r>   r%   r$   r   PyTypeTestNoder   rq   r   rF  r	   	bool_typecoerce_to_booleanr}   r<   r&   r%   r    r    r!   visit_CoerceToBooleanNodeN  s    
z.OptimizeBuiltinCalls.visit_CoerceToBooleanNodeoNc                 C   s   |  | |j}t|tjr"|j}t|tjr|jjdkrt|j	dkr|j	d }|j
tjkrh|dS |j
jr|jjdkrtj|jd| j|gd|jtdd|jd	|j
|  S |S )
z3Drop redundant conversion nodes after tree changes.r  r   r   =float() argument must be a string or a number, not 'NoneType'__Pyx_PyObject_AsDoubleZ__Pyx_PyNumber_FloatZpynumber_floatzTypeConversion.c)r   py_namer   r  r  )r>   r%   r$   r   CoerceFromPyTypeNoder   r   r   rL   r   rq   r	   r  r   r   r|  rn   PyNumber_Float_func_typer   r   r   r  r  r}   )r<   r&   r%   func_argr    r    r!   visit_CoerceToPyTypeNode_  s0    


  
 z-OptimizeBuiltinCalls.visit_CoerceToPyTypeNodec                 C   s  |  | |j}|jjs:|j|jkr6||j|  }|S t|tjrL|j}|j	r|jj
rft|tjs|jjrzt|tjs|jj
rt|tjr||j|  S nt|tjr|jtjkr|j|jjr|j|j|  S n8|jtjkr|jjjr|jjr|j|j|  S njt|tjrL|jj
s>|jjr| ||S n:|jr|j}t|tjrn|j}|jj
r| |||S |S )zDrop redundant conversion nodes after tree changes.

        Also, optimise away calls to Python's builtin int() and
        float() if the result is going to be coerced back into a C
        type anyway.
        )r>   r%   rq   r   r  r}   r$   r   r  r  r   r   is_floatr  rx   r   r   rF  r%  r	   r   is_unicode_charr   _optimise_numeric_cast_callro   r   _optimise_int_indexing)r<   r&   r%   r  r    r    r!   visit_CoerceFromPyTypeNodev  sH    



z/OptimizeBuiltinCalls.visit_CoerceFromPyTypeNodebytesr   Zcheck_boundsz
((char)-1)T)r   Zexception_checkc              
   C   s   |   }|jd rdpd}|jjtjkr|jtjtjfkrt	j
|jt||d}t	j|jd| j|jd|tj||gdtdd	d
}|jtjk	r||j|}|S |S )Nr   r   r   r.  Z__Pyx_PyBytes_GetItemIntz&'NoneType' object is not subscriptableTZbytes_indexStringTools.cr   r   r  )r}   r   rp   rq   r	   r   r   c_char_typeZc_uchar_typer   r   rn   r	  r   PyBytes_GetItemInt_func_typer   r  r   r   r   )r<   Zcoerce_noder%   r  r   Zbound_check_boolZbound_check_noder&   r    r    r!   r'    s6      
 z+OptimizeBuiltinCalls._optimise_int_indexingc                 C   s&   i | ]}|t |t d |dgqS )r%   N)r   rU  rV  )rP   r  r    r    r!   
<dictcomp>  s    zOptimizeBuiltinCalls.<dictcomp>c              	   C   s  |j }d }t|tjr|j}n*t|tjrH|jjrHt|jtj	rH|jj}|d ks\t
|dkr`|S |d }t|tjr||j}n|jjr|S |jdkrr|jjs|jjr|j|jkr|S |jtjtjfkr| ||j|S |j|js|jjrptj|j||jdS nj|jjr|jjr|jjdkr.d}nd|jj }tj|j|| j|j |gd|j|jd|j|  S n|jd	kr|jjs|jjr|j|jkr|S |jtjtjfkr| ||j|S |j|js|jjrtj|j||jdS |S )
Nr   r   r  r   lZ__Pyx_truncltrunc)r  r   r  r   r  r  )r   r$   r   r   r   r-   rq   is_builtin_typer   r  rL   r   r%   r   r   r   r   r$  c_py_unicode_type_pyucs4_to_numberr%  r$  r^  rn   
is_numericZmath_h_modifierfloat_float_func_typesr   r  r  r}   )r<   r&   r%   r   r   r"  Ztrunclr    r    r!   r&    sf     
   z0OptimizeBuiltinCalls._optimise_numeric_cast_callr%   r   r   g      c                 C   sl   |dkst tj|j|dkr dnd|dkr0| jn| j|g||j|jt	|dkrRdnddd
|j|  S )	N)r  r  r  Z__Pyx_int_from_UCS4Z__Pyx_double_from_UCS4Z
int_pyucs4Zfloat_pyucs4
Builtins.c)r  r   r  r   r  r  )r  r   r   rn   pyucs4_int_func_typepyucs4_double_func_typer   r  r   r   r  rq   r}   )r<   r&   Zpy_type_namer"  r    r    r!   r3  		  s      z&OptimizeBuiltinCalls._pyucs4_to_numberc                 C   sj   |s
d}n*t |ts|dkr"d}n|dkr0d}nd}|d k	rFd| }nd}t|jd|||t|f  d S r  r  r  r    r    r!   r  	  s     
   z+OptimizeBuiltinCalls._error_wrong_arg_countc                 C   s   |S r#   r    )r<   r&   r  r   arg_listr  r    r    r!   _handle_function'	  s    z%OptimizeBuiltinCalls._handle_functionc                 C   s   |r|S |r|j r|jjs|S |  |}|s4|S tj|jjtj	|j|||j
d|dd|  }	|	dkr| |||||S |j}
|
dkr|jr|jj}
tj|j|	|
d}|s|j|_||   d|_||j
|  S )a  
        Try to inject C-API calls for unbound method calls to builtin types.
        While the method declarations in Builtin.py already handle this, we
        can additionally resolve bound and unbound methods here that were
        assigned to variables ahead of time.
        )r   r   rq   T)r1   r2   Z	is_calledNr   )r   r1   r   r}   r   r   r.   r   rn   r-   rq   Zanalyse_as_type_attribute%_optimise_generic_builtin_method_callr   r   r   r<   Zanalyse_c_function_callZanalysedr  )r<   r&   	type_name	attr_namer   r9  is_unbound_methodr  
type_entryr   r   	call_noder    r    r!   _handle_method*	  sR    	    z#OptimizeBuiltinCalls._handle_methodc                 C   sV   t |}|s |dks |jr |js$|S |jjjs2|S |jjtjkrD|S t	||j||S )z
        Try to inject an unbound method call for a call to a method of a known builtin type.
        This enables caching the underlying C function of the method at runtime.
        r   )
rL   r   r/   r1   rq   r1  r	   	type_typer   ZCachedBuiltinMethodCallNode)r<   r&   r=  r   r9  r>  r   r    r    r!   r;  V	  s    
   z:OptimizeBuiltinCalls._optimise_generic_builtin_method_callr1   c              	   C   s   t |dkr.t |dkr*tj|jt dS |S |d }|jtjkr`| sN|S d}t	
dd}nd}t	
dd}tj|j|| j||j|d	d
S )z5Optimise single argument calls to unicode().
        r   r   rZ   Z__Pyx_PyUnicode_UnicodeZPyUnicode_Unicoder*  Z__Pyx_PyObject_UnicodeZPyObject_Unicodeunicoder   r   r  r  )rL   r   r   rn   r   rq   r	   r   may_be_noner   r   r   PyObject_Unicode_func_typer   )r<   r&   r   r  r%   r|  r  r    r    r!   _handle_simple_function_unicodek	  s*      z4OptimizeBuiltinCalls._handle_simple_function_unicodec                 C   sJ   |  | |jjtjkrF|jsF|jsF|jr4|jdkrF| |d|jgS |S )zSimplify or avoid plain string formatting of a unicode value.
        This seems misplaced here, but plain unicode formatting is essentially
        a call to the unicode() builtin, which is optimised right above.
        r   N)	r>   r[   rq   r	   r   c_format_specformat_specconversion_charrG  r?   r    r    r!   visit_FormattedValueNode	  s
    
z-OptimizeBuiltinCalls.visit_FormattedValueNoder   c                 C   sN   t |dkr|S |d }|jtjkrJ|d}tj|jd| j|g|j	dS |S )z;Replace dict(some_dict) by PyDict_Copy(some_dict).
        r   r   r   ZPyDict_Copyr   )
rL   rq   r	   r   r   r   r   rn   PyDict_Copy_func_typer   r<   r&   r   r  r%   r    r    r!   r  	  s    
  z1OptimizeBuiltinCalls._handle_simple_function_dictr  c                 C   sX   t |dkr|S |d }tj|j| rF| rF|jtjtj	fkrFdnd| j
||jdS )z0Turn list(ob) into PySequence_List(ob).
        r   r   r  r  r   )rL   r   r   rn   r  rq   r   rF  r	   r   r  r   rM  r    r    r!   r  	  s     z1OptimizeBuiltinCalls._handle_simple_function_listrr  c                 C   s   t |dks| s|S |d }|jtjkr8| s8|S |jtjkrj|d|d< tj	|j
d| j|ddS tj|j
|tjdS dS )	zDReplace tuple([...]) by PyList_AsTuple or PySequence_Tuple.
        r   r   r   ZPyList_AsTupleTr   )r%   rq   N)rL   r  rq   r	   r   rE  r   r   r   r   rn   PyList_AsTuple_func_typer  rM  r    r    r!   _handle_simple_function_tuple	  s"       z2OptimizeBuiltinCalls._handle_simple_function_tuplec           	      C   s   t |dkr|S |d jrg }g }|d jD ]*}| sLt|}|| || q,tj|j	d|d}| 
|| |d d d D ]}t||}q|S | 
|tj|j	d| j||jddS d S )Nr   r   )r   r   r   Z	PySet_NewrQ  r   r   r  )rL   r*  r   	is_simpler
   r   r=   r   r  rn   r  r\  r   PySet_New_func_typer   )	r<   r&   r   r  r   rj   r%   r  r-  r    r    r!   r  	  s.    



 z0OptimizeBuiltinCalls._handle_simple_function_setc              
   C   sn   |st |jg}n4t|dkr$|S |d jtjkrH|d  sH|d S t j|jd| j	||j
tddddS )Nr   r   Z__Pyx_PyFrozenSet_NewZpyfrozenset_newr6  	frozensetrD  )r   rI  rn   rL   rq   r	   r   rE  r   PyFrozenSet_New_func_typer   r   r   r<   r&   r   r  r    r    r!   r  	  s     
z6OptimizeBuiltinCalls._handle_simple_function_frozensetz((double)-1)c              	   C   sj  t |dkr*tj|dddtj|  S t |dkrJ| d||d |S |d }t|tj	rd|j
}|jtjkrt|S |jtjtjfkr| ||j|S |j|js|jjrtj|j||jdS |d d	}|jtjkrd
}d}nX|jtjk rd}d}n@|jtjkrd}d}n(|jtjkr,d}d}n|d }d}d}tj|j|| j|g|j|r`t|ndddS )zYTransform float() into either a C type cast or a faster C
        function call.
        r   r  g        r.  r   r  0 or 1r   r  Z__Pyx_PyBytes_AsDoubleZpybytes_as_doubleZ__Pyx_PyByteArray_AsDoubleZ__Pyx_PyUnicode_AsDoubleZpyunicode_as_doubleZPyLong_AsDoubleNr  Zpyobject_as_doublerD  )rL   r   r  r  r	   r  r}   r  r$   r   r%   rq   r   r  r$  r2  r3  r   r%  r4  r^  rn   r   r   r   r   int_typer   PyObject_AsDouble_func_typer   r"   )r<   r&   r   r  r"  r%   
cfunc_nameutility_code_namer    r    r!   r  
  sh          z2OptimizeBuiltinCalls._handle_simple_function_floatr[   c                 C   s   t |dkr"tj|jddtjdS t |dkr2|S |d }t|tjrr|jj	j
rntj|jd| j|jgdddS |S |j	jr|j	jrtj|jd	| j|dddS |S )
z7Transform int() into a faster C function call.
        r   r   r   r   ZPyLong_FromDoubleTr  rP  Z__Pyx_PyNumber_Int)rL   r   r   rn   r	   rW  r$   r   r%   rq   r$  r   PyLong_FromDouble_func_typer   PyNumber_Int_func_type)r<   r&   r   r  r"  r    r    r!   _handle_simple_function_intO
  s8    
        z0OptimizeBuiltinCalls._handle_simple_function_intc                 C   s   t |dkr,tj|jdddtj|  S t |dkrL| d||d |S |d 	|  }tj
|j|d}tj
|j|d}||  S dS )	z=Transform bool(x) into a type coercion to a boolean.
        r   Fr.  r   boolrV  rl   N)rL   r   rx   rn   r  r	   r  r}   r  r  r   coerce_to_pyobject)r<   r&   r   r  rm   r    r    r!   _handle_simple_function_boolf
  s        z1OptimizeBuiltinCalls._handle_simple_function_boolc                 C   s   t |dkr | d||d |S |d jjrNtj|jd| j|d g|jddS |d jj	r|d j
tjkrtj|jd| j|d g|jddS |S )Nr   
memoryviewr  r   ZPyMemoryView_FromObjectrP  ZPyMemoryView_FromBuffer)rL   r  rq   r   r   r   rn   !PyMemoryView_FromObject_func_typer   r   rr   r	   py_buffer_type!PyMemoryView_FromBuffer_func_typerU  r    r    r!   "_handle_simple_function_memoryview
  s,      z7OptimizeBuiltinCalls._handle_simple_function_memoryviewrC  Z__Pyx_PyUnicode_GET_LENGTHr   Z__Pyx_PyByteArray_GET_SIZEZ__Pyx_PyList_GET_SIZEZ__Pyx_PyTuple_GET_SIZEZ__Pyx_PySet_GET_SIZEZPyDict_Sizezcpython.array.arrayc           	   
   C   s  t |dkr | d||d |S |d }t|tjr:|j}|jjrbtj|j	d| j
|g|jd}n|jjrtj|j	d| j|g|jtddd	}n|jjrtjtjtd
|jdgdd}tj|j	d||g|jd}n|jjrN| |j}|dkr&|j}|js|jr"|jj| jkr"d}n|S |d}tj|j	|| j|g|jd}n$|jjrntj|j	dd|jdS |S |jtj tjfkr|!|j| " }|S )zReplace len(char*) by the equivalent call to strlen(),
        len(Py_UNICODE) by the equivalent Py_UNICODE_strlen() and
        len(known_builtin_type) by an equivalent C-API call.
        r   rL   r   __Pyx_ssize_strlenr   Z__Pyx_Py_UNICODE_ssize_strlenZssize_pyunicode_strlenr*  r+  ZmemoryviewsliceNT)ZnogilZ__Pyx_MemoryView_LenZPy_SIZEz&object of type 'NoneType' has no len()r  r   )#rL   r  r$   r   r   r%   rq   r"  r   rn   Pyx_ssize_strlen_func_typer   Zis_pyunicode_ptrPyx_Py_UNICODE_strlen_func_typer   r   r   r   rU  r   rV  r   _map_to_capi_len_functionis_extension_typer1  r   Zqualified_name_ext_types_with_pysizer   PyObject_Size_func_typer%  r   Zc_size_t_typer  r}   )	r<   r&   r   r  r%   r   r  rY  r  r    r    r!   _handle_simple_function_len
  s      
  
   

   
z0OptimizeBuiltinCalls._handle_simple_function_lenobjectc                 C   s6   t |dkr|S tj|jd| j|dd}t|tjS )z7Replace type(o) by a macro call to Py_TYPE(o).
        r   ZPy_TYPEFr   )rL   r   r   rn   Pyx_Type_func_typer#  r   rF  rU  r    r    r!   _handle_simple_function_type
  s      z1OptimizeBuiltinCalls._handle_simple_function_typec              
      s  t |dkrS |\}}g }t|tjrr|j}t |dkrN|d jtjk	rNS |js\|	 st
|}|| n|jtjkr|g}nS g }g }|   |D ]}	d}
|	jr|	jr؈ |	jj}|r|jr|jjr|j}
|
tjkr|jdks|jr|jjsd}
|
dk	r4|jjdd}||kr"q|| |g}nD|	jtjkrPd}||	g}n(|	jslt
|	}	||	 d	}||	g}|tj|	j|| j|d
d qtjf fdd	}t||j }|ddd D ]}t
||}q|S )zcReplace isinstance() checks against builtin types by the
        corresponding C-API call.
        r   r   r   Nrq   F)exactZ__Pyx_TypeCheckZPyObject_IsInstanceTr   c                    s&   |j d| |}tj|_|  |S )NrY  )rn   r   r  rq   r  )r3   r4   Zmake_binop_nodeZor_noder   r&   r    r!   join_with_or>  s    
zMOptimizeBuiltinCalls._handle_simple_function_isinstance.<locals>.join_with_orr   )rL   r$   r   r  r   rq   r	   rB  r   rQ  r
   r(   r=   r}   r   r   r   r   r1  scopeZis_builtin_scopetype_check_functionr  r   rn   Py_type_check_func_typer7  r   r  r\  )r<   r&   r   r  r%   typesrj   testsZ
test_nodesZtest_type_nodeZbuiltin_typer   ru  Ztype_check_argsrs  r  r-  r    rr  r!   "_handle_simple_function_isinstance  sv    








  z7OptimizeBuiltinCalls._handle_simple_function_isinstancec                 C   s   t |dkr|S |d }t|tjrT|jjjrtj|j|jt	j
d|j|  S nTt|tjtjfrt |jdkrtj|jt	jtt|jt|jd|j|  S |S )z-Unpack ord(Py_UNICODE) and ord('X').
        r   r   r   r  )rL   r$   r   r   r%   rq   r%  r^  rn   r   r  r  r}   r   r  r[   r   r
  r	  rt  rM  r    r    r!   r  I  s2    
     z0OptimizeBuiltinCalls._handle_simple_function_ordrq   r   r  c              
   C   s  |j }|rt|dk r|S |d }|jr.|js2|S |jtjksJ|jtjkrN|S |jrZ|jsl|j|jkr||S n|j|jkr||S tj	|j
|dd d}|j|  dd}|jr|jj}	|	jr|	jr|	j |   krtdd}
t|	j|
}|r| jj}t|d	j}t|	td
|dtdtjdtdtjdg}t||}|sptj|j
tjd}tj|j
|||||gdddS n
|d}t !dd}|rtj|j
d| j"|||g||j#dS tj|j
d| j$||g||j#dS dS )zOReplace 'exttype.__new__(exttype, ...)' by a call to exttype->tp_new()
        r   r   N)r   TZskip_childrenZtp_new__new__PyTypeObjectrq   r   r  rq   F)r   may_return_noner   z4object.__new__(X): X is not a type object (NoneType)zObjectHandling.cZ__Pyx_tp_new_kwargs)r   r  r   Z__Pyx_tp_new)%r1   rL   r   rq   r	   rB  r?  r   r   r  rn   analyse_typesr}   rj  Ztypeobj_cnamert  r   r   ZConstructorSlotZget_slot_functionr   cython_scoper   CPtrTyper   rU  rV  rF  r#  rI  r   r   r   r   Pyx_tp_new_kwargs_func_typer   Pyx_tp_new_func_type)r<   r&   r   r   r>  r  r1   type_argZ
args_tupleZext_typeZtp_slotZslot_func_cnamer  PyTypeObjectPtrZpyx_tp_new_kwargs_func_typer  r    r    r!   _handle_any_slot__new__l  s     
     z,OptimizeBuiltinCalls._handle_any_slot__new__c                 C   s   |S r#   r    )r<   r&   r   r   r>  r  r    r    r!   _handle_any_slot__class__  s    z.OptimizeBuiltinCalls._handle_any_slot__class__r+  c              
   C   sB   t |dks|js|jjr|S tj|jd| j|d|jdt	ddS )z\Optimistic optimisation as X.append() is almost always
        referring to a list.
        r   Z__Pyx_PyObject_AppendFr=   )r   r~  r   r  r  )
rL   r  r   r   r   r   rn   PyObject_Append_func_typer   r"   r<   r&   r   r   r>  r    r    r!   #_handle_simple_method_object_append  s      z8OptimizeBuiltinCalls._handle_simple_method_object_appendc                 C   s  t |dkr|S |\}}|js"|S t|j}|jdk	sBt |dkrdr~t|tjr~|d  j	| 
 dd}t||d | |S | |||d}	|s|j|	_|	S |	 }
}t |dkr| st|}
g }|d	 }| st|}|| tj|jd
| j|
|gdtdd}|ddd	 D ]\}| sBt|}|| tj|jdtj|jd| j|
|gddtdd|tjd}q |j|_|
|k	r||
 |D ]}t||}|j|_q|S )zReplace list.extend([...]) for short sequence literals values by sequential appends
        to avoid creating an intermediate sequence argument.
        r   N   Fr   Trz  extendr   Z__Pyx_PyList_AppendZ
ListAppendr+  |Z__Pyx_ListComp_AppendZListCompAppend)r   r  r   r  r}  )rL   r*  rr  r   mult_factorr$   r   r  r  r  r}   r   r  _wrap_self_argr  rQ  r
   r   r=   r   rn   r  r"   r7  r   c_returncode_typer\  )r<   r&   r   r   r>  r1   r[   r   Z
tuple_nodeZwrapped_objZ
cloned_objrj   r%   r   r-  r    r    r!   !_handle_simple_method_list_extend  sr    



  


    



z6OptimizeBuiltinCalls._handle_simple_method_list_extend	bytearrayc           
   	   C   s   t |dkr|S d}| j}t|d }|jjs:t|tjrZ|t	j
|  }tdd}nV|jr| sl|S |t	j|  }tdd}n$|jjrd}| j}tdd}n|S tj|j|||d |gd	|j|d
}	|jr|	|j|  }	|	S )Nr   Z__Pyx_PyByteArray_Appendr   ZByteArrayAppendr*  Z__Pyx_PyByteArray_AppendObjectZByteArrayAppendObjectr   Fr   r~  r   r  )rL   PyByteArray_Append_func_typer'   rq   r   r$   r   r   r  r   r
  r}   r   r   is_string_literalZcan_coerce_to_char_literalr,  r   "PyByteArray_AppendObject_func_typer   rn   r   r  )
r<   r&   r   r   r>  	func_namer  r[   r  r   r    r    r!   &_handle_simple_method_bytearray_append"  s<      
z;OptimizeBuiltinCalls._handle_simple_method_bytearray_appendpy_indexZc_index	is_signed)Zhas_varargsc                 C   s   | j ||||ddS )NT)is_list) _handle_simple_method_object_popr  r    r    r!   _handle_simple_method_list_popQ  s        z3OptimizeBuiltinCalls._handle_simple_method_list_popFc                 C   s  |s|S |d }|r,d}|j dddgd}nd}t|dkrdtj|jd	| | j|gd
|jtddS t|dkrt|d }t	|j}	|j
}
|j
jst|tjr||  }	|tj|  }n>|r|j
jr||  }	t|	}|tj|  }n|S n2t|j
tjs|S t|tjr:||  }	|
jsH|j
}
|
|  s\|S |
j}ttjtd|
dg}tj|jd| | j||	|tj|jt|
jrdpd|
jrdpdtjdt |jtj!|
" t |j||gd
|jtddS |S )z\Optimistic optimisation as X.pop([n]) is almost always
        referring to a list.
        r   List*'NoneType' object has no attribute '%.30s'r>  popr?  ZObjectr   z__Pyx_Py%s_PopTr  r   ZintvalNz__Pyx_Py%s_PopIndexr   Z	pop_index)#r   rL   r   r   rn   PyObject_Pop_func_typer   r"   r'   r  rq   r   r$   r   r_  r}   r  r   r   r   r  r!  Znumeric_type_fitsZcreate_to_py_utility_codeZto_py_functionrU  rF  rV  PyObject_PopIndex_func_typer	  signedr
  RawCNameExprNodeZc_void_typeZempty_declaration_code)r<   r&   r   r   r>  r  r1   r<  r   r  Zorig_index_typeZconvert_funcZconversion_typer    r    r!   r  U  s     

  z5OptimizeBuiltinCalls._handle_simple_method_object_popc              	   C   s4   t |dkr|S | ||d| jd|||j| jS )z?Call PyList_Sort() instead of the 0-argument l.sort().
        r   ZPyList_Sortru  )rL   _substitute_method_callsingle_param_func_typer  rq   r}   r  r    r    r!   _handle_simple_method_list_sort  s          z4OptimizeBuiltinCalls._handle_simple_method_list_sortkeydefaultc                 C   sb   t |dkr |t|j n t |dkr@| d||d |S | j||d| jd||dtdd		S )
z:Replace dict.get() by a call to PyDict_GetItem().
        r   r   zdict.get2 or 3Z__Pyx_PyDict_GetItemDefaultr  TZdict_getitem_defaultr~  r  )	rL   r=   r   r  rn   r  r  Pyx_PyDict_GetItem_func_typer"   r  r    r    r!   _handle_simple_method_dict_get  s         z3OptimizeBuiltinCalls._handle_simple_method_dict_getis_safe_typec                 C   s   t |dkr |t|j n t |dkr@| d||d |S |d j}|jr`t|j	dk}n|t
jkrpd}nd}|tj|jt||d	 | j||d
| jd||dtdd	S )zUReplace dict.setdefault() by calls to PyDict_GetItem() and PyDict_SetItem().
        r   r   zdict.setdefaultr  r   z%str bytes unicode float int long boolr   r   r.  Z__Pyx_PyDict_SetDefault
setdefaultTZdict_setdefaultr  )rL   r=   r   r  rn   r  rq   r1  r  r   r   rF  r   r	  r  Pyx_PyDict_SetDefault_func_typer"   )r<   r&   r   r   r>  Zkey_typer  r    r    r!   %_handle_simple_method_dict_setdefault  s:    

      z:OptimizeBuiltinCalls._handle_simple_method_dict_setdefaultc                 C   s   d}d}| j }t|dkr.|t|j n6t|dkrP|jsdd}d}| j}n| d||d |S | j	||||d	||d
t
|d	S )z7Replace dict.pop() by a call to _PyDict_Pop().
        Z__Pyx_PyDict_PopZpy_dict_popr   r   Z__Pyx_PyDict_Pop_ignoreZpy_dict_pop_ignorezdict.popr  r  Tr  )PyDict_Pop_func_typerL   r=   r   rI  rn   r  PyDict_Pop_ignore_func_typer  r  r"   )r<   r&   r   r   r>  Z	capi_funcrZ  r  r    r    r!   _handle_simple_method_dict_pop  s.        z3OptimizeBuiltinCalls._handle_simple_method_dict_popc                 C   s   i | ]|}t jt jfD ]j}||ft j|t d t jdt dt jdt d|dt dt jdt dt jdg|jrtdn|jdqqS )Zop1NZop2cvalinplaceZzerodiv_checkr   )r   rF  r  rU  rV  r   r   )rP   ctyperet_typer    r    r!   r.    s   	  c                 C   s   |  d||||S NAdd_optimise_num_binopr  r    r    r!   $_handle_simple_method_object___add__  s    z9OptimizeBuiltinCalls._handle_simple_method_object___add__c                 C   s   |  d||||S NSubtractr  r  r    r    r!   $_handle_simple_method_object___sub__  s    z9OptimizeBuiltinCalls._handle_simple_method_object___sub__c                 C   s   |  d||||S )NZMultiplyr  r  r    r    r!   $_handle_simple_method_object___mul__  s    z9OptimizeBuiltinCalls._handle_simple_method_object___mul__c                 C   s   |  d||||S NEqr  r  r    r    r!   #_handle_simple_method_object___eq__!  s    z8OptimizeBuiltinCalls._handle_simple_method_object___eq__c                 C   s   |  d||||S NNer  r  r    r    r!   #_handle_simple_method_object___ne__$  s    z8OptimizeBuiltinCalls._handle_simple_method_object___ne__c                 C   s   |  d||||S )NAndr  r  r    r    r!   $_handle_simple_method_object___and__'  s    z9OptimizeBuiltinCalls._handle_simple_method_object___and__c                 C   s   |  d||||S )NOrr  r  r    r    r!   #_handle_simple_method_object___or__*  s    z8OptimizeBuiltinCalls._handle_simple_method_object___or__c                 C   s   |  d||||S )NZXorr  r  r    r    r!   $_handle_simple_method_object___xor__-  s    z9OptimizeBuiltinCalls._handle_simple_method_object___xor__c                 C   s^   t |dkst|d tjs |S |d  rHd|d j  krFdksLn |S | d||||S )Nr   r   ?   ZRshiftrL   r$   r   r   r   r5   r  r  r    r    r!   '_handle_simple_method_object___rshift__0  s
    (z<OptimizeBuiltinCalls._handle_simple_method_object___rshift__c                 C   s^   t |dkst|d tjs |S |d  rHd|d j  krFdksLn |S | d||||S )Nr   r   r  ZLshiftr  r  r    r    r!   '_handle_simple_method_object___lshift__7  s
    (z<OptimizeBuiltinCalls._handle_simple_method_object___lshift__c                 C   s   |  d||||S N	Remainder_optimise_num_divr  r    r    r!   $_handle_simple_method_object___mod__>  s    z9OptimizeBuiltinCalls._handle_simple_method_object___mod__c                 C   s   |  d||||S )NFloorDivider  r  r    r    r!   )_handle_simple_method_object___floordiv__A  s    z>OptimizeBuiltinCalls._handle_simple_method_object___floordiv__c                 C   s   |  d||||S N
TrueDivider  r  r    r    r!   (_handle_simple_method_object___truediv__D  s    z=OptimizeBuiltinCalls._handle_simple_method_object___truediv__c                 C   s   |  d||||S NDivider  r  r    r    r!   $_handle_simple_method_object___div__G  s    z9OptimizeBuiltinCalls._handle_simple_method_object___div__c                 C   s   t |dks&|d  r&|d jdkr*|S t|d tjr\d|d j  krTdksn |S n6t|d tjrd|d j  krdksn |S n|S | |||||S )Nr   r   r   r   r   l       l          )rL   r   r5   r$   r   r   r  r  )r<   rW   r&   r   r   r>  r    r    r!   r  X  s    &z&OptimizeBuiltinCalls._optimise_num_divc                 C   s   |  d||||S r  r  r  r    r    r!   #_handle_simple_method_float___add__e  s    z8OptimizeBuiltinCalls._handle_simple_method_float___add__c                 C   s   |  d||||S r  r  r  r    r    r!   #_handle_simple_method_float___sub__h  s    z8OptimizeBuiltinCalls._handle_simple_method_float___sub__c                 C   s   |  d||||S r  r  r  r    r    r!   '_handle_simple_method_float___truediv__k  s    z<OptimizeBuiltinCalls._handle_simple_method_float___truediv__c                 C   s   |  d||||S r  r  r  r    r    r!   #_handle_simple_method_float___div__n  s    z8OptimizeBuiltinCalls._handle_simple_method_float___div__c                 C   s   |  d||||S r  r  r  r    r    r!   #_handle_simple_method_float___mod__q  s    z8OptimizeBuiltinCalls._handle_simple_method_float___mod__c                 C   s   |  d||||S r  r  r  r    r    r!   "_handle_simple_method_float___eq__t  s    z7OptimizeBuiltinCalls._handle_simple_method_float___eq__c                 C   s   |  d||||S r  r  r  r    r    r!   "_handle_simple_method_float___ne__w  s    z7OptimizeBuiltinCalls._handle_simple_method_float___ne__c                 C   s   t |ddr|S t|dkr |S |jjr0tj}n |jtjkrL|dkrLtj}n|S t||||d |d }|sp|S |\}}	}
}tdd |D st	t
||
 }| j|||| j||f d	|dd
   ||dd|	d
}|jjr|jst||  |j}|S )zY
        Optimise math operators for (likely) float or small integer operations.
        Zspecial_bool_cmp_functionNr   r  r  r   r   c                 S   s   g | ]}|j jqS r    )rq   r   r  r    r    r!   rS     s     z<OptimizeBuiltinCalls._optimise_num_binop.<locals>.<listcomp>z__%s__r   TF)r~  with_none_checkr  )rb  rL   rq   r   r   rF  r  optimise_numeric_binopr  r  rr  r  Pyx_BinopInt_func_typeslowerr   r   r}   )r<   rW   r&   r   r   r>  r  r  
func_cnamer  
extra_argsnum_typer@  r    r    r!   r  z  s<       	z(OptimizeBuiltinCalls._optimise_num_binopucharc              
   C   s   |st |dkr|S |d }t|tjr2|jjjs6|S |j}|j}tj	ddt
|dd}d|  }	| j|||	| j|||g|d}
|jjr|
| j}
|
S )	Nr   r   Zpy_unicode_predicater*  )rP  r   z__Pyx_Py_UNICODE_%sr  )rL   r$   r   r   r%   rq   r%  r2   r   r   r   upperr  #PyUnicode_uchar_predicate_func_typer   r_  r}   )r<   r&   r   r   r>  ustringr  rP  r  r  Z	func_callr    r    r!   _inject_unicode_predicate  s8         z.OptimizeBuiltinCalls._inject_unicode_predicater	  keependsc              	   C   sH   t |dkr | d||d |S | ||dd | ||d| jd||S )zfReplace unicode.splitlines(...) by a direct call to the
        corresponding C-API function.
        r  zunicode.splitlinesz1 or 2r   FZPyUnicode_Splitlines
splitlines)rL   r  _inject_bint_default_argumentr  PyUnicode_Splitlines_func_typer  r    r    r!   (_handle_simple_method_unicode_splitlines  s        z=OptimizeBuiltinCalls._handle_simple_method_unicode_splitlinessepmaxsplitc              	   C   sx   t |dkr | d||d |S t |dk r@|t|j n| |d | ||dtj	d | 
||d| jd||S )	zaReplace unicode.split(...) by a direct call to the
        corresponding C-API function.
        )r   r   r   zunicode.split1-3r   r   r  ZPyUnicode_Splitsplit)rL   r  r=   r   rI  rn   _inject_null_for_none_inject_int_default_argumentr   r   r  PyUnicode_Split_func_typer  r    r    r!   #_handle_simple_method_unicode_split  s,            z8OptimizeBuiltinCalls._handle_simple_method_unicode_splitseqc              	   C   s   t |dkr | d||d |S t|d tjr|d }|j}t|}|rtj|j|dt	j
d}|D ]*\}	}
tj|	j|	|jd}t||
| qd||d< | ||d| jd	||S )
z^
        unicode.join() builds a list first => see if we can do this more efficiently
        r   zunicode.join2r   rr  r  r  ZPyUnicode_Joinr  )rL   r  r$   r   r  r  rK   r  rn   r	   r   r  rg   r   r  r  PyUnicode_Join_func_type)r<   r&   r   r   r>  r  r   rN   Zinlined_genexprr  r  r  r    r    r!   "_handle_simple_method_unicode_join  s>          z7OptimizeBuiltinCalls._handle_simple_method_unicode_joinZ	substringr   end	directionc              
   C   s   |  ||||ddtdS )Nr	  endswithr   _inject_tailmatchunicode_tailmatch_utility_coder  r    r    r!   &_handle_simple_method_unicode_endswithF  s          z;OptimizeBuiltinCalls._handle_simple_method_unicode_endswithc              
   C   s   |  ||||ddtdS )Nr	  
startswithr   r  r  r    r    r!   (_handle_simple_method_unicode_startswithK  s          z=OptimizeBuiltinCalls._handle_simple_method_unicode_startswithc	              
   C   s   t |dkr*| | d| ||d |S | ||dtjd | ||dtjd |tj|jt	|tj
d |d	kr~d
}	nd|  d}	| j|||	| j||||d}
|
tj|  S )zReplace unicode.startswith(...) and unicode.endswith(...)
        by a direct call to the corresponding C-API function.
        r   r      r  2-4r   r   r   PY_SSIZE_T_MAXr[   rq   r	  Z__Pyx_PyUnicode_TailmatchZ__Pyx_PyZ
_Tailmatchr  )rL   r  r  r   r   r=   r   r   rn   r	  r
  
capitalizer  PyString_Tailmatch_func_typer  r	   r  r}   )r<   r&   r   r   r>  r<  rP  r  r  r  method_callr    r    r!   r	  P  sH                  z&OptimizeBuiltinCalls._inject_tailmatchr  c                 C   s   |  ||||ddS )Nfindr   _inject_unicode_findr  r    r    r!   "_handle_simple_method_unicode_findu  s         z7OptimizeBuiltinCalls._handle_simple_method_unicode_findc                 C   s   |  ||||ddS )Nrfindr   r  r  r    r    r!   #_handle_simple_method_unicode_rfindy  s         z8OptimizeBuiltinCalls._handle_simple_method_unicode_rfindc              	   C   s   t |dkr$| d| ||d |S | ||dtjd | ||dtjd |tj|jt	|tj
d | ||d	| j|||}||  S )
zwReplace unicode.find(...) and unicode.rfind(...) by a
        direct call to the corresponding C-API function.
        r  z
unicode.%sr  r   r   r   r  r  ZPyUnicode_Find)rL   r  r  r   r   r=   r   r   rn   r	  r
  r  PyUnicode_Find_func_typer_  r}   )r<   r&   r   r   r>  rP  r  r  r    r    r!   r  }  s@                   z)OptimizeBuiltinCalls._inject_unicode_findc              	   C   sn   t |dkr | d||d |S | ||dtjd | ||dtjd | ||d| jd	||}||  S )
zaReplace unicode.count(...) by a direct call to the
        corresponding C-API function.
        r  zunicode.countr  r   r   r   r  ZPyUnicode_Countcount)	rL   r  r  r   r   r  PyUnicode_Count_func_typer_  r}   )r<   r&   r   r   r>  r  r    r    r!   #_handle_simple_method_unicode_count  s6                 z8OptimizeBuiltinCalls._handle_simple_method_unicode_countZreplstrZmaxcountc              	   C   sL   t |dkr | d||d |S | ||dtjd | ||d| jd||S )zcReplace unicode.replace(...) by a direct call to the
        corresponding C-API function.
        )r   r  zunicode.replacez3-4r   r  ZPyUnicode_Replacer  )rL   r  r  r   r   r  PyUnicode_Replace_func_typer  r    r    r!   %_handle_simple_method_unicode_replace  s&             z:OptimizeBuiltinCalls._handle_simple_method_unicode_replaceencodingerrorsUTF8UTF16UTF-16LEUTF-16BELatin1ASCIIZunicode_escapeZraw_unicode_escapec                 C   s   g | ]}|t |fqS r    )r   
getencoder)rP   r   r    r    r!   rS     s   zOptimizeBuiltinCalls.<listcomp>c                 C   sH  t |dk st |dkr,| d||d |S |d }| |j|}|dkrN|S |\}}}	}
| rz|j||	}W n   Y n$X t||pd}tj	|j|t
jdS t |dkrt|j}| ||d	| jd
||||gS |r*|	dkr*| |}|dk	r*d|kr*d| }| |||| jd
||gS | ||d	| jd
||||
gS )z_Replace unicode.encode(...) by a direct C-API call to the
        corresponding codec.
        r   r   zunicode.encoder  r   NzUTF-8r  ZPyUnicode_AsEncodedStringr  strictr5  zPyUnicode_As%sString)rL   r  _unpack_encoding_and_error_modern   r   r5   r  r   r   r  r	   r   rI  r  #PyUnicode_AsEncodedString_func_type_find_special_codec_namePyUnicode_AsXyzString_func_type)r<   r&   r   r   r>  string_node
parametersr"  encoding_nodeerror_handlingerror_handling_noder[   	null_node
codec_nameZencode_functionr    r    r!   $_handle_simple_method_unicode_encode  s`        
       z9OptimizeBuiltinCalls._handle_simple_method_unicode_encodestringr  r   decode_funcc                 C   s  dt |  krdks.n | d||d |S |d }| |j|}|dkrP|S |\}}}	}
| rz|j||	}W n ttt	fk
r   Y nX t
|jt||jdS d }}t|tjr|}|j}|j|j }}|r|jdkrd}t|tjr|j}|j}|tjtjfkr@|r,|jdd	|jgd
}n|jddd	gd}n|jsT|jsT|S |sntj|jddd}n|jjs|tj | ! }|r|jjs|tj | ! }d}|dk	r| "|}|dk	r|dkrd|#dd }nd| }tj$|j| j%|d}t&|j}nt&|j}g }|jrt|sh|j'sNt()|}|*| tj+|jd| j,|gdd}| j-}d}n|jr|stj|jdtj.d}| j/dkrt0tj1t2d|dt2dtj dt2dtj dt2dtj3dt2dtj3dt2d | j%dg| _/| j/}d!|j }n6|s2tj|jdtj.d}| j4}|tjkrJd"}nd#}tj+|jd$| ||||||
|g|j5t67|d%d&}|ddd' D ]}t(8||}q|S )(zReplace char*.decode() by a direct C-API call to the
        corresponding codec, possibly resolving a slice on the char*.
        r   r   zbytes.decoder  r   Nr[   r  @descriptor '%s' requires a '%s' object but received a 'NoneType'decoder@  r  r>  r?  r   r.  )r%  r&  r'  z__Pyx_PyUnicode_Decode%sr5  r=  zPyUnicode_Decode%s)rq   r|  rf  Tr   Zdecode_c_stringr  r8  r   r   r"  r#  r9  Zdecode_cpp_Zdecode_bytesZdecode_bytearrayz__Pyx_%sr*  r+  r   )9rL   r  r,  rn   r   r5   r<  r}  
ValueErrorUnicodeDecodeErrorr   r   r$   r   r   rp   r   r   r   r%   rq   r	   r   r   r   r   r"  Zis_cpp_stringr   r   r  r   r   r}   r.  r  r  !PyUnicode_DecodeXyz_func_ptr_typerI  r   r
   r   r=   r   rg  _decode_c_string_func_typer   _decode_cpp_string_func_typerU  r   rV  r  _decode_bytes_func_typer   r   r   r\  )r<   r&   r   r   r>  r0  r1  r"  r2  r3  r4  r5   r   r   r  Zstring_typer6  Zcodec_cnameZdecode_functionrj   Zhelper_func_typerZ  r-  r    r    r!   "_handle_simple_method_bytes_decode!  s    




  

  
	
  
z7OptimizeBuiltinCalls._handle_simple_method_bytes_decodec                 C   sl   zt |}W n tk
r$   Y d S X | jD ]:\}}||kr,d|kr^ddd |dD }|  S q,d S )Nr  r=  c                 S   s   g | ]}|  qS r    )r  )rP   r   r    r    r!   rS     s   zAOptimizeBuiltinCalls._find_special_codec_name.<locals>.<listcomp>)r   r*  LookupError_special_codecsr  r  )r<   r"  Zrequested_codecr   codecr    r    r!   r.    s    

z-OptimizeBuiltinCalls._find_special_codec_namec                 C   s   t |}t|dkr6| |d \}}|d kr>d S nd }|}t|dkrv| |d \}}|d krhd S |dkr~|}nd}|}||||fS )Nr   r   r   r+  )r   rI  rL   _unpack_string_and_cstring_node)r<   rn   r   r5  r"  r2  r3  r4  r    r    r!   r,    s     
z4OptimizeBuiltinCalls._unpack_encoding_and_error_modec                 C   s   t |tjr|j}t |tjr>|j}tj|j| t	j
d}njt |tjrn|jd}tj|j|jt	j
d}n:|jtjkrd }|t	j
|  }n|jjrd }nd  }}||fS )Nr  z
ISO-8859-1)r$   r   r   r%   r   r[   r  rn   Zas_utf8_stringr   r  r<  rq   r	   r   r  r}   r"  )r<   r&   r"  r    r    r!   rH    s.        z4OptimizeBuiltinCalls._unpack_string_and_cstring_nodec              
   C   s   |  ||||ddtdS )Nr)  r  r   r	  bytes_tailmatch_utility_coder  r    r    r!   $_handle_simple_method_bytes_endswith  s          z9OptimizeBuiltinCalls._handle_simple_method_bytes_endswithc              
   C   s   |  ||||ddtdS )Nr)  r  r   rI  r  r    r    r!   &_handle_simple_method_bytes_startswith  s          z;OptimizeBuiltinCalls._handle_simple_method_bytes_startswithr    c              
   C   sT   t |}|r(|r(| |d ||||d< |	d kr6|j}	tj|j||||	||
|jdS )Nr   )r   r   r  r~  r  )rr  r  r   r   r   rn   r  )r<   r&   r   r   r  r=  r>  r   r  r   r~  r  r    r    r!   r    s      z,OptimizeBuiltinCalls._substitute_method_callc                 C   sR   |j r
|S |r&|jd||jjgd}n(|jdt|dkr>dndd|gd}|S )	Nr;  r=  r:  r;  r<  r=  r>  r?  )r  r   rq   r   rH  rL   )r<   Zself_argr   r>  r=  r    r    r!   r  	  s    
z#OptimizeBuiltinCalls._wrap_self_argc                 C   sV   t ||krd S || }|jr*t|jn"tj|jd| j||  gdd||< d S )NZ__Pyx_NoneAsNullr   r   )	rL   r  r   rI  rn   r   obj_to_obj_func_typer  r}   )r<   r   r   r%   r    r    r!   r    s     z*OptimizeBuiltinCalls._inject_null_for_nonec                 C   s|   t ||kstt ||ks&|| jrF|tj|jt|||d n2|| || 	 }t
|tjrpt||_|||< d S )Nr  )rL   r  r  r=   r   r   rn   r	  r  r}   r$   r   Zspecial_none_cvalue)r<   r&   r   	arg_indexrq   default_valuer%   r    r    r!   r  '  s     

z1OptimizeBuiltinCalls._inject_int_default_argumentc                 C   sX   t ||kstt ||kr>t|}|tj|j||d n|| |  ||< d S Nr.  )	rL   r  r^  r=   r   rx   rn   r  r}   )r<   r&   r   rN  rO  r    r    r!   r  5  s    
z2OptimizeBuiltinCalls._inject_bint_default_argument)N)N)N)F)rF   rG   rH   rI   r  r  rB   r  r   rU  rF  rV  r!  r#  r(  r,  r	   r   r   r
  r-  r'  Zc_float_typer  Zc_longdouble_typer5  r&  r$  r7  r8  r3  r  r:  rA  r;  r   rF  rG  Z_handle_simple_function_strrK  r   rL  r  r   r  r  r   rN  rO  r   rR  r  r   rT  r  rX  r  rW  r\  r[  r]  r`  Zmemoryview_typerb  rc  rd  re  r  rg  Zc_const_py_unicode_ptr_typerh  rl  r   r  ri  rk  rm  rB  ro  rp  r  rv  ry  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  r  r  r  r  r  r  r  Z!_handle_simple_method_int___add__Z!_handle_simple_method_int___sub__Z!_handle_simple_method_int___mul__Z _handle_simple_method_int___eq__Z _handle_simple_method_int___ne__Z!_handle_simple_method_int___and__Z _handle_simple_method_int___or__Z!_handle_simple_method_int___xor__Z$_handle_simple_method_int___rshift__Z$_handle_simple_method_int___lshift__Z!_handle_simple_method_int___mod__Z&_handle_simple_method_int___floordiv__Z%_handle_simple_method_int___truediv__r  r  r  r  r  r  r  r  r  r  r  Z%_handle_simple_method_unicode_isalnumZ%_handle_simple_method_unicode_isalphaZ'_handle_simple_method_unicode_isdecimalZ%_handle_simple_method_unicode_isdigitZ%_handle_simple_method_unicode_islowerZ'_handle_simple_method_unicode_isnumericZ%_handle_simple_method_unicode_isspaceZ%_handle_simple_method_unicode_istitleZ%_handle_simple_method_unicode_isupperZ)_handle_simple_method_unicode_isprintableZ$PyUnicode_uchar_conversion_func_typer  r  r  r   r  r  r  r  r  r	  r  r  r  r  r  r  r   r!  r-  r/  Z_special_encodingsrF  r7  r  r@  rA  rC  rB  rD  Z&_handle_simple_method_bytearray_decoder.  r,  rH  rK  rL  r   r   r~  r  r  rM  r  r  r  r    r    r    r!   r  "  s  	(	5
,6        5D 
J 
	?!	
D			
' 

	 1

  
r  c                 C   s  t jt jf}t||r<|jtjk	r2|jtjk	r2dS |}d}n4t||rl|jtjk	rb|jtjk	rbdS |}d}ndS |	 s|dS t|t j}|rtj
ntj}	|r| dkrdS n| dkrdS t|jdkrdS | dkr|jdkrdS g }
|
|rt jnt j|j|j|j|	d	 t|t jr|jnd
}|
t j|j||d |sJ| dkr|dkolt|t jrj|j nd
}|
t j|j||d tj|rdn| dkrdnddt| ||dd}d|rdnd|jrdnd| |f }|||
|	fS )zQ
    Optimise math operators for (likely) float or small integer operations.
    NZObjCZCObj)r  r  r  r  r  r  r  r  r   )r  r  r  r  r   r   Fr.  r  ZPyFloatBinopZPyLongCompareZPyLongBinopr   )oporderr  r  z__Pyx_Py%s_%s%s%sZFloatZLongr=  ZBool)r   r   r  r$   rq   r   rF  r	   rW  r   r  r  r  r5   r=   rn   r[   ZNumBinopNoder  rx   r8  Z	cdivisionr   r   r   r   )rW   r&   r  Zarg0Zarg1Z	num_nodesZnumvalZ	arg_orderr$  r  r  r  Zzerodivision_checkr  r  r    r    r!   r  ?  sh    


  
r  Zunicode_tailmatchr*  Zbytes_tailmatchc                       sJ  e Zd ZdZdI fdd	Zdd Zejejej	ej
gZdd Zd	d
 Zdd Zdd Zdddddj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(Zd)d* Zd+d, Zd-d. Zd/d0 Z d1d2 Z!d3d4 Z"d5d6 Z#d7d8 Z$d9d: Z%d;d< Z&d=d> Z'd?d@ Z(dAdB Z)dCdD Z*dEdF Z+dGdH Z,e-j.j/Z0  Z1S )JConstantFoldingaF  Calculate the result of constant expressions to store it in
    ``expr_node.constant_result``, and replace trivial cases by their
    constant result.

    General rules:

    - We calculate float constants to make them available to the
      compiler, but we do not aggregate them into a single literal
      node to prevent any loss of precision.

    - We recursively calculate constants from non-literal nodes to
      make them available to the compiler, but we only aggregate
      literal nodes at each step.  Non-literal nodes are never merged
      into a single node.
    Fc                    s   t    || _dS )z
        The reevaluate argument specifies whether constant values that were
        previously computed should be recomputed.
        N)superr9   
reevaluate)r<   rU  	__class__r    r!   r9     s    
zConstantFolding.__init__c                 C   s   | j s|jtjk	rd S tj}||_| |}| D ]J}t|tkrh|D ]}t	|d||krH  d S qHq4t	|d||kr4 d S q4z|
  W nP ttttttfk
r   Y n2 tk
r   dd l}dd l}|j|jd Y nX d S )Nr5   r   )file)rU  r5   r   constant_value_not_setr   r>   r   rq   rr  rb  Zcalculate_constant_resultr>  	TypeErrorrT   
IndexErrorr}  ArithmeticError	Exception	tracebacksys	print_excstdout)r<   r&   r   childrenZchild_resultchildr^  r_  r    r    r!   _calculate_const  s*    

z ConstantFolding._calculate_constc                 G   s<   z | j tt| j jtt| W S  tk
r6   Y d S X d S r#   )NODE_TYPE_ORDERmaxrs  r   rq   r>  )r<   Znodesr    r    r!   _widest_node_class  s    z"ConstantFolding._widest_node_classc                 C   s   t |}tj|j||dS rP  )r^  r   rx   rn   )r<   r&   r[   r    r    r!   
_bool_node  s    zConstantFolding._bool_nodec                 C   s   |  | |S r#   )rd  r?   r    r    r!   visit_ExprNode  s    
zConstantFolding.visit_ExprNodec                 C   s   |  | | s*|jdkr&| |S |S |jjs6|S |jdkrN| ||jS t|jt	j
rt	j|jtt|jtjt|jdS |jdkr| |S |jdkr| |S |S )N!r  r  r5  )rd  r   rW   _handle_NotNoderm   r  rh  r5   r$   r   rx   r   rn   r	  r  r   r
  _handle_UnaryPlusNode_handle_UnaryMinusNoder?   r    r    r!   visit_UnopNode  s&    







zConstantFolding.visit_UnopNoderk   r  is_notis)r  rk   rp  ro  c                 C   s@   |j }t|tjr<| |j}|r<t|}||_| |}|S r#   )rm   r$   r   ru   _negate_operatorrW   r   r   )r<   r&   rm   rW   r    r    r!   rk    s    

zConstantFolding._handle_NotNodec                 C   s   dd }|j j}t|j tjr<tj|j||j j||jdS |jrH|j	s\t|j tj
r|jrtj
|j||j j||j j|jdS |S )Nc                 S   s$   |  dr| dd  } nd|  } | S )Nr5  r   )r  rZ   r    r    r!   _negate  s    
z7ConstantFolding._handle_UnaryMinusNode.<locals>._negater  )r[   rq   longnessr5   )rm   rq   r$   r   r  rn   r[   r5   r   r  r   r   rs  )r<   r&   rr  Z	node_typer    r    r!   rm    s$    z&ConstantFolding._handle_UnaryMinusNodec                 C   s"   |j  r|j|j jkr|j S |S r#   )rm   r   r5   r?   r    r    r!   rl    s
    
z%ConstantFolding._handle_UnaryPlusNodec                 C   sR   |  | |j s|S |jjr8|jdkr0|jS |jS n|jdkrH|jS |jS d S )NrZ  )rd  rX   r   r5   rW   rY   r?   r    r    r!   r    s    



z#ConstantFolding.visit_BoolBinopNodec              	   C   s  |  | |jtjkr|S t|jtr*|S |j|j }}|jrD|jsH|S z(|j	|j	 }}|d ksh|d krn|W S W n t
k
r   | Y S X |jr|jrt||}ntj}| ||}|d kr|S |tjkr|jdkrtj}n|tjk r|jdk rtj}|tjkrt|ddo t|dd}dd ttt|ddtt|dd }	tt|j}
t|
}
tj|j||	|
t|jd}|js|j	jrtj|_	nt||j	|_	n2|tjkr|j}n
t|j}||j|||jd}|S )	Nz+-//<<%**>>z+-//<<%**>>&|^unsignedr=  ZLLrs  )rn   rt  rs  r[   r5   )rn   rq   r[   r5   )rd  r5   r   r   r$   r  rX   rY   r  rq   r}  r4  r   Zwidest_numeric_typerF  rg  rx   rW   r   rq  rb  rf  rL   hexr  r   Zstrip_py2_long_suffixrn   r   r	  )r<   r&   rX   rY   Ztype1Ztype2Zwidest_typeZtarget_classrt  rs  r[   r   Z
node_valuer    r    r!   visit_BinopNode#  sd    




 

zConstantFolding.visit_BinopNodec                 C   s(  |  | t|jtr.tj|jjt|jdS |j|j	 }}t|tj
rt|tj
rt|j|j tj|_| |S t|jtr|js|S t|tjstj|j|jd}|j| tj|_| |S nft|tj
r.t|jtr.|js|S t|tjstj|j|jd}|jd| tj|_| |S |jtjkr@|S |jr|jrt|tjrt|tjrd }|jd k	r|jd k	r|jj|jjkrt|j|j |jj}t|j}tj|j||dS t|tjrt|tjr|jj|jjkrt|j|jj}tj|j||jdS | |S )NrZ   r   r:  r.  )rd  r$   r5   r	  r   r   rX   rn   r   rY   JoinedStrNoder   r  rY  simplify_JoinedStrNoder=   r   r   r  r  r"  r   r  r[   rv  )r<   r&   rX   rY   r  Zstring_valuer    r    r!   visit_AddNode_  sj    
 
  


zConstantFolding.visit_AddNodec                 C   s   |  | |jjr$| ||j|jS t|jtjrL|jjrL| ||j|jS |jjrf| 	||j|jS |jjr| 	||j|jS | 
|S r#   )rd  rX   r*  _calculate_constant_seqrY   r$   r   r   r  _multiply_stringrv  r?   r    r    r!   visit_MulNode  s    
zConstantFolding.visit_MulNodec                 C   s   |j }t|ts|S | r(t|j ts,|S t|j dkr>|S t|tjrPt}nFt|tj	rt
}|jd k	rt|j| |jj|_ndstdt| ||j| |jj|_|j|_ |S )N   Fzunknown string node type: %s)r5   r$   r  r   _py_string_typesrL   r   r  r   r   r   r  r"  r  rq   r[   )r<   r&   r0  Zmultiplier_nodeZ
multiplierZbuild_stringr    r    r!   r{    s.    

z ConstantFolding._multiply_stringc                 C   s   |j dkr|jrt|j tr:|j dkr:|jd d = d |_n`|jd k	rt|j trt|jj tr|jj |j  }tj|jjt||d|_q| 	|S n||_|S rA  )
r5   r   r$   r  r  r   r   rn   r	  rv  )r<   r&   Zsequence_nodeZfactorr[   r    r    r!   rz    s"    
 
z'ConstantFolding._calculate_constant_seqc                 C   s^   |  | t|jtjrTt|jtjrT|jjsT| |jj	|jj
|jj}|d k	rT|S | |S r#   )r>   r$   rX   r   r   rY   r  r  _build_fstringrn   r[   r   rv  )r<   r&   Zfstringr    r    r!   visit_ModNode  s    
zConstantFolding.visit_ModNodez'(%(?:(?:[-0-9]+|[ ])?(?:[.][0-9]+)?)?.)c                 C   s"  t |}g }d}t| j|D ]}|s*q|dkrL|tj|tdd q|d dkr|d dkrt|d|dd   d	d
d d}|tj|t|d q|d }zt	|}	W n. t
k
r   t|dd
d d}Y  qY nX |	jrd} q|dkr|d
d  }
d }|dkr(d|
kr(d}nF|dkr`|
d d }
|}|
drnd|
d
d   }
n|dkrnd}|
drd|
d
d   }
|tj|	j|	||
rtj|t|
dnd d qd} qq|sd S zt	| W n t
k
r   Y nX t|dd
d d S tj||d}| |S )NTz%%%rZ   r   r   zIncomplete format: '...'r   )levelFz)Too few arguments for format placeholdersZasrfdoxXZdoxXr  Zarsr   r   dr5  r   )r[   rJ  rI  z*Too many arguments for format placeholders)r   )iterr   r  _parse_string_format_regexr=   r   r   r   r   nextStopIterationr  r  FormattedValueNodern   rw  visit_JoinedStrNode)r<   rn   r  r@  r   
substringsZcan_be_optimisedr   Zformat_typer%   rI  rJ  r&   r    r    r!   r    sv    


 
 zConstantFolding._build_fstringc                 C   s   |  | |jpd}|jd k	r4|jjr4|jjs4d |_|jd krx|j rxt|jjtrxt	t
|jj}tj|jj|dS |jd kr|dkr|jjr|jS |S )Nr   rZ   )r>   rJ  rI  r  r[   r   r$   r5   r  r   r	  r   r   rn   )r<   r&   rJ  r[   r    r    r!   rK  '  s    

"z(ConstantFolding.visit_FormattedValueNodec                 C   s   |  | | |S r#   )r>   rx  r?   r    r    r!   r  4  s    
z#ConstantFolding.visit_JoinedStrNodec                 C   s   g }t j|jtddD ]l\}}|rzt|}|d }t|dkrhtddd |D }tj	|j
|d}|jr|| q|| q|stj	|j
tdd}n>t|dkr|d }n(t|d	krtj|j
d
f| }n||_|S )z
        Clean up after the parser by discarding empty Unicode strings and merging
        substring sequences.  Empty or single-value join lists are not uncommon
        because f-string format specs are always parsed into JoinedStrNodes.
        r  )r  r   r   r=  c                 s   s   | ]}|j V  qd S r#   rZ   )rP   r[   r    r    r!   	<genexpr>D  s     z9ConstantFolding.simplify_JoinedStrNode.<locals>.<genexpr>rZ   r   r  )r   groupbyr   r   rr  rL   r   r  r   r   rn   r[   r=   r  r7  )r<   r&   r   Zis_unode_groupr  Zunoder[   r    r    r!   rx  8  s&    
z&ConstantFolding.simplify_JoinedStrNodec                    s   |  | g g  fdd |jD ]} || q(rF tdkrpd }|jslt|tjrp|S |jdd< | | |S )z!Unpack **args in place if we can.c                    s   |j r:r.d j|jkr.d j|j q| nRt|tjrj| j|jkrj|jD ]} || qXn"r d d = | d S )Nr   )	is_dict_literalZreject_duplicatesr
  r  r=   r$   r   MergedDictNoder  )parentr%   	child_argr{  r   r   r    r!   r{  ]  s    


z1ConstantFolding.visit_MergedDictNode.<locals>.addr   r   N)	r>   r  r  rL   r  r$   r   r  rd  r  r    r  r!   visit_MergedDictNodeW  s    



z$ConstantFolding.visit_MergedDictNodec                    s   |  | |jtjkg g  fdd |jD ]} | q6rVd  tdkrd }rt|js|jr|j|jkst	|t
jr|S |jdd< | | |S ) Unpack *args in place if we can.c                    s   r
| j s| jr:| js:r.d j| j q|  nHt| tjr\| jD ]} | qLn&rxd  d d = |  d S )Nr   )	is_set_literalr*  r  r   r  r=   r$   r   MergedSequenceNode)r%   r  r{  r   rR  r   r    r!   r{    s    

z5ConstantFolding.visit_MergedSequenceNode.<locals>.addr   r   N)r>   rq   r	   r   r   r=   rL   r  r*  r$   r   r  rd  r  r    r  r!   visit_MergedSequenceNodey  s,    






z(ConstantFolding.visit_MergedSequenceNodec                 C   sr   |  | g }|jD ]@}|js*|| q|jjrJ|jjsJ||jj q|| q||jdd< | | |S )r  N)	r>   r   r  r=   rg   r*  r  r  rd  )r<   r&   r   r%   r    r    r!   visit_SequenceNode  s    


z"ConstantFolding.visit_SequenceNodec                 C   s  |  |dg |j}|}|d k	r|  |dg |j}t|_| r|| r|z||j W n  ttt	t
ttfk
rz   Y nX |}|j}q|js| r| ||jS |S |jgg}g }|}|d k	r| r|js|| |d qn||jg n|d | |j}qg }|D ]p}t|dk r.q|d }tj|j|d |j|jtd}	||	 |	}
|dd  D ]}||
_|}
qnd |
_q|r||d  n|s| |d	S |d }t|dkr| r| ||jS n*|dd  D ]}tj|j|d
|td}q|S )NrX   rY   Fr   r   r   r   )rX   rW   rY   r5   TrZ  )r>   rX   rY   r   r5   r   Z"calculate_cascaded_constant_resultr>  rZ  rT   r[  r}  r\  r_  rh  r=   rL   r   ru   rn   rW   rc  )r<   r&   Z	left_noder   Z
right_nodeZcascadesZfinal_false_resultZ	cmp_nodesr_  Z	pcmp_nodeZlast_cmp_noder    r    r!   r     s    





z$ConstantFolding.visit_PrimaryCmpNodec                 C   s0   |  | |j s|S |jjr&|jS |jS d S r#   )rd  r  r   r5   r  r  r?   r    r    r!   r    s    

z"ConstantFolding.visit_CondExprNodec                 C   st   |  | g }|jD ]0}|j}| r:|jrD|j|_ qFq|| q|rT||_|S |jr`|jS tj	|j
g dS d S Nr_   )r>   rd   rb   r   r5   rc   re   r=   r   rv   rn   )r<   r&   rd   r  rb   r    r    r!   r    s    

z ConstantFolding.visit_IfStatNodec                 C   s   |  | |jd ks |jjd kr,d  }|_n|jj}|jd ksJ|jjd krVd  }|_n|jj}|jtk	r|j}|jr|jd kr|j|| |_|S |j	r|
||}|d k	r|S |S r#   )rd  r   r5   r   r   rp   r*  r  r   r  Zas_sliced_node)r<   r&   r   r   rp   r    r    r!   visit_SliceIndexNode  s"    

z$ConstantFolding.visit_SliceIndexNodec                 C   s   |  | t|jtjr||jjs||jtjkr>t	j
|jg g dS |jtjkr^t	j|jg t dS |jtjkr|t	j|jg i dS |S )Nr  r	  )r>   r$   r  r   rv   r`   rq   r	   r   r   r  rn   r   r  rQ  r   r  r?   r    r    r!   visit_ComprehensionNode5  s*    
      z'ConstantFolding.visit_ComprehensionNodec                 C   s\   |  | |jj}t|tjrX|js@|jr0|jS tj	|j
g dS t|tjrX| |j_|S r  )r>   rh   rf   r$   r   ZSequenceNoder   re   r   rv   rn   r  r  )r<   r&   rf   r    r    r!   r   D  s    
z#ConstantFolding.visit_ForInStatNodec                 C   s:   |  | |jr6|j r6|jjr0d |_d |_n|jS |S r#   )r>   rb   r   r5   re   r?   r    r    r!   visit_WhileStatNodeS  s    
z#ConstantFolding.visit_WhileStatNodec                 C   s.   |  | t|jtjs|S |j r*d S |S r#   )r>   r$   rA   r   ZExprNoder   r?   r    r    r!   rB   ]  s    

z"ConstantFolding.visit_ExprStatNodec                 C   s<   |  | |jd kr|S |j r8|jjr2d |_n|jS |S r#   )r>   rb   r   r5   rc   r?   r    r    r!   visit_GILStatNodeg  s    


z!ConstantFolding.visit_GILStatNode)F)2rF   rG   rH   rI   r9   rd  r   rx   rq  r   r  re  rg  rh  ri  rn  r  rq  rk  rm  rl  r  rv  ry  r|  r{  rz  r  r  r  rK  r  rx  r  r  r  r   r  r  r  r  r   r  rB   r  r   r  r  rJ   __classcell__r    r    rV  r!   rS    sZ     
<7
F"&P	

rS  c                   @   sv   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d Zdd ZdddZejdddZdS )FinalOptimizePhasea  
    This visitor handles several commuting optimizations, and is run
    just before the C code generation phase.

    The optimizations currently implemented in this class are:
        - eliminate None assignment and refcounting for first assignment.
        - isinstance -> typecheck for cdef types
        - eliminate checks for None and/or types that became redundant after tree changes
        - eliminate useless string formatting steps
        - inject branch hints for unlikely if-cases that only raise exceptions
        - replace Python function calls that look like method calls by a faster PyMethodCallNode
        - replace duplicate FormattedValueNodes in f-strings with CloneNodes
    Fc                 C   s    |  | |jr|j}d|_|S )zaAvoid redundant initialisation of local variables before their
        first assignment.
        T)r>   r  r]   Zlhs_of_first_assignment)r<   r&   r]   r    r    r!   visit_SingleAssignmentNode  s
    
z-FinalOptimizePhase.visit_SingleAssignmentNodec                 C   s   |j }|j}|js|jr|jnd }|  }|jpB|jpB|joB|j	j}|
 o|jo|tjk	o|od|j o| j| js||r|dndS )Nz&optimize.unpack_method_calls_in_pyinitzoptimize.unpack_method_calls)r   rq   r   r   r   r}   Zis_module_scopeZis_c_class_scopeZis_py_class_scopeZouter_scoper  r   r	   rB  r   r  r  in_loop)r<   r&   r   Zfunction_typer   r   Zin_global_scoper    r    r!   _check_optimize_method_calls  s0    
z/FinalOptimizePhase._check_optimize_method_callsc                 C   s  |  | |j}|jjr|jr|jdkrt|jdkr|jd }|jjr|jjdkr| j	j
}|d|_|jj|_t|dj}t|jd ||jd< n|tjj|jddrtj|r|jr|jrt|jtjr|jj|jkr|jj|_| |tjj|||j|j| |d	}|S )
z
        Replace generic calls to isinstance(x, type) by a more efficient type check.
        Replace likely Python method calls by a specialised PyMethodCallNode.
        r$   r   r   rq   ZPyObject_TypeCheckr|  F)
has_kwargs)r   r   rq   unpack)r>   r   rq   Zis_cfunctionr   r   rL   r   r1  r   r  r   r   r   r  r   r#  PyMethodCallNodecan_be_used_for_posargsr   can_be_used_for_functionr<   r   r$   r1   r!  r%   r  	from_noder  )r<   r&   r   r  r  r  r    r    r!   r    s6    



   z'FinalOptimizePhase.visit_SimpleCallNodec                 C   s   |  | t|j}t|jtj}tjj|j||ds:|S |j	}tj
|sP|S | |tjj|||j|j|j| |d}|S )zW
        Replace likely Python method calls by a specialised PyMethodCallNode.
        )r  has_explicit_kwargs)r   r   Zkwdictrq   r  )r>   r^  r  r$   r   r  r  r  r  r   r  r  r  rq   r  )r<   r&   r  r  r   r    r    r!   r    s*    

      z(FinalOptimizePhase.visit_GeneralCallNodec                 C   s   |  | |S r#   )r>   r?   r    r    r!   visit_NumPyMethodCallNode  s    
z,FinalOptimizePhase.visit_NumPyMethodCallNodec                 C   s$   |  | |js |j s d|_|S )zRemove tests for alternatively allowed None values from
        type tests when we know that the argument cannot be None
        anyway.
        T)r>   Znotnoner%   rE  r?   r    r    r!   r    s
    

z'FinalOptimizePhase.visit_PyTypeTestNodec                 C   s   |  | |j s|jS |S )z_Remove None checks from expressions that definitely do not
        carry a None value.
        )r>   r%   rE  r?   r    r    r!   visit_NoneCheckNode  s    

z&FinalOptimizePhase.visit_NoneCheckNodec                 C   s    | j }d| _ | | || _ |S )zeRemember when we enter a loop as some expensive optimisations might still be worth it there.
        T)r  r>   )r<   r&   Zold_valr    r    r!   visit_LoopNode  s
    
z!FinalOptimizePhase.visit_LoopNodec                 C   sZ   |  | d}t|jD ] \}}| ||j |js|}q|jrV|rV| j||jdd |S )zQAssign 'unlikely' branch hints to if-clauses that only raise exceptions.
        NT)inverse)r>   r   rd   _set_ifclause_branch_hintrc   branch_hintre   )r<   r&   Zlast_non_unlikely_clausern  r  r    r    r!   r    s    

z#FinalOptimizePhase.visit_IfStatNodec                 C   s   |j s
dS tjtjtjtjtjtjf}|g}t|dD ]z\}}t	|tj
rZ|||j q6t	|tjrv|j|||< q6t	||s6|t|krt	|tjtjfr|rdnd|_ qq6dS )z\Inject a branch hint if the if-clause unconditionally leads to a 'raise' statement.
        Nr   ZlikelyZunlikely)Zis_terminatorr   r   ZAssignmentNodeZAssertStatNodeZDelStatNodeZ
GlobalNodeZNonlocalNoder   r$   ZGILStatNoder   rc   rv   r`   rL   ZRaiseStatNodeZReraiseStatNoder  )r<   ZclauseZstatements_noder  Znon_branch_nodesZ
statementsZnext_node_posr&   r    r    r!   r    s*    
z,FinalOptimizePhase._set_ifclause_branch_hintr*   c                 C   s   t j}t j}i }|jdd }t|jD ]\}}t||s<q(|j}t|j|rV|j}n|jdk	rbn|j	j
r(nq(|jr(| s~q(|j|j|j|jpdf}	||	|}
|
|krq(t |
}|j|_|||< q(||jdd< |S )a  
        Deduplicate repeatedly formatted (C) values by replacing them with CloneNodes.
        It's not uncommon for a formatting expression to appear multiple times in an f-string.

        Note that this is somewhat handwavy since it's potentially possible even for simple
        expressions to change their value while processing an f-string, e.g. by modifying the
        world in a ".__format__" method.  However, this seems unlikely enough to appear in
        real-world code that we ignore the case here.
        Nr   )r   r  r   r   r   r$   r[   r%   rH  rq   r1  r   rQ  r   rI  rJ  r  r!  rn   )r<   r&   r  r   r  r   rn  ZfnodeZfnode_value_noder  Z
seen_fnodeZdedup_fnoder    r    r!   r  1  s4    




z&FinalOptimizePhase.visit_JoinedStrNodeN)F)rF   rG   rH   rI   r  r  r  r  r  r  r  r  r  r  r  r   rw  r  r    r    r    r!   r    s   
		
r  c                   @   s$   e Zd ZdZdZdd Zdd ZdS )ConsolidateOverflowChecka5  
    This class facilitates the sharing of overflow checking among all nodes
    of a nested arithmetic expression.  For example, given the expression
    a*b + c, where a, b, and x are all possibly overflowing ints, the entire
    sequence will be evaluated and the overflow bit checked only at the end.
    Nc                 C   s6   | j d k	r(| j }d | _ | | || _ n
| | |S r#   )overflow_bit_noder>   )r<   r&   Zsavedr    r    r!   rJ   q  s    


z#ConsolidateOverflowCheck.visit_Nodec                 C   sT   |j rF|jrF| jd k}|r"|| _n| j|_d|_ | | |rPd | _n
| | |S r,   )Zoverflow_checkZoverflow_foldr  r>   )r<   r&   Ztop_level_overflowr    r    r!   visit_NumBinopNode{  s    


z+ConsolidateOverflowCheck.visit_NumBinopNode)rF   rG   rH   rI   r  rJ   r  r    r    r    r!   r  h  s   
r  )DZcythonZdeclarern  r   r   r   r   rW   r   r=  r   r   r   r   r)  r	  r~  r   r   r   r	   r
   r   ZCoder   r   ZStringEncodingr   r   r   ZErrorsr   r   ZParseTreeTransformsr   r   	functoolsr   r"   r   r   r'   r+   r0   r6   r8   r7   rO   rK   ZEnvTransformrU   rW  r  r  r  r  ZNodeRefCleanupMixinr  ZMethodDispatcherTransformr  r  r   r
  rJ  rS  r  ZCythonTransformr  r    r    r    r!   <module>   s           
           It   M"                -E       d