o
    f+u                    @   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rGe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' ddlm(Z( zd dl)m*Z* W n e+y   d dl,m*Z* Y nw zd dl)m-Z- W n e+y   eZ-Y nw dd Z.e	j/e	j0ffddZ1dd Z2dd Z3dd  Z4G d!d" d"ej5Z6d#d$ Z7d%d& Z8G d'd( d(ej9Z:G d)d* d*ej9Z;G d+d, d,ej<e'Z=G d-d. d.ej<Z>G d/d0 d0ej9Z?G d1d2 d2ej@ej9ZAG d3d4 d4ej@ejBZCd5d6 ZDeEd7d8ZFeEd9d8ZGeEd:d8ZHG d;d< d<ej<e'ZIG d=d> d>ej9ej@ZJG d?d@ d@ejKZLdS )A    )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   )Utils)reduce)
basestringc                 C   s   t | dS )N
Optimize.c)r   load_cached)name r   T/var/www/html/mig_web/myenv/lib/python3.10/site-packages/Cython/Compiler/Optimize.pyload_c_utility0   s   r    c                 C   s   t | |r| jS | S N)
isinstancearg)nodecoercion_nodesr   r   r   unwrap_coerced_node4   s   
r&   c                 C   s"   t | tjr| j} t | tjs| S r!   )r"   r   ResultRefNode
expressionr$   r   r   r   unwrap_node:   s   r*   c                 C   sr   t | } t |}t| tjrt|tjr| j|jkS t| tjr7t|tjr7| j o6t| j|jo6| 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_nodeJ   s   r5   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   r8   T   s   
z_YieldNodeCollector.__init__c                 C   s   | j | | | d S r!   )r:   appendvisitchildrenr;   r$   r   r   r   visit_YieldExprNode[   s   z'_YieldNodeCollector.visit_YieldExprNodec                 C   s*   |  | |j| jv r|| j|j< d S d S r!   )r=   exprr:   r9   r>   r   r   r   visit_ExprStatNode_   s   
z&_YieldNodeCollector.visit_ExprStatNodec                 C      d S r!   r   r>   r   r   r   visit_GeneratorExpressionNodef      z1_YieldNodeCollector.visit_GeneratorExpressionNodec                 C   rB   r!   r   r>   r   r   r   visit_LambdaNodei   rD   z$_YieldNodeCollector.visit_LambdaNodec                 C   rB   r!   r   r>   r   r   r   visit_FuncDefNodel   rD   z%_YieldNodeCollector.visit_FuncDefNodeN)__name__
__module____qualname____doc__r8   r   r7   r=   
visit_Noder?   rA   rC   rE   rF   r   r   r   r   r6   P   s    r6   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_expressionp   s   rP   c                    sD   t    |  z fdd jD }W |S  ty!   g }Y |S w )Nc                    s   g | ]
}|j  j| fqS r   )r#   r9   ).0
yield_node	collectorr   r   
<listcomp>{   s    z*_find_yield_statements.<locals>.<listcomp>)r6   r=   r:   KeyErrorrN   r   rS   r   rL   w   s   

rL   c                   @   s  e Zd ZdZdd Zdd Zd/ddZd	d
 Zd/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d/ddZdd Zdd Zd/d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 )0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   sB  |  r|j}t|}|jjr|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rtj||d}|S | | |S )N==)operatoroperand1operand2r   valuelhsrhsstats	conditionbody)
if_clauseselse_clause)sequencer   )targetiteratorre   rg   tempsre   not_inoperand)is_ptr_containsposr   r'   r[   is_subscriptbasetype	base_type
TempHandlerefr   PrimaryCmpNoderZ   r
   StatListNodeSingleAssignmentNodeBoolNodeBreakStatNode
IfStatNodeIfClauseNodeTempsBlockNodeForInStatNodeIteratorNodeanalyse_expressionscurrent_envvisitTempResultFromStatNoderY   NotNoder=   )r;   r$   rq   
result_refru   target_handleri   cmp_nodeif_bodyif_nodefor_loopnew_noder   r   r   visit_PrimaryCmpNode   sR   	




	


z'IterationTransform.visit_PrimaryCmpNodec                 C   s   |  | | ||jjS r!   )r=   _optimise_for_looprj   rh   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}|jr|j}tj|j	|fv r0|r&|S | j
||d dddS tj|j	|fv s@tj|j	|fv rJ|rD|S | ||S |j	jsR|j	jrZ| j|||dS |j	tju rh| j|||dS |j	tju rv| j|||dS |j	tju r| j||d|dS t|tjr|jj	jr| j||jd|dS t|tjs|S |jd u r|jrt|jjpd}nt|j}|r|j d ur|d8 }|j!}|jrL|sL|sL|j p|j"}|j#}	| $ j%j&dk}
|
s|	d	v rt|tj'r|j!}|j r|j(d
kr|jr|jj)rd}
d }}|	dks|
r|	dkrd}n!|	dks)|
r,|	dkr,d}n|	dks9|
r=|	dkr=d }}|sC|rL| 
|||	||S |j d u r|j r|jr|jj)r|j(dkrp|rj|S | *||S |j(dkr|r{|S | +||S t,j-r d|  krdkr n |S |j d u r |j r |j(dv r |jr |jj)r |j.j	j/s|j.j	j0r| j1|||dS |j.j	j2r |jd u r|jjn|jD ]#}t|tj3r|4 rd|j5  krdk rn  |S q |S | j1|||dS |S )NTF)dict_objmethodkeysvaluesreversed)
is_mutabler   r   r   r   )r   r   itemsdictiterkeysr   
itervaluesr   	iteritemsr   	enumerater   )rangexrange      @)6is_nameis_attributeentry
annotationr@   rr   rs   r   	dict_typert   _transform_dict_iterationset_typefrozenset_type_transform_set_iterationis_ptris_array_transform_carray_iteration
bytes_type_transform_bytes_iterationunicode_type_transform_unicode_iterationbytearray_type_transform_indexable_iterationr"   r   CoerceToPyTypeNoder#   is_memoryviewsliceSimpleCallNodeargs	arg_tuplerM   r;   functionr0   r1   global_scopecontextlanguage_levelCallNoder   
is_builtin_transform_enumerate_iteration_transform_reversed_iterationr   convert_rangeri   is_intis_enum_transform_range_iterationis_pyobjectIntNodehas_constant_resultr4   )r;   r$   iterabler   annotation_typer   	arg_countr   base_objr   is_safe_iter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 r:|	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   rM   r   rq   rt   r   
tuple_type	list_typeas_none_safe_noderj   rh   r   r   )r;   r$   reversed_functionr   r#   r   r   r   r   /  s"   z0IterationTransform._transform_reversed_iterationc                    sr  t j|ddddtj jddtjd} fdd	}t j| tjdd
}|}|r5d\}	}
||}}nd\}	}
t j jtjd}tj|j|d}t	j
 jj j|d}|  }tj|jddd}t	j|j||d}t	j j|gd}|rt	j
 j|| d}|j| t	j j||	||
|d| jdd
}t t |t	j jt ||d|}|jd j |S )zWIn principle can handle any iterable that Cython has a len() for and knows how to index'NoneType' is not iterableFT)may_hold_noneis_temp0r   r]   r4   rt   c                     s.   t j jdtjdd} t j j| gdS )NrM   )r   r   r   r   )r   r,   rq   r   builtin_scopelookupr   )builtin_lenr$   unpack_temp_noder   r   make_length_callL  s   

zKIterationTransform._transform_indexable_iteration.<locals>.make_length_call)rt   r   >>=<=<rq   rt   )rs   indexrq   r_   r`   )boundscheck
wraparound)
directivesre   ra   r^   N	bound1	relation1ri   	relation2bound2stepre   rg   
from_ranger@   r   )r   
LetRefNoder   r   r   rq   r   c_py_ssize_t_type	IndexNoder
   rz   ri   r   r   copy_inherited_directivesr   CompilerDirectivesNodery   rb   r<   ForFromStatNoderg   LetNodeExprStatNoder   r   insertre   )r;   r$   
slice_noder   r   
start_noder   length_tempend_noder   r   counter_reftarget_valuetarget_assignenvnew_directivesre   loop_length_reassign	loop_noderetr   r   r   r   C  s   
	z1IterationTransform._transform_indexable_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 )	Nr   PyBytes_AS_STRINGr   r   r   PyBytes_GET_SIZEr   )rs   startr   stoprt   r   r   )ri   rt   r   r   r   r   r   r   r   PythonCapiCallNoderq   PyBytes_AS_STRING_func_typePyBytes_GET_SIZE_func_typer   r   SliceIndexNode)r;   r$   r   r   target_typer   slice_base_nodelen_noder   r   r   r     sD   	z-IterationTransform._transform_bytes_iterationkinddatar   length-1exception_valuec                 C   sz  |j rJzt|jdd}W n	 ty   Y n3w 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}	|rud\}
}|	|}}	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r||jj|  }t j!|jj|j|d}t j"|j||j#gd}t j$|j||
||jj||	d ||j%dd
}t j&|jtj|jd| j'|tj(|j||jt	j)dtj(|j||jt	j*dtj(|j||jt	j+dgddt,-dddd}t.|tj/|j||||gt j"|j||gddS )Nlatin1z	iso8859-1r   )rs   r  r  rt   r   r   r   r   r   __Pyx_PyUnicode_READFr
  r   ra   Tr   __Pyx_init_unicode_iterationro   rt   unicode_iterr   )r   r   result_is_usedutility_coder   rk   )0
is_literalr   r]   encodeUnicodeEncodeErrorr   r  rq   	BytesNoder   c_const_char_ptr_type	coerce_toc_const_uchar_ptr_typer   r   strrM   r   r   r   r   r   r   r   rv   rw   
c_int_typec_void_ptr_typer  PyUnicode_READ_func_typeri   rt   r
   rz   ry   re   r   rg   r    init_unicode_iteration_func_typeAmpersandNodec_py_ssize_t_ptr_typec_void_ptr_ptr_typec_int_ptr_typer   r   r   r   )r;   r$   r   r   bytes_valuebytes_slicer   r   r   r   r   r   	kind_temp	data_tempcounter_tempr  r  re   r  
setup_noder   r   r   r     s   



	
z/IterationTransform._transform_unicode_iterationc                 C   s@  d}t |tjr&|j}t|j}t|j}d }|s%|jjs#t	|j
d |S n|jrt |jtjs2J |j}|j}	t|	j}t|	j}t|	j}|rt |jtrb|jdksb|jdkr[|rb|jdk rn|sn|jjslt	|j
d |S |j}
|rv|
 }
|
dk }tj|j
tjtt|
t|
d}n6|jjr|jjd u rt	|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| }||  }|r/|jdkr/tj|j
|d||d}n|}|rN|jdkrNtj|j
t|d||d|  }nt|}t|}| |j!j
}|jj"r|j!jjr|jt#j$u rt%tj&|j!j
||j'dtj(|j!j|  }nKt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}n(|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rt   r]   r4   r]   rt   r4   r  r   r   +rZ   rY   r[   rt   r  1r   )r  r  rs   rt   r   )r   rs   rt   r   ra   Tr   rk   )6r"   r   r  rs   r5   r  r  rt   r   r   rq   rr   r   	SliceNoder   r4   r   r   r   r   r)  absr   sizer'  r   element_ptr_typecoerce_to_simpleAddNode	CloneNoder   rv   rw   ri   	is_stringr   r   CastNodeDereferenceNoderu   c_py_ucs4_typer*  r   r   assignable_fromr   r
   rz   ry   re   _find_for_from_node_relationsr   rg   r   )r;   r$   r   r   neg_step
slice_baser  r  r   r   
step_valueptr_type
carray_ptrstart_ptr_nodestop_ptr_nodecounterr6  r  r  re   r   r   for_noder   r   r   r   5  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s&|S |jj}t|dkr2|S |\}}|j}|jsA|j	sA|S t|dkrTt
|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r||jj |j_n||j tj|jj|d|_||_|j|j|  |_|d |j_t|	| ||jjS )Nr   z)enumerate() requires an iterable argumentr   z%enumerate() takes at most 2 argumentsr   r   r9  r=  r;  )rZ   r[   rY   rt   r   r   ra   )r   r   rM   r   rq   ri   is_sequence_constructorrt   r   r   r&   r'  r   r   r   r   r   rC  r
   rz   r"   re   ry   rb   r<   itemrj   rh   r   r   )r;   r$   enumerate_functionr   targetsenumerate_targetiterable_targetcounter_typer  tempinc_expression	loop_bodyr   r   r   r     sz   

z1IterationTransform._transform_enumerate_iterationc                 C   s   |r|rdS dS |rdS dS )N)r   r   r   )r   r   r   r   )r;   neg_step_valuer   r   r   r   rJ  "  s   z0IterationTransform._find_for_from_node_relationsc                 C   sF  |j j}t|dk r|j}d}tj|ddd}n"|d }|j}t|jts'|S |j}|dkr0|S tj|t	||d}t|dkrSt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 r|	j}|j}|||| d |   d }n|j}|	j}|||| d |   d }tj|jt	||t|j|	jd}nt|	}| ||||}|dk r| }t	||_||_|
|  }|	jsd	}|pt|	}	nd
}tj|j|j||
||	||j|jd	d
}||   |r!t|	|}|S )Nr   r   r=  r]   r4   r   r   r   r   TF)	ri   r   r   r   r   r   re   rg   r   )r   r   rM   rq   r   r   r"   r4   r   r)  coerce_to_integerr   rJ  r?  r   spanning_typert   r   r   _build_range_step_calculationr]   r"  r
   r   ri   re   rg   set_up_loopr   )r;   r$   range_functionr   r   step_posrM  r   r   r   r   r   bound2_ref_nodeabs_stepbegin_value	end_valuebound1_valuebound2_is_temprS  r   r   r   r   .  s   




z-IterationTransform._transform_range_iterationc                 C   s   t |}t|j|j}|jjr|dk rt|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   ra  rt   r   r*  r   
binop_noderq   MulNoder   r)  DivNodeSubNode)r;   r   rf  r   rM  rg  ra  spanning_step_typerh  ri  final_opstep_calculation_noder   r   r   rb    s    %-z0IterationTransform._build_range_step_calculationc                    sv  g }t tj}|| ||j}t tj}|| | j}	d  }
 }}|rG|rG jj	rCt
 jjdkrA jj\}
}n S  j}n	|rM 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   rq   rb   r  r   T)is_identifierr]   *'NoneType' object has no attribute '%{0}s'   .30 PyExc_AttributeErrorr   format_argsr   c                    "   | rdpd} t j jt| | dS Nr   r   r_  r   r   rq   r)  r\   r)   r   r   	flag_node     z?IterationTransform._transform_dict_iteration.<locals>.flag_noder   r_  r^   __Pyx_dict_iterator	dict_iterr   r!  r   r   rd   re   rg   ra   rk   )(r   rv   r   py_object_typer<   rw   rq   r   ri   rT  rM   r   r"   re   r
   ry   r   r.  
c_ptr_typert   r*  DictIterationNextNoder   r   rb   
StringNoder   formatNullNoderz   r   r  PyDict_Iterator_func_typer   r   r   r   WhileStatNoderg   r   )r;   r$   r   r   r   r   rl   r[  	dict_temppos_temp
key_targetvalue_targettuple_targetre   dict_len_tempdict_len_temp_addris_dict_tempis_dict_temp_addriter_next_nodemethod_noder  result_coder   r)   r   r     s   









z,IterationTransform._transform_dict_iterationr   is_dictmethod_namep_orig_length	p_is_dictsetis_set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 )Nru  r  r   c                    r~  r  r  r\   r)   r   r   r  W  r  z>IterationTransform._transform_set_iteration.<locals>.flag_noder   r_  r^   __Pyx_set_iteratorset_iterr   Tr  r  ra   rk   )!r   rv   r   r  r<   rw   rq   r   r"   re   r
   ry   r   r.  r  rt   r*  ri   SetIterationNextNoder   r   rb   rz   r   r  PySet_Iterator_func_typer   r   r   r   r  rg   r   )r;   r$   set_objrl   r[  set_tempr  re   set_len_tempset_len_temp_addris_set_tempis_set_temp_addrr  r  r  r  r   r)   r   r   5  s   







z+IterationTransform._transform_set_iterationF)&rG   rH   rI   rJ   r   r   r   r   r   r   	CFuncTypec_char_ptr_typeCFuncTypeArgr   r   r  r   r  r   rH  r*  r+  r,  r  r/  r0  r1  r-  r   r   r   rJ  r   rb  r   r  r  r   r   r   r   r   rW      sx    1
n
V
&
	
\ %I
S@c	rW   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   sP  	 t |tjtjfr|j}n t |tjr|jj}nt |tjr#|j}nt |tj	r-|j
}nnqt |tjr|jd ur=| jS | rpt |jtjtjfrp|jdk}|rW|sW| jS t |jtjrf|j rf| jS ||j| |jfS | s|jdkr|d}n|r|jdkrd}n| j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 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 | jS t |tjr%|jdks|r%|jdkr%|jdk}| |j|\}}}| |j|\}}}	|d ur%||kr%t||r%|r|r%||||	 fS | jS )	NTrm   rX   F!=r   orand)r"   r   CoerceToTempNodeCoerceToBooleanNoder#   BoolBinopResultNoder   EvalWithTempExprNodesubexpressionTypecastNodero   rx   cascadeNO_MATCHis_c_string_containsr[   UnicodeNoder%  rY   contains_surrogatesrZ   extract_in_string_conditionsis_python_comparisonr/   r"  getattrr   is_constBoolBinopNodeextract_conditions)
r;   condallow_not_inrm   not_in_1t1c1not_in_2t2c2r   r   r   r    sr   



	
 z"SwitchTransform.extract_conditionsc                    sx   t tjrttttj}|  fdd|D S j t fddt	t
 D     fdd D S )Nc                    s"   g | ]}t j jt||d qS r_  r  rQ   charvalstring_literalr   r   rU     s
    
z@SwitchTransform.extract_in_string_conditions.<locals>.<listcomp>c                    s   h | ]
} ||d   qS )r   r   )rQ   i)
charactersr   r   	<setcomp>  s    z?SwitchTransform.extract_in_string_conditions.<locals>.<setcomp>c                    s   g | ]}t j j||d qS r  )r   CharNoderq   r  r  r   r   rU     s
    

)r"   r   r  listmapordr  r]   sortr   rM   )r;   r  charvalsr   )r  r  r   r    s   

z,SwitchTransform.extract_in_string_conditionsc                 C   sj   |  ||\}}}|d u r| jS |d urt||s| jS |jjs$|jjr-tdd |D r0| jS |||fS )Nc                 S   s   g | ]}|j jp|j j qS r   )rt   r   r   )rQ   r  r   r   r   rU     s    z=SwitchTransform.extract_common_conditions.<locals>.<listcomp>)r  r  r/   rt   r   r   any)r;   
common_varrd   r  rm   var
conditionsr   r   r   extract_common_conditions  s   
z)SwitchTransform.extract_common_conditionsc              	   C   s   t  }|D ]F}| r|j|v r dS ||j qz|j}|jjs&|jjr/|jd ur/|j}n|j	}W n t
y>   Y  dS w ||v rF dS || qdS )NTF)r  r   r4   addr   rt   r   is_cpp_enumenum_int_valuecnameAttributeError)r;   condition_valuesseenr]   value_entryvalue_for_seenr   r   r   has_duplicate_values  s(   

z$SwitchTransform.has_duplicate_valuesc           
      C   s   | j ds| | |S d }g }|jD ]'}| ||jd\}}}|d u r.| | |  S |tj|j	||j
d qdd |D }t|dk rP| | |S | |r\| | |S | |d |D ]}| |d qdt|}tj|j	|||jd	}	|	S )
Noptimize.use_switchFrq   r  re   c                 S   s   g | ]
}|j D ]}|qqS r   )r  )rQ   caser  r   r   r   rU   	  s
    z4SwitchTransform.visit_IfStatNode.<locals>.<listcomp>r   rg   re   rq   testcasesrg   )current_directivesgetr=   rf   r  rd   r<   r
   SwitchCaseNoderq   re   rM   r  r*   SwitchStatNoderg   )
r;   r$   r  r  	if_clause_r  r  r  switch_noder   r   r   visit_IfStatNode  sF   







z SwitchTransform.visit_IfStatNodec                 C   st   | j ds| | |S | d |jd\}}}|d u s't|dk s'| |r.| | |S | |||||j|j	S )Nr  Tr   )
r  r  r=   r  r  rM   r  build_simple_switch_statementtrue_val	false_valr;   r$   rm   r  r  r   r   r   visit_CondExprNode  s    


z"SwitchTransform.visit_CondExprNodec                 C   s   | j ds| | |S | d |d\}}}|d u s&t|dk s&| |r4| | ||   |S | ||||t	j
|jdddt	j
|jdddS Nr  Tr   r_  F)r  r  r=   r  rM   r  wrap_operandsr   r  r   r{   rq   r  r   r   r   visit_BoolBinopNode/  s$   


z#SwitchTransform.visit_BoolBinopNodec                 C   s   | j ds| | |S | d |d\}}}|d u s&t|dk s&| |r-| | |S | ||||tj|j	dddtj|j	dddS r  )
r  r  r=   r  rM   r  r  r   r{   rq   r  r   r   r   r   B  s"   


z$SwitchTransform.visit_PrimaryCmpNodec                 C   s   t |}tj|j|||j|  dd}tj|j|||j|  dd}	|r.|	|}}	tj|j||dg}
t	|}tj
|j||
|	d}t ||}|S )NTr_   r`   firstr  r  )r   r'   r
   rz   rq   r'  rt   r   r  r*   r  r   )r;   r$   r  r  rm   r  r  r   	true_body
false_bodyr  r  replacementr   r   r   r  T  s6   

z-SwitchTransform.build_simple_switch_statementc                 C   sR   | j ds| | |S |j}|j}| | |j|ur't|j|s'|jS |S )Nr  )r  r  r=   r  	lazy_tempr   tree_contains)r;   r$   	orig_exprtemp_refr   r   r   visit_EvalWithTempExprNodeq  s   


z*SwitchTransform.visit_EvalWithTempExprNodeN)rG   rH   rI   rJ   r  r  r  r  r  r  r  r  r   r  r	  r   VisitorTransformrecurse_to_childrenrK   r   r   r   r   r  }  s    =&r  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              	      s`  |   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s0S jj	}t
|dkr<S tdd	 |D rGS tj}g }g }|D ]8}z| }W n tyf   d
}Y nw |sst|}|| tjj|||d d}	|tjj|	tjd qS fdd}
t|
|}t||}|d d d D ]}t||}q|S )Ninr  rX   rm   r  r  r   c                 S      g | ]}|j qS r   )
is_starredrQ   r#   r   r   r   rU         z?FlattenInListTransform.visit_PrimaryCmpNode.<locals>.<listcomp>F)rq   rZ   rY   r[   r  )rq   ro   rt   c                    s   t jj | |dS )N)rq   rY   rZ   r[   )r   r  rq   )leftrightconjunctionr$   r   r   concat  s   z;FlattenInListTransform.visit_PrimaryCmpNode.<locals>.concatr:  )r=   r  rY   r"   r[   r   	TupleNodeListNodeSetNoder   rM   r  r   r'   rZ   	is_simple	Exceptionr   r<   rx   rq   r  r   c_bint_typer   r  )r;   r$   	eq_or_neqr   r_   condsrl   r#   is_simple_argr  r  rd   r   r[  r   r  r   r     sd   








z+FlattenInListTransform.visit_PrimaryCmpNodeN)	rG   rH   rI   rJ   r   r   r
  r  rK   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 ]0}t|tjr2| |j|||s$|  S | |j|||s1|  S qt|tjr<|  S |  S |sD|rhdd |D }dd |D }	t|t|	kr\|S t	t|t	|krh|S |sl|rg }
|D ]}| 
|}|s}|  S |
| qpg }|D ]}| 
|}|s|  S || qt|
t|kr|S t	t|
t	|kr|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      g | ]\}}|qS r   r   rQ   pathnr   r   r   rU         zIDropRefcountingTransform.visit_ParallelAssignmentNode.<locals>.<listcomp>c                 S   r!  r   r   r"  r   r   r   rU     r%  c                 S   r  r   r#   )rQ   tr   r   r   rU     r  F)rb   r"   r
   rz   _extract_operandr_   r`   CascadedAssignmentNoder  rM   _extract_index_idr<   use_managed_ref)r;   r$   
left_namesright_namesleft_indicesright_indicesrl   statlnamesrnameslindiceslhs_nodeindex_idrindicesrhs_node	temp_argsr[  r  	name_node
index_noder   r   r   visit_ParallelAssignmentNode  sh   






z5DropRefcountingTransform.visit_ParallelAssignmentNodec                 C   s   t |}|jjs
dS t|tjr|| |j}g }|}|jr0|j	r$dS ||j
 |j}|js|jrJ||j |d|d d d |f dS |jrj|jjtjkrVdS |jjjs]dS |jjscdS || dS dS )NF.r:  T)r*   rt   r   r"   r   r  r<   r#   r   r.   memberr0   r   r   joinrr   rs   r   r   r   r   )r;   r$   namesindicesrl   	name_pathobj_noder   r   r   r(    s8   


z)DropRefcountingTransform._extract_operandc                 C   s>   |j }|j}t|tjr|j}n
t|tjrd S d S |j|fS r!   )rs   r   r"   r   r,   r   	ConstNode)r;   r:  rs   r   	index_valr   r   r   r*  6  s   
z*DropRefcountingTransform._extract_index_idN)rG   rH   rI   rJ   r   r
  r  rK   r;  r(  r*  r   r   r   r   r     s    Er   c                   @   s   e Zd ZdZejjZdd Zdd Z	dd Z
d4d	d
Zd4ddZd4d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 )5EarlyReplaceBuiltinCallsa  Optimize some common calls to builtin types *before* the type
    analysis phase and *after* the declarations analysis phase.

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

    Introducing C function calls here may not be a good idea.  Move
    them to the OptimizeBuiltinCalls transform instead, which runs
    after type analysis.
    c                 C   s.   |  | |j}| |s|S | |||jS r!   )r=   r   _function_is_builtin_name_dispatch_to_handlerr   )r;   r$   r   r   r   r   visit_SimpleCallNodeR  s
   

z-EarlyReplaceBuiltinCalls.visit_SimpleCallNodec                 C   sL   |  | |j}| |s|S |j}t|tjs|S |j}| ||||j	S r!   )
r=   r   rF  positional_argsr"   r   r  r   rG  keyword_args)r;   r$   r   r   r   r   r   r   visit_GeneralCallNodeY  s   


z.EarlyReplaceBuiltinCalls.visit_GeneralCallNodec                 C   s:   |j sdS |  }||j}|| |jurdS dS )NFT)r   r   r   r   r   lookup_here)r;   r   r  r   r   r   r   rF  e  s   z2EarlyReplaceBuiltinCalls._function_is_builtin_nameNc                 C   sT   |d u r
d|j  }nd|j  }t| |d }|d ur(|d u r"|||S ||||S |S )Nz_handle_simple_function_%sz_handle_general_function_%s)r   r  )r;   r$   r   r   kwargshandler_namehandle_callr   r   r   rG  o  s   

z-EarlyReplaceBuiltinCalls._dispatch_to_handlerc                 C   s"   t j|jj|jj|||d|_d S )Nr!  )r   PythonCapiFunctionNoder   rq   r   )r;   r$   r  	func_typer!  r   r   r   _inject_capi_function|  s   z.EarlyReplaceBuiltinCalls._inject_capi_functionc                 C   j   |sd}nt |ts|dkrd}n	|dkrd}nd}|d ur#d| }nd}t|jd|||t|f  d S Nrz  r   z...xzexpected %s, z3%s(%s) called with wrong number of args, %sfound %dr"   r   r   rq   rM   r;   function_namer$   r   expectedarg_strexpected_strr   r   r   _error_wrong_arg_count     
z/EarlyReplaceBuiltinCalls._error_wrong_arg_countc                 C   s\   |s
t j|jddS t|dkr| d||d t|d dd }|tjtj	fv r,|d S |S )N0.0r\   r   floatr   rt   )
r   	FloatNoderq   rM   r]  r  r   c_double_typer   
float_type)r;   r$   pos_argsarg_typer   r   r   _handle_simple_function_float  s   z6EarlyReplaceBuiltinCalls._handle_simple_function_floatc                 C   s   t |}d  }}|dkr|\}n|dkr|\}}n|dkr#|\}}}n	| d|| |S tj|j|p7t|j||p?t|jdS )Nr   r   r   slice)r  r  r   )rM   r]  r   r>  rq   NoneNode)r;   r$   rd  r   r  r   r  r   r   r   _handle_simple_function_slice  s    
z6EarlyReplaceBuiltinCalls._handle_simple_function_slicec                 C   s   t |dkr|S |d }t|tjtjfr1t |jdkr/tj|jtj	t
t|jt|jdS |S t|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S |S )zUnpack ord('X').
        r   r   r8     )rM   r"   r   r  r%  r]   r   rq   r   c_long_typer)  r  r  unicode_valuer*  )r;   r$   rd  r#   r   r   r   _handle_simple_function_ord  s(   z4EarlyReplaceBuiltinCalls._handle_simple_function_ordc                 C      |  ||dS )zTransform

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

        into

        for L in LL:
            for x in L:
                if not p(x):
                    return False
        else:
            return True
        F_transform_any_allr;   r$   rd  r   r   r   _handle_simple_function_all     z4EarlyReplaceBuiltinCalls._handle_simple_function_allc                 C   rn  )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
        Tro  rq  r   r   r   _handle_simple_function_any  rs  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 r)|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	||rxdd
S d	d
S )Nr   r   rn   r_  r\   rc   )rg   rf   r  all)gen	orig_func)rM   r"   r   GeneratorExpressionNodedef_nodegbodyre   rP   r   rq   r
   r}   r~   ReturnStatNoder{   rg   r   recursively_replace_nodeInlinedGeneratorExpressionNode)r;   r$   rd  is_anygen_expr_nodegenerator_bodyr  yield_expressionyield_stat_noderd   	test_noder   r   r   rp    sF   
z+EarlyReplaceBuiltinCalls._transform_any_allitc                 C   s~  t |dkr|S |d }t|tjr|jtju r|}|j}n]t|tjrU|}|j}t	|}|s1|S tj
|j|dtjd}|D ]\}}	tj|j||jd}
t||	|
 q>n&|jr_|  }}ntj|j|jrq|jtjtjfv rqdn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rw  comprehension_typer@   ri   __Pyx_PySequence_ListKeepNewPySequence_ListTr
  F)rq   rt   r   r   r  )r0   r1   needs_none_checkr   r   ra   )#rM   r"   r   ComprehensionNodert   r   r   looprx  rL   r}  rq   ComprehensionAppendNoderi   r   r|  rT  as_listr  r   r   r  PySequence_List_func_typer   r'   r
   rz   r-   r   r   r   analyse_declarationsr   r   ry   )r;   r$   rd  r#   	list_noder  r  rO   r  r  append_noderesult_nodelist_assign_nodesort_method	sort_noder   r   r   _handle_simple_function_sorted  sp   


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r1t|\}}d}|du r0|S n|j}|j}z|j	r?|j
jsB|W S W n tyN   | Y S w t |dkr_tj|jddd}n|d }tj|jtjd}tj|j|t|jd||d	}	t|||	 tj|jtj|jtj|j|d
|dd|gd}
tj|j|
||jd|jdS )zLTransform sum(genexpr) into an equivalent inlined aggregation loop.
        r   r   r   Nr   r   r_  r   r;  r^   )rq   r(   Tr   ra   sum)r  r  
expr_scoperw  has_local_scope)rM   r"   r   rx  r  r  rP   r<   r@   r"  rt   r   r  r   rq   r   r'   r   r  r
   rz   rn  r   r|  ry   r}  r  r  )r;   r$   rd  r  r  r  r  r  r   add_node	exec_coder   r   r   __handle_simple_function_sumT  sb   z5EarlyReplaceBuiltinCalls.__handle_simple_function_sumc                 C   rn  )Nr   _optimise_min_maxrq  r   r   r   _handle_simple_function_min     z4EarlyReplaceBuiltinCalls._handle_simple_function_minc                 C   rn  )Nr   r  rq  r   r   r   _handle_simple_function_max  r  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||}q0|ddd D ]}t||}qW|S )zKReplace min(a,b,...) and max(a,b,...) by explicit comparison code.
        r   r   N)rZ   rY   r[   )r  r  r  r:  )rM   rT  r   r  r  r   r'   r   CondExprNoderq   rx   r  )	r;   r$   r   rY   cascaded_nodeslast_resultarg_noder   ref_noder   r   r   r    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   r4   r&  )r   r  rq   _transform_list_set_genexprr   r   AsTupleNode)r;   r$   rd  resultr   r   r   &_DISABLED_handle_simple_function_tuple  s   z?EarlyReplaceBuiltinCalls._DISABLED_handle_simple_function_tuplec                 C   sR   t |dkr|S |d jr|d js|d= |S t|d tjr'|d  |d< |S )zSReplace frozenset([...]) by frozenset((...)) as tuples are more efficient.
        r   r   )rM   rT  r   r"   r   r  as_tuplerq  r   r   r   !_handle_simple_function_frozenset  s   z:EarlyReplaceBuiltinCalls._handle_simple_function_frozensetc                 C   s&   |st j|jg g dS | ||tjS Nr  )r   r  rq   r  r   r   rq  r   r   r   _handle_simple_function_list  s   z5EarlyReplaceBuiltinCalls._handle_simple_function_listc                 C   s(   |st j|jg t dS | ||tjS r  )r   r  rq   r  r  r   r   rq  r   r   r   _handle_simple_function_set  s   z4EarlyReplaceBuiltinCalls._handle_simple_function_setc                 C   s   t |dkr|S t|d tjs|S |d }|j}t|}|s!|S tj|j||tj	u r-dnd|d}|D ]\}}	tj
|j||jd}
t||	|
 q4|S )zLReplace set(genexpr) and list(genexpr) by an inlined comprehension.
        r   r   r  r  r  r  )rM   r"   r   rx  r  rL   r}  rq   r   r   r  ri   r   r|  )r;   r$   rd  r  r  r  rO   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s!|S |d }|j}t|}|s0|S |D ]\}}t|tjs@|  S t |j	dkrK|  S q2tj
|j|dtjd}|D ]\}}	tj|j|j	d |j	d |jd}
t||	|
 qY|S )zDReplace dict( (a,b) for ... ) by an inlined { a:b for ... }
        r   key_value_pairsr4   r   r   r   r  )key_expr
value_exprri   )rM   r   DictNoderq   r"   rx  r  rL   r  r   r}  r   r   DictComprehensionAppendNoderi   r   r|  )r;   r$   rd  r  r  rO   r  r  r  r  r  r   r   r   _handle_simple_function_dict  s<   z5EarlyReplaceBuiltinCalls._handle_simple_function_dictc                 C   s$   t |dkr|S t|tjs|S |S )zlReplace dict(a=b,c=d,...) by the underlying keyword dict
        construction which is done anyway.
        r   )rM   r"   r   r  )r;   r$   rd  rM  r   r   r   _handle_general_function_dict  s
   z6EarlyReplaceBuiltinCalls._handle_general_function_dictr!   )'rG   rH   rI   rJ   r   r
  r  rK   rH  rK  rF  rG  rS  r]  rf  ri  rm  rr  rt  rp  r   r  r   r   r  r  r  r  5_EarlyReplaceBuiltinCalls__handle_simple_function_sumr  r  r  r  r  r  r  r  r  r  r   r   r   r   rE  C  s>    




$D:#&rE  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}|r!|jr!t|jdkr#d S |jd jS )Nr   r   )cf_state
cf_is_nullr   r   r   cf_assignmentsrM   r`   )r;   r9  r   r   r   r   get_constant_value_node+  s   

z*InlineDefNodeCalls.get_constant_value_nodec                 C   sv   |  | | jds|S |j}|js|S | |}t|tjs"|S tj	|j
|||j|jd}| r9| ||S |S )Nzoptimize.inline_defnode_calls)rY  r   r   generator_arg_tag)r=   r  r  r   r   r  r"   r   PyCFunctionNodeInlinedDefNodeCallNoderq   r   r  can_be_inlinedreplace)r;   r$   rY  r   inlinedr   r   r   rH  7  s"   

z'InlineDefNodeCalls.visit_SimpleCallNodeN)	rG   rH   rI   r   r
  r  rK   r  rH  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ej	ejedejdgddZej	ejedejdgddZd d! Zdd"d#Z d$d% Z!d&d' Z"d(d) Z#e	ej
ed*ej
dgZ$d+d, Z%e	ej&ed*ej
dgZ'd-d. Z(d/d0 Z)e	ej*ed1ej*dgZ+d2d3 Z,e	ej-ed4ej
dgZ.d5d6 Z/e	ej0ed7ej-dgZ1d8d9 Z2e	ej3ed4ej
dgZ4d:d; Z5e	ej6ed4ej
dgZ7d<d= Z8ej	ejed*ej
dgd>ddZ9d?d@ Z:e	ej
ed
ej
dgZ;e	ej
edAejdgZ<dBdC Z=dDdE Z>e	ej?edAej
dgZ@e	ej?edAejAdgZBdFdG ZCej	ejedejDdgddZEej	ejedHejFdgddZGej	ejed*ej
dgddZHej&dIejdJejIdKej-dLej0dMej3dNej6dNej*dOijJZKdPhZLdQdR ZMe	ejNedSej
dgZOdTdU ZPe	ejQedej
dgZRdVdW ZSdXdY ZTe	ej
edZej
ded[ej0dgZUe	ej
edZej
ded[ej0ded\ej*dgZV	dd]d^ZW	dd_d`ZXej	ejYed7ej
dedaej
dgddZZdbdc Z[ddde Z\ej	ejYedfej
dedAejdgddZ]ej	ejYedfej
dedAej
dgddZ^dgdh Z_e	ej
ed7ej
dgZ`ej	ej
ed7ej
dediej
dedjejdedkejdgddlZadmdn ZbddpdqZcej	ejYed*ej
dgddZddrds Zee	ej
ed1ej
dedtej
deduej
dgZfdvdw Zge	ej
ed1ej
dedtej
deduej
dedxejdgZhdydz Zie	ej
ed1ej
dedtej
deduej
dgZjd{d| Zked}d ejlejfD Zmd~d Zndd Zodd Zpdd Zqdd Zrdd Zsdd Ztdd Zudd Zvdd Zwdd Zxdd Zydd Zzdd Z{dd Z|dd Z}dd Z~dd Zdd Zdd Zdd Zdd Zdd Ze	ejQedejdgZdd ZeZeZeZeZeZeZeZeZeZe	ejedejdgZ	 e	ej-edej&dedejQd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jQe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jDdedejDdgZe	ejed*ej&dgZg dӢZddՄ eD Zddׄ Zee	ej&edejDdedejdedejDdgZe	ej&edejDdedejdedejdedejDdedejDdededgZe	ej&edej
dedejdedejdedejDdedejDdededgZdZdd݄ ZeZdd߄ Zdd Zdd Zdd Zdd Zdd Zdd Z	 dddejjdfddZdd Ze	ej
ed*ej
dgZdd Zdd Zdd ZdS )OptimizeBuiltinCallsa<  Optimize some common methods calls and instantiation patterns
    for builtin types *after* the type analysis phase.

    Running after type analysis, this transform can only perform
    function replacements that do not alter the function return type
    in a way that was not anticipated by the type analysis.
    c                 C   s   |  | | S )z:Flatten redundant type checks after tree changes.
        )r=   	reanalyser>   r   r   r   visit_PyTypeTestNodeU  s   
z)OptimizeBuiltinCalls.visit_PyTypeTestNodec                 C   s"   |  | |j|jjkr|jS |S )z,
        Drop redundant type casts.
        )r=   rt   ro   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r0|j	r0|j	j
s.|j	jr0dS |S )z7
        Drop dead code and useless coercions.
        N)r=   r"   r@   r   r   r#   is_noner"  r   r   is_localis_arg)r;   r$   r@   r   r   r   rA   f  s   

z'OptimizeBuiltinCalls.visit_ExprStatNodec                 C   sT   |  | |j}t|tjr|j}t|tjr(|jtjt	j
fv r(|j|  S |S )z<Drop redundant conversion nodes after tree changes.
        )r=   r#   r"   r   PyTypeTestNoder   rt   r   r  r   	bool_typecoerce_to_booleanr   r;   r$   r#   r   r   r   visit_CoerceToBooleanNodev  s   
z.OptimizeBuiltinCalls.visit_CoerceToBooleanNodeoNc                 C   s   |  | |j}t|tjr|j}t|tjr[|jjdkr[t|j	dkr[|j	d }|j
tju r4|dS |j
jr[|jjdkr[tj|jd| j|gd|jtdd|jd	|j
|  S |S )
z3Drop redundant conversion nodes after tree changes.r`  r   r   =float() argument must be a string or a number, not 'NoneType'__Pyx_PyObject_AsDouble__Pyx_PyNumber_Floatpynumber_floatTypeConversion.c)r   py_namer   r!  r   )r=   r#   r"   r   CoerceFromPyTypeNoder  r   r   rM   r   rt   r   rc  r   r   r  rq   PyNumber_Float_func_typer   r   r   r   r'  r   )r;   r$   r#   func_argr   r   r   visit_CoerceToPyTypeNode  s*   




z-OptimizeBuiltinCalls.visit_CoerceToPyTypeNodec                 C   s~  |  | |j}|jjs|j|jkr||j|  }|S t|tjr&|j}|j	rR|jj
r3t|tjsG|jjr=t|tjsG|jj
rPt|tjrP||j|  S |S t|tjr|jtju rr|j|jjrp|j|j|  S |S |jtju r|jjjr|jjr|j|j|  S |S t|tjr|jj
s|jjr| ||S |S |jr|j}t|tjr|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#   rt   r   r'  r   r"   r   r  r"  r   r   is_floatra  r{   r   r   r  rI  r   r   is_unicode_charr   _optimise_numeric_cast_callrr   r   _optimise_int_indexing)r;   r$   r#   r:  r   r   r   visit_CoerceFromPyTypeNode  sP   



z/OptimizeBuiltinCalls.visit_CoerceFromPyTypeNodebytesr   check_boundsz
((char)-1)T)r  exception_checkc              
   C   s   |   }|jd rdpd}|jjtju rT|jtjtjfv rTt	j
|jt||d}t	j|jd| j|jd|tj||gdtdd	d
}|jtjurR||j|}|S |S )Nr   r   r   r_  __Pyx_PyBytes_GetItemIntz&'NoneType' object is not subscriptableTbytes_indexStringTools.cr   r   r!  )r   r   rs   rt   r   r   r   c_char_typec_uchar_typer   r   rq   r)  r  PyBytes_GetItemInt_func_typer   r'  r   r   r   )r;   coerce_noder#   r:  r  bound_check_boolbound_check_noder$   r   r   r   r    s0   

z+OptimizeBuiltinCalls._optimise_int_indexingc              
   c   s,    | ]}|t |t d |dgfV  qdS )r#   N)r   r  r  )rQ   rc  r   r   r   	<genexpr>  s    
zOptimizeBuiltinCalls.<genexpr>c              	   C   s  |j }d }t|tjr|j}nt|tjr$|jjr$t|jtj	r$|jj}|d u s.t
|dkr0|S |d }t|tjr>|j}n|jjrD|S |jdkr|jjsQ|jjr|j|jkrY|S |jtjtjfv rj| ||j|S |j|jsu|jjrtj|j||jdS |S |jjr|jjr|jjdkrd}nd|jj }tj|j|| j|j |gd|j|jd|j|  S |S |jd	kr|jjs|jjr|j|jkr|S |jtjtjfv r| ||j|S |j|js|jjrtj|j||jdS |S )
Nr   r   intr  l__Pyx_truncltrunc)rR  r   r  r   r   r`  )r   r"   r   r  r   r,   rt   is_builtin_typer   r  rM   r   r#   r   r   r   r   rH  c_py_unicode_type_pyucs4_to_numberrI  r  r  rq   
is_numericmath_h_modifierfloat_float_func_typesr   r   r'  r   )r;   r$   r#   r   r   r  trunclr   r   r   r    sb   



z0OptimizeBuiltinCalls._optimise_numeric_cast_callr#   r  r  z-1.0c                 C   sl   |dv sJ t j|j|dkrdnd|dkr| jn| j|g||j|jt|dkr)dnddd	|j
|  S )	N)r  r`  r  __Pyx_int_from_UCS4__Pyx_double_from_UCS4
int_pyucs4float_pyucs4
Builtins.c)rR  r   r  r   r   r!  )r   r  rq   pyucs4_int_func_typepyucs4_double_func_typer   r   r   r   r'  rt   r   )r;   r$   py_type_namer  r   r   r   r  0	  s   z&OptimizeBuiltinCalls._pyucs4_to_numberc                 C   rT  rU  rW  rX  r   r   r   r]  <	  r^  z+OptimizeBuiltinCalls._error_wrong_arg_countc                 C      |S r!   r   )r;   r$   rY  r   arg_listrM  r   r   r   _handle_functionN	  rD   z%OptimizeBuiltinCalls._handle_functionc                 C   s   |r|S |r|j r|jjs|S |  |}|s|S tj|jjtj	|j|||j
d|dd|  }	|	du r@| |||||S |j}
|
du rN|jrN|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   rt   T)r0   r1   	is_calledNr   )r   r0   r   r   r   r   r-   r   rq   r,   rt   analyse_as_type_attribute%_optimise_generic_builtin_method_callr   r   r   r;   analyse_c_function_callanalysedr'  )r;   r$   	type_name	attr_namer   r  is_unbound_methodrM  
type_entryr   r   	call_noder   r   r   _handle_methodQ	  sJ   
	
z#OptimizeBuiltinCalls._handle_methodc                 C   sV   t |}|s|dks|jr|js|S |jjjs|S |jjjdv r"|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   rt   )	rM   r   r.   r0   rt   r  r   r   CachedBuiltinMethodCallNode)r;   r$   r  r   r  r  r   r   r   r   r
  }	  s   

z:OptimizeBuiltinCalls._optimise_generic_builtin_method_callr0   c              	   C   s   |j tju r| |||S t|dkr%t|dkr#tj|jt ddS |S |d }|j tj	u r>|
 s5|S d}tdd}nd}td	d}tj|j|| j||j|d
dS )z1Optimize single argument calls to str().
        r   r   rz  r_  __Pyx_PyStr_Str	PyStr_Strr  __Pyx_PyObject_StrPyObject_Strr)  r   r   r!  r  )rt   r   r   _handle_simple_function_unicoderM   r   r  rq   r   str_typemay_be_noner   r   r  PyObject_String_func_typer   r;   r$   r   rd  r#   r  r!  r   r   r   _handle_simple_function_str	  s*   
z0OptimizeBuiltinCalls._handle_simple_function_strc              	   C   s   t |dkrt |dkrtj|jt ddS |S |d }|jtju r1| s(|S d}t	
dd}nd}t	
d	d}tj|j|| j||j|d
dS )z5Optimise single argument calls to unicode().
        r   r   rz  r_  __Pyx_PyUnicode_UnicodePyUnicode_Unicoder  __Pyx_PyObject_UnicodePyObject_Unicodeunicoder  )rM   r   r  rq   r   rt   r   r   r  r   r   r  PyObject_Unicode_func_typer   r  r   r   r   r  	  s&   
z4OptimizeBuiltinCalls._handle_simple_function_unicodec                 C   sJ   |  | |jjtju r#|js#|js#|jr|jdkr#| |d|jgS |S )zSimplify or avoid plain string formatting of a unicode value.
        This seems misplaced here, but plain unicode formatting is essentially
        a call to the unicode() builtin, which is optimised right above.
        r  N)	r=   r]   rt   r   r   c_format_specformat_specconversion_charr  r>   r   r   r   visit_FormattedValueNode	  s
   
z-OptimizeBuiltinCalls.visit_FormattedValueNoder   c                 C   sN   t |dkr|S |d }|jtju r%|d}tj|jd| j|g|j	dS |S )z;Replace dict(some_dict) by PyDict_Copy(some_dict).
        r   r   r   PyDict_Copyr
  )
rM   rt   r   r   r   r   r  rq   PyDict_Copy_func_typer   r;   r$   r   rd  r#   r   r   r   r  	  s   

z1OptimizeBuiltinCalls._handle_simple_function_dictr  c                 C   sT   t |dkr|S |d }tj|j|jr!|jr!|jtjtj	fv r!dnd| j
||jdS )z0Turn list(ob) into PySequence_List(ob).
        r   r   r  r  r
  )rM   r   r  rq   r   rt   r   r  r   r   r  r+  r   r   r   r  	  s    z1OptimizeBuiltinCalls._handle_simple_function_listr  c                 C   s~   t |dks	|js|S |d }|jtju r| s|S |jtju r5|d|d< tj	|j
d| j||jdS tj|j
|tjdS )zDReplace tuple([...]) by PyList_AsTuple or PySequence_Tuple.
        r   r   r   PyList_AsTupler
  )r#   rt   )rM   r   rt   r   r   r  r   r   r   r  rq   PyList_AsTuple_func_typer  r+  r   r   r   _handle_simple_function_tuple
  s   
z2OptimizeBuiltinCalls._handle_simple_function_tuplec           	      C   s   t |dkr|S |d jrMg }g }|d jD ]}| s&t|}|| || qtj|j	d|d}| 
|| |d d d D ]}t||}qB|S | 
|tj|j	d| j||jddS )Nr   r   )r   r   r:  	PySet_Newr  r   r   r  )rM   rT  r   r  r   r   r<   r   r  rq   r  r  r  PySet_New_func_typer   )	r;   r$   r   rd  r   rl   r#   r  r[  r   r   r   r  
  s,   



z0OptimizeBuiltinCalls._handle_simple_function_setc              
   C   sn   |s
t |jg}nt|dkr|S |d jtju r$|d  s$|d S t j|jd| j	||j
tddddS )Nr   r   __Pyx_PyFrozenSet_Newpyfrozenset_newr  	frozensetr  )r   r  rq   rM   rt   r   r   r  r  PyFrozenSet_New_func_typer   r   r   r;   r$   r   rd  r   r   r   r  ?
  s   
z6OptimizeBuiltinCalls._handle_simple_function_frozensetz((double)-1)c              	   C   sz  t |dkrtj|dddtj|  S t |dkr%| d||d |S |d }t|tj	r2|j
}|jtju r:|S |jtjtjfv rK| ||j|S |j|jsV|jjr`tj|j||jdS |d d	}|jtju rrd
}d}n2|jtju r}d}d}n'|jtju rd}d}n|jtju rd}d}n|jtju rd}n|d }d}d}tj|j|| j|g|j|rt|ddS dddS )zYTransform float() into either a C type cast or a faster C
        function call.
        r   r_  g        r_  r   r`  0 or 1r  r  __Pyx_PyBytes_AsDoublepybytes_as_double__Pyx_PyByteArray_AsDouble__Pyx_PyUnicode_AsDoublepyunicode_as_double__Pyx_PyString_AsDoublepystring_as_doublePyLong_AsDoubler  pyobject_as_doubleNr  ) rM   r   ra  r'  r   rc  r   r]  r"   r   r#   rt   r   rb  rH  r  r  r   rI  r  r  rq   r   r   r   r   r  	long_typer  PyObject_AsDouble_func_typer   r    )r;   r$   r   rd  r  r#   
cfunc_nameutility_code_namer   r   r   rf  V
  sf   

z2OptimizeBuiltinCalls._handle_simple_function_floatr]   c                 C   s   t |dkrtj|jddtjdS t |dkr|S |d }t|tjr>|jj	j
r<tj|jd| j|jgddtdd	d
S |S |j	jrS|j	jrStj|jd| j|dddS |S )z7Transform int() into a faster C function call.
        r   r   r   r   __Pyx_PyInt_FromDoubleTr  PyIntFromDoubler  )r   r   r  r!  __Pyx_PyNumber_Intr0  )rM   r   r   rq   r   r  r"   r   r#   rt   r  r  PyInt_FromDouble_func_typer   r   r   PyNumber_Int_func_type)r;   r$   r   rd  r  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r&| d||d |S |d 	|  }tj
|j|d}tj
|j|d}||  S )z=Transform bool(x) into a type coercion to a boolean.
        r   Fr_  r   boolr7  rn   )rM   r   r{   rq   r'  r   r  r   r]  r  r   coerce_to_pyobject)r;   r$   r   rd  ro   r   r   r   _handle_simple_function_bool
  s   z1OptimizeBuiltinCalls._handle_simple_function_boolc                 C   s   t |dkr| d||d |S |d jjr'tj|jd| j|d g|jddS |d jj	rF|d j
tju rFtj|jd| j|d g|jddS |S )Nr   
memoryviewr=  r   PyMemoryView_FromObjectr0  PyMemoryView_FromBuffer)rM   r]  rt   r   r   r  rq   !PyMemoryView_FromObject_func_typer   r   ru   r   py_buffer_type!PyMemoryView_FromBuffer_func_typer6  r   r   r   "_handle_simple_function_memoryview
  s(   z7OptimizeBuiltinCalls._handle_simple_function_memoryviewr#  __Pyx_PyUnicode_GET_LENGTH__Pyx_PyBytes_GET_SIZE__Pyx_PyByteArray_GET_SIZE__Pyx_PyList_GET_SIZE__Pyx_PyTuple_GET_SIZE__Pyx_PySet_GET_SIZEPyDict_Sizezcpython.array.arrayc           	   
   C   s  t |dkr| d||d |S |d }t|tjr|j}|jjr0tj|j	d| j
|g|jd}n|jjrHtj|j	d| j|g|jtddd	}nj|jjrjtjtjtd
|jdgdd}tj|j	d||g|jd}nH|jjr| |j}|du r|j}|js|jr|jj| jv rd}n|S |d}tj|j	|| j|g|jd}n|jjrt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   rM   r   __Pyx_ssize_strlenr
  __Pyx_Py_UNICODE_ssize_strlenssize_pyunicode_strlenr  r  memoryviewsliceNT)nogil__Pyx_MemoryView_LenPy_SIZEz&object of type 'NoneType' has no len()r=  r   )#rM   r]  r"   r   r   r#   rt   rE  r  rq   Pyx_ssize_strlen_func_typer   is_pyunicode_ptrPyx_Py_UNICODE_strlen_func_typer   r   r   r   r  r   r  r   _map_to_capi_len_functionis_extension_typer  r   qualified_name_ext_types_with_pysizer   PyObject_Size_func_typer  r   c_size_t_typer'  r   )	r;   r$   r   rd  r#   r   rR  rC  re  r   r   r   _handle_simple_function_len  sj   



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   Py_TYPEFr
  )rM   r   r  rq   Pyx_Type_func_typerF  r   r  r6  r   r   r   _handle_simple_function_type>  s   
z1OptimizeBuiltinCalls._handle_simple_function_typec              
      s  t |dkrS |\}}g }t|tjr9|j}t |dkr'|d jtjur'S |js.|	 s8t
|}|| n|jtju rC|g}nS g }g }|   |D ]}	d}
|	jrl|	jrl |	jj}|rl|jrl|jjrl|j}
|
tju r|jdks}|jr}|jjsd}
|
dur|jjdd}|dkr|
tju rd	}||v rqO|| |g}n |	jtju rd
}||	g}n|	jst
|	}	||	 d}||	g}|tj|	j|| j|dd qOt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   Nrt   F)exact__Pyx_Py3Int_CheckPyInt_Check__Pyx_TypeCheckPyObject_IsInstanceTr
  c                    s&   |j d| |}tj|_|  |S )Nr  )rq   r   r  rt   r  )r2   r3   make_binop_nodeor_noder  r$   r   r   join_with_or  s   
zMOptimizeBuiltinCalls._handle_simple_function_isinstance.<locals>.join_with_orr:  )rM   r"   r   r  r   rt   r   	type_typer   r  r   r'   r<   r   r   r   r   r   r  scopeis_builtin_scopetype_check_functionint_typer"  r  rq   Py_type_check_func_typern  r   r'  r  )r;   r$   r   rd  r#   typesrl   tests
test_nodestest_type_nodebuiltin_typer   r}  type_check_argsry  r  r[  r   rx  r   "_handle_simple_function_isinstanceN  sx   








z7OptimizeBuiltinCalls._handle_simple_function_isinstancec                 C   s  t |dkr|S |d }t|tjr+|jjjr)tj|j|jt	j
d|j|  S |S t|tjrTt |jdkrRtj|jt	jtt|jt|jd|j|  S |S t|tjr|jrt |jdkrt|jdkrtj|jt	jtt|jt|jd|j|  S |S )z-Unpack ord(Py_UNICODE) and ord('X').
        r   r   r  r8  rj  )rM   r"   r   r   r#   rt   r  r  rq   r   rk  r'  r   r  r]   r   r*  r)  r  r  rl  r+  r   r   r   rm    s@   
z0OptimizeBuiltinCalls._handle_simple_function_ordrt   r   rM  c              
   C   s  |j }|rt|dk r|S |d }|jr|js|S |jtjks%|jtjkr'|S |jr-|js6|j|jkr5|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||}|st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 )zOReplace 'exttype.__new__(exttype, ...)' by a call to exttype->tp_new()
        r   r   N)r   Tskip_childrentp_new__new__PyTypeObjectrt   r   rM  rt   F)r   may_return_noner   z4object.__new__(X): X is not a type object (NoneType)zObjectHandling.c__Pyx_tp_new_kwargs)r   r!  r   __Pyx_tp_new)%r0   rM   r   rt   r   rz  r  r   r   r  rq   analyse_typesr   rg  typeobj_cnamer{  r   r   ConstructorSlotget_slot_functionr   cython_scoper   CPtrTyper   r  r  r  rF  r  r  r   r   r   Pyx_tp_new_kwargs_func_typer   Pyx_tp_new_func_type)r;   r$   r   r   r  rM  r0   type_arg
args_tupleext_typetp_slotslot_func_cnamer  PyTypeObjectPtrpyx_tp_new_kwargs_func_typer!  r   r   r   _handle_any_slot__new__  s   


z,OptimizeBuiltinCalls._handle_any_slot__new__c                 C   r  r!   r   )r;   r$   r   r   r  rM  r   r   r   _handle_any_slot__class__	  s   z.OptimizeBuiltinCalls._handle_any_slot__class__rU  c              
   C   sB   t |dks|js|jjr|S tj|jd| j|d|jdt	ddS )z\Optimistic optimisation as X.append() is almost always
        referring to a list.
        r   __Pyx_PyObject_AppendFr<   )r   r  r   r   r!  )
rM   r   r   r   r   r  rq   PyObject_Append_func_typer   r    r;   r$   r   r   r  r   r   r   #_handle_simple_method_object_append  s   
z8OptimizeBuiltinCalls._handle_simple_method_object_appendc                 C   s|  t |dkr|S |\}}|js|S t|j}|jdus!t |dkr$	 |S | |||d}	|s4|j|	_|	S |	 }
}t |dkrG| sGt|}
g }|d	 }| s[t|}|| tj|jd
| j|
|gdtdd}|ddd	 D ],}| st|}|| tj|jdtj|jd| j|
|gddtdd|tjd}qs|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:  __Pyx_PyList_Append
ListAppendr  |__Pyx_ListComp_AppendListCompAppend)r   r  r   r!  r  )rM   rT  r  r   mult_factorr"   r   r  r  r  r   r   r|  _wrap_self_argr   r  r   r   r<   r  rq   r  r    rn  r   c_returncode_typer  )r;   r$   r   r   r  r0   r]   r   
tuple_nodewrapped_obj
cloned_objrl   r#   r   r[  r   r   r   !_handle_simple_method_list_extend)  sb   










z6OptimizeBuiltinCalls._handle_simple_method_list_extend	bytearrayc           
   	   C   s   t |dkr|S d}| j}t|d }|jjst|tjr-|t	j
|  }tdd}n+|jrF| s6|S |t	j|  }tdd}n|jjrVd}| j}tdd}n|S tj|j|||d |gd	|j|d
}	|jrv|	|j|  }	|	S )Nr   __Pyx_PyByteArray_Appendr   ByteArrayAppendr  __Pyx_PyByteArray_AppendObjectByteArrayAppendObjectr   Fr   r  r   r!  )rM   PyByteArray_Append_func_typer&   rt   r   r"   r   r   r'  r   r*  r   r   r   is_string_literalcan_coerce_to_char_literalr  r   "PyByteArray_AppendObject_func_typer  rq   r   r   )
r;   r$   r   r   r  	func_namerR  r]   r!  r   r   r   r   &_handle_simple_method_bytearray_appendv  s8   
z;OptimizeBuiltinCalls._handle_simple_method_bytearray_appendpy_indexc_index	is_signed)has_varargsc                 C   s   | j ||||ddS )NT)is_list) _handle_simple_method_object_popr  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r2tj|jd	| | j|gd
|jtddS t|dkrt|d }t	|j}	|j
}
|j
jst|tjrb||  }	|tj|  }n5|r~|j
jrt||  }	t|	}|tj|  }n|S t|j
tjs|S t|tjr||  }	|
js|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|  Objectr   z__Pyx_Py%s_PopTr  r   intvalNz__Pyx_Py%s_PopIndexr   	pop_index)#r   rM   r   r  rq   PyObject_Pop_func_typer   r    r&   rh  rt   r   r"   r   rL  r   r'  r   r   r   rB  rD  numeric_type_fitscreate_to_py_utility_codeto_py_functionr  r  r  PyObject_PopIndex_func_typer)  signedr*  RawCNameExprNodec_void_typeempty_declaration_code)r;   r$   r   r   r  r  r0   r  r   r  orig_index_typeconvert_func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   PyList_Sortr  )rM   _substitute_method_callsingle_param_func_typer'  rt   r   r  r   r   r   _handle_simple_method_list_sort  s   
z4OptimizeBuiltinCalls._handle_simple_method_list_sortkeydefaultc                 C   b   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 3__Pyx_PyDict_GetItemDefaultr  Tdict_getitem_defaultr  r!  )	rM   r<   r   rh  rq   r]  r  Pyx_PyDict_GetItem_func_typer    r  r   r   r   _handle_simple_method_dict_get     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r0t|j	dv }n
|t
ju r8d}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_  __Pyx_PyDict_SetDefault
setdefaultTdict_setdefaultr  )rM   r<   r   rh  rq   r]  rt   r  r  r   r   r  r   r)  r  Pyx_PyDict_SetDefault_func_typer    )r;   r$   r   r   r  key_typer  r   r   r   %_handle_simple_method_dict_setdefault  s.   

z:OptimizeBuiltinCalls._handle_simple_method_dict_setdefaultc                 C   r  )
z7Replace dict.pop() by a call to _PyDict_Pop().
        r   r   zdict.popr  __Pyx_PyDict_Popr  Tpy_dict_popr  )	rM   r<   r   r  rq   r]  r  PyDict_Pop_func_typer    r  r   r   r   _handle_simple_method_dict_pop<  r  z3OptimizeBuiltinCalls._handle_simple_method_dict_popc                 c   s    | ]@}t jt jfD ]7}||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r:dn|jdfV  q
qdS )op1Nop2cvalinplacezerodiv_checkr  )r   r  r  r  r  r   r  )rQ   ctyperet_typer   r   r   r  L  s"    	


c                 C      |  d||||S NAdd_optimise_num_binopr  r   r   r   $_handle_simple_method_object___add__Y     z9OptimizeBuiltinCalls._handle_simple_method_object___add__c                 C   r  NSubtractr  r  r   r   r   $_handle_simple_method_object___sub__\  r  z9OptimizeBuiltinCalls._handle_simple_method_object___sub__c                 C   r  )NMultiplyr  r  r   r   r   $_handle_simple_method_object___mul___  r  z9OptimizeBuiltinCalls._handle_simple_method_object___mul__c                 C   r  NEqr  r  r   r   r   #_handle_simple_method_object___eq__b  r  z8OptimizeBuiltinCalls._handle_simple_method_object___eq__c                 C   r  NNer  r  r   r   r   #_handle_simple_method_object___ne__e  r  z8OptimizeBuiltinCalls._handle_simple_method_object___ne__c                 C   r  )NAndr  r  r   r   r   $_handle_simple_method_object___and__h  r  z9OptimizeBuiltinCalls._handle_simple_method_object___and__c                 C   r  )NOrr  r  r   r   r   #_handle_simple_method_object___or__k  r  z8OptimizeBuiltinCalls._handle_simple_method_object___or__c                 C   r  )NXorr  r  r   r   r   $_handle_simple_method_object___xor__n  r  z9OptimizeBuiltinCalls._handle_simple_method_object___xor__c                 C   `   t |dkst|d tjs|S |d  r%d|d j  kr$dks'|S  |S | d||||S )Nr   r   ?   RshiftrM   r"   r   r   r   r4   r  r  r   r   r   '_handle_simple_method_object___rshift__q     $z<OptimizeBuiltinCalls._handle_simple_method_object___rshift__c                 C   r  )Nr   r   r  Lshiftr  r  r   r   r   '_handle_simple_method_object___lshift__x  r  z<OptimizeBuiltinCalls._handle_simple_method_object___lshift__c                 C   r  N	Remainder_optimise_num_divr  r   r   r   $_handle_simple_method_object___mod__  r  z9OptimizeBuiltinCalls._handle_simple_method_object___mod__c                 C   r  )NFloorDivider  r  r   r   r   )_handle_simple_method_object___floordiv__  r  z>OptimizeBuiltinCalls._handle_simple_method_object___floordiv__c                 C   r  N
TrueDivider  r  r   r   r   (_handle_simple_method_object___truediv__  r  z=OptimizeBuiltinCalls._handle_simple_method_object___truediv__c                 C   r  NDivider  r  r   r   r   $_handle_simple_method_object___div__  r  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r+dks.|S  |S nt|d tjrId|d j  krEdksH|S  |S n|S | |||||S )Nr   r   r   r   r   l       l          )rM   r   r4   r"   r   r   ra  r  )r;   rY   r$   r   r   r  r   r   r   r    s    &z&OptimizeBuiltinCalls._optimise_num_divc                 C   r  r  r  r  r   r   r   #_handle_simple_method_float___add__  r  z8OptimizeBuiltinCalls._handle_simple_method_float___add__c                 C   r  r   r  r  r   r   r   #_handle_simple_method_float___sub__  r  z8OptimizeBuiltinCalls._handle_simple_method_float___sub__c                 C   r  r   r  r  r   r   r   '_handle_simple_method_float___truediv__  r  z<OptimizeBuiltinCalls._handle_simple_method_float___truediv__c                 C   r  r#  r  r  r   r   r   #_handle_simple_method_float___div__  r  z8OptimizeBuiltinCalls._handle_simple_method_float___div__c                 C   r  r  r  r  r   r   r   #_handle_simple_method_float___mod__  r  z8OptimizeBuiltinCalls._handle_simple_method_float___mod__c                 C   r  r  r  r  r   r   r   "_handle_simple_method_float___eq__  r  z7OptimizeBuiltinCalls._handle_simple_method_float___eq__c                 C   r  r  r  r  r   r   r   "_handle_simple_method_float___ne__  r  z7OptimizeBuiltinCalls._handle_simple_method_float___ne__c                 C   s   t |ddr|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||||d |d }|s8|S |\}}	}
}tdd |D sIJ t	||
 }| j
|||| j||f d	|dd
   ||dd|	d
}|jjr||js|t||  |j}|S )zY
        Optimise math operators for (likely) float or small integer operations.
        special_bool_cmp_functionNr   r  r	  r   r   c                 S   s   g | ]}|j jqS r   )rt   r   r  r   r   r   rU     r%  z<OptimizeBuiltinCalls._optimise_num_binop.<locals>.<listcomp>z__%s__r   TF)r  with_none_checkr!  )r  rM   rt   r   r   r  r  optimise_numeric_binopru  r  r  Pyx_BinopInt_func_typeslowerr   r   r   )r;   rY   r$   r   r   r  r  r  
func_cnamer!  
extra_argsnum_typer  r   r   r   r    s6   	z(OptimizeBuiltinCalls._optimise_num_binopucharc              
   C   s   |st |dkr
|S |d }t|tjr|jjjs|S |j}|j}|dkr.t	dd}d}	nd }d|
  }	| j|||	| j|||g|d}
|jjrO|
| j}
|
S )	Nr   r   istitlepy_unicode_istitler  __Pyx_Py_UNICODE_ISTITLEzPy_UNICODE_%srP  )rM   r"   r   r   r#   rt   r  r1   r   r   upperr  #PyUnicode_uchar_predicate_func_typer   rL  r   )r;   r$   r   r   r  ustringr6  r  r!  rY  	func_callr   r   r   _inject_unicode_predicate  s2   z.OptimizeBuiltinCalls._inject_unicode_predicater)  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   FPyUnicode_Splitlines
splitlines)rM   r]  _inject_bint_default_argumentr  PyUnicode_Splitlines_func_typer  r   r   r   (_handle_simple_method_unicode_splitlines!  s   z=OptimizeBuiltinCalls._handle_simple_method_unicode_splitlinessepmaxsplitc              	   C   sx   t |dvr| d||d |S t |dk r |t|j n| |d | ||dtj	d | 
||d| jd||S )	zaReplace unicode.split(...) by a direct call to the
        corresponding C-API function.
        )r   r   r   zunicode.split1-3r   r   r  PyUnicode_Splitsplit)rM   r]  r<   r   r  rq   _inject_null_for_none_inject_int_default_argumentr   r   r  PyUnicode_Split_func_typer  r   r   r   #_handle_simple_method_unicode_split7  s   z8OptimizeBuiltinCalls._handle_simple_method_unicode_splitseqc              	   C   s   t |dkr| d||d |S t|d tjrL|d }|j}t|}|rLtj|j|dt	j
d}|D ]\}	}
tj|	j|	|jd}t||
| q2||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  PyUnicode_Joinr>  )rM   r]  r"   r   rx  r  rL   r}  rq   r   r   r  ri   r   r|  r  PyUnicode_Join_func_type)r;   r$   r   r   r  r  r  rO   inlined_genexprr  r  r  r   r   r   "_handle_simple_method_unicode_joinP  s2   z7OptimizeBuiltinCalls._handle_simple_method_unicode_join	substringr  end	directionc              
   C      |  ||||ddtdS )Nr#  endswithr   _inject_tailmatchunicode_tailmatch_utility_coder  r   r   r   &_handle_simple_method_unicode_endswithz     z;OptimizeBuiltinCalls._handle_simple_method_unicode_endswithc              
   C   rW  )Nr#  
startswithr:  rY  r  r   r   r   (_handle_simple_method_unicode_startswith  r]  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r]   rt   z__Pyx_Py%s_TailmatchrP  )rM   r]  rK  r   r   r<   r   r   rq   r)  r*  r  
capitalizePyString_Tailmatch_func_typer'  r   r  r   )
r;   r$   r   r   r  r  r  r!  rV  method_callr   r   r   rZ    s(   
z&OptimizeBuiltinCalls._inject_tailmatchz-2c                 C      |  ||||ddS )Nfindr   _inject_unicode_findr  r   r   r   "_handle_simple_method_unicode_find     z7OptimizeBuiltinCalls._handle_simple_method_unicode_findc                 C   rh  )Nrfindr:  rj  r  r   r   r   #_handle_simple_method_unicode_rfind  rm  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.%srb  r   r   r   rc  rd  PyUnicode_Find)rM   r]  rK  r   r   r<   r   r   rq   r)  r*  r  PyUnicode_Find_func_typerL  r   )r;   r$   r   r   r  r  rV  rg  r   r   r   rk    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.countrb  r   r   r   rc  PyUnicode_Countcount)	rM   r]  rK  r   r   r  PyUnicode_Count_func_typerL  r   )r;   r$   r   r   r  rg  r   r   r   #_handle_simple_method_unicode_count  s   
z8OptimizeBuiltinCalls._handle_simple_method_unicode_countreplstr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   ra  zunicode.replacez3-4r   r  PyUnicode_Replacer  )rM   r]  rK  r   r   r  PyUnicode_Replace_func_typer  r   r   r   %_handle_simple_method_unicode_replace  s   
z:OptimizeBuiltinCalls._handle_simple_method_unicode_replaceencodingerrors)UTF8UTF16UTF-16LEUTF-16BELatin1ASCIIunicode_escaperaw_unicode_escapec                 C   s   g | ]	}|t |fqS r   )codecs
getencoder)rQ   r   r   r   r   rU      s    zOptimizeBuiltinCalls.<listcomp>c                 C   sB  t |dk st |dkr| d||d |S |d }t |dkr5t|j}| ||d| jd||||gS | |j|}|du rB|S |\}}	}
}|rnt|tj	rnz	|j
||
}W n   Y nt||}tj|j|tjd	S |r|
d
kr| |}|durd|vrd| }| |||| 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.encoderG  r   PyUnicode_AsEncodedStringr#  Nrd  strictrl  zPyUnicode_As%sString)rM   r]  r   r  rq   r  #PyUnicode_AsEncodedString_func_type_unpack_encoding_and_error_moder"   r  r]   r#  r   r%  r   r   _find_special_codec_namePyUnicode_AsXyzString_func_type)r;   r$   r   r   r  string_node	null_node
parametersr{  encoding_nodeerror_handlingerror_handling_noder]   
codec_nameencode_functionr   r   r   $_handle_simple_method_unicode_encode  sJ   

z9OptimizeBuiltinCalls._handle_simple_method_unicode_encodestringr@  r  decode_funcc                 C   s:  dt |  krdksn | d||d |S |d }d }}t|tjr:|}|j}|j|j}}|r8|jdkr:d}t|tj	rC|j
}|j}	|	tjtjfv re|r[|jdd|	jgd	}n|jd
ddgd}n|	jsm|	jsm|S | |j|}
|
du rz|S |
\}}}}|stj|jddd}n|jjs|tj|  }|r|jjs|tj|  }d}|dur| |}|dur|dv rd|dd }nd| }tj|j| j|d}t|j}nt|j}g }|	jr|s|j st!"|}|#| tj$|jd| j%|gdd}| j&}d}ni|	jrV|stj|jdtj'd}| j(du rPt)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 }n|sctj|jdtj'd}| j-}|	tju rod!}nd"}tj$|jd#| |||||||g|j.t/0|d$d%}|ddd& D ]	}t!1||}q|S )'zReplace char*.decode() by a direct C-API call to the
        corresponding codec, possibly resolving a slice on the char*.
        r   r   zbytes.decoderG  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%srl  rz  zPyUnicode_Decode%s)rt   r  r\  Tr
  decode_c_stringrc  r  r  r  r{  r|  r  decode_cpp_stringdecode_bytesdecode_bytearrayz__Pyx_%sr  r  r:  )2rM   r]  r"   r   r  rs   r  r  r4   r   r#   rt   r   r   r   r   r   rE  is_cpp_stringr  rq   r   r   r'  r   r   r   r  r  r  !PyUnicode_DecodeXyz_func_ptr_typer  r   r   r   r<   r  rc  _decode_c_string_func_typer   _decode_cpp_string_func_typer  r   r  r&  _decode_bytes_func_typer   r   r   r  )r;   r$   r   r   r  r  r  r  r:  string_typer  r{  r  r  r  r  codec_cnamedecode_functionrl   helper_func_typerD  r[  r   r   r   "_handle_simple_method_bytes_decodeQ  s   





	

z7OptimizeBuiltinCalls._handle_simple_method_bytes_decodec                 C   sj   zt |}W n
 ty   Y d S w | jD ]\}}||kr2d|v r.ddd |dD }|  S qd S )Nr  rz  c                 S   s   g | ]}|  qS r   )re  )rQ   r  r   r   r   rU     s    zAOptimizeBuiltinCalls._find_special_codec_name.<locals>.<listcomp>)r  r  LookupError_special_codecsr>  rI  )r;   r{  requested_codecr   codecr   r   r   r    s   
z-OptimizeBuiltinCalls._find_special_codec_namec                 C   s   t |}t|dkr| |d \}}|d u rd S nd }|}t|dkr;| |d \}}|d u r4d S |dkr:|}nd}|}||||fS )Nr   r   r   r  )r   r  rM   _unpack_string_and_cstring_node)r;   rq   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}||fS t |tjtjfr@|jd}tj|j|jt	j
d}||fS |jtju rUd }|t	j
|  }||fS |jjr_d }||fS d  }}||fS )Nrd  z
ISO-8859-1)r"   r   r   r#   r  r]   r%  rq   as_utf8_stringr   r&  r  r  rt   r   r   r'  r   rE  )r;   r$   r{  r   r   r   r    s.   	z4OptimizeBuiltinCalls._unpack_string_and_cstring_nodec              
   C   rW  )Nr)  rX  r   rZ  str_tailmatch_utility_coder  r   r   r   "_handle_simple_method_str_endswith  r]  z7OptimizeBuiltinCalls._handle_simple_method_str_endswithc              
   C   rW  )Nr)  r^  r:  r  r  r   r   r   $_handle_simple_method_str_startswith  r]  z9OptimizeBuiltinCalls._handle_simple_method_str_startswithc              
   C   rW  )Nr  rX  r   rZ  bytes_tailmatch_utility_coder  r   r   r   $_handle_simple_method_bytes_endswith  r]  z9OptimizeBuiltinCalls._handle_simple_method_bytes_endswithc              
   C   rW  )Nr  r^  r:  r  r  r   r   r   &_handle_simple_method_bytes_startswith  r]  z;OptimizeBuiltinCalls._handle_simple_method_bytes_startswithr   c              
   C   sT   t |}|r|r| |d ||||d< |	d u r|j}	tj|j||||	||
|jdS )Nr   )r   r   r!  r  r   )r  r  r   r   r  rq   r   )r;   r$   r   r   rR  r  r  r   r!  r   r  r/  r   r   r   r  #  s   z,OptimizeBuiltinCalls._substitute_method_callc                 C   sT   |j r|S |r|jd||jjgd}|S |jdt|dkr dndd|gd}|S )	Nr  r  rw  rx  ry  rz  r{  r|  )r"  r   rt   r   r  rM   )r;   self_argr   r  r  r   r   r   r  6  s   
z#OptimizeBuiltinCalls._wrap_self_argc                 C   sV   t ||krd S || }|jrt|jntj|jd| j||  gdd||< d S )N__Pyx_NoneAsNullr   r
  )	rM   r  r   r  rq   r  obj_to_obj_func_typerB  r   )r;   r   r   r#   r   r   r   rJ  I  s   z*OptimizeBuiltinCalls._inject_null_for_nonec                 C   s~   t ||ksJ t ||ks|| jr$|tj|jt|||d d S || ||  }t	|tj
r9t||_|||< d S )Nr9  )rM   r  r<   r   r   rq   r)  r'  r   r"   r  special_none_cvalue)r;   r$   r   	arg_indexrt   default_valuer#   r   r   r   rK  T  s   
z1OptimizeBuiltinCalls._inject_int_default_argumentc                 C   sZ   t ||ksJ t ||kr t|}|tj|j||d d S || |  ||< d S Nr_  )rM   rK  r<   r   r{   rq   r  r   )r;   r$   r   r  r  r   r   r   rB  b  s   z2OptimizeBuiltinCalls._inject_bint_default_argumentr!   r  )rG   rH   rI   rJ   r  r  rA   r  r   r  r  r  r  r  r  r  r   r   r   r*  r  r  r   c_float_typerb  c_longdouble_typer  r  rH  r  r  r  r]  r  r  r
  r  r  r   r$  r  r(  r   r*  r  r   r  r  r   r-  r.  r   r1  r  r   r5  r  rB  rf  rI  rH  rJ  rM  memoryview_typerQ  rR  rS  rT  r&  rc  c_const_py_unicode_ptr_typere  rj  r   r  rf  ri  rl  rz  ro  rp  r  r  r  rm  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rk  r1  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>  %_handle_simple_method_unicode_isalnum%_handle_simple_method_unicode_isalpha'_handle_simple_method_unicode_isdecimal%_handle_simple_method_unicode_isdigit%_handle_simple_method_unicode_islower'_handle_simple_method_unicode_isnumeric%_handle_simple_method_unicode_isspace%_handle_simple_method_unicode_istitle%_handle_simple_method_unicode_isupper$PyUnicode_uchar_conversion_func_typerC  rD  rL  rM  rQ  rS  rf  r\  r_  rZ  rq  rl  ro  rk  rt  ru  ry  rz  r  r  _special_encodingsr  r  r  r  r  r  r  r  &_handle_simple_method_bytearray_decoder  r  r  r  r  r  r  r   r  r  r  r  r  rJ  rK  rB  r   r   r   r   r  J  sb   	(	5
,8	5G
J
	?!	
D	
	' 

	1

v
r  c                 C   s  t jt jf}t||r|jtjurdS |}d}nt||r*|jtjur%dS |}d}ndS | s2dS t|t j}|r=tjntj	}	|rI| dvrHdS n| dkrOdS t
|jdkrXdS | dv rc|jdkrcdS g }
|
|rlt jnt j|j|j|j|	d	 t|t jr|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}d|rdnd|jrdnd| |f }|||
|	fS )zQ
    Optimise math operators for (likely) float or small integer operations.
    NObjCCObj)r  r  r  r!  r$  r  r	  r$  r   )r!  r  r$  r  r   r   Fr_  r.  PyFloatBinopPyIntCompare
PyIntBinopr   )oporderr  )r   z__Pyx_Py%s_%s%s%sFloatIntrz  Bool)r   r   ra  r"   rt   r   r  r   rb  rk  r?  r4   r<   rq   r]   NumBinopNoder  r{   rp  	cdivisionr   r   r   r   )rY   r$   r  arg0arg1	num_nodesnumval	arg_orderr  r5  r4  r  zerodivision_checkr!  r3  r   r   r   r0  l  sf   



r0  unicode_tailmatchr  bytes_tailmatchstr_tailmatchc                       sB  e Zd ZdZdG fdd	Zdd Zejejej	ej
gZdd Zd	d
 Zdd Zdd ZdddddjZdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(Zd)d* Zd+d, Zd-d. Zd/d0 Z d1d2 Z!d3d4 Z"d5d6 Z#d7d8 Z$d9d: Z%d;d< Z&d=d> Z'd?d@ Z(dAdB Z)dCdD Z*dEdF Z+e,j-j.Z/  Z0S )H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)superr  r8   
reevaluate)r;   r  	__class__r   r   r8     s   
zConstantFolding.__init__c                 C   s   | j s|jtjurd S tj}||_| |}| D ]%}t|tu r4|D ]}t	|d||u r2  d S q$qt	|d||u r? d S qz|
  W d S  ttttttfyW   Y d S  tyo   dd l}dd l}|j|jd Y d S w )Nr4   r   )file)r  r4   r   constant_value_not_setr   r=   r   rt   r  r  calculate_constant_result
ValueError	TypeErrorrV   
IndexErrorr  ArithmeticErrorr  	tracebacksys	print_excstdout)r;   r$   r   childrenchild_resultchildr  r  r   r   r   _calculate_const  s0   
z ConstantFolding._calculate_constc                 G   s6   z| j tt| j jtt| W S  ty   Y d S w r!   )NODE_TYPE_ORDERmaxr  r   rt   r  )r;   nodesr   r   r   _widest_node_class  s   z"ConstantFolding._widest_node_classc                 C   s   t |}tj|j||dS r  )rK  r   r{   rq   )r;   r$   r]   r   r   r   
_bool_node  s   zConstantFolding._bool_nodec                 C      |  | |S r!   )r  r>   r   r   r   visit_ExprNode  s   
zConstantFolding.visit_ExprNodec                 C   s   |  | | s|jdkr| |S |S |jjs|S |jdkr'| ||jS t|jt	j
rAt	j|jtt|jtjt|jdS |jdkrK| |S |jdkrU| |S |S )N!r9  r;  rl  )r  r   rY   _handle_NotNodero   r"  r  r4   r"   r   r{   r   rq   r)  r  r   r*  _handle_UnaryPlusNode_handle_UnaryMinusNoder>   r   r   r   visit_UnopNode  s&   







zConstantFolding.visit_UnopNoderm   r  is_notis)r  rm   r  r  c                 C   s@   |j }t|tjr| |j}|rt|}||_| |}|S r!   )ro   r"   r   rx   _negate_operatorrY   copyr   )r;   r$   ro   rY   r   r   r   r    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r$|j	s.t|j tj
r@|jr@tj
|j||j j||j j|jdS |S )Nc                 S   s&   |  dr| dd  } | S d|  } | S )Nrl  r   )r^  r\   r   r   r   _negate'  s
   
z7ConstantFolding._handle_UnaryMinusNode.<locals>._negater9  )r]   rt   longnessr4   )ro   rt   r"   r   ra  rq   r]   r4   r   r  r   r   r  )r;   r$   r  	node_typer   r   r   r  &  s$   z&ConstantFolding._handle_UnaryMinusNodec                 C   s"   |j  r|j|j jkr|j S |S r!   )ro   r   r4   r>   r   r   r   r   <  s   
z%ConstantFolding._handle_UnaryPlusNodec                 C   sL   |  | |j s|S |jjr|jdkr|jS |jS |jdkr#|jS |jS )Nr  )r  rZ   r   r4   rY   r[   r>   r   r   r   r  B  s   



z#ConstantFolding.visit_BoolBinopNodec              	   C   s  |  | |jtju r|S t|jtr|S |j|j}}|jr"|js$|S z|j	|j	}}|d u s4|d u r7|W S W n t
yC   | Y S w |jrQ|jrQt||}ntj}| ||}|d u r`|S |tju rn|jdv rntj}n|tju r{|jdv r{tj}|tju rt|ddot|dd}dd ttt|ddtt|dd }	tt|j}
t|
}
tj|j||	|
t|jd}|js|j	jrtj|_	|S t||j	|_	|S |tju r|j}nt|j}||j|||jd}|S )	Nz+-//<<%**>>z+-//<<%**>>&|^unsignedrz  LLr  )rq   r
  r  r]   r4   )rq   rt   r]   r4   )r  r4   r   r   r"   r`  rZ   r[   r"  rt   r  r  r   widest_numeric_typer  r  r{   rY   r   r  r  r  rM   hexr  r   strip_py2_long_suffixrq   r   r)  )r;   r$   rZ   r[   type1type2widest_typetarget_classr
  r  r]   r   
node_valuer   r   r   visit_BinopNodeQ  sj   



	

zConstantFolding.visit_BinopNodec                 C   s  |  | |jtju r|S |jjr}|jjr}|j|j}}t|tjrWt|tjrWd }|j	d urG|j	d urG|j	j
|j	j
krGt|j	|j	 |j	j
}t|j}tj|j||j|dS t|tjr}t|tjr}|jj
|jj
kr}t|j|jj
}tj|j||jdS | |S )N)r]   r4   r2  r_  )r  r4   r   r   rZ   r  r[   r"   r  r2  r{  r   r   rq   r%  r]   r  )r;   r$   str1str2r2  string_valuer   r   r   visit_AddNode  s,   



zConstantFolding.visit_AddNodec                 C   s   |  | |jjr| ||j|jS t|jtjr&|jjr&| ||j|jS |jjr3| 	||j|jS |jjr@| 	||j|jS | 
|S r!   )r  rZ   rT  _calculate_constant_seqr[   r"   r   r   r  _multiply_stringr  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r*t	}n>t|tj
rI|jd ur@t|j| |jj|_|jjrFtnt	}nt|tjr`|jd ur_t	|j| |jj|_nJ dt| ||j| |jj|_t|tj
r|jd ur|j|_ |S |j|_ |S )N   Fzunknown string node type: %s)r4   r"   r   r   _py_string_typesrM   r	   r   r%  r   r  rl  r{  r]   
is_unicoder  r2  rt   )r;   r$   r  multiplier_node
multiplierbuild_stringr   r   r   r    sD   


z ConstantFolding._multiply_stringc                 C   s   |j dkrN|jrNt|j tr|j dkr|jd d = d |_|S |jd urKt|j trFt|jj trF|jj |j  }tj|jjt||d|_|S | 	|S ||_|S r  )
r4   r   r"   r   r  r   r   rq   r)  r  )r;   r$   sequence_nodefactorr]   r   r   r   r    s$   

z'ConstantFolding._calculate_constant_seqc                 C   s^   |  | t|jtjr*t|jtjr*|jjs*| |jj	|jj
|jj}|d ur*|S | |S r!   )r=   r"   rZ   r   r  r[   r  r  _build_fstringrq   r]   r   r  )r;   r$   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r&|tj|tddd q|d dkrO|d dkrAt|d|dd   d	d
 d}|tj|t||d q|d }zt	|}	W n t
yl   t|dd	d
 d}Y  niw |	jrtd} na|dv r|d	d  }
d }|dv rd|
v rd}n |dv r|
d d }
|}|
drd|
d	d   }
n|dkrd}|
drd|
d	d   }
|tj|	j|	||
rtj|t|
|
dnd d qd} |sd S zt	| W n	 t
y   Y n
w 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 placeholdersasrfdoxXdoxXr<  arsr   r   drl  r   )r]   r'  r&  z*Too many arguments for format placeholders)r   )iterrerI  _parse_string_format_regexr<   r   r  r   r   nextStopIterationr  r^  FormattedValueNoderq   JoinedStrNodevisit_JoinedStrNode)r;   rq   r<  r}  r   
substringscan_be_optimisedr  format_typer#   r&  r'  r$   r   r   r   r$    sz   



	
zConstantFolding._build_fstringc                 C   s   |  | |jp	d}t|jtjr|jjsd |_|jd u r8t|jtjr8t|jj}|	 r8tj|jj
||dS |jd u rh|dkrhd }t|jtjrO|jj}nt|jtjrZ|jj}|d urhtj|jj
||dS |S )Nr  r_  )r=   r'  r"   r&  r   r  r]   r   r   isdigitrq   r  rl  )r;   r$   r'  r]   r   r   r   r(  A  s"   


z(ConstantFolding.visit_FormattedValueNodec                    s  |  | tj g }t|j fddD ]7\}}|rGt|}|d }t|dkr>td	dd |D }tj|j
||d}|jrF|| q|| q|s^td}tj|j
||d}|S t|dkrj|d }|S t|d	kr}tj|j
d
g|R  }|S ||_|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unicode_noder   r   <lambda>^  s   
 z5ConstantFolding.visit_JoinedStrNode.<locals>.<lambda>r   r   rz  c                 s   s    | ]}|j V  qd S r!   r\   )rQ   r]   r   r   r   r  c  s    z6ConstantFolding.visit_JoinedStrNode.<locals>.<genexpr>r_  r   r;  )r=   r   r  	itertoolsgroupbyr   r  rM   r   r>  rq   r]   r<   r  rn  )r;   r$   r   is_unode_groupr6  unoder]   r   r;  r   r5  T  s4   

z#ConstantFolding.visit_JoinedStrNodec                    s   |  | g g  fdd |jD ]} || qr# tdkr8d }|js6t|tjr8|S |jdd< | | |S )z!Unpack **args in place if we can.c                    s   |j rrd j|jkrd j|j d S | d S t|tjr8| j|jkr8|jD ]} || q.d S rD d d = | d S )Nr:  )	is_dict_literalreject_duplicatesr  r  r<   r"   r   MergedDictNoderJ  )parentr#   	child_argr  r   r   r   r   r  }  s   


z1ConstantFolding.visit_MergedDictNode.<locals>.addr   r   N)	r=   rJ  r  rM   rB  r"   r   rD  r  r  r   rG  r   visit_MergedDictNodew  s   



z$ConstantFolding.visit_MergedDictNodec                    s   |  | |jtju g g  fdd |jD ]} | qr+d  tdkrKd }r:|jsI|jrC|j|ju sIt	|t
jrK|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 d S |  d S t| tjr1| jD ]} | q(d S r?d  d d = |  d S )Nr   )	is_set_literalrT  r  r   r  r<   r"   r   MergedSequenceNode)r#   rF  r  r   r  r   r   r   r    s   


z5ConstantFolding.visit_MergedSequenceNode.<locals>.addr   r   N)r=   rt   r   r   r   r<   rM   rJ  rT  r"   r   rK  r  r  r   rL  r   visit_MergedSequenceNode  s*   





z(ConstantFolding.visit_MergedSequenceNodec                 C   sr   |  | g }|jD ] }|js|| q
|jjr%|jjs%||jj q
|| q
||jdd< | | |S )rI  N)	r=   r   r  r<   ri   rT  r  r  r  )r;   r$   r   r#   r   r   r   visit_SequenceNode  s   


z"ConstantFolding.visit_SequenceNodec                 C   s  |  |dg |j}|}|d urF|  |dg |j}t|_| r=| r=z||j W n ttt	t
ttfy<   Y nw |}|j}|d us|jsV| rT| ||jS |S |jgg}g }|}|d ur| r||jst|| |d n||jg n|d | |j}|d uscg }|D ]4}t|dk rq|d }tj|j|d |j|jtd}	||	 |	}
|dd  D ]}||
_|}
qd |
_q|r||d  n|s| |d	S |d }t|dkr| r| ||jS |S |dd  D ]}tj|j|d
|td}q|S )NrZ   r[   Fr:  r   r   r   )rZ   rY   r[   r4   Tr  )r=   rZ   r[   r   r4   r   "calculate_cascaded_constant_resultr  r  rV   r  r  r  r  r  r<   rM   r   rx   rq   rY   r  )r;   r$   	left_noder   
right_nodecascadesfinal_false_result	cmp_nodesr  	pcmp_nodelast_cmp_noder   r   r   r     s   

	z$ConstantFolding.visit_PrimaryCmpNodec                 C   s,   |  | |j s|S |jjr|jS |jS r!   )r  r  r   r4   r  r  r>   r   r   r   r    s   

z"ConstantFolding.visit_CondExprNodec                 C   sp   |  | g }|jD ]}|j}| r|jr|j|_ nq
|| q
|r*||_|S |jr0|jS tj	|j
g dS Nra   )r=   rf   rd   r   r4   re   rg   r<   r
   ry   rq   )r;   r$   rf   r  rd   r   r   r   r  '  s    

z ConstantFolding.visit_IfStatNodec                 C   s   |  | |jd u s|jjd u rd  }|_n|jj}|jd u s%|jjd u r+d  }|_n|jj}|jturX|j}|jrI|jd u rI|j|| |_|S |j	rX|
||}|d urX|S |S r!   )r  r  r4   r  r   rs   rT  r  r   r  as_sliced_node)r;   r$   r  r  rs   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
   ry   rb   rt   r   r   r   r  rq   r   r  r  r   r  r>   r   r   r   visit_ComprehensionNodeU  s   

z'ConstantFolding.visit_ComprehensionNodec                 C   s\   |  | |jj}t|tjr,|js |jr|jS tj	|j
g dS t|tjr,| |j_|S rW  )r=   rj   rh   r"   r   SequenceNoder   rg   r
   ry   rq   r  r  )r;   r$   rh   r   r   r   r   d  s   
z#ConstantFolding.visit_ForInStatNodec                 C   s<   |  | |jr|j r|jjrd |_d |_|S |jS |S r!   )r=   rd   r   r4   rg   r>   r   r   r   visit_WhileStatNodes  s   
z#ConstantFolding.visit_WhileStatNodec                 C   s.   |  | t|jtjs|S |j rd S |S r!   )r=   r"   r@   r   ExprNoder   r>   r   r   r   rA   }  s   

z"ConstantFolding.visit_ExprStatNodec                 C   s>   |  | |jd u r|S |j r|jjrd |_|S |jS |S r!   )r=   rd   r   r4   re   r>   r   r   r   visit_GILStatNode  s   


z!ConstantFolding.visit_GILStatNoder  )1rG   rH   rI   rJ   r8   r  r   r{   r  r   ra  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r  r  r&  r0  r$  r(  r5  rH  rM  rN  r   r  r  rY  rZ  r   r\  rA   r^  r   r
  r  rK   __classcell__r   r   r  r   r    s\     
<$
G#"&P	

r  c                   @   sV   e Zd ZdZdZdd Zdd Zdd Zd	d
 Zdd Z	dd Z
dd ZdddZdS )FinalOptimizePhaseap  
    This visitor handles several commuting optimizations, and is run
    just before the C code generation phase.

    The optimizations currently implemented in this class are:
        - eliminate None assignment and refcounting for first assignment.
        - isinstance -> typecheck for cdef types
        - eliminate checks for None and/or types that became redundant after tree changes
        - eliminate useless string formatting steps
        - inject branch hints for unlikely if-cases that only raise exceptions
        - replace Python function calls that look like method calls by a faster PyMethodCallNode
    Fc                 C   s    |  | |jr|j}d|_|S )zaAvoid redundant initialisation of local variables before their
        first assignment.
        T)r=   r  r_   lhs_of_first_assignment)r;   r$   r_   r   r   r   visit_SingleAssignmentNode  s
   
z-FinalOptimizePhase.visit_SingleAssignmentNodec              	      s  |  | |j}|jjrP|jrP|jdkrNt|jdkrN|jd }|jjrN|jjdkrN| j	j
}|d|_|jj|_t|dj}t|jd ||jd< |S |jr|jjr| j| jsd|  jrddndrt|jtjr|jjs|jjr~t|jjdksd	}|jtju rd
}n5|jr|jr|jjjrd
}n'|jr|j}|j s|jjrd
}n|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   rt   PyObject_TypeCheckr  z&optimize.unpack_method_calls_in_pyinitzoptimize.unpack_method_callsTFc                 3   s$    | ]}|j ot|j   V  qd S r!   )r`   r"   )rQ   
assignmentnon_method_nodesr   r   r    s
    
z:FinalOptimizePhase.visit_SimpleCallNode.<locals>.<genexpr>)r   r   rt   )-r=   r   rt   is_cfunctionr   r   rM   r   r  r   r  r   r   r   r  r   rF  r   r   r  r  in_loopr   is_module_scoper"   r   r  r  r"  r   rz  r   r   r  r  	ClassNodePy3ClassNoder  r;   r0   rD  r#   r  PyMethodCallNode	from_node)r;   r$   r   r  r  r  may_be_a_methodr   r   re  r   rH    sf   


!
z'FinalOptimizePhase.visit_SimpleCallNodec                 C   r  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=   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)rh  r=   )r;   r$   old_valr   r   r   visit_LoopNode	  s
   
z!FinalOptimizePhase.visit_LoopNodec                 C   sZ   |  | d}t|jD ]\}}| ||j |js|}q|jr+|r+| j||jdd |S )zQAssign 'unlikely' branch hints to if-clauses that only raise exceptions.
        NT)inverse)r=   r   rf   _set_ifclause_branch_hintre   branch_hintrg   )r;   r$   last_non_unlikely_clauser  r  r   r   r   r    s   

z#FinalOptimizePhase.visit_IfStatNodec                 C   s   |j sdS tjtjtjtjtjtjf}|g}t|dD ]>\}}t	|tj
r-|||j qt	|tjr;|j|||< qt	||sY|t|krVt	|tjtjfrV|rSdnd|_ dS qdS )z\Inject a branch hint if the if-clause unconditionally leads to a 'raise' statement.
        Nr   likelyunlikely)is_terminatorr
   r   AssignmentNodeAssertStatNodeDelStatNode
GlobalNodeNonlocalNoder   r"   GILStatNoder   re   ry   rb   rM   RaiseStatNodeReraiseStatNoderv  )r;   clausestatements_nodert  non_branch_nodes
statementsnext_node_posr$   r   r   r   ru     s.   
z,FinalOptimizePhase._set_ifclause_branch_hintNr  )rG   rH   rI   rJ   rh  rb  rH  ro  r  rq  rs  r  ru  r   r   r   r   r`    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   s8   | j d ur| j }d | _ | | || _ |S | | |S r!   )overflow_bit_noder=   )r;   r$   savedr   r   r   rK   F  s   


z#ConsolidateOverflowCheck.visit_Nodec                 C   sV   |j r$|jr$| jd u }|r|| _n| j|_d|_ | | |r"d | _|S | | |S r+   )overflow_checkoverflow_foldr  r=   )r;   r$   top_level_overflowr   r   r   visit_NumBinopNodeP  s   


z+ConsolidateOverflowCheck.visit_NumBinopNode)rG   rH   rI   rJ   r  rK   r  r   r   r   r   r  =  s
    
r  )M
__future__r   r/  r  r  r  r>  rz  r   r   r   cythondeclarerm  version_infor  r   r  r)  r  longr#  r
   r   r   r   r   r   Coder   r   StringEncodingr   r   r	   Errorsr   r   ParseTreeTransformsr   r   __builtin__r   ImportError	functoolsr   r    r   r  r&   r*   r/   r5   r7   r6   rP   rL   EnvTransformrW   r  r
  r  r   rE  NodeRefCleanupMixinr  MethodDispatcherTransformr  r0  r   r[  r  r  r  r`  CythonTransformr  r   r   r   r   <module>   s    

          Lt   h"                2E     t 