a
    ba5                    @   s  d dl mZ d dlZ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Zejeeeeeeeeeed
 ejd  dkreZeefZneef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' zd dl(m)Z) W n  e*yb   d dl+m)Z) Y n0 zd dl(m,Z, W n e*y   eZ,Y n0 dd Z-e	j.e	j/ffddZ0dd Z1dd Z2dd Z3G dd  d ej4Z5d!d" Z6d#d$ Z7G d%d& d&ej8Z9G d'd( d(ej8Z:G d)d* d*ej;e'Z<G d+d, d,ej;Z=G d-d. d.ej8Z>G d/d0 d0ej?ej8Z@G d1d2 d2ej?ejAZBeCd3d4ZDeCd5d4ZEeCd6d4ZFG d7d8 d8ej;e'ZGG d9d: d:ej8ej?ZHG d;d< d<ejIZJdS )=    )absolute_importN   )	TypeSlots)not_a_constant)
UtilityCodeEncodedStringbytes_literalencoded_stringNodes	ExprNodes
PyrexTypesBuiltin	UtilNodes_py_int_types   )r
   )r   )r   )Visitor)r   )r   )Options)r   TempitaUtilityCode)r   r   r	   )errorwarning)SkipDeclarations)reduce)
basestringc                 C   s   t | dS )N
Optimize.c)r   load_cached)name r   h/Users/vegardjervell/Documents/master/model/venv/lib/python3.9/site-packages/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_node3   s    
r#   c                 C   s   t | tjr| j} q | S r   )r    r   ResultRefNode
expressionr"   r   r   r   unwrap_node9   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   r,   ?   s    "r,   c                 C   s   | d ur| j d u rd S | S r   )constant_resultr&   r   r   r   filter_none_nodeI   s    r2   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   r5   S   s    z_YieldNodeCollector.__init__c                 C   s   | j | | | d S r   )r7   appendvisitchildrenr8   r"   r   r   r   visit_YieldExprNodeZ   s    z'_YieldNodeCollector.visit_YieldExprNodec                 C   s&   |  | |j| jv r"|| j|j< d S r   )r:   exprr7   r6   r;   r   r   r   visit_ExprStatNode^   s    
z&_YieldNodeCollector.visit_ExprStatNodec                 C   s   d S r   r   r;   r   r   r   visit_GeneratorExpressionNodee   s    z1_YieldNodeCollector.visit_GeneratorExpressionNodec                 C   s   d S r   r   r;   r   r   r   visit_LambdaNodeh   s    z$_YieldNodeCollector.visit_LambdaNodec                 C   s   d S r   r   r;   r   r   r   visit_FuncDefNodek   s    z%_YieldNodeCollector.visit_FuncDefNodeN)__name__
__module____qualname____doc__r5   r   r4   r:   
visit_Noder<   r>   r?   r@   rA   r   r   r   r   r3   O   s   r3   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_expressiono   s    rK   c                    sD   t    |  z fdd jD }W n ty>   g }Y n0 |S )Nc                    s   g | ]}|j  j| fqS r   )r!   r6   ).0Z
yield_node	collectorr   r   
<listcomp>z   s   z*_find_yield_statements.<locals>.<listcomp>)r3   r:   r7   KeyErrorrI   r   rM   r   rG   v   s    



rG   c                   @   s  e Zd ZdZdd Zdd Zd-ddZd	d
 Ze	ej
edejdgZe	ejedejdgZd.d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d/ddZd0ddZdd Zdd Zd1d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 )2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iteratorr_   ra   tempsr_   not_inoperand)Zis_ptr_containsposr   r$   rU   is_subscriptbasetype	base_type
TempHandlerefr   PrimaryCmpNoderT   r
   StatListNodeSingleAssignmentNodeBoolNodeZBreakStatNode
IfStatNodeIfClauseNodeTempsBlockNodeZForInStatNodeZIteratorNodeanalyse_expressionscurrent_envvisitTempResultFromStatNoderS   NotNoder:   )r8   r"   rj   
result_refrn   Ztarget_handlerc   cmp_nodeZif_bodyZif_nodeZfor_loopnew_noder   r   r   visit_PrimaryCmpNode   sR    
	




	

z'IterationTransform.visit_PrimaryCmpNodec                 C   s   |  | | ||jjS r   )r:   _optimise_for_looprd   rb   r;   r   r   r   visit_ForInStatNode   s    
z&IterationTransform.visit_ForInStatNodeFc                 C   s&  d }|j s|jr|jr|jjr|jj}|jr2|j}|j r|jrR|jjdkrRtj}n|j	dkrbtj}|jr||jjdv r|tj
}n|j	dv rtj
}tj|j|fv r|r|S | j||d dddS tj
|j|fv stj|j|fv r|r|S | ||S |jjs|jjr| j|||dS |jtju r,| j|||dS |jtju rJ| j|||dS t|tjs\|S |jd u r|jr~t|jjpd	}n$t|j}|r|jd ur|d
8 }|j}|jr|s|s|jp|j}|j}	|   j!j"dk}
|
s4|	dv r4t|tj#r4|j}|j r4|j	dkr4|jr4|jj$r4d}
d }}|	dksV|
r\|	dkr\d}nB|	dksv|
r||	dkr|d}n"|	dks|
r|	dkrd }}|s|r| |||	||S |jd u 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rFdkr"n n|jd u r"|j r"|j	dv r"|jr"|jj$r"|j)jj*s|j)jj+r| j,|||dS |j)jj-r"|jd u r|jjn|jD ]F}t|tj.r|/ rd|j0  kr dk rn nq q"q| j,|||dS |S )Nztyping.DictDict)z
typing.Setztyping.FrozenSet)Set	FrozenSetTF)dict_objmethodkeysvaluesreversedr   r   r   )r   r   itemsdictiterkeysr   
itervaluesr   	iteritemsr   	enumerater   )rangexrange      @)1is_nameis_attributeentry
annotationrk   rl   qualified_namer   	dict_typer   set_typerm   _transform_dict_iterationfrozenset_type_transform_set_iterationis_ptris_array_transform_carray_iteration
bytes_type_transform_bytes_iterationunicode_type_transform_unicode_iterationr    r   SimpleCallNodeargs	arg_tuplerH   r8   functionr-   r.   global_scopecontextZlanguage_levelZCallNode
is_builtin_transform_enumerate_iteration_transform_reversed_iterationr   Zconvert_rangerc   is_intis_enum_transform_range_iterationis_pyobjectIntNodehas_constant_resultr1   )r8   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v 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   rH   r   rj   rm   r   
tuple_type	list_typeas_none_safe_noderd   rb   r   r   )r8   r"   Zreversed_functionr   r!   r   r   r   r   2  s"    z0IterationTransform._transform_reversed_iterationsNc                 C   s   |j j}|js|tju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 )	N'NoneType' is not iterableZPyBytes_AS_STRINGr   r   is_tempPyBytes_GET_SIZEr   )rl   startstepstoprm   r   r   )rc   rm   r   r   r   r   
LetRefNoder   r   PythonCapiCallNoderj   PyBytes_AS_STRING_func_typePyBytes_GET_SIZE_func_typeLetNoder   SliceIndexNode)r8   r"   
slice_noder   target_typeunpack_temp_nodeZslice_base_nodeZlen_noder   r   r   r   P  sD    	z-IterationTransform._transform_bytes_iterationkinddataindexlength-1exception_valuec                 C   s|  |j rzt|jdd}W n ty.   Y nf0 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rr||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-1rW   r1   rm   )rl   r   r   rm   r   0r   >>=<=<Z__Pyx_PyUnicode_READFr   rj   rY   rZ   r[   T	bound1	relation1rc   	relation2bound2r   r_   ra   
from_rangeZ__Pyx_init_unicode_iterationri   rm   Zunicode_iterr   )r   r   result_is_usedutility_coder=   re   )0
is_literalr   rW   encodeUnicodeEncodeErrorr   r   rj   	BytesNoder   c_const_char_ptr_type	coerce_toZc_const_uchar_ptr_typery   r   strrH   c_py_ssize_t_typer   r   r   r   r   r   ro   rp   
c_int_typec_void_ptr_typer   PyUnicode_READ_func_typerc   rm   r
   rs   rr   r_   ForFromStatNodera   ExprStatNode init_unicode_iteration_func_typeAmpersandNodec_py_ssize_t_ptr_typec_void_ptr_ptr_typec_int_ptr_typer   r   r   rw   )r8   r"   r   r   bytes_valueZbytes_slicer   Z
start_nodeZlength_tempZend_noder   r   Z	kind_tempZ	data_tempcounter_temptarget_valuetarget_assignr_   	loop_nodeZ
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shJ |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 u 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 u 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$u 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.j/|j!j
|j!|d}t.j0|j
||j1gd}| 2||\}}t.j3|j
||||||||j4dd
}tj5|j
|g|dS )NFz*C array iteration requires known end indexr   z8C array iteration requires known step size and end indexrm   rW   r1   rW   rm   r1   r   r   r   +rT   rS   rU   rm   r   1r   )r   r   rl   rm   r   )r   rl   rm   r   r[   Tr   re   )6r    r   r   rl   r2   r   r   rm   r   r   rj   rk   r   	SliceNoder   r1   r   r   r   r   r   absr   sizer   ry   Zelement_ptr_typecoerce_to_simpleAddNode	CloneNoder   ro   rp   rc   	is_stringr   r   CastNodeZDereferenceNodern   c_py_ucs4_typer   r   r   assignable_fromZ	IndexNoder
   rs   rr   r_   _find_for_from_node_relationsr   ra   rw   )r8   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   r_   r   r   for_noder   r   r   r     s@   













	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 argument   z%enumerate() takes at most 2 argumentsr   r   r   r  r  )rT   rU   rS   rm   r   r   r[   )r   r   rH   r   rj   rc   is_sequence_constructorrm   r   r   r#   r   ry   r   r   r   r   r	  r
   rs   r    r_   rr   r\   r9   itemrd   rb   r   r   )r8   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   )r8   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  rW   r1   r  r   r   r   TF)	rc   r   r   r   r   r   r_   ra   r   )r   r   rH   rj   r   r   r    r1   r   r   Zcoerce_to_integerry   r  r  r   spanning_typerm   r   r   _build_range_step_calculationrW   r   r
   r   rc   r_   ra   Zset_up_loopr   )r8   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  rm   r   r   r   
binop_noderj   ZMulNoder   r   DivNodeZSubNode)r8   r   r  r   r  r  r  Zspanning_step_typer  r  Zfinal_opZstep_calculation_noder   r   r   r  .  s     %-z0IterationTransform._build_range_step_calculationc                    s|  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|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$u |||gdddtj% jd | j&dg}t j' j|tj j|ddS )Nr  rj   r\   r   r   T)Zis_identifierrW   *'NoneType' object has no attribute '%{0}s'   .30 PyExc_AttributeErrorr   format_argsr   c                    s"   | rdp
d} t j jt| | dS Nr   r   r  r   r   rj   r   rV   r&   r   r   	flag_node  s    z?IterationTransform._transform_dict_iteration.<locals>.flag_noder   r  rX   Z__Pyx_dict_iteratorZ	dict_iterr   r   r   r   r^   r_   ra   r[   re   )(r   ro   r   py_object_typer9   rp   rj   r   rc   r  rH   r   r    r_   r
   rr   r   r   
c_ptr_typerm   r   ZDictIterationNextNoderx   ry   r\   
StringNoder   formatNullNoders   r   r   PyDict_Iterator_func_typer   r   r   r   WhileStatNodera   rw   )r8   r"   r   r   r   r   rf   r  Z	dict_temppos_tempZ
key_targetvalue_targetZtuple_targetr_   Zdict_len_tempZdict_len_temp_addrZis_dict_tempZis_dict_temp_addriter_next_nodeZmethod_noder-  result_coder   r&   r   r   n  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u |	|gdddt
j jd | jdg}t j  j|t
j j|ddS )Nr#  r   r   c                    s"   | rdp
d} t j jt| | dS r+  r,  rV   r&   r   r   r-    s    z>IterationTransform._transform_set_iteration.<locals>.flag_noder   r  rX   Z__Pyx_set_iteratorZset_iterr   Tr.  r/  r[   re   )!r   ro   r   r0  r9   rp   rj   r   r    r_   r
   rr   r   r   r1  rm   r   rc   ZSetIterationNextNoderx   ry   r\   rs   r   r   PySet_Iterator_func_typer   r   r   r   r6  ra   rw   )r8   r"   set_objrf   r  Zset_tempr7  r_   Zset_len_tempZset_len_temp_addrZis_set_tempZis_set_temp_addrr8  r9  r-  r:  r   r&   r   r     s    







z+IterationTransform._transform_set_iteration)F)F)F)F)F)%rB   rC   rD   rE   r   r   r   r   r   	CFuncTypeZc_char_ptr_typeCFuncTypeArgr   r   r   r   r   r   r  r   r   r   r0  r   r   r   r   r   r   r   r  r   r  r   r5  r>  r   r   r   r   r   rQ      st   1
r
&	
\
 %I
S@c	rQ   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 u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 ur`||kr`t||r`|rR|r`||||	 fS | jS )	Nrg   rR   F!=Tr   orand)r    r   CoerceToTempNodeZCoerceToBooleanNoder!   ZBoolBinopResultNoder   EvalWithTempExprNodesubexpressionTypecastNoderi   rq   cascadeNO_MATCHZis_c_string_containsrU   UnicodeNoder   rS   Zcontains_surrogatesrT   extract_in_string_conditionsZis_python_comparisonr,   r   getattrr   Zis_constBoolBinopNodeextract_conditions)
r8   condallow_not_inrg   Znot_in_1t1Zc1Znot_in_2t2c2r   r   r   rP  2  sl    






 z"SwitchTransform.extract_conditionsc                    s   t tjr:ttttj}|  fdd|D S j t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  r,  rL   Zcharvalstring_literalr   r   rO   s  s   z@SwitchTransform.extract_in_string_conditions.<locals>.<listcomp>c                    s   g | ]} ||d   qS )r   r   )rL   i)
charactersr   r   rO   {      c                    s   g | ]}t j j||d qS rV  )r   CharNoderj   rW  rX  r   r   rO   }  s   
)r    r   rL  listmapordr<  rW   sortr   rH   )r8   rY  Zcharvalsr   )r[  rY  r   rM  o  s    
"
z,SwitchTransform.extract_in_string_conditionsc                 C   sj   |  ||\}}}|d u r | jS |d u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   )rm   r   r   )rL   rQ  r   r   r   rO     r\  z=SwitchTransform.extract_common_conditions.<locals>.<listcomp>)rP  rK  r,   rm   r   r   sum)r8   
common_varr^   rR  rg   var
conditionsr   r   r   extract_common_conditions  s    "z)SwitchTransform.extract_common_conditionsc              	   C   sx   t  }|D ]h}| r4|j|v r& dS ||j q
z|jj|v rJW  dS W n tyb   Y  dS 0 ||jj q
dS )NTF)r<  r   r1   addr   cnameAttributeError)r8   condition_valuesseenrW   r   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 u 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rj   re  r_   c                 S   s   g | ]}|j D ]}|qqS r   )re  )rL   caserQ  r   r   r   rO     s   z4SwitchTransform.visit_IfStatNode.<locals>.<listcomp>r  ra   r_   rj   testcasesra   )current_directivesgetr:   r`   rf  r^   r9   r
   SwitchCaseNoderj   r_   rH   rl  r'   SwitchStatNodera   )
r8   r"   rc  rr  	if_clause_re  rj  ro  switch_noder   r   r   visit_IfStatNode  sF    







z SwitchTransform.visit_IfStatNodec                 C   st   | j ds| | |S | d |jd\}}}|d u sNt|dk sN| |r\| | |S | |||||j|j	S )Nrm  Tr  )
rs  rt  r:   rf  rq  rH   rl  build_simple_switch_statementtrue_val	false_valr8   r"   rg   rc  re  r   r   r   visit_CondExprNode  s"    



z"SwitchTransform.visit_CondExprNodec                 C   s   | j ds| | |S | d |d\}}}|d u sLt|dk sL| |rh| | ||   |S | ||||t	j
|jdddt	j
|jdddS Nrm  Tr  r  F)rs  rt  r:   rf  rH   rl  wrap_operandsry   r{  r   rt   rj   r~  r   r   r   visit_BoolBinopNode  s&    



z#SwitchTransform.visit_BoolBinopNodec                 C   s   | j ds| | |S | d |d\}}}|d u sLt|dk sL| |rZ| | |S | ||||tj|j	dddtj|j	dddS r  )
rs  rt  r:   rf  rH   rl  r{  r   rt   rj   r~  r   r   r   r     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rY   rZ   firstrn  rp  )r   r$   r
   rs   rj   r   rm   ry   ru  r'   rv  r{   )r8   r"   rc  re  rg   r|  r}  r}   Z	true_bodyZ
false_bodyrr  ry  replacementr   r   r   r{    s6    

z-SwitchTransform.build_simple_switch_statementc                 C   sR   | j ds| | |S |j}|j}| | |j|urNt|j|sN|jS |S )Nrm  )rs  rt  r:   rH  Z	lazy_tempr   Ztree_contains)r8   r"   Z	orig_exprZtemp_refr   r   r   visit_EvalWithTempExprNode  s    


z*SwitchTransform.visit_EvalWithTempExprNodeN)rB   rC   rD   rE   rK  rP  rM  rf  rl  rz  r  r  r   r{  r  r   VisitorTransformrecurse_to_childrenrF   r   r   r   r   rB  *  s   =
&rB  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              	      sb  |   jd u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	}t
|dkrxS tdd	 |D rS tj}g }g }|D ]p}z| }W n ty   d
}Y n0 |st|}|| tjj|||d d}	|tjj|	tjd q fdd}
t|
|}t||}|d d d D ]}t||}qJ|S )NinrD  rR   rg   rE  rC  r   c                 S   s   g | ]
}|j qS r   )
is_starred)rL   r!   r   r   r   rO   F  r\  z?FlattenInListTransform.visit_PrimaryCmpNode.<locals>.<listcomp>F)rj   rT   rS   rU   rJ  )rj   ri   rm   c                    s   t jj | |dS )N)rj   rS   rT   rU   )r   rO  rj   )leftrightZconjunctionr"   r   r   concate  s    z;FlattenInListTransform.visit_PrimaryCmpNode.<locals>.concatr  )r:   rJ  rS   r    rU   r   	TupleNodeListNodeSetNoder   rH   anyr   r$   rT   	is_simple	Exceptionr   r9   rq   rj   rI  r   c_bint_typer   rG  )r8   r"   Z	eq_or_neqr   rY   Zcondsrf   r!   Zis_simple_argrQ  r  r^   r   r  r   r  r   r   /  sb    









z+FlattenInListTransform.visit_PrimaryCmpNodeN)	rB   rC   rD   rE   r   r   r  r  rF   r   r   r   r   r  )  s   Cr  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 ]\}}||v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   rL   pathnr   r   r   rO     r\  zIDropRefcountingTransform.visit_ParallelAssignmentNode.<locals>.<listcomp>c                 S   s   g | ]\}}|qS r   r   r  r   r   r   rO     r\  c                 S   s   g | ]
}|j qS r   r!   )rL   tr   r   r   rO     r\  F)r\   r    r
   rs   _extract_operandrY   rZ   ZCascadedAssignmentNoder<  rH   _extract_index_idr9   Zuse_managed_ref)r8   r"   Z
left_namesZright_namesZleft_indicesZright_indicesrf   statZlnamesZrnamesZlindicesZlhs_nodeZindex_idZrindicesZrhs_nodeZ	temp_argsr  rx  	name_node
index_noder   r   r   visit_ParallelAssignmentNodez  sd    













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'   rm   r   r    r   rF  r9   r!   r   r+   memberr-   r   r   joinrk   rl   r   r   r   r   )r8   r"   namesindicesrf   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   )rl   r   r    r   r)   r   Z	ConstNode)r8   r  rl   r   Z	index_valr   r   r   r    s    z*DropRefcountingTransform._extract_index_idN)rB   rC   rD   rE   r   r  r  rF   r  r  r  r   r   r   r   r  u  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   )r8   r"   r   r   r   r   visit_SimpleCallNode  s
    

z-EarlyReplaceBuiltinCalls.visit_SimpleCallNodec                 C   sL   |  | |j}| |s|S |j}t|tjs4|S |j}| ||||j	S r   )
r:   r   r  Zpositional_argsr    r   r  r   r  keyword_args)r8   r"   r   r   r   r   r   r   visit_GeneralCallNode  s    


z.EarlyReplaceBuiltinCalls.visit_GeneralCallNodec                 C   s:   |j s
dS |  }||j}|| |jur6dS dS )NFT)r   ry   lookupr   Zbuiltin_scopeZlookup_here)r8   r   envr   r   r   r   r    s    z2EarlyReplaceBuiltinCalls._function_is_builtin_nameNc                 C   sT   |d u rd|j  }n
d|j  }t| |d }|d urP|d u rD|||S ||||S |S )Nz_handle_simple_function_%sz_handle_general_function_%s)r   rN  )r8   r"   r   r   kwargsZhandler_nameZhandle_callr   r   r   r    s    

z-EarlyReplaceBuiltinCalls._dispatch_to_handlerc                 C   s"   t j|jj|jj|||d|_d S )Nr   )r   ZPythonCapiFunctionNoder   rj   r   )r8   r"   rh  	func_typer   r   r   r   _inject_capi_function"  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 u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   rj   rH   r8   function_namer"   r   expectedZarg_strZexpected_strr   r   r   _error_wrong_arg_count'  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v rX|d S |S )N0.0rV   r   floatr   rm   )
r   	FloatNoderj   rH   r  rN  r   c_double_typer   
float_type)r8   r"   pos_argsarg_typer   r   r   _handle_simple_function_float9  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   )rH   r  r   r  rj   NoneNode)r8   r"   r  r   r   r   r   r   r   r   _handle_simple_function_sliceC  s     
z6EarlyReplaceBuiltinCalls._handle_simple_function_slicec                 C   s   t |dkr|S |d }t|tjtjfr`t |jdkrtj|jtj	t
t|jt|jdS nTt|tjr|jrt |jdkrt|jdkrtj|jtjt
t|jt|jdS |S )zUnpack ord('X').
        r   r   r      )rH   r    r   rL  r   rW   r   rj   r   c_long_typer   r`  r2  unicode_valuer   )r8   r"   r  r!   r   r   r   _handle_simple_function_ordU  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r8   r"   r  r   r   r   _handle_simple_function_alln  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 u 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   rh   r  rV   r]   )ra   r`   r  all)gen	orig_func)rH   r    r   GeneratorExpressionNodeZdef_nodeZgbodyr_   rK   r|   rj   r
   ru   rv   ZReturnStatNodert   ra   r   recursively_replace_nodeInlinedGeneratorExpressionNode)r8   r"   r  Zis_anygen_expr_nodeZgenerator_bodyr   yield_expressionyield_stat_noder^   	test_noder   r   r   r    sB    
z+EarlyReplaceBuiltinCalls._transform_any_allitc                 C   sf  t |dkr|S |d }t|tjr@|jtju r@|d }|j}nt|tjr|}|j}t	|}|sf|S tj
|j|dtjd}|D ]*\}}	tj|j||jd}
t||	|
 qn0|jr|  }}ntj|jd| j|dd }}tj|jtjd	d
}tj|j||dd}tj|j|tdd	d}tj|jtj|j|g dd}||   t|tj|j||gd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r=   rc   PySequence_ListTr   F)rj   rm   Zmay_hold_noner  ra  )r-   r.   Zneeds_none_checkr   r   r   r[   ) rH   r    r   ComprehensionNoderm   r   r   loopr  rG   r  rj   ComprehensionAppendNoderc   r   r  r  Zas_listr   PySequence_List_func_typer   r$   r
   rs   r*   r   r   r   Zanalyse_declarationsry   r{   rr   )r8   r"   r  r!   Z	list_noder   r  rJ   r  r  append_noderesult_nodeZlist_assign_nodeZsort_methodZ	sort_noder   r   r   _handle_simple_function_sorted  sb    



z7EarlyReplaceBuiltinCalls._handle_simple_function_sortedc              	   C   sR  t |dvr|S t|d tjtjfs*|S |d }|j}t|tjrbt|\}}d}|du r|S n<|j}|j}z|j	r~|j
js|W S W n ty   | Y S 0 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  )rj   rm   r  rX   )rj   r%   Tr  r[   rb  )r  r  
expr_scoper  has_local_scope)rH   r    r   r  r  r  rK   r9   r=   r   rm   r   ri  r   rj   r   r$   r   r0  r
   rs   r!  r   r  rr   r  r  r  )r8   r"   r  r  r   r  r  r   r}   add_nodeZ	exec_coder   r   r   Z__handle_simple_function_sum  s\    

z5EarlyReplaceBuiltinCalls.__handle_simple_function_sumc                 C   s   |  ||dS )Nr   _optimise_min_maxr  r   r   r   _handle_simple_function_min0  s    z4EarlyReplaceBuiltinCalls._handle_simple_function_minc                 C   s   |  ||dS )Nr   r  r  r   r   r   _handle_simple_function_max3  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)rT   rS   rU   )r|  r}  rq  r  )rH   r  r   r^  r_  r   r$   r   ZCondExprNoderj   rq   rG  )	r8   r"   r   rS   Zcascaded_nodesZlast_resultZarg_noder}   Zref_noder   r   r   r  6  s0    

z*EarlyReplaceBuiltinCalls._optimise_min_maxc                 C   sB   |st j|jg ddS | ||tj}||ur>t j|j|dS |S )Nr   r   r1   r  )r   r  rj   _transform_list_set_genexprr   r   AsTupleNode)r8   r"   r  resultr   r   r   &_DISABLED_handle_simple_function_tupleY  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   )rH   r  r   r    r   r  as_tupler  r   r   r   !_handle_simple_function_frozenseth  s    z:EarlyReplaceBuiltinCalls._handle_simple_function_frozensetc                 C   s&   |st j|jg g dS | ||tjS Nr  )r   r  rj   r  r   r   r  r   r   r   _handle_simple_function_lists  s    z5EarlyReplaceBuiltinCalls._handle_simple_function_listc                 C   s(   |st j|jg t dS | ||tjS r  )r   r  rj   r<  r  r   r   r  r   r   r   _handle_simple_function_setx  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	u 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   r<  r^  r  r  )rH   r    r   r  r  rG   r  rj   r   r   r  rc   r   r  )r8   r"   r  r   r  r   rJ   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_pairsr1   r   r  r   r  )Zkey_exprZ
value_exprrc   )rH   r   DictNoderj   r    r  r  rG   r  r   r  r   r   ZDictComprehensionAppendNoderc   r   r  )r8   r"   r  r  r   rJ   r  rx  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   )rH   r    r   r  )r8   r"   r  r  r   r   r   _handle_general_function_dict  s
    z6EarlyReplaceBuiltinCalls._handle_general_function_dict)N)N)N)'rB   rC   rD   rE   r   r  r  rF   r  r  r  r  r  r  r  r  r  r  r  r  r   r@  r   r   rA  r0  r  r  Z5_EarlyReplaceBuiltinCalls__handle_simple_function_sumr  r  r  r  r  r  r  r  r  r  r   r   r   r   r    s<   




$@:#&r  c                   @   s$   e Zd ZejjZdd Zdd ZdS )InlineDefNodeCallsc                 C   sR   |j d u 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_nullry   r  r   cf_assignmentsrH   rZ   )r8   r  r   r   r   r   get_constant_value_node  s    

z*InlineDefNodeCalls.get_constant_value_nodec                 C   sr   |  | | jds|S |j}|js*|S | |}t|tjsD|S tj	|j
|||jd}| rn| ||S |S )Nzoptimize.inline_defnode_calls)r  r   r   )r:   rs  rt  r   r   r  r    r   PyCFunctionNodeZInlinedDefNodeCallNoderj   r   Zcan_be_inlinedreplace)r8   r"   r  r   Zinlinedr   r   r   r    s     

z'InlineDefNodeCalls.visit_SimpleCallNodeN)	rB   rC   rD   r   r  r  rF   r  r  r   r   r   r   r    s   r  c                   @   s
  e Zd ZdZdd Zdd Zdd 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edd ejejejf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"d'd( Z#e	ej$ed)ej$dgZ%d*d+ Z&e	ej'ed,ej
dgZ(d-d. Z)e	ej*ed/ej'dgZ+d0d1 Z,e	ej-ed,ej
dgZ.d2d3 Z/e	ej0ed,ej
dgZ1d4d5 Z2ej	ejed$ej
dgd6ddZ3d7d8 Z4e	ej
ed
ej
dgZ5e	ej
ed9ejdgZ6d:d; Z7d<d= Z8e	ej9edej:dgZ;e	ej9ed>ej<dgZ=ej	ejed$ej
dgd?d@Z>ej dAejdBej?dCej'dDej*dEej-dFej0dFej$dGij@ZAeBdHgZCdIdJ ZDe	ejEedKej
dgZFdLdM ZGe	ejHedNej
dgZIdOdP ZJdQdR ZKe	ej
edSej
dedTej*dgZLe	ej
edSej
dedTej*dedUej$dgZMddVdWZNej	ejOed/ej
dedXej
dgd?d@ZPdYdZ ZQd[d\ ZRej	ejOed]ej
ded9ejdgd?d@ZSej	ejOed]ej
ded9ej
dgd?d@ZTd^d_ ZUe	ej
ed/ej
dgZVej	ej
ed/ej
ded`ej
dedaejdedbejdgddcZWddde ZXddgdhZYej	ejOed$ej
dgd?d@ZZdidj Z[e	ej
ed)ej
dedkej
dedlej
dgZ\dmdn Z]e	ej
ed)ej
dedkej
dedlej
dedoejdgZ^dpdq Z_e	ej
ed)ej
dedkej
dedlej
dgZ`drds Zaedtd ejbejfD Zcdudv Zddwdx Zedydz Zfd{d| Zgd}d~ Zhdd Zidd Zjdd Zkdd Zldd Zmdd Zndd Zodd Zpdd Zqdd Zrdd Zsdd Ztdd Zudd Zvdd Zwdd Zxdd Zye	ejHedejzdgZ{dd Z|e|Z}e|Z~e|Ze|Ze|Ze|Ze|Ze|Ze|Ze	ejzedejzdgZdd ZeZeZeZe	ej'edej dedejHd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jHe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j:dedej:dgZe	ejed$ej dgZg dʢZdd̄ eD Zdd΄ Zee	ej edej:dedejdedej:dgZe	ej edej:dedejdedejdedej:dedej:dededgZe	ej edej
dedejdedejdedej:dedej:dededgZdZddԄ ZeZddք Zdd؄ Zddڄ Zdd܄ Zddބ Zdd Zdd Zdddejjdfdd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:   rm   ri   r;   r   r   r   _visit_TypecastNode  s    
z(OptimizeBuiltinCalls._visit_TypecastNodec                 C   sd   |  | t|jtjr"|jj|_|j}|du 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    r=   r   CoerceToPyTypeNoder!   Zis_noner   r   r   is_localZis_arg)r8   r"   r=   r   r   r   r>     s    

z'OptimizeBuiltinCalls.visit_ExprStatNodec                 C   sT   |  | |j}t|tjr"|j}t|tjrP|jtjt	j
fv rP|j|  S |S )z<Drop redundant conversion nodes after tree changes.
        )r:   r!   r    r   PyTypeTestNoder  rm   r   r0  r   	bool_typecoerce_to_booleanry   r8   r"   r!   r   r   r   visit_CoerceToBooleanNode  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u rh|dS |j
jrtj|jd| j|gd|j|jd|j
|  S |S )z3Drop redundant conversion nodes after tree changes.r  r   r   z=float() argument must be a string or a number, not 'NoneType'Z__Pyx_PyNumber_Float)r   py_namer   r   )r:   r!   r    r   CoerceFromPyTypeNoder   r   r   rH   r   rm   r   r  r   r   rj   PyNumber_Float_func_typer   r   r   ry   )r8   r"   r!   func_argr   r   r   visit_CoerceToPyTypeNode(  s(    




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u r|j|jjr|j|j|  S n8|jtju 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!   rm   r   r   ry   r    r   r  r   r   r   is_floatr  rt   r  r   r0  r  r   r   is_unicode_charr   _optimise_numeric_cast_callrk   r   _optimise_int_indexing)r8   r"   r!   r  r   r   r   visit_CoerceFromPyTypeNode>  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u r|jtjtjfv rt	j
|jt||d}t	j|jd| j|jd|tj||gdtdd	d
}|jtjur||j|}|S |S )NZboundscheckr   r   r  Z__Pyx_PyBytes_GetItemIntz&'NoneType' object is not subscriptableTZbytes_indexStringTools.cr   r   r   )ry   Z
directivesrl   rm   r   r   r   c_char_typeZc_uchar_typer   r   rj   r   r   PyBytes_GetItemInt_func_typer   r   r   r   r   )r8   Zcoerce_noder!   r  r  Zbound_check_boolZbound_check_noder"   r   r   r   r  o  s0    

z+OptimizeBuiltinCalls._optimise_int_indexingc              
   c   s*   | ]"}|t |t d |dgfV  qdS )r!   N)r   r@  rA  )rL   r  r   r   r   	<genexpr>  s   zOptimizeBuiltinCalls.<genexpr>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 u s\t
|dkr`|S |d }t|tjr||j}n|jjr|S |jdkrL|jjs|jjr|j|jkr|S |j|js|jjrt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sl|jjr|j|jkr~|S |j|js|jjrtj|j||jdS |S )
Nr   r   intr   lZ__Pyx_truncltrunc)r  r   r  r   r   r  )r   r    r   r   r   r)   rm   is_builtin_typer   r  rH   r  r!   r   r   r   r  r  rI  rj   
is_numericZmath_h_modifierfloat_float_func_typesr   r   r   ry   )r8   r"   r!   r   r   r  Ztrunclr   r   r   r    sV    


z0OptimizeBuiltinCalls._optimise_numeric_cast_callc                 C   sj   |s
d}n*t |ts|dkr"d}n|dkr0d}nd}|d u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   )r8   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u r| |||||S |j}
|
du 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   rm   T)r-   r.   Z	is_calledNr  )r   r-   r   ry   r  r   r*   r   rj   r)   rm   Zanalyse_as_type_attribute%_optimise_generic_builtin_method_callr   r   r   r8   Zanalyse_c_function_callZanalysedr   )r8   r"   	type_name	attr_namer   r#  is_unbound_methodr  
type_entryr   r   	call_noder   r   r   _handle_method  sJ    	
z#OptimizeBuiltinCalls._handle_methodc                 C   sV   t |}|s |dks |jr |js$|S |jjjs2|S |jjjdv 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   )r   rm   )	rH   r   r+   r-   rm   r   r   r   ZCachedBuiltinMethodCallNode)r8   r"   r'  r   r#  r(  r   r   r   r   r%    s    

z:OptimizeBuiltinCalls._optimise_generic_builtin_method_callr-   c              	   C   s   t |dkr0t |dkr,tj|jt ddS |S |d }|jtju rb| sP|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   r'  r  Z__Pyx_PyUnicode_UnicodeZPyUnicode_Unicoder  Z__Pyx_PyObject_UnicodeZPyObject_Unicodeunicoder   r   r   r  )rH   r   rL  rj   r   rm   r   r   may_be_noner   r   r   PyObject_Unicode_func_typer   )r8   r"   r   r  r!   rh  r   r   r   r   _handle_simple_function_unicode	  s&    
z4OptimizeBuiltinCalls._handle_simple_function_unicodec                 C   sJ   |  | |jjtju 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:   rW   rm   r   r   Zc_format_specformat_specconversion_charr0  r;   r   r   r   visit_FormattedValueNode+	  s
    
z-OptimizeBuiltinCalls.visit_FormattedValueNoder   c                 C   sN   t |dkr|S |d }|jtju 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   )
rH   rm   r   r   r   r   r   rj   PyDict_Copy_func_typer   r8   r"   r   r  r!   r   r   r   r  <	  s    

z1OptimizeBuiltinCalls._handle_simple_function_dictr  c                 C   s2   t |dkr|S |d }tj|jd| j||jdS )z0Turn list(ob) into PySequence_List(ob).
        r   r   r  r   )rH   r   r   rj   r  r   r5  r   r   r   r  O	  s    
z1OptimizeBuiltinCalls._handle_simple_function_listr^  c                 C   s   t |dks|js|S |d }|jtju r6| s6|S |jtju rj|d|d< tj	|j
d| j||jdS tj|j
|tjdS dS )zDReplace tuple([...]) by PyList_AsTuple or PySequence_Tuple.
        r   r   r   ZPyList_AsTupler   )r!   rm   N)rH   r   rm   r   r   r.  r   r   r   r   rj   PyList_AsTuple_func_typer  r5  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_Newr<  r   r   r  )rH   r  r   r  r   r   r9   r   r  rj   r  rG  r   PySet_New_func_typer   )	r8   r"   r   r  r   rf   r!   r  r  r   r   r   r  u	  s,    



z0OptimizeBuiltinCalls._handle_simple_function_setc              
   C   sn   |st |jg}n4t|dkr$|S |d jtju rH|d  sH|d S t j|jd| j	||j
tddddS )Nr   r   Z__Pyx_PyFrozenSet_NewZpyfrozenset_newz
Builtins.c	frozensetr-  )r   r4  rj   rH   rm   r   r   r.  r   PyFrozenSet_New_func_typer   r   r   r8   r"   r   r  r   r   r   r  	  s    
z6OptimizeBuiltinCalls._handle_simple_function_frozensetz((double)-1)c              	   C   s   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u rt|S |j|js|jjrtj|j||jdS tj|jd	| j||jt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   Z__Pyx_PyObject_AsDoubleZpyobject_as_doubler-  )rH   r   r  r   r   r  ry   r  r    r  r!   rm   r   r  r  r!  rI  rj   r   PyObject_AsDouble_func_typer   r   r8   r"   r   r  r  r   r   r   r  	  s4    

z2OptimizeBuiltinCalls._handle_simple_function_floatrW   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r||jj	j
rxtj|jd| j|jgddt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__Pyx_PyInt_FromDoubleTr  ZPyIntFromDoublezTypeConversion.c)r   r   r  r   Z__Pyx_PyNumber_Intr8  )rH   r   r   rj   r   r0  r    r  r!   rm   r  r   PyInt_FromDouble_func_typer   r   r   PyNumber_Int_func_typer?  r   r   r   _handle_simple_function_int	  s*    




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   boolr=  rh   N)rH   r   rt   rj   r   r   r  ry   r  r	  r|   coerce_to_pyobject)r8   r"   r   r  ri   r   r   r   _handle_simple_function_bool	  s    
z1OptimizeBuiltinCalls._handle_simple_function_boolr,  r   r   Z__Pyx_PyUnicode_GET_LENGTHr   ZPyByteArray_GET_SIZEZPyList_GET_SIZEZPyTuple_GET_SIZEZ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rltj|j	d| j
|g|jtddd}n|jjrtj|j	d| j|g|j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u r&|j}|js|jr"|jj| jv 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v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   rH   r   strlenIncludeStringHr  r  Z__Pyx_Py_UNICODE_strlenr   ZmemoryviewsliceNT)ZnogilZ__Pyx_MemoryView_LenZPy_SIZEz&object of type 'NoneType' has no len()r  r   )#rH   r  r    r   r  r!   rm   r  r   rj   Pyx_strlen_func_typer   r   r   Zis_pyunicode_ptrPyx_Py_UNICODE_strlen_func_typeZis_memoryviewslicer   r@  c_size_t_typerA  r   _map_to_capi_len_functionis_extension_typer   r   r   _ext_types_with_pysizer   PyObject_Size_func_typer  r   r   r   ry   )	r8   r"   r   r  r!   r   r  Z
cfunc_namer  r   r   r   _handle_simple_function_len
  sl    







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   )rH   r   r   rj   Pyx_Type_func_typer  r   r0  r<  r   r   r   _handle_simple_function_typeX
  s    
z1OptimizeBuiltinCalls._handle_simple_function_typer!   c              
      s  t |dkrS |\}}g }t|tjrr|j}t |dkrN|d jtjurNS |js\|	 st
|}|| n|jtju r|g}nS g }g }|   |D ]}	d}
|	jr|	jr؈ |	jj}|r|jr|jjr|j}
|
tju r|jdks|jr|jjsd}
|
dur4|jjdd}||v r"q|| |g}nD|	jtju 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   Nrm   F)exactZ__Pyx_TypeCheckZPyObject_IsInstanceTr   c                    s&   |j d| |}tj|_|  |S )NrD  )rj   r   r  rm   r  )r/   r0   Zmake_binop_nodeZor_noder  r"   r   r   join_with_or
  s    
zMOptimizeBuiltinCalls._handle_simple_function_isinstance.<locals>.join_with_orr  )rH   r    r   r  r   rm   r   	type_typer   r  r   r$   r9   ry   r   r   r  r   r   scopeZis_builtin_scopetype_check_functionr   r   rj   Py_type_check_func_typer!  r   r   rG  )r8   r"   r   r  r!   typesrf   testsZ
test_nodesZtest_type_nodeZbuiltin_typer   rX  Ztype_check_argsrU  r  r  r   rT  r   "_handle_simple_function_isinstanceh
  sr    









z7OptimizeBuiltinCalls._handle_simple_function_isinstancec                 C   s  t |dkr|S |d }t|tjrT|jjjrRtj|j|jt	j
d|j|  S nt|tjrt |jdkrtj|jt	jtt|jt|jd|j|  S njt|tjr|jrt |jdkrt|jdkrt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   r  )rH   r    r   r  r!   rm   r  rI  rj   r   r  r   ry   rL  rW   r   r   r   r`  r2  r  r5  r   r   r   r  
  s>    



z0OptimizeBuiltinCalls._handle_simple_function_ordrm   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__PyTypeObjectrm   r   r  rm   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)%r-   rH   r   rm   r   rV  r)  r   r   r  rj   analyse_typesry   rL  Ztypeobj_cnamerW  r   r   ZConstructorSlotZget_slot_functionr   cython_scoper   CPtrTyper  r@  rA  r0  r  r4  r   r   r   r   Pyx_tp_new_kwargs_func_typer   Pyx_tp_new_func_type)r8   r"   r   r   r(  r  r-   type_argZ
args_tupleZext_typeZtp_slotZslot_func_cnamerc  PyTypeObjectPtrZpyx_tp_new_kwargs_func_typer   r   r   r   _handle_any_slot__new__
  s~    


z,OptimizeBuiltinCalls._handle_any_slot__new__r  c              
   C   s:   t |dks|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_AppendFr9   )r   ra  r   r   r   )rH   r   r   r   rj   PyObject_Append_func_typer   r   r8   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u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|_|
|u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   Tr]  extendr  Z__Pyx_PyList_AppendZ
ListAppendr  |Z__Pyx_ListComp_AppendZListCompAppend)r   r  r   r   r`  )rH   r  r^  r   mult_factorr    r   r  r  rb  ry   r   r  _wrap_self_argr   r  r   r   r9   r   rj   rj  r   r!  r   c_returncode_typerG  )r8   r"   r   r   r(  r-   rW   r   Z
tuple_nodeZwrapped_objZ
cloned_objrf   r!   r   r  r   r   r   !_handle_simple_method_list_extend;  sf    












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   ra  r   r   )rH   PyByteArray_Append_func_typer#   rm   r   r    r   r   r   r   r   ry   r   r   is_string_literalZcan_coerce_to_char_literalr  r   "PyByteArray_AppendObject_func_typer   rj   r   r   )
r8   r"   r   r   r(  	func_namer  rW   r   r   r   r   r   &_handle_simple_method_bytearray_append  s8    
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_poprk  r   r   r   _handle_simple_method_list_pop  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_PopTrv  r  ZintvalNz__Pyx_Py%s_PopIndexr   Z	pop_index)#r   rH   r   r   rj   PyObject_Pop_func_typer   r   r#   r  rm   r   r    r   rD  ry   r   r   r   r   r  r
  Znumeric_type_fitsZcreate_to_py_utility_codeZto_py_functionr@  r0  rA  PyObject_PopIndex_func_typer   signedr   RawCNameExprNodeZc_void_typeZempty_declaration_code)r8   r"   r   r   r(  r~  r-   r&  r   r|  Zorig_index_typeZconvert_funcZconversion_typer   r   r   r    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_Sortra  )rH   _substitute_method_callsingle_param_func_typer   rm   ry   rk  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_GetItemDefaultrt  TZdict_getitem_defaultra  r   )	rH   r9   r   r  rj   r  r  Pyx_PyDict_GetItem_func_typer   rk  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v }n|t
ju 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  )rH   r9   r   r  rj   r  rm   r   r  r   r   r0  r   r   r  Pyx_PyDict_SetDefault_func_typer   )r8   r"   r   r   r(  Zkey_typer  r   r   r   %_handle_simple_method_dict_setdefault-  s.    

z:OptimizeBuiltinCalls._handle_simple_method_dict_setdefaultc                 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 )
z7Replace dict.pop() by a call to _PyDict_Pop().
        r  r   zdict.popr  Z__Pyx_PyDict_Popr  TZpy_dict_popr  )	rH   r9   r   r4  rj   r  r  PyDict_Pop_func_typer   rk  r   r   r   _handle_simple_method_dict_popN  s    z3OptimizeBuiltinCalls._handle_simple_method_dict_popc                 c   s   | ]}t jt jfD ]n}||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rrdn|jdfV  qqdS )Zop1NZop2cvalinplaceZzerodiv_checkr   )r   r0  r  r@  rA  r   r   )rL   ctyperet_typer   r   r   r  ^  s   	
c                 C   s   |  d||||S NAdd_optimise_num_binoprk  r   r   r   $_handle_simple_method_object___add__k  s    z9OptimizeBuiltinCalls._handle_simple_method_object___add__c                 C   s   |  d||||S NSubtractr  rk  r   r   r   $_handle_simple_method_object___sub__n  s    z9OptimizeBuiltinCalls._handle_simple_method_object___sub__c                 C   s   |  d||||S NEqr  rk  r   r   r   #_handle_simple_method_object___eq__q  s    z8OptimizeBuiltinCalls._handle_simple_method_object___eq__c                 C   s   |  d||||S NNer  rk  r   r   r   #_handle_simple_method_object___ne__t  s    z8OptimizeBuiltinCalls._handle_simple_method_object___ne__c                 C   s   |  d||||S )NAndr  rk  r   r   r   $_handle_simple_method_object___and__w  s    z9OptimizeBuiltinCalls._handle_simple_method_object___and__c                 C   s   |  d||||S )NOrr  rk  r   r   r   #_handle_simple_method_object___or__z  s    z8OptimizeBuiltinCalls._handle_simple_method_object___or__c                 C   s   |  d||||S )NZXorr  rk  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rH   r    r   r   r   r1   r  rk  r   r   r   '_handle_simple_method_object___rshift__  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  rk  r   r   r   '_handle_simple_method_object___lshift__  s
    (z<OptimizeBuiltinCalls._handle_simple_method_object___lshift__c                 C   s   |  d||||S N	Remainder_optimise_num_divrk  r   r   r   $_handle_simple_method_object___mod__  s    z9OptimizeBuiltinCalls._handle_simple_method_object___mod__c                 C   s   |  d||||S )NFloorDivider  rk  r   r   r   )_handle_simple_method_object___floordiv__  s    z>OptimizeBuiltinCalls._handle_simple_method_object___floordiv__c                 C   s   |  d||||S N
TrueDivider  rk  r   r   r   (_handle_simple_method_object___truediv__  s    z=OptimizeBuiltinCalls._handle_simple_method_object___truediv__c                 C   s   |  d||||S NDivider  rk  r   r   r   $_handle_simple_method_object___div__  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          )rH   r   r1   r    r   r   r  r  )r8   rS   r"   r   r   r(  r   r   r   r    s    &z&OptimizeBuiltinCalls._optimise_num_divc                 C   s   |  d||||S r  r  rk  r   r   r   #_handle_simple_method_float___add__  s    z8OptimizeBuiltinCalls._handle_simple_method_float___add__c                 C   s   |  d||||S r  r  rk  r   r   r   #_handle_simple_method_float___sub__  s    z8OptimizeBuiltinCalls._handle_simple_method_float___sub__c                 C   s   |  d||||S r  r  rk  r   r   r   '_handle_simple_method_float___truediv__  s    z<OptimizeBuiltinCalls._handle_simple_method_float___truediv__c                 C   s   |  d||||S r  r  rk  r   r   r   #_handle_simple_method_float___div__  s    z8OptimizeBuiltinCalls._handle_simple_method_float___div__c                 C   s   |  d||||S r  r  rk  r   r   r   #_handle_simple_method_float___mod__  s    z8OptimizeBuiltinCalls._handle_simple_method_float___mod__c                 C   s   |  d||||S r  r  rk  r   r   r   "_handle_simple_method_float___eq__  s    z7OptimizeBuiltinCalls._handle_simple_method_float___eq__c                 C   s   |  d||||S r  r  rk  r   r   r   "_handle_simple_method_float___ne__  s    z7OptimizeBuiltinCalls._handle_simple_method_float___ne__c                 C   s  t |dkr|S |jjr tj}n |jtju r<|dv r<tj}n|S tjtjf}t	|d |r||d jtjurn|S |d }d}	n4t	|d |r|d jtjur|S |d }d}	n|S |
 s|S t	|tj}
|
rtjntj}|
r|dvr|S n |dkr|S t|jd	kr
|S |d
v r(|d jdkr(|S t|}||
r@tjntj|j|j|j|d t	|tjrn|jnd}|tj|j||d |
s|dvr|	dkot	|tjr|j nd}|tj|j||d tj|
rdn|dv rdnddt||	|dd}| j||d|
rdnd|jr*dnd||	f | 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.
        r  )r  r  r   r   ZObjCZCObj)r  r  r  r  r  r  r  r  r   )r  r  r  r  r   Fr  ZPyFloatBinopZPyIntCompareZ
PyIntBinopr   )oporderr  )r   z__Pyx_Py%s_%s%s%sZFloatZIntr'  ZBoolz__%s__Nr   T)ra  with_none_checkr   ) rH   rm   r   r   r0  r  r   r   r  r    r   r  r  r  r1   r^  r9   rj   rW   ZNumBinopNoder  rt   r"  Z	cdivisionr   r   r   r  Pyx_BinopInt_func_typeslowerr  ry   )r8   rS   r"   r   r   r(  r  Z	num_nodesZnumvalZ	arg_orderr  Znum_typer  Zzerodivision_checkr   r*  r   r   r   r    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}|dkr\t	dd}d}	nd }d|
  }	| j|||	| j|||g|d}
|jjr|
| j}
|
S )	Nr   r   istitleZpy_unicode_istitler  Z__Pyx_Py_UNICODE_ISTITLEzPy_UNICODE_%sr  )rH   r    r   r  r!   rm   r  r.   r   r   upperr  #PyUnicode_uchar_predicate_func_typer   rD  ry   )r8   r"   r   r   r(  ustringr  r;  r   r  	func_callr   r   r   _inject_unicode_predicate  s2    z.OptimizeBuiltinCalls._inject_unicode_predicatec           
   	   C   s   |st |dkr|S |d }t|tjr2|jjjs6|S |j}|j}d|  }| 	|||| j
|||g}	|jjr||	| j}	|	S )Nr   r   zPy_UNICODE_TO%s)rH   r    r   r  r!   rm   r  r.   r  r  $PyUnicode_uchar_conversion_func_typer   rD  ry   )
r8   r"   r   r   r(  r  r  r;  r  r  r   r   r   $_inject_unicode_character_conversion@  s$    z9OptimizeBuiltinCalls._inject_unicode_character_conversionr   keependsc              	   C   sH   t |dv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)rH   r  _inject_bint_default_argumentr  PyUnicode_Splitlines_func_typerk  r   r   r   (_handle_simple_method_unicode_splitlines\  s    z=OptimizeBuiltinCalls._handle_simple_method_unicode_splitlinessepmaxsplitc              	   C   sj   t |dvr | d||d |S t |dk r>|t|j | ||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   ZPyUnicode_Splitsplit)rH   r  r9   r   r4  rj   _inject_int_default_argumentr   r   r  PyUnicode_Split_func_typerk  r   r   r   #_handle_simple_method_unicode_splitr  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   r^  r  r  ZPyUnicode_Joinr  )rH   r  r    r   r  r  rG   r  rj   r   r   r  rc   r   r  r  PyUnicode_Join_func_type)r8   r"   r   r   r(  r  r   rJ   Zinlined_genexprr  r  r  r   r   r   "_handle_simple_method_unicode_join  s2    z7OptimizeBuiltinCalls._handle_simple_method_unicode_joinZ	substringr   end	directionc              
   C   s   |  ||||ddtdS )Nr,  endswithr   _inject_tailmatchunicode_tailmatch_utility_coderk  r   r   r   &_handle_simple_method_unicode_endswith  s    z;OptimizeBuiltinCalls._handle_simple_method_unicode_endswithc              
   C   s   |  ||||ddtdS )Nr,  
startswithr  r  rk  r   r   r   (_handle_simple_method_unicode_startswith  s    z=OptimizeBuiltinCalls._handle_simple_method_unicode_startswithc	           
   
   C   s   t |dvr(| d||f ||d |S | ||dtjd | ||dtjd |tj|jt	|tj
d | j||d	|  | j||||d
}	|	tj|  S )zReplace unicode.startswith(...) and unicode.endswith(...)
        by a direct call to the corresponding C-API function.
        r  r      z%s.%s2-4r  r   r   PY_SSIZE_T_MAXrW   rm   z__Pyx_Py%s_Tailmatchr  )rH   r  r  r   r   r9   r   r   rj   r   r   r  
capitalizePyString_Tailmatch_func_typer   r   r  ry   )
r8   r"   r   r   r(  r&  r;  r   r  method_callr   r   r   r    s(    
z&OptimizeBuiltinCalls._inject_tailmatchz-2c                 C   s   |  ||||ddS )Nfindr   _inject_unicode_findrk  r   r   r   "_handle_simple_method_unicode_find  s    z7OptimizeBuiltinCalls._handle_simple_method_unicode_findc                 C   s   |  ||||ddS )Nrfindr  r  rk  r   r   r   #_handle_simple_method_unicode_rfind  s    z8OptimizeBuiltinCalls._handle_simple_method_unicode_rfindc              	   C   s   t |dv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)rH   r  r  r   r   r9   r   r   rj   r   r   r  PyUnicode_Find_func_typerD  ry   )r8   r"   r   r   r(  r;  r  r  r   r   r   r    s"    
z)OptimizeBuiltinCalls._inject_unicode_findc              	   C   sn   t |dv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)	rH   r  r  r   r   r  PyUnicode_Count_func_typerD  ry   )r8   r"   r   r   r(  r  r   r   r   #_handle_simple_method_unicode_count  s    
z8OptimizeBuiltinCalls._handle_simple_method_unicode_countZreplstrZmaxcountc              	   C   sL   t |dv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  )rH   r  r  r   r   r  PyUnicode_Replace_func_typerk  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ASCIIunicode_escapeZraw_unicode_escapec                 C   s   g | ]}|t |fqS r   )codecs
getencoder)rL   r   r   r   r   rO   9  s   zOptimizeBuiltinCalls.<listcomp>c                 C   sL  t |dk st |dkr,| d||d |S |d }t |dkrjt|j}| ||d| jd||||gS | |j|}|du r|S |\}}	}
}|rt|tj	rz|j
||
}W n   Y n 0 t||}tj|j|tjd	S |r.|
d
kr.| |}|dur.d|v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   ZPyUnicode_AsEncodedStringr   Nr  strictr  zPyUnicode_As%sString)rH   r  r   r4  rj   r  #PyUnicode_AsEncodedString_func_type_unpack_encoding_and_error_moder    rL  rW   r   r   r   r   r   _find_special_codec_namePyUnicode_AsXyzString_func_type)r8   r"   r   r   r(  string_node	null_node
parametersr  encoding_nodeerror_handlingerror_handling_noderW   
codec_nameZencode_functionr   r   r   $_handle_simple_method_unicode_encode<  sJ    

z9OptimizeBuiltinCalls._handle_simple_method_unicode_encodestringr  r   decode_funcc                 C   sb  dt |  krdks.n | d||d |S |d }d }}t|tjrt|}|j}|j|j }}|rp|jdkrtd}t|tj	r|j
}|j}	|	tjtjfv r|r|jdd|	jgd	}q|jd
ddgd}n|	js|	js|S | |j|}
|
du r|S |
\}}}}|stj|jddd}n|jjs6|tj|  }|rX|jjsX|tj|  }d}|durp| |}|dur|dv rd|dd }nd| }tj|j| j|d}t|j}nt|j}g }|	jr8|s,|j st!"|}|#| tj$|jd| j%|gdt&'dddtj|  }| j(}d}n|	jr|sZtj|jdtj)d}| j*du rt+tj,t-d|	dt-dtjdt-dtjdt-dtj.dt-d tj.dt-d!| jdg| _*| j*}d"}n6|stj|jdtj)d}| j/}|	tju rd#}nd$}tj$|jd%| |||||||g|j0t&'|dd}|ddd& D ]}t!1||}qJ|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@descriptor '%s' requires a '%s' object but received a 'NoneType'decoder*  r  r(  r)  r   r  )r  r  r  z__Pyx_PyUnicode_Decode%sr  r'  zPyUnicode_Decode%s)rm   rh  rF  FrG  r  r  Zdecode_c_stringr  r  r   r   r  r  r  Zdecode_cpp_stringZdecode_bytesZdecode_bytearrayz__Pyx_%sr  )2rH   r  r    r   r   rl   r   r   r1   r  r!   rm   r   r   bytearray_typer   r   r  Zis_cpp_stringr  rj   r   r   r   r   r   ry   r  r  r  !PyUnicode_DecodeXyz_func_ptr_typer4  r   r   r   r9   r   rH  r   r   _decode_c_string_func_typer   _decode_cpp_string_func_typer@  r   rA  r   _decode_bytes_func_typer   rG  )r8   r"   r   r   r(  r  r   r   r  Zstring_typer  r  r  r  r  r  Zcodec_cnameZdecode_functionrf   Zhelper_func_typeZutility_code_namer  r   r   r   "_handle_simple_method_bytes_decode  s    











	

z7OptimizeBuiltinCalls._handle_simple_method_bytes_decodec                 C   sj   zt |}W n ty"   Y d S 0 | jD ]:\}}||kr*d|v r\ddd |dD }|  S q*d S )Nrx  r'  c                 S   s   g | ]}|  qS r   )r  )rL   r   r   r   r   rO     s   zAOptimizeBuiltinCalls._find_special_codec_name.<locals>.<listcomp>)r
  r  LookupError_special_codecsr  r  )r8   r  Zrequested_codecr   codecr   r   r   r    s    

z-OptimizeBuiltinCalls._find_special_codec_namec                 C   s   t |}t|dkr6| |d \}}|d u r>d S nd }|}t|dkrv| |d \}}|d u rhd S |dkr~|}nd}|}||||fS )Nr  r   r   r  )r   r4  rH   _unpack_string_and_cstring_node)r8   rj   r   r  r  r  r  r  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}npt |tjtjfrt|jd}tj|j|jt	j
d}n:|jtju rd }|t	j
|  }n|jjrd }nd  }}||fS )Nr  z
ISO-8859-1)r    r   r  r!   rL  rW   r   rj   Zas_utf8_stringr   r   r2  r  rm   r   r   r   ry   r  )r8   r"   r  r   r   r   r'  '  s&    z4OptimizeBuiltinCalls._unpack_string_and_cstring_nodec              
   C   s   |  ||||ddtdS )Nr   r  r   r  str_tailmatch_utility_coderk  r   r   r   "_handle_simple_method_str_endswith;  s    z7OptimizeBuiltinCalls._handle_simple_method_str_endswithc              
   C   s   |  ||||ddtdS )Nr   r  r  r(  rk  r   r   r   $_handle_simple_method_str_startswith@  s    z9OptimizeBuiltinCalls._handle_simple_method_str_startswithc              
   C   s   |  ||||ddtdS )Nr  r  r   r  bytes_tailmatch_utility_coderk  r   r   r   $_handle_simple_method_bytes_endswithE  s    z9OptimizeBuiltinCalls._handle_simple_method_bytes_endswithc              
   C   s   |  ||||ddtdS )Nr  r  r  r,  rk  r   r   r   &_handle_simple_method_bytes_startswithJ  s    z;OptimizeBuiltinCalls._handle_simple_method_bytes_startswithr   c              
   C   sT   t |}|r(|r(| |d ||||d< |	d u r6|j}	tj|j||||	||
|jdS )Nr   )r   r   r   ra  r   )r^  rr  r   r   r   rj   r   )r8   r"   r   r   r  r'  r(  r   r   r   ra  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   rm   r   r3  rH   )r8   Zself_argr   r(  r'  r   r   r   rr  p  s    
z#OptimizeBuiltinCalls._wrap_self_argc                 C   sX   t ||ksJ t ||kr<|tj|jt|||d n|| ||  ||< d S )Nr   )rH   r9   r   r   rj   r   r   ry   )r8   r"   r   	arg_indexrm   default_valuer   r   r   r  ~  s    
z1OptimizeBuiltinCalls._inject_int_default_argumentc                 C   sX   t ||ksJ t ||kr>t|}|tj|j||d n|| |  ||< d S Nr  )rH   rC  r9   r   rt   rj   r	  ry   )r8   r"   r   r0  r1  r   r   r   r    s    
z2OptimizeBuiltinCalls._inject_bint_default_argument)N)N)F)rB   rC   rD   rE   r  r  r>   r  r   r@  r0  rA  r  r  r  r  r   r   r   r   r  r  r   Zc_float_typer  Zc_longdouble_typer"  r  r  r$  r+  r%  r   r/  r0  r3  r   r4  r  r   r  r  r   r6  r7  r   r9  r  r   r;  r  r>  r  rA  r@  rB  rE  rJ  r   rH  Zc_const_py_unicode_ptr_typerI  rN  r  rt  rK  r<  rM  rO  rV  rQ  rR  r  rY  r\  r  rf  re  ri  rs  rj  rl  rt  rw  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  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_isupperr  r  Z#_handle_simple_method_unicode_lowerZ#_handle_simple_method_unicode_upperZ#_handle_simple_method_unicode_titler  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  Z_special_encodingsr%  r  rd  r  r   r"  r!  r#  Z&_handle_simple_method_bytearray_decoder  r  r'  r*  r+  r.  r/  r   r   ra  r  rr  r  r  r   r   r   r   r    s  	(	/
,

5D 
M?!	
D		
V 

	1

w
r  Zunicode_tailmatchr  Zbytes_tailmatchZstr_tailmatchc                       s:  e Zd ZdZdE 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*e+j,j-Z.  Z/S )F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 t|   || _dS )z
        The reevaluate argument specifies whether constant values that were
        previously computed should be recomputed.
        N)superr3  r5   
reevaluate)r8   r5  	__class__r   r   r5     s    zConstantFolding.__init__c                 C   s   | j s|jtjurd S tj}||_| |}| D ]J}t|tu rh|D ]}t	|d||u rH  d S qHq4t	|d||u r4 d S q4z|
  W nL ttttttfy   Y n0 ty   dd l}dd l}|j|jd Y n0 d S )Nr1   r   )file)r5  r1   r   Zconstant_value_not_setr   r:   r   rm   r^  rN  Zcalculate_constant_result
ValueError	TypeErrorrP   
IndexErrorri  ArithmeticErrorr  	tracebacksys	print_excstdout)r8   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y4   Y d S 0 d S r   )NODE_TYPE_ORDERmaxr_  r   rm   r9  )r8   nodesr   r   r   _widest_node_class  s    z"ConstantFolding._widest_node_classc                 C   s   t |}tj|j||dS r2  )rC  r   rt   rj   )r8   r"   rW   r   r   r   
_bool_node  s    zConstantFolding._bool_nodec                 C   s   |  | |S r   )rC  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  r  )rC  r   rS   _handle_NotNoderi   r   rH  r1   r    r   rt   r   rj   r   r  r   r   _handle_UnaryPlusNode_handle_UnaryMinusNoder;   r   r   r   visit_UnopNode  s&    







zConstantFolding.visit_UnopNoderg   r  is_notis)r  rg   rP  rO  c                 C   s@   |j }t|tjr<| |j}|r<t|}||_| |}|S r   )ri   r    r   rq   _negate_operatorrS   copyr   )r8   r"   ri   rS   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 )Nr  r   )r  rV   r   r   r   _negate  s    
z7ConstantFolding._handle_UnaryMinusNode.<locals>._negater   )rW   rm   longnessr1   )ri   rm   r    r   r  rj   rW   r1   r   r  r   r   rT  )r8   r"   rS  Z	node_typer   r   r   rM    s$    z&ConstantFolding._handle_UnaryMinusNodec                 C   s"   |j  r|j|j jkr|j S |S r   )ri   r   r1   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 )NrE  )rC  rT   r   r1   rS   rU   r;   r   r   r   r  !  s    



z#ConstantFolding.visit_BoolBinopNodec              	   C   s  |  | |jtju r|S t|jtr*|S |j|j }}|jrD|jsH|S z(|j	|j	 }}|d u sh|d u rn|W S W n t
y   | Y S 0 |jr|jrt||}ntj}| ||}|d u r|S |tju r|jdv rtj}n|tju  r|jdv  rtj}|tju rt|ddot|dd}dd ttt|ddtt|dd }	tj|j||	tt|jt|jd}
|js|
j	jrtj|
_	nt||
j	|
_	n2|tju r|j}n
t|j}||j|||jd}
|
S )	Nz+-//<<%**>>z+-//<<%**>>&|^unsignedr'  ZLLrT  )rj   rU  rT  rW   r1   )rj   rm   rW   r1   )rC  r1   r   r   r    r  rT   rU   r   rm   ri  r!  r   Zwidest_numeric_typer0  rG  rt   rS   r   r]  rN  rE  rH   rj   r   r  r   )r8   r"   rT   rU   Ztype1Ztype2Zwidest_typeZtarget_classrU  rT  r   Z
node_valuer   r   r   visit_BinopNode0  s^    





zConstantFolding.visit_BinopNodec                 C   s  |  | |jtju r|S |jjr|jjr|j|j }}t|tjrt|tjrd }|j	d ur|j	d ur|j	j
|j	j
krt|j	|j	 |j	j
}t|j}tj|j||j|dS t|tjrt|tjr|jj
|jj
krt|j|jj
}tj|j||jdS | |S )N)rW   r1   r   r  )rC  r1   r   r   rT   rx  rU   r    rL  r   r  r   r   rj   r   rW   rV  )r8   r"   Zstr1Zstr2r   Zstring_valuer   r   r   visit_AddNodej  s,    


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   )rC  rT   r  _calculate_constant_seqrU   r    r   r   rx  _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|tjrTt	}nt|tj
r|jd urt|j| |jj|_|jjrtnt	}nBt|tjr|jd urt	|j| |jj|_ndsJ dt| ||j| |jj|_t|tj
r|jd ur|j|_ n|j|_ |S )N   Fzunknown string node type: %s)r1   r    r   r   _py_string_typesrH   r	   r   r   r   r2  r  r  rW   Z
is_unicoderL  r   rm   )r8   r"   r  Zmultiplier_node
multiplierZbuild_stringr   r   r   rY    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 urt|j trt|jj tr|jj |j  }tj|jjt||d|_q| 	|S n||_|S r+  )
r1   r   r    r   rq  r   r   rj   r   rV  )r8   r"   Zsequence_nodeZfactorrW   r   r   r   rX    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 urT|S | |S r   )r:   r    rT   r   rL  rU   r  rq  _build_fstringrj   rW   r   rV  )r8   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rN|tj|tddd q|d dkr|d dkrt|d|dd   d	d
 d}|tj|t||d q|d }zt	|}	W n, t
y   t|dd	d
 d}Y  qY n0 |	jrd} q|dv r|d	d  }
d }|dv r&d|
v r&d}nF|dv r^|
d d }
|}|
drld|
d	d   }
n|dkrld}|
drd|
d	d   }
|tj|	j|	||
rtj|t|
|
dnd d qd} qq|sd S zt	| W n t
y   Y n0 t|dd	d
 d S tj||d}| |S )NTz%%%r  r   r  zIncomplete format: '...%s'r   )levelFz)Too few arguments for format placeholdersZasrfdoxXZdoxXr  Zarsr   r   dr  r   )rW   r2  r1  z*Too many arguments for format placeholders)r   )iterrer  _parse_string_format_regexr9   r   rL  r   r   nextStopIterationr  r  ZFormattedValueNoderj   ZJoinedStrNodevisit_JoinedStrNode)r8   rj   r  r*  r   
substringsZcan_be_optimisedr   Zformat_typer!   r1  r2  r"   r   r   r   r^    sv    




	zConstantFolding._build_fstringc                 C   s   |  | |jpd}t|jtjr0|jjs0d |_|jd u rpt|jtjrpt|jj}|	 rptj|jj
||dS |jd u r|dkrd }t|jtjr|jj}nt|jtjr|jj}|d urtj|jj
||dS |S )Nr   r  )r:   r2  r    r1  r   rL  rW   r   r   isdigitrj   r2  r  )r8   r"   r2  rW   r   r   r   r3    s"    


z(ConstantFolding.visit_FormattedValueNodec                    s   |  | tj g }t|j fddD ]n\}}|rt|}|d }t|dkr|td	dd |D }tj|j
||d}|jr|| q*|| q*|std}tj|j
||d}n@t|dkr|d }n*t|d	krtj|j
d
g|R  }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.
        c                    s
   t |  S r   )r    )vZunicode_noder   r   <lambda>;  r\  z5ConstantFolding.visit_JoinedStrNode.<locals>.<lambda>r   r   r'  c                 s   s   | ]}|j V  qd S r   rV   )rL   rW   r   r   r   r  @  r\  z6ConstantFolding.visit_JoinedStrNode.<locals>.<genexpr>r  r  r  )r:   r   rL  	itertoolsgroupbyr   r^  rH   r   r  rj   rW   r9   rn  r!  )r8   r"   r   Zis_unode_grouprj  ZunoderW   r   rm  r   ri  1  s,    

z#ConstantFolding.visit_JoinedStrNodec                    s   |  | g g  fdd |jD ]} | q(rHd  tdkrrd }|jsnt|tjrr|S |jdd< | | |S )z!Unpack **args in place if we can.c                    sv   | j r*rd j| j qr|  nHt| tjrL| jD ]} | q<n&rhd  d d = |  d S Nr   )is_dict_literalr  rn  r9   r    r   MergedDictNoder  r!   Z	child_argrg  r   r   r   r   rg  Z  s    

z1ConstantFolding.visit_MergedDictNode.<locals>.addr   r   N)	r:   r  r9   rH   rr  r    r   rs  rC  r
  r   ru  r   visit_MergedDictNodeT  s    



z$ConstantFolding.visit_MergedDictNodec                    s   |  | |jtju g g  fdd |jD ]} | q6rVd  tdkrd }rt|js|jr|j|ju 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 rq  )	is_set_literalr  rq  r   rn  r9   r    r   MergedSequenceNodert  rg  r   r=  r   r   r   rg  ~  s    

z5ConstantFolding.visit_MergedSequenceNode.<locals>.addr   r   N)r:   rm   r   r   r   r9   rH   rx  r  r    r   ry  rC  r
  r   rz  r   visit_MergedSequenceNodev  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 )rw  N)	r:   r   r  r9   rc   r  rq  rn  rC  )r8   r"   r   r!   r   r   r   visit_SequenceNode  s    


z"ConstantFolding.visit_SequenceNodec           	         s   |dg |j}|}|d ur |dg |j}t|_| rz| rzz||j W n ttt	t
ttfyx   Y n0 |}|j}q|js| r||jS |S |jgg g  fdd| g } D ]j}t|dk rq|d }tj|j|d |j|jtd}|| |}|dd  D ]}||_|}q(d |_qֈrX|d  n|sj|d	S |d }t|dkr| rĈ||jS n*|dd  D ]}tj|j|d
|td}q|S )NrT   rU   c                    sV   |   r4| js$| d d S  | jg n d |  | jrR| j d S )NFr  )r   r1   r9   rH  rU   rJ  )r~   ZcascadesZfinal_false_resultr8   split_cascadesr   r   r~    s    z<ConstantFolding.visit_PrimaryCmpNode.<locals>.split_cascadesr  r   r   )rT   rS   rU   r1   TrE  )r:   rT   rU   r   r1   r   Z"calculate_cascaded_constant_resultr9  r:  rP   r;  ri  r<  rJ  rH  rH   r   rq   rj   rS   r9   rO  )	r8   r"   Z	left_noder~   Z
right_nodeZ	cmp_nodesrJ  Z	pcmp_nodeZlast_cmp_noder   r}  r   r     sr    



z$ConstantFolding.visit_PrimaryCmpNodec                 C   s0   |  | |j s|S |jjr&|jS |jS d S r   )rC  rq  r   r1   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:   r`   r^   r   r1   r_   ra   r9   r
   rr   rj   )r8   r"   r`   rw  r^   r   r   r   rz    s    

z ConstantFolding.visit_IfStatNodec                 C   s   |  | |jd u s |jjd u r,d  }|_n|jj}|jd u sJ|jjd u rVd  }|_n|jj}|jtur|j}|jr|jd u r|j|| |_|S |j	r|
||}|d ur|S |S r   )rC  r   r1   r   r   rl   r  rq  r   rx  Zas_sliced_node)r8   r"   r   r   rl   r   r   r   visit_SliceIndexNode  s"    

z$ConstantFolding.visit_SliceIndexNodec                 C   s   |  | t|jtjr||jjs||jtju r>t	j
|jg g dS |jtju r^t	j|jg t dS |jtju r|t	j|jg i dS |S )Nr  r  )r:   r    r  r
   rr   r\   rm   r   r   r   r  rj   r   r  r<  r   r  r;   r   r   r   visit_ComprehensionNode4  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:   rd   rb   r    r   ZSequenceNoder   ra   r
   rr   rj   r  r  )r8   r"   rb   r   r   r   r   C  s    
z#ConstantFolding.visit_ForInStatNodec                 C   s:   |  | |jr6|j r6|jjr0d |_d |_n|jS |S r   )r:   r^   r   r1   ra   r;   r   r   r   visit_WhileStatNodeR  s    
z#ConstantFolding.visit_WhileStatNodec                 C   s.   |  | t|jtjs|S |j r*d S |S r   )r:   r    r=   r   ZExprNoder   r;   r   r   r   r>   \  s    

z"ConstantFolding.visit_ExprStatNode)F)0rB   rC   rD   rE   r5   rC  r   rt   r]  r   r  rD  rG  rH  rI  rN  rt  rQ  rK  rM  rL  r  rV  rW  rZ  rY  rX  r_  rf  r^  r3  ri  rv  r{  r|  r   r  rz  r  r  r   r  r>   r   r  r  rF   __classcell__r   r   r6  r   r3    sT    
:$
G#"&R	
r3  c                   @   sD   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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
        - replace Python function calls that look like method calls by a faster PyMethodCallNode
    Fc                 C   s    |  | |jr|j}d|_|S )zaAvoid redundant initialisation of local variables before their
        first assignment.
        T)r:   r  rY   Zlhs_of_first_assignment)r8   r"   rY   r   r   r   visit_SingleAssignmentNodez  s
    
z-FinalOptimizePhase.visit_SingleAssignmentNodec              	      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< nZ|jr|jjr| j| js|  jrdndrt|jtjr|jjs|jjr
t|jjdksd	}|jtju r"d
}nx|jrD|jr|jjjrd
}nV|jr|j}|j sd|jjrjd
}n0|j!rtj"tj#tj$f t% fdd|j!D }|r|j&r|jrt|j'tj(r|j'j)|j&u 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   rm   ZPyObject_TypeCheckr_  z&optimize.unpack_method_calls_in_pyinitzoptimize.unpack_method_callsTFc                 3   s"   | ]}|j ot|j   V  qd S r   )rZ   r    )rL   Z
assignmentZnon_method_nodesr   r   r    s   z:FinalOptimizePhase.visit_SimpleCallNode.<locals>.<genexpr>)r   r   rm   )-r:   r   rm   Zis_cfunctionr   r   rH   r   r   r   rc  r  r   r   rd  r   r  r   r   rs  rt  in_loopry   Zis_module_scoper    r   r  rq  r   r   rV  r   r   r  r   Z	ClassNodeZPy3ClassNoder  r8   r-   r
  r!   r  ZPyMethodCallNodeZ	from_node)r8   r"   r   rg  rc  rh  Zmay_be_a_methodr   r   r  r   r    sf    



z'FinalOptimizePhase.visit_SimpleCallNodec                 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!   r.  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!   r.  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:   )r8   r"   Zold_valr   r   r   visit_LoopNode  s
    
z!FinalOptimizePhase.visit_LoopNodeN)rB   rC   rD   rE   r  r  r  r  r  r  r  r   r   r   r   r  l  s   
2	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 ur(| j }d | _ | | || _ n
| | |S r   )overflow_bit_noder:   )r8   r"   Zsavedr   r   r   rF     s    


z#ConsolidateOverflowCheck.visit_Nodec                 C   sT   |j rF|jrF| jd u }|r"|| _n| j|_d|_ | | |rPd | _n
| | |S r(   )Zoverflow_checkZoverflow_foldr  r:   )r8   r"   Ztop_level_overflowr   r   r   visit_NumBinopNode  s    


z+ConsolidateOverflowCheck.visit_NumBinopNode)rB   rC   rD   rE   r  rF   r  r   r   r   r   r    s   
r  )K
__future__r   re  r>  rR  r
  ro  r'  r   r   r   ZcythonZdeclarerP  version_infor  r   r  r   r\  longr,  r
   r   r   r   r   r   ZCoder   r   ZStringEncodingr   r   r	   ZErrorsr   r   ZParseTreeTransformsr   __builtin__r   ImportError	functoolsr   r   r  r  r#   r'   r,   r2   r4   r3   rK   rG   ZEnvTransformrQ   rB  r  r  r  r  ZNodeRefCleanupMixinr  ZMethodDispatcherTransformr  r   r  r-  r)  r3  r  ZCythonTransformr  r   r   r   r   <module>   s   


        -  Lt   d!               4     \m