B
    Í‹dx5 ã               @   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rŽe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' yd dl(m)Z) W n" e*k
rd   d dl+m)Z) Y nX yd dl(m,Z, W n e*k
r   eZ,Y nX dd„ Z-e	j.e	j/ffdd„Z0dd„ Z1dd„ Z2dd„ Z3G dd „ d ej4ƒZ5d!d"„ Z6d#d$„ Z7G d%d&„ d&ej8ƒZ9G d'd(„ d(ej8ƒZ:G d)d*„ d*ej;e'ƒZ<G d+d,„ d,ej;ƒZ=G d-d.„ d.ej8ƒZ>G d/d0„ d0ej?ej8ƒZ@G d1d2„ d2ej?ejAƒZBe Cd3d4¡ZDe Cd5d4¡ZEe Cd6d4¡ZFG d7d8„ d8ej;e'ƒZGG d9d:„ d:ej8ej?ƒZHG d;d<„ d<ejIƒZJdS )=é    )Úabsolute_importNé   )Ú	TypeSlots)Únot_a_constant)
ÚUtilityCodeÚEncodedStringÚbytes_literalÚencoded_stringÚNodesÚ	ExprNodesÚ
PyrexTypesÚBuiltinÚ	UtilNodesÚ_py_int_typesé   )r
   )r   )r   )ÚVisitor)r   )r   )ÚOptions)r   ÚTempitaUtilityCode)r   r   r	   )ÚerrorÚwarning)ÚSkipDeclarations)Úreduce)Ú
basestringc             C   s   t  | d¡S )Nz
Optimize.c)r   Úload_cached)Úname© r   úe/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/Cython/Compiler/Optimize.pyÚload_c_utility/   s    r   c             C   s   t | |ƒr| jS | S )N)Ú
isinstanceÚarg)ÚnodeZcoercion_nodesr   r   r   Úunwrap_coerced_node3   s    
r!   c             C   s   xt | tjƒr| j} qW | S )N)r   r   ÚResultRefNodeÚ
expression)r    r   r   r   Úunwrap_node9   s    
r$   c             C   sr   t | ƒ} t |ƒ}t| tjƒr4t|tjƒr4| j|jkS t| tjƒrnt|tjƒrn| j olt| j|jƒol| j	|j	kS dS )NF)
r$   r   r   ÚNameNoder   ÚAttributeNodeÚ
is_py_attrÚis_common_valueÚobjÚ	attribute)ÚaÚbr   r   r   r(   ?   s    "r(   c             C   s   | d k	r| j d krd S | S )N)Úconstant_result)r    r   r   r   Úfilter_none_nodeI   s    r.   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 )N)r   ÚTreeVisitorÚ__init__Úyield_stat_nodesÚyield_nodes)Úselfr   r   r   r1   S   s    z_YieldNodeCollector.__init__c             C   s   | j  |¡ |  |¡ d S )N)r3   ÚappendÚvisitchildren)r4   r    r   r   r   Úvisit_YieldExprNodeZ   s    z'_YieldNodeCollector.visit_YieldExprNodec             C   s&   |   |¡ |j| jkr"|| j|j< d S )N)r6   Úexprr3   r2   )r4   r    r   r   r   Úvisit_ExprStatNode^   s    
z&_YieldNodeCollector.visit_ExprStatNodec             C   s   d S )Nr   )r4   r    r   r   r   Úvisit_GeneratorExpressionNodee   s    z1_YieldNodeCollector.visit_GeneratorExpressionNodec             C   s   d S )Nr   )r4   r    r   r   r   Úvisit_LambdaNodeh   s    z$_YieldNodeCollector.visit_LambdaNodec             C   s   d S )Nr   )r4   r    r   r   r   Úvisit_FuncDefNodek   s    z%_YieldNodeCollector.visit_FuncDefNodeN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r1   r   r0   r6   Ú
visit_Noder7   r9   r:   r;   r<   r   r   r   r   r/   O   s   r/   c             C   s    t | ƒ}t|ƒdkrdS |d S )Nr   )NNr   )Ú_find_yield_statementsÚlen)r    Úyield_statementsr   r   r   Ú_find_single_yield_expressiono   s    rE   c                sF   t ƒ ‰ ˆ  | ¡ y‡ fdd„ˆ jD ƒ}W n tk
r@   g }Y nX |S )Nc                s   g | ]}|j ˆ j| f‘qS r   )r   r2   )Ú.0Z
yield_node)Ú	collectorr   r   ú
<listcomp>{   s   z*_find_yield_statements.<locals>.<listcomp>)r/   r6   r3   ÚKeyError)r    rD   r   )rG   r   rB   v   s    


rB   c               @   sÖ  e Zd ZdZdd„ Zdd„ Zd-dd„Zd	d
„ Ze 	ej
e dejd¡g¡Ze 	eje dejd¡g¡Zd.dd„Ze 	eje dejd¡e dejd¡e dejd¡g¡Zej	eje dejd¡e dejd¡e dejd¡e dejd¡gddZd/dd„Zd0dd„Zdd„ Zdd„ Zd1dd„Zdd „ Z d!d"„ Z!e 	eje d#ejd¡e d$ejd¡e d%ejd¡e d&ejd¡e d'ejd¡g¡Z"e 	eje d(ejd¡e d)ejd¡e d&ejd¡e d*ejd¡g¡Z#d+d,„ Z$dS )2ÚIterationTransforma   Transform some common for-in loop patterns into efficient C loops:

    - for-in-dict loop becomes a while loop calling PyDict_Next()
    - for-in-enumerate is replaced by an external counter variable
    - for-in-range loop becomes a plain C for loop
    c             C   sJ  |  ¡ r8|j}t |¡}|jjr0|jjjj}n
|jjj}t 	|¡}| 
|¡}tj|d|j|d}tj|tj||tj|dddt |¡gd}tj|tj|||dgd d}	tj||gtj||tj|jj|jd	|	tj||tj|d
dddd}
|
 |  ¡ ¡}
|  |
¡}
t ||
¡}|jdkr4tj||d}|S |  |¡ |S d S )Nz==)ÚoperatorÚoperand1Úoperand2r   )Úvalue)ÚlhsÚrhs)Ústats)Ú	conditionÚbody)Ú
if_clausesÚelse_clause)Úsequencer   )ÚtargetÚiteratorrS   rU   )ÚtempsrS   Únot_in)Úoperand)Zis_ptr_containsÚposr   r"   rM   Úis_subscriptÚbaseÚtypeÚ	base_typeÚ
TempHandleÚrefr   ÚPrimaryCmpNoderL   r
   ÚStatListNodeÚSingleAssignmentNodeÚBoolNodeZBreakStatNodeÚ
IfStatNodeÚIfClauseNodeÚTempsBlockNodeZForInStatNodeZIteratorNodeÚanalyse_expressionsÚcurrent_envÚvisitÚTempResultFromStatNoderK   ÚNotNoder6   )r4   r    r\   Ú
result_refr`   Ztarget_handlerW   Úcmp_nodeZif_bodyZif_nodeZfor_loopÚnew_noder   r   r   Úvisit_PrimaryCmpNode‹   sF    
	



"

z'IterationTransform.visit_PrimaryCmpNodec             C   s   |   |¡ |  ||jj¡S )N)r6   Ú_optimise_for_looprX   rV   )r4   r    r   r   r   Úvisit_ForInStatNode¼   s    
z&IterationTransform.visit_ForInStatNodeFc             C   s&  d }|j s|jrŒ|jrŒ|jjrŒ|jj}|jr2|j}|j rŒ|jrR|jjdkrRtj}n|j	dkrbtj}|jr||jjdkr|tj
}n|j	dkrŒtj
}tj|j|fkr¸|r¤|S | j||d dddS tj
|j|fksØtj|j|fkrì|rà|S |  ||¡S |jjsþ|jjr| j|||dS |jtjkr,| j|||dS |jtjkrJ| j|||dS t|tjƒs\|S |jd kr„|jr~t|jjƒp€d	}n$t|jƒ}|r¨|jd k	r¨|d
8 }|j}|jr¼|s¼|s¼|jpÎ|j}|j}	|   ¡ j!j"dk}
|
s4|	dkr4t|tj#ƒr4|j}|j r4|j	dkr4|jr4|jj$r4d}
d }}|	dksV|
r\|	dkr\d}nB|	dksv|
r||	dkr|d}n"|	dks–|
rž|	dkržd }}|sª|r¼|  |||	||¡S |jd kr&|j r&|jr&|jj$r&|j	dkr|rø|S |  %||¡S |j	dkr&|r|S |  &||¡S t'j(r"d
|  krFdkr"n nØ|jd kr"|j r"|j	dkr"|jr"|jj$r"|j)jj*s”|j)jj+r¤| j,|||dS |j)jj-r"xp|jd krÆ|jjn|jD ]B}t|tj.ƒr
| /¡ r
d|j0  krdk r
n nqÌP qÌW | j,|||dS |S )Nztyping.DictÚDict)z
typing.Setztyping.FrozenSet)ÚSetÚ	FrozenSetTF)Údict_objÚmethodÚkeysÚvalues)Úreversedr   r   r   )rz   r{   ÚitemsÚdictÚiterkeysrz   Ú
itervaluesr{   Ú	iteritemsr}   Ú	enumerater|   )ÚrangeÚxrangei   Ài   @)1Úis_nameÚis_attributeÚentryÚ
annotationr]   r^   Úqualified_namer   Ú	dict_typer   Úset_typer_   Ú_transform_dict_iterationÚfrozenset_typeÚ_transform_set_iterationÚis_ptrÚis_arrayÚ_transform_carray_iterationÚ
bytes_typeÚ_transform_bytes_iterationÚunicode_typeÚ_transform_unicode_iterationr   r   ÚSimpleCallNodeÚargsÚ	arg_tuplerC   r4   Úfunctionr)   r*   Úglobal_scopeÚcontextZlanguage_levelZCallNodeÚ
is_builtinÚ_transform_enumerate_iterationÚ_transform_reversed_iterationr   Zconvert_rangerW   Úis_intÚis_enumÚ_transform_range_iterationÚis_pyobjectÚIntNodeÚhas_constant_resultr-   )r4   r    Úiterabler|   Úannotation_typerˆ   Ú	arg_countr™   Zbase_objry   Zis_safe_iterZinner_functionrz   r{   r   r   r   r   rs   À   s¦    



$ (z%IterationTransform._optimise_for_loopc             C   s„   |j j}t|ƒdkr$t|jdƒ |S t|ƒdkr@t|jdƒ |S |d }|jtjtjfkrt| 	d¡|j
_d|j
_|S | j||ddS )Nr   z(reversed() requires an iterable argumentr   z#reversed() takes exactly 1 argumentz!'NoneType' object is not iterableT)r|   )r˜   r—   rC   r   r\   r_   r   Ú
tuple_typeÚ	list_typeÚas_none_safe_noderX   rV   r|   rs   )r4   r    Zreversed_functionr—   r   r   r   r   rž   2  s    z0IterationTransform._transform_reversed_iterationÚsNc             C   s   |j j}|js|tjk	r|S t | d¡¡}tj	|j
d| j|gdd}tj	|j
d| j|gdd}t || j|tj|j
|d d ||jdd|d¡S )	Nz'NoneType' is not iterableZPyBytes_AS_STRINGr   )r—   Úis_tempÚPyBytes_GET_SIZEr   )r^   ÚstartÚstepÚstopr_   r¬   )r|   )rW   r_   rŸ   r   r’   r   Ú
LetRefNoderª   r   ÚPythonCapiCallNoder\   ÚPyBytes_AS_STRING_func_typeÚPyBytes_GET_SIZE_func_typeÚLetNoder‘   ÚSliceIndexNode)r4   r    Ú
slice_noder|   Útarget_typeÚunpack_temp_nodeZslice_base_nodeZlen_noder   r   r   r“   P  s8    z-IterationTransform._transform_bytes_iterationÚkindÚdataÚindexÚlengthz-1)Úexception_valuec             C   s~  |j r–yt|j d¡dƒ}W n tk
r0   Y nfX tj|jtj|j||t	j
d t	j|  ¡ ¡d tj|jtt|ƒƒt|ƒt	jdtjd}|  |||¡S t | d¡¡}tj|jddt	jd}t t	j¡}| |j¡}	|rìd\}
}|	| }}	nd	\}
}t t	j¡}t t	j¡}t t	j¡}tj|jd
| j| |j¡| |j¡| |jj¡gdd}|j|jjkrt| |jj|  ¡ ¡}t j!|jj|j|d}t j"|j||j#gd}t j$|j||
| |jj¡||	d ||j%dd
}t j&|jtj|jd| j'|tj(|j| |j¡t	j)dtj(|j| |j¡t	j*dtj(|j| |j¡t	j+dgddt, -dd¡dd}t .|tj/|j||||gt j"|j||gdd¡S )NÚlatin1z	iso8859-1)rN   r-   r_   )r^   r®   r°   r_   z'NoneType' is not iterableÚ0r   )ú>z>=)z<=ú<Z__Pyx_PyUnicode_READF)r—   r¬   )r\   rO   rP   )rQ   T)	Úbound1Ú	relation1rW   Ú	relation2Úbound2r¯   rS   rU   Ú
from_rangeZ__Pyx_init_unicode_iteration)r[   r_   Zunicode_iterz
Optimize.c)r—   r¬   Úresult_is_usedÚutility_code)r8   )rY   rS   )0Ú
is_literalr   rN   ÚencodeÚUnicodeEncodeErrorr   r¶   r\   Ú	BytesNoder   Úc_const_char_ptr_typeÚ	coerce_toZc_const_uchar_ptr_typerk   r£   ÚstrrC   Úc_py_ssize_t_typer   r”   r‘   r   r±   rª   ra   rb   Ú
c_int_typeÚc_void_ptr_typer²   ÚPyUnicode_READ_func_typerW   r_   r
   re   rd   rS   ÚForFromStatNoderU   ÚExprStatNodeÚ init_unicode_iteration_func_typeÚAmpersandNodeÚc_py_ssize_t_ptr_typeÚc_void_ptr_ptr_typeÚc_int_ptr_typer   r   rµ   ri   )r4   r    r·   r|   Úbytes_valueZbytes_slicer¹   Z
start_nodeZlength_tempZend_noderÄ   rÅ   Z	kind_tempZ	data_tempÚcounter_tempÚtarget_valueÚtarget_assignrS   Ú	loop_nodeZ
setup_noder   r   r   r•   †  sš    






z/IterationTransform._transform_unicode_iterationc             C   sT  d}t |tjƒrN|j}t|jƒ}t|jƒ}d }|sJ|jjsFt	|j
dƒ |S nB|jrt |jtjƒsht‚|j}|j}	t|	jƒ}t|	jƒ}t|	jƒ}|rt |jtƒrÊ|jdksÊ|jdkr¼|rÊ|jdk râ|sâ|jjsÞt	|j
dƒ |S |j}
|rò|
 }
|
dk }tj|j
tjtt|
ƒƒt|
ƒd}nr|jjrv|jjd krFt	|j
dƒ |S |}d }tj|j
t|jjƒtj|jjd}d }n|jjsŒt	|j
dƒ |S |r¨| tj|  ¡ ¡}|rÀ| tj|  ¡ ¡}|d krø|rètj|j
dtjdd}nt	|j
dƒ |S |r$|stj|j
d	dtjd
}|| }}|j}|jr:| ¡ }| |  ¡ ¡}|rr|jdkrrtj|j
|d||d}n|}|r°|jdkr°tj|j
t |¡d||d |  ¡ ¡}n
t |¡}t  |¡}| !|j"j
¡}|jj#rn|j"jjrn|jt$j%kr(t &tj'|j"j
||j(dtj)¡ |j"j|  ¡ ¡}nDtj|j"j
tj|j"j
d	dtj*d
tj|j"j
ddtj*d
|t$j+dd}nP|j"jj,r’|j"j -|j(¡s’|}n,tj.|j"j
tj|j"j
d	dtj*d
||j(d}|j|j"jkrâ| |j"j|  ¡ ¡}t/j0|j"j
|j"|d}t/j1|j
||j2gd}|  3||¡\}}t/j4|j
||||||||j5dd
}tj6|j
|g|dS )NFz*C array iteration requires known end indexr   z8C array iteration requires known step size and end index)r_   rN   r-   )rN   r_   r-   z-1éÿÿÿÿrÀ   )rN   r-   r_   ú+)rL   rK   rM   r_   )r[   r_   Ú1r   )r®   r°   r^   r_   r¬   )r¼   r^   r_   )r\   rO   rP   )rQ   T)	rÃ   rÄ   rW   rÅ   rÆ   r¯   rS   rU   rÇ   )rY   rS   )7r   r   r¶   r^   r.   r®   r°   r_   r¢   r   r\   r]   r¼   Ú	SliceNodeÚAssertionErrorr¯   r-   r   r£   r   rÑ   rÐ   Úabsr   ÚsizerÏ   rk   Zelement_ptr_typeÚcoerce_to_simpleÚAddNodeÚ	CloneNoder   ra   rb   rW   Ú	is_stringr   r”   ÚCastNodeZDereferenceNoder`   Úc_py_ucs4_typerÒ   r’   r   Úassignable_fromZ	IndexNoder
   re   rd   rS   Ú_find_for_from_node_relationsrÕ   rU   ri   )r4   r    r·   r|   Zneg_stepZ
slice_baser®   r°   r¯   r¼   Ú
step_valueZptr_typeZ
carray_ptrZstart_ptr_nodeZstop_ptr_nodeÚcounterrÝ   rÞ   rß   rS   rÄ   rÅ   Úfor_noder   r   r   r‘   â  s
   


















z.IterationTransform._transform_carray_iterationc          	   C   s–  |j j}t|ƒdkr$t|jdƒ |S t|ƒdkr@t|jdƒ |S |jjsL|S |jj}t|ƒdkrd|S |\}}|j}|js‚|j	s‚|S t|ƒdkr¨t
|d ƒ ||  ¡ ¡}ntj|jd|dd}t |¡}	tj|j|	tj|jd|ddd	||jd
}
tj|j||	dtj|j|	|
dg}t|jtjƒr6||jj |j_n | |j¡ tj|jj|d|_||_|j |j|  ¡ ¡|_|d |j_t |	|  ||jj¡¡S )Nr   z)enumerate() requires an iterable argumenté   z%enumerate() takes at most 2 argumentsr   rÀ   )rN   r_   r-   rã   râ   )rL   rM   rK   r_   r¬   )r\   rO   rP   )rQ   )r˜   r—   rC   r   r\   rW   Úis_sequence_constructorr_   r¢   rŸ   r!   rÏ   rk   r   r£   r   r±   ré   r
   re   r   rS   rd   rQ   r5   ÚitemrX   rV   rµ   rs   )r4   r    Zenumerate_functionr—   ÚtargetsZenumerate_targetZiterable_targetZcounter_typer®   ÚtempZinc_expressionZ	loop_bodyr   r   r   r   †  sh    




z1IterationTransform._transform_enumerate_iterationc             C   s"   |r|rdS dS n|rdS dS d S )N)rÂ   z<=)rÁ   z>=)z>=rÁ   )z<=rÂ   r   )r4   Zneg_step_valuer|   r   r   r   rï   Ï  s    z0IterationTransform._find_for_from_node_relationsc             C   sV  |j j}t|ƒdk r0|j}d}tj|ddd}nD|d }|j}t|jtƒsN|S |j}|dkr`|S tj|t	|ƒ|d}t|ƒdkr¦tj|jddd}|d  
|  ¡ ¡}	n$|d  
|  ¡ ¡}|d  
|  ¡ ¡}	|  |dk |¡\}
}d }|r¼|	| }}	t|ƒ}|dkr¼t|jtƒr¢t|	jtƒr¢|dk rT|	j}|j}|||| d |   d }n(|j}|	j}|||| d |   d }tj|jt	|ƒ|t |j|	j¡d}nt |	¡}|  ||||¡}|dk rÌ| }t	|ƒ|_||_| 
|  ¡ ¡}|	jsd	}|pt |	¡}	nd
}tj|j|j||
||	||j|jd	d
}| |  ¡ ¡ |rRt |	|¡}|S )Nr   r   rã   )rN   r-   ró   r   rÀ   )rN   r-   r_   TF)	rW   rÃ   rÄ   rÅ   rÆ   r¯   rS   rU   rÇ   )r˜   r—   rC   r\   r   r£   r   r-   r   rÐ   Zcoerce_to_integerrk   rï   ræ   r   Úspanning_typer_   r   r±   Ú_build_range_step_calculationrN   rÊ   r
   rÕ   rW   rS   rU   Zset_up_looprµ   )r4   r    Zrange_functionr|   r—   Zstep_posrð   r¯   rÃ   rÆ   rÄ   rÅ   Úbound2_ref_nodeÚabs_stepÚbegin_valueÚ	end_valueZbound1_valueZbound2_is_temprò   r   r   r   r¡   Û  s|    






z-IterationTransform._transform_range_iterationc             C   s   t |ƒ}t |j|j¡}|jjr8|dk r8t |tj¡}nt ||j¡}|dk r\|}|}	d}
n|}|}	d}
tj|jtj|j||
tj	|jtj
|jt|ƒ||ddtj|jtj|jtj|j|d|	|ddtj
|jdd	d
|ddtj
|jt|ƒ||d|d|d|d|
tj
|jdd	d
|d}|S )Niÿ  r   ú-râ   )rN   r-   r_   Ú*)rL   rK   rM   r_   rã   r   )rN   r-   z//)ræ   r   rø   r_   rŸ   rÒ   r   Ú
binop_noder\   ZMulNoder£   rÐ   ÚDivNodeZSubNode)r4   rÃ   rú   r¯   rð   rû   rø   Zspanning_step_typerü   rý   Zfinal_opZstep_calculation_noder   r   r   rù   .  st    z0IterationTransform._build_range_step_calculationc                s|  g }t  tj¡}| |¡ | |j¡}t  tj¡}| |¡ | ˆ j¡}	d  }
 }}|r|rˆ jj	rˆt
ˆ jjƒdkr‚ˆ jj\}
}qŽˆ S q¢ˆ j}n|rœˆ j}
nˆ j}tˆ jtjƒr¸ˆ j}ntjˆ jjˆ jgd}t  tj¡}| |¡ tjˆ j| |j¡t |j¡d}t  tj¡}| |¡ | ˆ j¡}tjˆ j|t |j¡d}t || |j¡|	|
|||¡}| |  ¡ ¡}|g|jdd…< |rÂtj|jd|d}|jd t
|ƒdkr°d	nd
¡d|gd}nt |j¡}| d¡}‡ fdd„}tjˆ j|	tjˆ jddddtj|j|tj|jd| j t! "dd¡|||jt#j$kƒ|||gdddtj%ˆ jd |ˆ j&dg}t j'ˆ j|tjˆ j|ddS )Nró   )r\   rQ   )r[   r_   r   T)Zis_identifierrN   z*'NoneType' object has no attribute '%{0}s'é   z.30Ú ÚPyExc_AttributeError)r   Úformat_argsz!'NoneType' object is not iterablec                s"   | rdp
d} t jˆ jt| ƒ| dS )Nr   r   )rN   r-   )r   r£   r\   rÐ   )rN   )r    r   r   Ú	flag_node«  s    z?IterationTransform._transform_dict_iteration.<locals>.flag_noderÀ   )rN   r-   )rO   rP   Z__Pyx_dict_iteratorZ	dict_iterz
Optimize.c)rÉ   r—   r¬   )rR   rS   rU   )rQ   )rY   rS   )(r   ra   r   Úpy_object_typer5   rb   r\   rÑ   rW   rô   rC   r—   r   rS   r
   rd   r   rØ   Ú
c_ptr_typer_   rÒ   ZDictIterationNextNoderj   rk   rQ   Ú
StringNoderª   ÚformatÚNullNodere   r£   r²   ÚPyDict_Iterator_func_typer   r   r   rŠ   ÚWhileStatNoderU   ri   )r4   r    rx   ry   rz   r{   rY   r÷   Z	dict_tempÚpos_tempZ
key_targetÚvalue_targetZtuple_targetrS   Zdict_len_tempZdict_len_temp_addrZis_dict_tempZis_dict_temp_addrÚiter_next_nodeZmethod_noder  Úresult_coder   )r    r   rŒ   n  s”    









z,IterationTransform._transform_dict_iterationr~   Zis_dictÚmethod_nameZp_orig_lengthZ	p_is_dictÚsetÚis_setZp_is_setc                sÈ  g }t  tj¡}| |¡ | |j¡}t  tj¡}| |¡ | ˆ j¡}tˆ j	t
jƒr^ˆ j	}nt
jˆ j	jˆ j	gd}t  tj¡}| |¡ tjˆ j| |j¡t |j¡d}	t  tj¡}| |¡ | ˆ j¡}
tjˆ j|
t |j¡d}ˆ j}t
 || |j¡|||
¡}| |  ¡ ¡}|g|jdd…< ‡ fdd„}t
jˆ j|tjˆ jddddt
j|j|tj|jd	| jt d
d¡|||jtjkƒ|	|gdddt
jˆ jd |ˆ jdg}t j ˆ j|t
jˆ j|ddS )N)r\   rQ   )r[   r_   r   c                s"   | rdp
d} t jˆ jt| ƒ| dS )Nr   r   )rN   r-   )r   r£   r\   rÐ   )rN   )r    r   r   r    s    z>IterationTransform._transform_set_iteration.<locals>.flag_noderÀ   )rN   r-   )rO   rP   Z__Pyx_set_iteratorZset_iterz
Optimize.cT)rÉ   r—   r¬   )rR   rS   rU   )rQ   )rY   rS   )!r   ra   r   r  r5   rb   r\   rÑ   r   rS   r
   rd   r   rØ   r  r_   rÒ   rW   ZSetIterationNextNoderj   rk   rQ   re   r£   r²   ÚPySet_Iterator_func_typer   r   r   r‹   r  rU   ri   )r4   r    Úset_objrY   r÷   Zset_tempr  rS   Zset_len_tempZset_len_temp_addrZis_set_tempZis_set_temp_addrr  r  r  r  r   )r    r   rŽ   â  sj    






z+IterationTransform._transform_set_iteration)F)F)F)F)F)%r=   r>   r?   r@   rr   rt   rs   rž   r   Ú	CFuncTypeZc_char_ptr_typeÚCFuncTypeArgr   r’   r³   rÑ   r´   r“   rí   rÒ   rÓ   rÔ   r  rÙ   rÚ   rÛ   r×   r•   r‘   r   rï   r¡   rù   rŒ   r  r  rŽ   r   r   r   r   rJ   „   s\   1
r
&
\
 %I
S@crJ   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   sj  x^t |tjtjfƒr|j}qt |tjƒr2|jj}qt |tjƒrF|j}qt |tj	ƒrZ|j
}qP qW t |tjƒrÌ|jd k	r~| jS | ¡ rät |jtjtjfƒrä|jdk}|r²|s²| jS t |jtjƒrÐ|j ¡ rÐ| jS ||j|  |j¡fS | ¡ sd|jdkr d}n|r|jdkrd}n| jS t|j|jƒrt|jjrH||j|jgfS t|jdd ƒrt|jjjrt||j|jgfS t|j|jƒrd|jjrž||j|jgfS t|jdd ƒrd|jjjrd||j|jgfS n˜t |tjƒrd|jdksø|rd|jdkrd|jdk}|  |j|¡\}}}|  |j|¡\}}}	|d k	rd||krdt||ƒrd|rV|rd||||	 fS | jS )	NrZ   z==Fz!=Tr‡   ÚorÚand)r   r   ÚCoerceToTempNodeZCoerceToBooleanNoder   ZBoolBinopResultNoder   ÚEvalWithTempExprNodeÚsubexpressionÚTypecastNoder[   rc   ÚcascadeÚNO_MATCHZis_c_string_containsrM   ÚUnicodeNoderÍ   rK   Zcontains_surrogatesrL   Úextract_in_string_conditionsZis_python_comparisonr(   rÊ   Úgetattrr‡   Zis_constÚBoolBinopNodeÚextract_conditions)
r4   ÚcondÚallow_not_inrZ   Znot_in_1Út1Úc1Znot_in_2Út2Úc2r   r   r   r&  2  sd    








 z"SwitchTransform.extract_conditionsc                s€   t ˆtjƒr:ttttˆjƒƒƒ}| ¡  ‡fdd„|D ƒS ˆj‰ tt‡ fdd„t	t
ˆ ƒƒD ƒƒƒ‰ ˆ  ¡  ‡fdd„ˆ D ƒS d S )Nc                s"   g | ]}t jˆ jt|ƒ|d ‘qS ))rN   r-   )r   r£   r\   rÐ   )rF   Úcharval)Ústring_literalr   r   rH   s  s   z@SwitchTransform.extract_in_string_conditions.<locals>.<listcomp>c                s   g | ]}ˆ ||d  … ‘qS )r   r   )rF   Úi)Ú
charactersr   r   rH   {  s    c                s   g | ]}t jˆ j||d ‘qS ))rN   r-   )r   ÚCharNoder\   )rF   r-  )r.  r   r   rH   }  s   )r   r   r"  ÚlistÚmapÚordr  rN   Úsortrƒ   rC   )r4   r.  Zcharvalsr   )r0  r.  r   r#  o  s    
"
z,SwitchTransform.extract_in_string_conditionsc             C   sj   |   ||¡\}}}|d kr | jS |d k	r8t||ƒs8| jS |jjsH|jjrZtdd„ |D ƒƒr`| jS |||fS )Nc             S   s   g | ]}|j jp|j j ‘qS r   )r_   rŸ   r    )rF   r'  r   r   r   rH   ‡  s    z=SwitchTransform.extract_common_conditions.<locals>.<listcomp>)r&  r!  r(   r_   rŸ   r    Úsum)r4   Ú
common_varrR   r(  rZ   ÚvarÚ
conditionsr   r   r   Úextract_common_conditions  s    "z)SwitchTransform.extract_common_conditionsc          	   C   st   t ƒ }xh|D ]`}| ¡ r4|j|kr&dS | |j¡ qy|jj|krFdS W n tk
r\   dS X | |jj¡ qW dS )NTF)r  r¤   r-   Úaddr‡   ÚcnameÚAttributeError)r4   Úcondition_valuesÚseenrN   r   r   r   Úhas_duplicate_values‹  s    

z$SwitchTransform.has_duplicate_valuesc       
      C   s   | j  d¡s|  |¡ |S d }g }xT|jD ]J}|  ||jd¡\}}}|d krZ|  |¡ |S | tj|j	||j
d¡ q*W dd„ |D ƒ}t|ƒdk r |  |¡ |S |  |¡r¸|  |¡ |S |  |d¡ x|D ]}|  |d¡ qÊW t|ƒ}tj|j	|||jd	}	|	S )
Nzoptimize.use_switchF)r\   r9  rS   c             S   s   g | ]}|j D ]}|‘qqS r   )r9  )rF   Úcaser'  r   r   r   rH   °  s    z4SwitchTransform.visit_IfStatNode.<locals>.<listcomp>ró   rU   rS   )r\   ÚtestÚcasesrU   )Úcurrent_directivesÚgetr6   rT   r:  rR   r5   r
   ÚSwitchCaseNoder\   rS   rC   r@  r$   ÚSwitchStatNoderU   )
r4   r    r7  rC  Ú	if_clauseÚ_r9  r>  rA  Úswitch_noder   r   r   Úvisit_IfStatNodež  s<    






z SwitchTransform.visit_IfStatNodec             C   st   | j  d¡s|  |¡ |S |  d |jd¡\}}}|d ksNt|ƒdk sN|  |¡r\|  |¡ |S |  |||||j|j	¡S )Nzoptimize.use_switchTró   )
rD  rE  r6   r:  rB  rC   r@  Úbuild_simple_switch_statementÚtrue_valÚ	false_val)r4   r    rZ   r7  r9  r   r   r   Úvisit_CondExprNodeÄ  s    


z"SwitchTransform.visit_CondExprNodec             C   s˜   | j  d¡s|  |¡ |S |  d |d¡\}}}|d ksLt|ƒdk sL|  |¡rh|  |¡ | |  ¡ ¡ |S |  ||||t	j
|jdddt	j
|jddd¡S )Nzoptimize.use_switchTró   )rN   r-   F)rD  rE  r6   r:  rC   r@  Úwrap_operandsrk   rL  r   rf   r\   )r4   r    rZ   r7  r9  r   r   r   Úvisit_BoolBinopNodeÕ  s    


z#SwitchTransform.visit_BoolBinopNodec             C   sŠ   | j  d¡s|  |¡ |S |  d |d¡\}}}|d ksLt|ƒdk sL|  |¡rZ|  |¡ |S |  ||||tj|j	dddtj|j	ddd¡S )Nzoptimize.use_switchTró   )rN   r-   F)
rD  rE  r6   r:  rC   r@  rL  r   rf   r\   )r4   r    rZ   r7  r9  r   r   r   rr   è  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)rO   rP   Úfirst)r\   r9  rS   )r\   rB  rC  rU   )r   r"   r
   re   r\   rÏ   r_   rk   rF  r$   rG  rm   )r4   r    r7  r9  rZ   rM  rN  ro   Z	true_bodyZ
false_bodyrC  rJ  Úreplacementr   r   r   rL  ú  s.    


z-SwitchTransform.build_simple_switch_statementc             C   sR   | j  d¡s|  |¡ |S |j}|j}|  |¡ |j|k	rNt |j|¡sN|jS |S )Nzoptimize.use_switch)rD  rE  r6   r  Z	lazy_tempr   Ztree_contains)r4   r    Z	orig_exprZtemp_refr   r   r   Úvisit_EvalWithTempExprNode  s    


z*SwitchTransform.visit_EvalWithTempExprNodeN)r=   r>   r?   r@   r!  r&  r#  r:  r@  rK  rO  rQ  rr   rL  rT  r   ÚVisitorTransformÚrecurse_to_childrenrA   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          	      sl  |   ˆ¡ ˆjd k	rˆS ˆjdkr,d‰ d}nˆjdkr@d‰ d}nˆS tˆjtjtjtjfƒs`ˆS ˆjj	}t
|ƒdkrxˆS tdd	„ |D ƒƒrŽˆS t ˆj¡}g }g }xz|D ]r}y| ¡ }W n tk
rÐ   d
}Y nX |sêt |¡}| |¡ tjˆj|||d d}	| tjˆj|	tjd¡ q¨W ‡ ‡fdd„}
t|
|ƒ}t ||¡}x$|d d d… D ]}t ||¡}qRW |S )NÚinr  z==rZ   r  z!=r   c             S   s   g | ]
}|j ‘qS r   )Ú
is_starred)rF   r   r   r   r   rH   F  s    z?FlattenInListTransform.visit_PrimaryCmpNode.<locals>.<listcomp>F)r\   rL   rK   rM   r   )r\   r[   r_   c                s   t jˆjˆ | |dS )N)r\   rK   rL   rM   )r   r%  r\   )ÚleftÚright)Úconjunctionr    r   r   Úconcate  s
    z;FlattenInListTransform.visit_PrimaryCmpNode.<locals>.concatrá   )r6   r   rK   r   rM   r   Ú	TupleNodeÚListNodeÚSetNoder—   rC   Úanyr   r"   rL   Ú	is_simpleÚ	Exceptionr±   r5   rc   r\   r  r   Úc_bint_typer   r  )r4   r    Z	eq_or_neqr—   rO   ZcondsrY   r   Zis_simple_argr'  r]  rR   rq   r÷   r   )r\  r    r   rr   /  s\    










z+FlattenInListTransform.visit_PrimaryCmpNodeN)	r=   r>   r?   r@   rr   r   rU  rV  rA   r   r   r   r   rW  )  s   CrW  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 }x\|j D ]R}t|tjƒr^|  |j|||¡sF|S |  |j|||¡sr|S q t|tjƒrn|S |S q W |s~|rÆdd„ |D ƒ}dd„ |D ƒ}	t|ƒt|	ƒkr®|S t	t|ƒƒt	|ƒkrÆ|S |sÐ|rdg }
x(|D ] }|  
|¡}|sð|S |
 |¡ qÚW g }x,|D ]$}|  
|¡}|s |S | |¡ qW t|
ƒt|ƒkrF|S t	t|
ƒƒt	|ƒkr`|S |S dd„ |D ƒ}x|D ]}d|_qxW x&|| D ]\}}||kr’d|_q’W x|| D ]}d|_qºW |S )zF
        Parallel swap assignments like 'a,b = b,a' are safe.
        c             S   s   g | ]\}}|‘qS r   r   )rF   ÚpathÚnr   r   r   rH   ’  s    zIDropRefcountingTransform.visit_ParallelAssignmentNode.<locals>.<listcomp>c             S   s   g | ]\}}|‘qS r   r   )rF   rf  rg  r   r   r   rH   “  s    c             S   s   g | ]
}|j ‘qS r   )r   )rF   Útr   r   r   rH   ²  s    F)rQ   r   r
   re   Ú_extract_operandrO   rP   ZCascadedAssignmentNoder  rC   Ú_extract_index_idr5   Zuse_managed_ref)r4   r    Z
left_namesZright_namesZleft_indicesZright_indicesrY   ÚstatZlnamesZrnamesZlindicesZlhs_nodeZindex_idZrindicesZrhs_nodeZ	temp_argsr÷   rI  Ú	name_nodeÚ
index_noder   r   r   Úvisit_ParallelAssignmentNodez  s`    










z5DropRefcountingTransform.visit_ParallelAssignmentNodec             C   sØ   t |ƒ}|jjsdS t|tjƒr0| |¡ |j}g }|}x&|jr^|j	rJdS | |j
¡ |j}q:W |jr’| |j¡ | d |d d d… ¡|f¡ nB|jrÐ|jjtjkrªdS |jjjs¸dS |jjsÄdS | |¡ ndS dS )NFÚ.rá   T)r$   r_   r¢   r   r   r  r5   r   r†   r'   Úmemberr)   r…   r   Újoinr]   r^   r   r©   r¼   rŸ   )r4   r    ÚnamesÚindicesrY   Z	name_pathZobj_noder   r   r   ri  ¿  s4    

 
z)DropRefcountingTransform._extract_operandc             C   s>   |j }|j}t|tjƒr |j}nt|tjƒr0d S d S |j|fS )N)r^   r¼   r   r   r%   r   Z	ConstNode)r4   rm  r^   r¼   Z	index_valr   r   r   rj  Ü  s    z*DropRefcountingTransform._extract_index_idN)r=   r>   r?   r@   r   rU  rV  rA   rn  ri  rj  r   r   r   r   re  u  s
   Ere  c               @   sú   e Zd ZdZejjZdd„ Zdd„ Z	dd„ Z
d4d	d
„Zd5dd„Zd6dd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Ze eje dejd¡g¡Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Z d(d)„ Z!d*d+„ Z"d,d-„ Z#d.d/„ Z$d0d1„ Z%d2d3„ Z&dS )7ÚEarlyReplaceBuiltinCallsa¼  Optimize some common calls to builtin types *before* the type
    analysis phase and *after* the declarations analysis phase.

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

    Introducing C function calls here may not be a good idea.  Move
    them to the OptimizeBuiltinCalls transform instead, which runs
    after type analysis.
    c             C   s.   |   |¡ |j}|  |¡s|S |  |||j¡S )N)r6   r™   Ú_function_is_builtin_nameÚ_dispatch_to_handlerr—   )r4   r    r™   r   r   r   Úvisit_SimpleCallNodeø  s
    

z-EarlyReplaceBuiltinCalls.visit_SimpleCallNodec             C   sL   |   |¡ |j}|  |¡s|S |j}t|tjƒs4|S |j}|  ||||j	¡S )N)
r6   r™   ru  Zpositional_argsr   r   r^  r—   rv  Úkeyword_args)r4   r    r™   r˜   r—   r   r   r   Úvisit_GeneralCallNodeÿ  s    

z.EarlyReplaceBuiltinCalls.visit_GeneralCallNodec             C   s:   |j s
dS |  ¡ }| |j¡}|| ¡  |j¡k	r6dS dS )NFT)r…   rk   Úlookupr   Zbuiltin_scopeZlookup_here)r4   r™   Úenvr‡   r   r   r   ru    s    z2EarlyReplaceBuiltinCalls._function_is_builtin_nameNc             C   sT   |d krd|j  }n
d|j  }t| |d ƒ}|d k	rP|d krD|||ƒS ||||ƒS |S )Nz_handle_simple_function_%sz_handle_general_function_%s)r   r$  )r4   r    r™   r—   ÚkwargsÚhandler_nameZhandle_callr   r   r   rv    s    

z-EarlyReplaceBuiltinCalls._dispatch_to_handlerc             C   s"   t j|jj|jj|||d|_d S )N)rÉ   )r   ZPythonCapiFunctionNoder™   r\   r   )r4   r    r<  Ú	func_typerÉ   r   r   r   Ú_inject_capi_function"  s    z.EarlyReplaceBuiltinCalls._inject_capi_functionc             C   sj   |s
d}n*t |tƒs|dkr"d}n|dkr0d}nd}|d k	rFd| }nd}t|jd|||t|ƒf ƒ d S )Nr  r   z...Úxzexpected %s, z3%s(%s) called with wrong number of args, %sfound %d)r   r   r   r\   rC   )r4   Úfunction_namer    r—   ÚexpectedÚarg_strÚexpected_strr   r   r   Ú_error_wrong_arg_count'  s    
z/EarlyReplaceBuiltinCalls._error_wrong_arg_countc             C   s\   |st j|jddS t|ƒdkr0|  d||d¡ t|d dd ƒ}|tjtj	fkrX|d S |S )Nz0.0)rN   r   Úfloatr   r_   )
r   Ú	FloatNoder\   rC   r…  r$  r   Úc_double_typer   Ú
float_type)r4   r    Úpos_argsÚarg_typer   r   r   Ú_handle_simple_function_float9  s    z6EarlyReplaceBuiltinCalls._handle_simple_function_floatc             C   s„   t |ƒ}d  }}|dkr |\}n8|dkr2|\}}n&|dkrF|\}}}n|  d||¡ |S tj|j|pnt |j¡||p~t |j¡dS )Nr   ró   r   Úslice)r®   r°   r¯   )rC   r…  r   rä   r\   ÚNoneNode)r4   r    rŠ  r§   r®   r¯   r°   r   r   r   Ú_handle_simple_function_sliceC  s    
z6EarlyReplaceBuiltinCalls._handle_simple_function_slicec             C   s¸   t |ƒdkr|S |d }t|tjtjfƒr`t |jƒdkr´tj|jtj	t
t|jƒƒt|jƒdS nTt|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   )r_   rN   r-   éÿ   )rC   r   r   r"  rÍ   rN   r£   r\   r   Úc_long_typerÐ   r4  r	  Úunicode_valuerÒ   )r4   r    rŠ  r   r   r   r   Ú_handle_simple_function_ordU  s"    z4EarlyReplaceBuiltinCalls._handle_simple_function_ordc             C   s   |   ||d¡S )zæTransform

        _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)r4   r    rŠ  r   r   r   Ú_handle_simple_function_alln  s    z4EarlyReplaceBuiltinCalls._handle_simple_function_allc             C   s   |   ||d¡S )zâTransform

        _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
        T)r”  )r4   r    rŠ  r   r   r   Ú_handle_simple_function_any~  s    z4EarlyReplaceBuiltinCalls._handle_simple_function_anyc             C   sô   t |ƒdkr|S t|d tjƒs$|S |d }|jj}|j}t|ƒ\}}|d krR|S |r\|}	ntj|j	|d}	t
j|j	d t
j|j	|	t
j|j	tj|j	||dddgd}
t
j|j	tj|j	| | dd|_t |||
¡ tj|j	||rìdnd	d
S )Nr   r   )r[   )rN   r-   )rN   )rR   rS   )rU   rT   ra  Úall)ÚgenÚ	orig_func)rC   r   r   ÚGeneratorExpressionNodeZdef_nodeZgbodyrS   rE   rn   r\   r
   rg   rh   ZReturnStatNoderf   rU   r   Úrecursively_replace_nodeÚInlinedGeneratorExpressionNode)r4   r    rŠ  Zis_anyÚgen_expr_nodeZgenerator_bodyrà   Úyield_expressionÚyield_stat_noderR   Ú	test_noder   r   r   r”  Ž  s6     z+EarlyReplaceBuiltinCalls._transform_any_allÚitc             C   sj  t |ƒdkr|S |d }t|tjƒr@|jtjkr@|d }|j}n¢t|tjƒr²|}|j}t	|ƒ}|sf|S tj
|j|dtjd}xd|D ]*\}}	tj|j||jd}
t ||	|
¡ q‚W n0|jrÆ| ¡  }}ntj|jd| j|dd }}tj|jtjd	d
}tj|j||dd}tj|j|tdƒd	d}tj|jtj|j|g dd}| |  ¡ ¡ t |tj|j||gd¡S )a  Transform sorted(genexpr) and sorted([listcomp]) into
        [listcomp].sort().  CPython just reads the iterable into a
        list and calls .sort() on it.  Expanding the iterable in a
        listcomp is still faster and the result can be sorted in
        place.
        r   r   Úsorted)r™  Úcomprehension_type)r8   rW   ÚPySequence_ListT)r—   r¬   F)r\   r_   Zmay_hold_none)rO   rP   rR  r5  )r)   r*   Zneeds_none_check)r™   r—   )r8   )rQ   ) rC   r   r   ÚComprehensionNoder_   r   r©   Úlooprš  rB   rœ  r\   ÚComprehensionAppendNoderW   r   r›  rô   Úas_listr²   ÚPySequence_List_func_typer   r"   r
   re   r&   r   rÖ   r–   Zanalyse_declarationsrk   rm   rd   )r4   r    rŠ  r   Z	list_noderà   r  rD   rž  rŸ  Úappend_nodeÚresult_nodeZlist_assign_nodeZsort_methodZ	sort_noder   r   r   Ú_handle_simple_function_sorted¶  sP    


z7EarlyReplaceBuiltinCalls._handle_simple_function_sortedc          	   C   sN  t |ƒdkr|S t|d tjtjfƒs*|S |d }|j}t|tjƒrbt|ƒ\}}d}|dkrš|S n8|j}|j}y|j	r~|j
js‚|S W n tk
r˜   |S X 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À   )rN   r-   )r\   r_   râ   )rO   rP   )r\   r#   T)rO   rP   rR  )rQ   r6  )r¦  r«  Ú
expr_scoper™  Úhas_local_scope)rC   r   r   rš  r¥  r¦  rE   r5   r8   rÊ   r_   rŸ   r=  r£   r\   r   r"   r   r  r
   re   r   r   r›  rd   rœ  r­  r®  )r4   r    rŠ  r  rà   rž  rŸ  r®   ro   Úadd_nodeZ	exec_coder   r   r   Z__handle_simple_function_sumö  sP    

z5EarlyReplaceBuiltinCalls.__handle_simple_function_sumc             C   s   |   ||d¡S )NrÂ   )Ú_optimise_min_max)r4   r    rŠ  r   r   r   Ú_handle_simple_function_min0  s    z4EarlyReplaceBuiltinCalls._handle_simple_function_minc             C   s   |   ||d¡S )NrÁ   )r°  )r4   r    rŠ  r   r   r   Ú_handle_simple_function_max3  s    z4EarlyReplaceBuiltinCalls._handle_simple_function_maxc       	      C   sÌ   t |ƒdkr<t |ƒdkr,|d jr,|d j}t |ƒdkr<|S tttj|dd… ƒƒ}|d }xF|D ]>}t |¡}tj|j	||tj
|j	|||dd}t ||¡}qbW x"|ddd… D ]}t ||¡}q´W |S )zKReplace min(a,b,...) and max(a,b,...) by explicit comparison code.
        r   r   N)rL   rK   rM   )rM  rN  rB  rá   )rC   rô   r—   r2  r3  r   r"   r   ZCondExprNoder\   rc   r  )	r4   r    r—   rK   Zcascaded_nodesZlast_resultZarg_nodero   Zref_noder   r   r   r°  6  s,    


z*EarlyReplaceBuiltinCalls._optimise_min_maxc             C   sB   |st j|jg ddS |  ||tj¡}||k	r>t j|j|dS |S )Nr   )r—   r-   )r   )r   r^  r\   Ú_transform_list_set_genexprr   r©   ÚAsTupleNode)r4   r    rŠ  Úresultr   r   r   Ú&_DISABLED_handle_simple_function_tupleY  s    z?EarlyReplaceBuiltinCalls._DISABLED_handle_simple_function_tuplec             C   sP   t |ƒdkr|S |d jr,|d js,|d= n t|d tjƒrL|d  ¡ |d< |S )zSReplace frozenset([...]) by frozenset((...)) as tuples are more efficient.
        r   r   )rC   rô   r—   r   r   r_  Úas_tuple)r4   r    rŠ  r   r   r   Ú!_handle_simple_function_frozenseth  s    z:EarlyReplaceBuiltinCalls._handle_simple_function_frozensetc             C   s&   |st j|jg g dS |  ||tj¡S )N)r—   r-   )r   r_  r\   r³  r   r©   )r4   r    rŠ  r   r   r   Ú_handle_simple_function_lists  s    z5EarlyReplaceBuiltinCalls._handle_simple_function_listc             C   s(   |st j|jg tƒ dS |  ||tj¡S )N)r—   r-   )r   r`  r\   r  r³  r   r‹   )r4   r    rŠ  r   r   r   Ú_handle_simple_function_setx  s    z4EarlyReplaceBuiltinCalls._handle_simple_function_setc             C   sœ   t |ƒdkr|S t|d tjƒs$|S |d }|j}t|ƒ}|sB|S tj|j||tj	krZdnd|d}x2|D ]*\}}	tj
|j||jd}
t ||	|
¡ qjW |S )zLReplace set(genexpr) and list(genexpr) by an inlined comprehension.
        r   r   r  r2  )r™  r£  )r8   rW   )rC   r   r   rš  r¦  rB   rœ  r\   r   r‹   r§  rW   r   r›  )r4   r    rŠ  r¸   r  rà   rD   r«  rž  rŸ  rª  r   r   r   r³  }  s(    
z4EarlyReplaceBuiltinCalls._transform_list_set_genexprc             C   sð   t |ƒdkrtj|jg i dS t |ƒdkr.|S t|d tjƒsB|S |d }|j}t|ƒ}|s`|S x2|D ]*\}}t|tjƒs~|S t |j	ƒdkrf|S qfW tj
|j|dtjd}x@|D ]8\}}	tj|j|j	d |j	d |jd}
t ||	|
¡ q°W |S )zDReplace dict( (a,b) for ... ) by an inlined { a:b for ... }
        r   )Úkey_value_pairsr-   r   ró   r~   )r™  r£  )Zkey_exprZ
value_exprrW   )rC   r   ÚDictNoder\   r   rš  r¦  rB   r^  r—   rœ  r   rŠ   ZDictComprehensionAppendNoderW   r   r›  )r4   r    rŠ  r  rà   rD   rž  rI  r«  rŸ  rª  r   r   r   Ú_handle_simple_function_dict™  s6    

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   )rC   r   r   r¼  )r4   r    rŠ  r|  r   r   r   Ú_handle_general_function_dict¿  s
    z6EarlyReplaceBuiltinCalls._handle_general_function_dict)N)N)N)'r=   r>   r?   r@   r   rU  rV  rA   rw  ry  ru  rv  r  r…  rŒ  r  r“  r•  r–  r”  r   r  r   r©   r  r  r©  r¬  Z5_EarlyReplaceBuiltinCalls__handle_simple_function_sumr±  r²  r°  r¶  r¸  r¹  rº  r³  r½  r¾  r   r   r   r   rt  é  s:   




$@:#&rt  c               @   s$   e Zd ZejjZdd„ Zdd„ ZdS )ÚInlineDefNodeCallsc             C   sR   |j d krd S |j jrd S |  ¡  |j¡}|rB|jrBt|jƒdkrFd S |jd jS )Nr   r   )Zcf_stateZ
cf_is_nullrk   rz  r   Úcf_assignmentsrC   rP   )r4   rl  r‡   r   r   r   Úget_constant_value_nodeÍ  s    

z*InlineDefNodeCalls.get_constant_value_nodec             C   sr   |   |¡ | j d¡s|S |j}|js*|S |  |¡}t|tjƒsD|S tj	|j
|||jd}| ¡ rn|  ||¡S |S )Nzoptimize.inline_defnode_calls)r  r™   r—   )r6   rD  rE  r™   r…   rÁ  r   r   ÚPyCFunctionNodeZInlinedDefNodeCallNoder\   r—   Zcan_be_inlinedÚreplace)r4   r    r  r™   Zinlinedr   r   r   rw  Ù  s    

z'InlineDefNodeCalls.visit_SimpleCallNodeN)	r=   r>   r?   r   rU  rV  rA   rÁ  rw  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dó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 	ej$e d)ej$d¡g¡Z%d*d+„ Z&e 	ej'e d,ej
d¡g¡Z(d-d.„ Z)e 	ej*e d/ej'd¡g¡Z+d0d1„ Z,e 	ej-e d,ej
d¡g¡Z.d2d3„ Z/e 	ej0e d,ej
d¡g¡Z1d4d5„ Z2ej	eje d$ej
d¡gd6ddZ3d7d8„ Z4e 	ej
e d
ej
d¡g¡Z5e 	ej
e d9ejd¡g¡Z6d:d;„ Z7d<d=„ Z8e 	ej9e dej:d¡g¡Z;e 	ej9e d>ej<d¡g¡Z=ej	eje d$ej
d¡gd?d@Z>ej dAejdBej?dCej'dDej*dEej-dFej0dFej$dGij@ZAeBdHgƒZCdIdJ„ ZDe 	ejEe dKej
d¡g¡ZFdLdM„ ZGe 	ejHe dNej
d¡g¡ZIdOdP„ ZJdQdR„ ZKe 	ej
e dSej
d¡e dTej*d¡g¡ZLe 	ej
e dSej
d¡e dTej*d¡e dUej$d¡g¡ZMdôdVdW„ZNej	ejOe d/ej
d¡e dXej
d¡gd?d@ZPdYdZ„ ZQd[d\„ ZRej	ejOe d]ej
d¡e d9ejd¡gd?d@ZSej	ejOe d]ej
d¡e d9ej
d¡gd?d@ZTd^d_„ ZUe 	ej
e d/ej
d¡g¡ZVej	ej
e d/ej
d¡e d`ej
d¡e daejd¡e dbejd¡gddcZWddde„ ZXdõdgdh„ZYej	ejOe d$ej
d¡gd?d@ZZdidj„ Z[e 	ej
e d)ej
d¡e dkej
d¡e dlej
d¡g¡Z\dmdn„ Z]e 	ej
e d)ej
d¡e dkej
d¡e dlej
d¡e doejd¡g¡Z^dpdq„ Z_e 	ej
e d)ej
d¡e dkej
d¡e dlej
d¡g¡Z`drds„ Zaedtd„ ejbejfD ƒƒZcdudv„ Zddwdx„ Zedydz„ Zfd{d|„ Zgd}d~„ Zhdd€„ Zidd‚„ Zjdƒd„„ Zkd…d†„ Zld‡dˆ„ Zmd‰dŠ„ Znd‹dŒ„ ZoddŽ„ Zpdd„ Zqd‘d’„ Zrd“d”„ Zsd•d–„ Ztd—d˜„ Zud™dš„ Zvd›dœ„ Zwddž„ ZxdŸd „ Zye 	ejHe d¡ejzd¡g¡Z{d¢d£„ Z|e|Z}e|Z~e|Ze|Z€e|Ze|Z‚e|Zƒe|Z„e|Z…e 	ejze d¡ejzd¡g¡Z†d¤d¥„ Z‡e‡Zˆe‡Z‰e‡ZŠe 	ej'e d¦ej d¡e d§ejHd¡g¡Z‹d¨d©„ ZŒe 	ej'e d¦ej d¡e dªej
d¡e d«ejd¡g¡Zd¬d­„ ZŽe 	ej e d¦ej d¡e d®ej
d¡g¡Zd¯d°„ Zej	ejHe 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d?d@Z‘dµd¶„ 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¡e d³ejd¡e d´ejd¡gd»d@Z•d¼d½„ 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¡e d³ejd¡g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¡g¡Z›dÆdÇ„ Zœe 	eje d$ej d¡e dÈej:d¡e dÉej:d¡g¡Ze 	eje d$ej d¡g¡ZždÊdËdÌdÍdÎdÏdÐdÑgZŸdÒdÓ„ eŸD ƒZ dÔdÕ„ Z¡e ¢e 	ej 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¡e dÉej:d¡e dÙe£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¡e dÉej:d¡e dÙe£d¡g¡Z¥dZ¦dÚdÛ„ Z§e§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e°j±j²dfdëdì„Z³dídî„ Z´dïdð„ Zµdñdò„ Z¶d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.
        )r6   Z	reanalyse)r4   r    r   r   r   Úvisit_PyTypeTestNodeö  s    
z)OptimizeBuiltinCalls.visit_PyTypeTestNodec             C   s"   |   |¡ |j|jjkr|jS |S )z,
        Drop redundant type casts.
        )r6   r_   r[   )r4   r    r   r   r   Ú_visit_TypecastNodeü  s    
z(OptimizeBuiltinCalls._visit_TypecastNodec             C   sd   |   |¡ t|jtjƒr"|jj|_|j}|dks<|js<|jr@dS |jr`|j	r`|j	j
s\|j	jr`dS |S )z7
        Drop dead code and useless coercions.
        N)r6   r   r8   r   ÚCoerceToPyTypeNoder   Zis_nonerÊ   r…   r‡   Úis_localZis_arg)r4   r    r8   r   r   r   r9     s    

z'OptimizeBuiltinCalls.visit_ExprStatNodec             C   sT   |   |¡ |j}t|tjƒr"|j}t|tjƒrP|jtjt	j
fkrP|j |  ¡ ¡S |S )z<Drop redundant conversion nodes after tree changes.
        )r6   r   r   r   ÚPyTypeTestNoderÇ  r_   r   r  r   Ú	bool_typeÚcoerce_to_booleanrk   )r4   r    r   r   r   r   Úvisit_CoerceToBooleanNode  s    
z.OptimizeBuiltinCalls.visit_CoerceToBooleanNodeÚoNc          	   C   s¤   |   |¡ |j}t|tjƒr"|j}t|tjƒr |jjdkr t|j	ƒdkr |j	d }|j
tjkrh| d¡S |j
jr tj|jd| j|gd|j|jd |j
|  ¡ ¡S |S )z3Drop redundant conversion nodes after tree changes.r†  r   r   z=float() argument must be a string or a number, not 'NoneType'Z__Pyx_PyNumber_Float)r—   Úpy_namer¬   rÈ   )r6   r   r   r   ÚCoerceFromPyTypeNoder²   r™   r   rC   r—   r_   r   r‰  rª   r¢   r\   ÚPyNumber_Float_func_typer¬   rÈ   rÏ   rk   )r4   r    r   Úfunc_argr   r   r   Úvisit_CoerceToPyTypeNode(  s$    




z-OptimizeBuiltinCalls.visit_CoerceToPyTypeNodec             C   sŠ  |   |¡ |j}|jjs:|j|jkr6| |j|  ¡ ¡}|S t|tjƒrL|j}|j	r¢|jj
rft|tjƒsŽ|jjrzt|tjƒsŽ|jj
r t|tjƒr | |j|  ¡ ¡S nät|tjƒr|jtjkrâ|j |jj¡rà|j |j|  ¡ ¡S n8|jtjkr†|jjjr†|jjr†|j |j|  ¡ ¡S njt|tjƒrL|jj
s>|jjr†|  ||¡S n:|jr†|j}t|tjƒrn|j}|jj
r†|  |||¡S |S )zÕDrop 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.
        )r6   r   r_   r¢   rÏ   rk   r   r   rÉ  rÊ   rŸ   r£   Úis_floatr‡  rf   rÇ  r   r  rî   r   r”   Úis_unicode_charr–   Ú_optimise_numeric_cast_callr]   r¼   Ú_optimise_int_indexing)r4   r    r   rm  r   r   r   Úvisit_CoerceFromPyTypeNode>  s<    

z/OptimizeBuiltinCalls.visit_CoerceFromPyTypeNodeÚbytesr¼   Zcheck_boundsz
((char)-1)T)r¾   Zexception_checkc          
   C   s¬   |   ¡ }|jd rdpd}|jjtjkr¨|jtjtjfkr¨t	j
|jt|ƒ|d}t	j|jd| j|j d¡| tj|¡|gdt dd	¡d
}|jtjk	r¤| |j|¡}|S |S )NZboundscheckr   r   )rN   r-   Z__Pyx_PyBytes_GetItemIntz&'NoneType' object is not subscriptableTZbytes_indexzStringTools.c)r—   r¬   rÉ   )rk   Z
directivesr^   r_   r   r’   r   Úc_char_typeZc_uchar_typer   r£   r\   rÐ   r²   ÚPyBytes_GetItemInt_func_typerª   rÏ   rÑ   r   r   )r4   Zcoerce_noder   rm  r{  Zbound_check_boolZbound_check_noder    r   r   r   rÖ  o  s(    

z+OptimizeBuiltinCalls._optimise_int_indexingc          
   c   s*   | ]"}|t  |t  d |d¡g¡fV  qdS )r   N)r   r  r  )rF   r‰  r   r   r   ú	<genexpr>‰  s   zOptimizeBuiltinCalls.<genexpr>c          	   C   s°  |j }d }t|tjƒr|j}n*t|tjƒrH|jjrHt|jtj	ƒrH|jj}|d ks\t
|ƒdkr`|S |d }t|tjƒr||j}n|jjrˆ|S |jdkrL|jjs¤|jjrà|j|jkr´|S |j |j¡sÊ|jjrÞtj|j||jdS nj|jjr¬|jjr¬|jjdkrd}nd|jj }tj|j|| j|j |gd|j|jd |j|  ¡ ¡S n`|jd	kr¬|jjsl|jjr¬|j|jkr~|S |j |j¡s˜|jjr¬tj|j||jdS |S )
Nr   r   Úint)r[   r_   ÚlZ__Pyx_trunclÚtrunc)r~  r—   rÎ  r¬   rÈ   r†  )r™   r   r   r²   r—   r%   r_   Úis_builtin_typer˜   r^  rC   rÇ  r   r¢   r   rŸ   rî   rÓ  r  r\   Ú
is_numericZmath_h_modifierÚfloat_float_func_typesr¬   rÈ   rÏ   rk   )r4   r    r   r™   r—   rÑ  Ztrunclr   r   r   rÕ    sP    

z0OptimizeBuiltinCalls._optimise_numeric_cast_callc             C   sj   |s
d}n*t |tƒs|dkr"d}n|dkr0d}nd}|d k	rFd| }nd}t|jd|||t|ƒf ƒ d S )Nr  r   z...r€  zexpected %s, z3%s(%s) called with wrong number of args, %sfound %d)r   r   r   r\   rC   )r4   r  r    r—   r‚  rƒ  r„  r   r   r   r…  ¾  s    
z+OptimizeBuiltinCalls._error_wrong_arg_countc             C   s   |S )Nr   )r4   r    r  r™   Úarg_listr|  r   r   r   Ú_handle_functionÐ  s    z%OptimizeBuiltinCalls._handle_functionc             C   sà   |r|S |r|j r|jjs|S |  ¡  |¡}|s4|S tj|jjtj	|j|||j
d|dd |  ¡ ¡}	|	dkr€|  |||||¡S |j}
|
dkrœ|jrœ|jj}
tj|j|	|
d}|sº|j|_| |  ¡ ¡ d|_| |j
|  ¡ ¡S )a  
        Try to inject C-API calls for unbound method calls to builtin types.
        While the method declarations in Builtin.py already handle this, we
        can additionally resolve bound and unbound methods here that were
        assigned to variables ahead of time.
        )r   r‡   r_   T)r)   r*   Z	is_calledN)r™   r—   )r†   r)   r…   rk   rz  r   r&   r™   r\   r%   r_   Zanalyse_as_type_attributeÚ%_optimise_generic_builtin_method_callr—   r˜   r–   r4   Zanalyse_c_function_callZanalysedrÏ   )r4   r    Ú	type_nameÚ	attr_namer™   râ  Úis_unbound_methodr|  Ú
type_entryry   r—   Ú	call_noder   r   r   Ú_handle_methodÓ  s>    z#OptimizeBuiltinCalls._handle_methodc             C   sV   t |ƒ}|s |dks |jr |js$|S |jjjs2|S |jjjdkrD|S t ||j||¡S )z·
        Try to inject an unbound method call for a call to a method of a known builtin type.
        This enables caching the underlying C function of the method at runtime.
        r   )r   r_   )	rC   r†   r'   r)   r_   rß  r   r   ZCachedBuiltinMethodCallNode)r4   r    ræ  r™   râ  rç  r§   r   r   r   rä  ÿ  s    
z:OptimizeBuiltinCalls._optimise_generic_builtin_method_callr)   c          	   C   s   t |ƒdkr0t |ƒdkr,tj|jtƒ ddS |S |d }|jtjkrb| ¡ sP|S d}t	 
dd¡}nd}t	 
d	d¡}tj|j|| j||j|d
dS )z5Optimise single argument calls to unicode().
        r   r   r  )rN   r-   Z__Pyx_PyUnicode_UnicodeZPyUnicode_UnicodezStringTools.cZ__Pyx_PyObject_UnicodeZPyObject_UnicodeÚunicode)r—   r¬   rÉ   rÎ  )rC   r   r"  r\   r   r_   r   r”   Úmay_be_noner   r   r²   ÚPyObject_Unicode_func_typer¬   )r4   r    r™   rŠ  r   r<  rÉ   r   r   r   Ú_handle_simple_function_unicode	  s$    
z4OptimizeBuiltinCalls._handle_simple_function_unicodec             C   sJ   |   |¡ |jjtjkrF|jsF|jsF|jr4|jdkrF|  |d|jg¡S |S )zÞSimplify 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)	r6   rN   r_   r   r”   Zc_format_specÚformat_specÚconversion_charrî  )r4   r    r   r   r   Úvisit_FormattedValueNode+	  s
    
z-OptimizeBuiltinCalls.visit_FormattedValueNoder~   c             C   sN   t |ƒdkr|S |d }|jtjkrJ| d¡}tj|jd| j|g|j	dS |S )z;Replace dict(some_dict) by PyDict_Copy(some_dict).
        r   r   z'NoneType' is not iterableZPyDict_Copy)r—   r¬   )
rC   r_   r   rŠ   rª   r   r²   r\   ÚPyDict_Copy_func_typer¬   )r4   r    r™   rŠ  r   r   r   r   r½  <	  s    


z1OptimizeBuiltinCalls._handle_simple_function_dictr¡  c             C   s2   t |ƒdkr|S |d }tj|jd| j||jdS )z0Turn list(ob) into PySequence_List(ob).
        r   r   r¤  )r—   r¬   )rC   r   r²   r\   r©  r¬   )r4   r    r™   rŠ  r   r   r   r   r¹  O	  s    
z1OptimizeBuiltinCalls._handle_simple_function_listr2  c             C   s‚   t |ƒdks|js|S |d }|jtjkr6| ¡ s6|S |jtjkrj| d¡|d< tj	|j
d| j||jdS tj|j
|tjdS dS )zDReplace tuple([...]) by PyList_AsTuple or PySequence_Tuple.
        r   r   z!'NoneType' object is not iterableZPyList_AsTuple)r—   r¬   )r   r_   N)rC   r¬   r_   r   r¨   rì  r©   rª   r   r²   r\   ÚPyList_AsTuple_func_typer´  )r4   r    r™   rŠ  r   r   r   r   Ú_handle_simple_function_tuple^	  s    

z2OptimizeBuiltinCalls._handle_simple_function_tuplec       	      C   sÊ   t |ƒdkr|S |d jr¢g }g }x8|d jD ]*}| ¡ sNt |¡}| |¡ | |¡ q.W tj|j	d|d}|  
||¡ x"|d d d… D ]}t ||¡}qŠW |S |  
|tj|j	d| j||jdd¡S d S )Nr   r   )r¬   r—   rá   Z	PySet_Newr  )r—   r¬   rÎ  )rC   rô   r—   rb  r   r±   r5   r   r`  r\   rÃ  r  r²   ÚPySet_New_func_typer¬   )	r4   r    r™   rŠ  r—   rY   r   rµ  r÷   r   r   r   rº  u	  s*    



z0OptimizeBuiltinCalls._handle_simple_function_setc          
   C   sn   |st  |j¡g}n4t|ƒdkr$|S |d jtjkrH|d  ¡ sH|d S t j|jd| j	||j
t dd¡ddS )Nr   r   Z__Pyx_PyFrozenSet_NewZpyfrozenset_newz
Builtins.cÚ	frozenset)r—   r¬   rÉ   rÎ  )r   r  r\   rC   r_   r   r   rì  r²   ÚPyFrozenSet_New_func_typer¬   r   r   )r4   r    r™   rŠ  r   r   r   r¸  ˜	  s    
z6OptimizeBuiltinCalls._handle_simple_function_frozensetz((double)-1)c          	   C   sÀ   t |ƒdkr*tj|ddd tj|  ¡ ¡S t |ƒdkrJ|  d||d¡ |S |d }t|tj	ƒrd|j
}|jtjkrt|S |j |j¡sŠ|jjržtj|j||jdS tj|jd	| j||jtd
ƒddS )zYTransform float() into either a C type cast or a faster C
        function call.
        r   z0.0g        )rN   r-   r   r†  z0 or 1)r[   r_   Z__Pyx_PyObject_AsDoubleZpyobject_as_double)r—   r¬   rÉ   rÎ  )rC   r   r‡  rÏ   r   r‰  rk   r…  r   rÇ  r   r_   r   rˆ  rî   rà  r  r\   r²   ÚPyObject_AsDouble_func_typer¬   r   )r4   r    r™   rŠ  rÑ  r   r   r   rŒ  ¯	  s,    z2OptimizeBuiltinCalls._handle_simple_function_floatrN   c             C   sª   t |ƒdkr"tj|jddtjdS t |ƒdkr2|S |d }t|tjƒr||jj	j
rxtj|jd| j|jgddt dd	¡d
S |S |j	jr¦|j	jr¦tj|jd| j|dddS |S )z7Transform int() into a faster C function call.
        r   rÀ   )rN   r-   r_   r   Z__Pyx_PyInt_FromDoubleTrÜ  ZPyIntFromDoublezTypeConversion.c)r—   r¬   rÎ  rÉ   Z__Pyx_PyNumber_Int)r—   r¬   rÎ  )rC   r   r£   r\   r   r  r   rÇ  r   r_   rÓ  r²   ÚPyInt_FromDouble_func_typer   r   r¢   ÚPyNumber_Int_func_type)r4   r    r™   rŠ  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rL|  d||d¡ |S |d  	|  ¡ ¡}tj
|j|d}tj
|j|d}| |  ¡ ¡S dS )	z=Transform bool(x) into a type coercion to a boolean.
        r   F)rN   r-   r   Úboolz0 or 1)r[   N)rC   r   rf   r\   rÏ   r   rÊ  rk   r…  rË  rn   Úcoerce_to_pyobject)r4   r    r™   rŠ  r[   r   r   r   Ú_handle_simple_function_boolí	  s    z1OptimizeBuiltinCalls._handle_simple_function_boolrë  z-1)r¾   Z__Pyx_PyUnicode_GET_LENGTHr­   ZPyByteArray_GET_SIZEZPyList_GET_SIZEZPyTuple_GET_SIZEZPySet_GET_SIZEZPyDict_Sizezcpython.array.arrayc       	   
   C   sœ  t |ƒdkr |  d||d¡ |S |d }t|tjƒr:|j}|jjrltj|j	d| j
|g|jt dd¡d}n|jjr’tj|j	d| j|g|jd	}nà|jjrÖtjtjt d
|jd¡gdd}tj|j	d||g|jd	}nœ|jjrN|  |j¡}|dkr&|j}|js|jr"|jj| jkr"d}n|S | d¡}tj|j	|| j|g|jd	}n$|jjrntj|j	dd|jdS |S |jtjtj fkr˜| !|j|  "¡ ¡}|S )z¾Replace 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   rC   r   ÚstrlenÚIncludeStringHzStringTools.c)r—   r¬   rÉ   Z__Pyx_Py_UNICODE_strlen)r—   r¬   ZmemoryviewsliceNT)ZnogilZ__Pyx_MemoryView_LenZPy_SIZEz&object of type 'NoneType' has no len()rã   )rN   r-   r_   )#rC   r…  r   r   rÇ  r   r_   rë   r²   r\   ÚPyx_strlen_func_typer¬   r   r   Zis_pyunicode_ptrÚPyx_Py_UNICODE_strlen_func_typeZis_memoryviewslicer   r  Úc_size_t_typer  r¢   Ú_map_to_capi_len_functionÚis_extension_typerß  r‡   r‰   Ú_ext_types_with_pysizerª   ÚPyObject_Size_func_typerÔ  r£   rÑ   rÏ   rk   )	r4   r    r™   rŠ  r   rq   r~  Z
cfunc_namer‹  r   r   r   Ú_handle_simple_function_len
  sZ    






z0OptimizeBuiltinCalls._handle_simple_function_lenÚobjectc             C   s6   t |ƒdkr|S tj|jd| j|dd}t |tj¡S )z7Replace type(o) by a macro call to Py_TYPE(o).
        r   ZPy_TYPEF)r—   r¬   )rC   r   r²   r\   ÚPyx_Type_func_typerì   r   r  )r4   r    r™   rŠ  r   r   r   Ú_handle_simple_function_typeX
  s    
z1OptimizeBuiltinCalls._handle_simple_function_typer   c          
      sú  t |ƒdkrˆS |\}}g }t|tjƒrr|j}t |ƒdkrN|d jtjk	rNˆS |js\| 	¡ sŠt
 |¡}| |¡ n|jtjkr†|g}nˆS g }g }|  ¡ ‰ x
|D ] }	d}
|	jrÞ|	jrÞˆ  |	jj¡}|rÞ|jrÞ|jjrÞ|j}
|
tjkr|jdks|jr|jjsd}
|
dk	rB|jjdd}||kr0q¢| |¡ |g}nD|	jtjkr^d}||	g}n(|	jszt
 |	¡}	| |	¡ d	}||	g}| tj|	j|| j|d
d¡ q¢W tjf‡ ‡fdd„	}t||ƒ ˆjˆ ¡}x$|ddd… D ]}t
 ||¡}qàW |S )zcReplace isinstance() checks against builtin types by the
        corresponding C-API call.
        ró   r   r   Nr_   F)ÚexactZ__Pyx_TypeCheckZPyObject_IsInstanceT)r—   r¬   c                s&   |ˆj d| |ƒ}tj|_| ˆ ¡ |S )Nr  )r\   r   rd  r_   rP  )r+   r,   Zmake_binop_nodeZor_node)r{  r    r   r   Újoin_with_or¡
  s    
zMOptimizeBuiltinCalls._handle_simple_function_isinstance.<locals>.join_with_orrá   )rC   r   r   r^  r—   r_   r   Ú	type_typer†   rb  r   r"   r5   rk   r…   r‡   rz  r   rß  ÚscopeZis_builtin_scopeÚtype_check_functionrÊ   r²   r\   ÚPy_type_check_func_typer   r   rÏ   r  )r4   r    r™   rŠ  r   ÚtypesrY   ÚtestsZ
test_nodesZtest_type_nodeZbuiltin_typer‡   r  Ztype_check_argsr  r   r÷   r   )r{  r    r   Ú"_handle_simple_function_isinstanceh
  sh    







z7OptimizeBuiltinCalls._handle_simple_function_isinstancec             C   s  t |ƒdkr|S |d }t|tjƒrT|jjjrRtj|j|jt	j
d |j|  ¡ ¡S nºt|tjƒr¤t |jƒdkr¢tj|jt	jtt|jƒƒt|jƒd |j|  ¡ ¡S njt|tjƒr|jrt |jƒdkrt|jƒdkrtj|jt	jtt|jƒƒt|jƒd |j|  ¡ ¡S |S )z-Unpack ord(Py_UNICODE) and ord('X').
        r   r   )r[   r_   )r_   rN   r-   r  )rC   r   r   rÇ  r   r_   rÔ  r  r\   r   r‘  rÏ   rk   r"  rN   r£   rÒ   rÐ   r4  r	  r’  )r4   r    r™   rŠ  r   r   r   r   r“  ¬
  s0    
z0OptimizeBuiltinCalls._handle_simple_function_ordr_   r—   r|  c          
   C   sò  |j }|rt|ƒdk r|S |d }|jr.|js2|S |jtjksJ|jtjkrN|S |jrZ|jsl|j|jkr||S n|j|jkr||S tj	|j
|dd… d}|j|  ¡ dd}|jr|jj}	|	jrš|	jrš|	j ¡ |  ¡  ¡ kršt dd¡}
t |	j|
¡}|rš| jj}t | d	¡j¡}t |	t d
|d¡t dtjd¡t dtjd¡g¡}t ||¡}|sptj|j
tjd}tj|j
|||||gdddS n
| d¡}t  !dd¡}|rÎtj|j
d| j"|||g||j#dS tj|j
d| j$||g||j#dS dS )zOReplace 'exttype.__new__(exttype, ...)' by a call to exttype->tp_new()
        r   r   N)r—   T)Úskip_childrenZtp_newÚ__new__ÚPyTypeObjectr_   r—   r|  )r_   F)r—   Úmay_return_noner¬   z4object.__new__(X): X is not a type object (NoneType)zObjectHandling.cZ__Pyx_tp_new_kwargs)r—   rÉ   r¬   Z__Pyx_tp_new)%r)   rC   r…   r_   r   r  rè  r   r   r^  r\   Úanalyse_typesrk   r  Ztypeobj_cnamer  rš   r   ZConstructorSlotZget_slot_functionr›   Úcython_scoper   ÚCPtrTyperz  r  r  r  rì   r  r²   rª   r   r   ÚPyx_tp_new_kwargs_func_typer¬   ÚPyx_tp_new_func_type)r4   r    r™   r—   rç  r|  r)   Útype_argZ
args_tupleZext_typeZtp_slotZslot_func_cnamer  ÚPyTypeObjectPtrZpyx_tp_new_kwargs_func_typerÉ   r   r   r   Ú_handle_any_slot__new__×
  sl    



z,OptimizeBuiltinCalls._handle_any_slot__new__rõ   c          
   C   sB   t |ƒdks|js|jjr|S tj|jd| j|d|jdt	dƒdS )z\Optimistic optimisation as X.append() is almost always
        referring to a list.
        ró   Z__Pyx_PyObject_AppendFr5   )r—   r  r¬   rÈ   rÉ   )
rC   rÈ   r™   r‡   r   r²   r\   ÚPyObject_Append_func_typer¬   r   )r4   r    r™   r—   rç  r   r   r   Ú#_handle_simple_method_object_append+  s    
z8OptimizeBuiltinCalls._handle_simple_method_object_appendc             C   sÆ  t |ƒdkr|S |\}}|js"|S t|jƒ}|jdk	sBt |ƒdkr‚dr~t|tjƒr~|d  ¡ j	|  
¡ dd}t ||d |¡ |S |  |||d¡}	|s¢|j|	_|	S |	 }
}t |ƒdkrÈ| ¡ sÈt |¡}
g }|d	 }| ¡ sðt |¡}| |¡ tj|jd
| j|
|gdtdƒd}xn|ddd	… D ]\}| ¡ sDt |¡}| |¡ tj|jdtj|jd| j|
|gddtdƒd|tjd}q"W |j|_|
|k	rž| |
¡ x"|D ]}t ||¡}|j|_q¤W |S )z™Replace list.extend([...]) for short sequence literals values by sequential appends
        to avoid creating an intermediate sequence argument.
        ró   Né   Fr   T)r  Úextendrá   Z__Pyx_PyList_AppendZ
ListAppend)r—   r¬   rÉ   éþÿÿÿú|Z__Pyx_ListComp_AppendZListCompAppend)r—   rÎ  r¬   rÉ   )r_   )rC   rô   r2  r—   Úmult_factorr   r   r_  r·  r  rk   r   r›  Ú_wrap_self_argrÈ   rb  r   r±   r5   r²   r\   r!  r   r   r   Úc_returncode_typer  )r4   r    r™   r—   rç  r)   rN   r}   Z
tuple_nodeZwrapped_objZ
cloned_objrY   r   rq   r÷   r   r   r   Ú!_handle_simple_method_list_extend;  s`    












z6OptimizeBuiltinCalls._handle_simple_method_list_extendÚ	bytearrayc       
   	   C   sð   t |ƒdkr|S d}| j}t|d ƒ}|jjs:t|tjƒrZ| t	j
|  ¡ ¡}t dd¡}nV|jrŒ| ¡ sl|S | t	j|  ¡ ¡}t dd¡}n$|jjr¬d}| j}t dd¡}n|S tj|j|||d |gd	|j|d
}	|jrì|	 |j|  ¡ ¡}	|	S )Nró   Z__Pyx_PyByteArray_Appendr   ZByteArrayAppendzStringTools.cZ__Pyx_PyByteArray_AppendObjectZByteArrayAppendObjectr   F)r—   r  r¬   rÉ   )rC   ÚPyByteArray_Append_func_typer!   r_   rŸ   r   r   r£   rÏ   r   rÒ   rk   r   r   Úis_string_literalZcan_coerce_to_char_literalrÙ  r¢   Ú"PyByteArray_AppendObject_func_typer²   r\   r¬   rÈ   )
r4   r    r™   r—   rç  Ú	func_namer~  rN   rÉ   rq   r   r   r   Ú&_handle_simple_method_bytearray_appendˆ  s6    
z;OptimizeBuiltinCalls._handle_simple_method_bytearray_appendÚpy_indexZc_indexÚ	is_signed)Zhas_varargsc             C   s   | j ||||ddS )NT)Úis_list)Ú _handle_simple_method_object_pop)r4   r    r™   r—   rç  r   r   r   Ú_handle_simple_method_list_pop·  s    z3OptimizeBuiltinCalls._handle_simple_method_list_popFc             C   s  |s|S |d }|r,d}|j dddgd}nd}t|ƒdkrdtj|jd	| | j|gd
|jtdƒdS t|ƒdkrþt|d ƒ}t 	|j¡}	|j
}
|j
jst|tjƒrÈ| |  ¡ ¡}	| tj|  ¡ ¡}n>|r|j
jrî| |  ¡ ¡}	t |	¡}| tj|  ¡ ¡}n|S n2t |j
tj¡s|S t|tjƒr:| |  ¡ ¡}	|
jsH|j
}
|
 |  ¡ ¡s\|S |
j}t tjt d|
d¡g¡}tj|jd| | j||	|tj|jt|
jr¬dp®dƒ|
jr¾dpÀd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   ÚListz*'NoneType' object has no attribute '%.30s'r  Úpop)r   r  ZObjectr   z__Pyx_Py%s_PopT)r—   r  r¬   rÉ   ró   ZintvalNz__Pyx_Py%s_PopIndex)rN   r-   r_   Z	pop_index)#rª   rC   r   r²   r\   ÚPyObject_Pop_func_typer¬   r   r!   rŽ  r_   rŸ   r   r£   rý  rk   rÏ   r   rÑ   r¢   rè   rê   Znumeric_type_fitsZcreate_to_py_utility_codeZto_py_functionr  r  r  ÚPyObject_PopIndex_func_typerÐ   ÚsignedrÒ   ÚRawCNameExprNodeZc_void_typeZempty_declaration_code)r4   r    r™   r—   rç  r3  r)   rå  r¼   r1  Zorig_index_typeZconvert_funcZconversion_typer   r   r   r4  »  sr    



z5OptimizeBuiltinCalls._handle_simple_method_object_popc          	   C   s4   t |ƒdkr|S |  ||d| jd||¡ |j| j¡S )z?Call PyList_Sort() instead of the 0-argument l.sort().
        r   ZPyList_Sortr5  )rC   Ú_substitute_method_callÚsingle_param_func_typerÏ   r_   rk   )r4   r    r™   r—   rç  r   r   r   Ú_handle_simple_method_list_sort  s
    
z4OptimizeBuiltinCalls._handle_simple_method_list_sortÚkeyÚdefaultc             C   sb   t |ƒdkr | t |j¡¡ n t |ƒdkr@|  d||d¡ |S | j||d| jd||dtdƒd		S )
z:Replace dict.get() by a call to PyDict_GetItem().
        ró   r   zdict.getz2 or 3Z__Pyx_PyDict_GetItemDefaultrE  TZdict_getitem_default)r  rÉ   )	rC   r5   r   rŽ  r\   r…  r<  ÚPyx_PyDict_GetItem_func_typer   )r4   r    r™   r—   rç  r   r   r   Ú_handle_simple_method_dict_get  s    z3OptimizeBuiltinCalls._handle_simple_method_dict_getÚis_safe_typec             C   s²   t |ƒdkr | t |j¡¡ n t |ƒdkr@|  d||d¡ |S |d j}|jr`t|j	dkƒ}n|t
jkrpd}nd}| tj|jt|ƒ|d	¡ | j||d
| jd||dtdƒd	S )zUReplace dict.setdefault() by calls to PyDict_GetItem() and PyDict_SetItem().
        ró   r   zdict.setdefaultz2 or 3r   z%str bytes unicode float int long boolrá   r   )rN   r-   Z__Pyx_PyDict_SetDefaultÚ
setdefaultTZdict_setdefault)r  rÉ   )rC   r5   r   rŽ  r\   r…  r_   rß  rÜ  r   r   r  r£   rÐ   r<  ÚPyx_PyDict_SetDefault_func_typer   )r4   r    r™   r—   rç  Zkey_typerC  r   r   r   Ú%_handle_simple_method_dict_setdefault-  s(    


z:OptimizeBuiltinCalls._handle_simple_method_dict_setdefaultc             C   sb   t |ƒdkr | t |j¡¡ n t |ƒdkr@|  d||d¡ |S | j||d| jd||dtdƒd		S )
z7Replace dict.pop() by a call to _PyDict_Pop().
        ró   r   zdict.popz2 or 3Z__Pyx_PyDict_Popr7  TZpy_dict_pop)r  rÉ   )	rC   r5   r   r  r\   r…  r<  ÚPyDict_Pop_func_typer   )r4   r    r™   r—   rç  r   r   r   Ú_handle_simple_method_dict_popN  s    z3OptimizeBuiltinCalls._handle_simple_method_dict_popc             c   sˆ   | ]€}t jt jfD ]n}||ft j|t  d t jd¡t  dt jd¡t  d|d¡t  dt jd¡t  dt jd¡g|jrrdn|jdfV  qqdS )Zop1NZop2ÚcvalÚinplaceZzerodiv_check)r¾   )r   r  rd  r  r  r¢   r¾   )rF   ÚctypeÚret_typer   r   r   rÛ  _  s   c             C   s   |   d||||¡S )NÚAdd)Ú_optimise_num_binop)r4   r    r™   r—   rç  r   r   r   Ú$_handle_simple_method_object___add__k  s    z9OptimizeBuiltinCalls._handle_simple_method_object___add__c             C   s   |   d||||¡S )NÚSubtract)rN  )r4   r    r™   r—   rç  r   r   r   Ú$_handle_simple_method_object___sub__n  s    z9OptimizeBuiltinCalls._handle_simple_method_object___sub__c             C   s   |   d||||¡S )NÚEq)rN  )r4   r    r™   r—   rç  r   r   r   Ú#_handle_simple_method_object___eq__q  s    z8OptimizeBuiltinCalls._handle_simple_method_object___eq__c             C   s   |   d||||¡S )NÚNe)rN  )r4   r    r™   r—   rç  r   r   r   Ú#_handle_simple_method_object___ne__t  s    z8OptimizeBuiltinCalls._handle_simple_method_object___ne__c             C   s   |   d||||¡S )NÚAnd)rN  )r4   r    r™   r—   rç  r   r   r   Ú$_handle_simple_method_object___and__w  s    z9OptimizeBuiltinCalls._handle_simple_method_object___and__c             C   s   |   d||||¡S )NÚOr)rN  )r4   r    r™   r—   rç  r   r   r   Ú#_handle_simple_method_object___or__z  s    z8OptimizeBuiltinCalls._handle_simple_method_object___or__c             C   s   |   d||||¡S )NZXor)rN  )r4   r    r™   r—   rç  r   r   r   Ú$_handle_simple_method_object___xor__}  s    z9OptimizeBuiltinCalls._handle_simple_method_object___xor__c             C   s^   t |ƒdkst|d tjƒs |S |d  ¡ rHd|d j  krFdksLn |S |  d||||¡S )Nró   r   é?   ZRshift)rC   r   r   r£   r¤   r-   rN  )r4   r    r™   r—   rç  r   r   r   Ú'_handle_simple_method_object___rshift__€  s
    (z<OptimizeBuiltinCalls._handle_simple_method_object___rshift__c             C   s^   t |ƒdkst|d tjƒs |S |d  ¡ rHd|d j  krFdksLn |S |  d||||¡S )Nró   r   r[  ZLshift)rC   r   r   r£   r¤   r-   rN  )r4   r    r™   r—   rç  r   r   r   Ú'_handle_simple_method_object___lshift__‡  s
    (z<OptimizeBuiltinCalls._handle_simple_method_object___lshift__c             C   s   |   d||||¡S )NÚ	Remainder)Ú_optimise_num_div)r4   r    r™   r—   rç  r   r   r   Ú$_handle_simple_method_object___mod__Ž  s    z9OptimizeBuiltinCalls._handle_simple_method_object___mod__c             C   s   |   d||||¡S )NÚFloorDivide)r_  )r4   r    r™   r—   rç  r   r   r   Ú)_handle_simple_method_object___floordiv__‘  s    z>OptimizeBuiltinCalls._handle_simple_method_object___floordiv__c             C   s   |   d||||¡S )NÚ
TrueDivide)r_  )r4   r    r™   r—   rç  r   r   r   Ú(_handle_simple_method_object___truediv__”  s    z=OptimizeBuiltinCalls._handle_simple_method_object___truediv__c             C   s   |   d||||¡S )NÚDivide)r_  )r4   r    r™   r—   rç  r   r   r   Ú$_handle_simple_method_object___div__—  s    z9OptimizeBuiltinCalls._handle_simple_method_object___div__c             C   s¤   t |ƒdks&|d  ¡ r&|d jdkr*|S t|d tjƒr\d|d j  krTdks’n |S n6t|d tjƒrŽd|d j  kr†dks’n |S n|S |  |||||¡S )Nró   r   r   i   Ài   @lüÿÿÿ       l          )rC   r¤   r-   r   r   r£   r‡  rN  )r4   rK   r    r™   r—   rç  r   r   r   r_  š  s    &z&OptimizeBuiltinCalls._optimise_num_divc             C   s   |   d||||¡S )NrM  )rN  )r4   r    r™   r—   rç  r   r   r   Ú#_handle_simple_method_float___add__§  s    z8OptimizeBuiltinCalls._handle_simple_method_float___add__c             C   s   |   d||||¡S )NrP  )rN  )r4   r    r™   r—   rç  r   r   r   Ú#_handle_simple_method_float___sub__ª  s    z8OptimizeBuiltinCalls._handle_simple_method_float___sub__c             C   s   |   d||||¡S )Nrc  )rN  )r4   r    r™   r—   rç  r   r   r   Ú'_handle_simple_method_float___truediv__­  s    z<OptimizeBuiltinCalls._handle_simple_method_float___truediv__c             C   s   |   d||||¡S )Nre  )rN  )r4   r    r™   r—   rç  r   r   r   Ú#_handle_simple_method_float___div__°  s    z8OptimizeBuiltinCalls._handle_simple_method_float___div__c             C   s   |   d||||¡S )Nr^  )rN  )r4   r    r™   r—   rç  r   r   r   Ú#_handle_simple_method_float___mod__³  s    z8OptimizeBuiltinCalls._handle_simple_method_float___mod__c             C   s   |   d||||¡S )NrR  )rN  )r4   r    r™   r—   rç  r   r   r   Ú"_handle_simple_method_float___eq__¶  s    z7OptimizeBuiltinCalls._handle_simple_method_float___eq__c             C   s   |   d||||¡S )NrT  )rN  )r4   r    r™   r—   rç  r   r   r   Ú"_handle_simple_method_float___ne__¹  s    z7OptimizeBuiltinCalls._handle_simple_method_float___ne__c             C   sŒ  t |ƒdkr|S |jjr tj}n |jtjkr<|dkr<tj}n|S tjtjf}t	|d |ƒr||d jtjk	rn|S |d }d}	n4t	|d |ƒr¬|d jtjk	rž|S |d }d}	n|S | 
¡ s¼|S t	|tjƒ}
|
rÒtjntj}|
rê|dkrè|S n |dkrö|S t|jƒd	kr
|S |d
kr(|d jdkr(|S t|ƒ}| |
r@tjntj|j|j|j|d¡ t	|tjƒrn|jnd}| tj|j||d¡ |
sš|dkrÖ|	dko¼t	|tjƒrº|j nd}| tj|j||d¡ tj|
rädn|dkròdnddt||	|dd}| j||d|
rdnd|jr*dnd||	f | j||f d|dd…  ¡  ||dd|d
}|jjrˆ|jsˆt ||  ¡ |j¡}|S )zY
        Optimise math operators for (likely) float or small integer operations.
        ró   )rR  rT  r   r   ZObjCZCObj)rM  rP  r^  rc  re  rR  rT  re  i   @)rc  ra  re  r^  )rN   r-   r_   F)rN   r-   ZPyFloatBinopZPyIntCompareZ
PyIntBinopz
Optimize.c)ÚopÚorderrL  )r›   z__Pyx_Py%s_%s%s%sÚFloatZIntr  ZBoolz__%s__Nr   T)r  Úwith_none_checkrÉ   ) rC   r_   r¢   r   r  rd  r   r£   r‡  r   r¤   rˆ  r‘  ræ   r-   r2  r5   r\   rN   ZNumBinopNoderJ  rf   r  Z	cdivisionr   r   r~   r<  ÚPyx_BinopInt_func_typesÚlowerrÇ  rk   )r4   rK   r    r™   r—   rç  rL  Z	num_nodesZnumvalZ	arg_orderrÓ  Znum_typerJ  Zzerodivision_checkrÉ   ré  r   r   r   rN  ¼  s|    


z(OptimizeBuiltinCalls._optimise_num_binopÚucharc          
   C   s¢   |st |ƒdkr|S |d }t|tjƒr2|jjjs6|S |j}|j}|dkr\t 	dd¡}d}	nd }d| 
¡  }	| j|||	| j|||g|d}
|jjrž|
 | j¡}
|
S )	Nr   r   ÚistitleZpy_unicode_istitlezStringTools.cZ__Pyx_Py_UNICODE_ISTITLEzPy_UNICODE_%s)rÉ   )rC   r   r   rÇ  r   r_   rÔ  r*   r   r   Úupperr<  Ú#PyUnicode_uchar_predicate_func_typer¢   rý  rk   )r4   r    r™   r—   rç  Úustringrt  r  rÉ   r  Ú	func_callr   r   r   Ú_inject_unicode_predicate  s,    
z.OptimizeBuiltinCalls._inject_unicode_predicatec       
   	   C   s€   |st |ƒdkr|S |d }t|tjƒr2|jjjs6|S |j}|j}d| ¡  }|  	|||| j
|||g¡}	|jjr||	 | j¡}	|	S )Nr   r   zPy_UNICODE_TO%s)rC   r   r   rÇ  r   r_   rÔ  r*   rv  r<  Ú$PyUnicode_uchar_conversion_func_typer¢   rý  rk   )
r4   r    r™   r—   rç  rx  rt  r  r  ry  r   r   r   Ú$_inject_unicode_character_conversion@  s     
z9OptimizeBuiltinCalls._inject_unicode_character_conversionrÐ   Úkeependsc          	   C   sH   t |ƒdkr |  d||d¡ |S |  ||dd¡ |  ||d| jd||¡S )zfReplace unicode.splitlines(...) by a direct call to the
        corresponding C-API function.
        )r   ró   zunicode.splitlinesz1 or 2r   FZPyUnicode_SplitlinesÚ
splitlines)rC   r…  Ú_inject_bint_default_argumentr<  ÚPyUnicode_Splitlines_func_type)r4   r    r™   r—   rç  r   r   r   Ú(_handle_simple_method_unicode_splitlines\  s    z=OptimizeBuiltinCalls._handle_simple_method_unicode_splitlinesÚsepÚmaxsplitc          	   C   sj   t |ƒdkr |  d||d¡ |S t |ƒdk r>| t |j¡¡ |  ||dtjd¡ |  	||d| j
d||¡S )zaReplace unicode.split(...) by a direct call to the
        corresponding C-API function.
        )r   ró   r   zunicode.splitz1-3ró   z-1ZPyUnicode_SplitÚsplit)rC   r…  r5   r   r  r\   Ú_inject_int_default_argumentr   rÑ   r<  ÚPyUnicode_Split_func_type)r4   r    r™   r—   rç  r   r   r   Ú#_handle_simple_method_unicode_splitr  s    z8OptimizeBuiltinCalls._handle_simple_method_unicode_splitÚseqc          	   C   s´   t |ƒdkr |  d||d¡ |S t|d tjƒrœ|d }|j}t|ƒ}|rœtj|j|dt	j
d}x2|D ]*\}	}
tj|	j|	|jd}t ||
|¡ qfW ||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   r2  )r™  r£  )r8   rW   ZPyUnicode_Joinrq  )rC   r…  r   r   rš  r¦  rB   rœ  r\   r   r©   r§  rW   r   r›  r<  ÚPyUnicode_Join_func_type)r4   r    r™   r—   rç  r  rà   rD   Zinlined_genexprrž  rŸ  rª  r   r   r   Ú"_handle_simple_method_unicode_join‰  s,    

z7OptimizeBuiltinCalls._handle_simple_method_unicode_joinZ	substringr®   ÚendÚ	directionc          
   C   s   |   ||||ddtd¡S )Nrë  Úendswithr   )Ú_inject_tailmatchÚunicode_tailmatch_utility_code)r4   r    r™   r—   rç  r   r   r   Ú&_handle_simple_method_unicode_endswith³  s    z;OptimizeBuiltinCalls._handle_simple_method_unicode_endswithc          
   C   s   |   ||||ddtd¡S )Nrë  Ú
startswithrá   )r  r  )r4   r    r™   r—   rç  r   r   r   Ú(_handle_simple_method_unicode_startswith¸  s    z=OptimizeBuiltinCalls._handle_simple_method_unicode_startswithc	       
   
   C   s¤   t |ƒdk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 )z€Replace unicode.startswith(...) and unicode.endswith(...)
        by a direct call to the corresponding C-API function.
        )ró   r   é   z%s.%sz2-4ró   rÀ   r   ÚPY_SSIZE_T_MAX)rN   r_   z__Pyx_Py%s_Tailmatch)rÉ   )rC   r…  r…  r   rÑ   r5   r   r£   r\   rÐ   rÒ   r<  Ú
capitalizeÚPyString_Tailmatch_func_typerÏ   r   rÊ  rk   )
r4   r    r™   r—   rç  rå  r  rÉ   r  Úmethod_callr   r   r   r  ½  s     
z&OptimizeBuiltinCalls._inject_tailmatchz-2c             C   s   |   ||||dd¡S )NÚfindr   )Ú_inject_unicode_find)r4   r    r™   r—   rç  r   r   r   Ú"_handle_simple_method_unicode_findÞ  s    z7OptimizeBuiltinCalls._handle_simple_method_unicode_findc             C   s   |   ||||dd¡S )NÚrfindrá   )rš  )r4   r    r™   r—   rç  r   r   r   Ú#_handle_simple_method_unicode_rfindâ  s    z8OptimizeBuiltinCalls._handle_simple_method_unicode_rfindc          	   C   s   t |ƒdkr$|  d| ||d¡ |S |  ||dtjd¡ |  ||dtjd¡ | tj|jt	|ƒtj
d¡ |  ||d	| j|||¡}| |  ¡ ¡S )
zwReplace unicode.find(...) and unicode.rfind(...) by a
        direct call to the corresponding C-API function.
        )ró   r   r”  z
unicode.%sz2-4ró   rÀ   r   r•  )rN   r_   ZPyUnicode_Find)rC   r…  r…  r   rÑ   r5   r   r£   r\   rÐ   rÒ   r<  ÚPyUnicode_Find_func_typerý  rk   )r4   r    r™   r—   rç  r  r  r˜  r   r   r   rš  æ  s    

z)OptimizeBuiltinCalls._inject_unicode_findc          	   C   sn   t |ƒdkr |  d||d¡ |S |  ||dtjd¡ |  ||dtjd¡ |  ||d| jd	||¡}| |  ¡ ¡S )
zaReplace unicode.count(...) by a direct call to the
        corresponding C-API function.
        )ró   r   r”  zunicode.countz2-4ró   rÀ   r   r•  ZPyUnicode_CountÚcount)	rC   r…  r…  r   rÑ   r<  ÚPyUnicode_Count_func_typerý  rk   )r4   r    r™   r—   rç  r˜  r   r   r   Ú#_handle_simple_method_unicode_count  s    

z8OptimizeBuiltinCalls._handle_simple_method_unicode_countZreplstrZmaxcountc          	   C   sL   t |ƒdkr |  d||d¡ |S |  ||dtjd¡ |  ||d| jd||¡S )zcReplace unicode.replace(...) by a direct call to the
        corresponding C-API function.
        )r   r”  zunicode.replacez3-4r   z-1ZPyUnicode_ReplacerÃ  )rC   r…  r…  r   rÑ   r<  ÚPyUnicode_Replace_func_type)r4   r    r™   r—   rç  r   r   r   Ú%_handle_simple_method_unicode_replace  s    
z:OptimizeBuiltinCalls._handle_simple_method_unicode_replaceÚencodingÚerrorsÚUTF8ÚUTF16zUTF-16LEzUTF-16BEÚLatin1ÚASCIIZunicode_escapeZraw_unicode_escapec             C   s   g | ]}|t  |¡f‘qS r   )ÚcodecsÚ
getencoder)rF   r   r   r   r   rH   9  s   zOptimizeBuiltinCalls.<listcomp>c             C   sL  t |ƒdk st |ƒdkr,|  d||d¡ |S |d }t |ƒdkrjt |j¡}|  ||d| jd||||g¡S |  |j|¡}|dkr„|S |\}}	}
}|rÞt|tj	ƒrÞy|j
 ||
¡}W n   Y n X t||ƒ}tj|j|tjd	S |r.|
d
kr.|  |¡}|dk	r.d|kr.d| }|  |||| jd||g¡S |  ||d| jd|||	|g¡S )z_Replace unicode.encode(...) by a direct C-API call to the
        corresponding codec.
        r   r   zunicode.encodez1-3r   ZPyUnicode_AsEncodedStringrË   N)rN   r_   Ústrictrþ   zPyUnicode_As%sString)rC   r…  r   r  r\   r<  Ú#PyUnicode_AsEncodedString_func_typeÚ_unpack_encoding_and_error_moder   r"  rN   rË   r   rÍ   r   r’   Ú_find_special_codec_nameÚPyUnicode_AsXyzString_func_type)r4   r    r™   r—   rç  Ústring_nodeÚ	null_nodeÚ
parametersr¤  Úencoding_nodeÚerror_handlingÚerror_handling_noderN   Ú
codec_nameZencode_functionr   r   r   Ú$_handle_simple_method_unicode_encode<  sD    

z9OptimizeBuiltinCalls._handle_simple_method_unicode_encodeÚstringrç   r°   Údecode_funcc             C   sf  dt |ƒ  krdks.n |  d||d¡ |S |d }d }}t|tjƒrt|}|j}|j|j }}|rp|jdkrtd}t|tj	ƒr†|j
}|j}	|	tjtjfkrÊ|r¶|jdd|	jgd	}qÚ|jd
ddgd}n|	jsÚ|	jsÚ|S |  |j|¡}
|
dkrô|S |
\}}}}|stj|jddd}n|jjs6| tj|  ¡ ¡}|rX|jjsX| tj|  ¡ ¡}d}|dk	rp|  |¡}|dk	rÀ|dkr–d| dd¡ }nd| }tj|j| j|d}t |j¡}nt |j¡}g }|	jr8|s,|j sút! "|¡}| #|¡ tj$|jd| j%|gdt& 'dd¡d tj|  ¡ ¡}| j(}d}nÒ|	jrÔ|sZtj|jdtj)d}| j*dkrÈt +tj,t -d|	d¡t -dtjd¡t -dtjd¡t -dtj.d¡t -d tj.d¡t -d!| jd¡g¡| _*| j*}d"}n6|sîtj|jdtj)d}| j/}|	tjkrd#}nd$}tj$|jd%| |||||||g|j0t& '|d¡d}x$|ddd&… D ]}t! 1||¡}qLW |S )'zƒReplace char*.decode() by a direct C-API call to the
        corresponding codec, possibly resolving a slice on the char*.
        r   r   zbytes.decodez1-3r   Nz@descriptor '%s' requires a '%s' object but received a 'NoneType'Údecode)r  z*'NoneType' object has no attribute '%.30s'r  )r   r  rÀ   )rN   r-   )r§  zUTF-16LEzUTF-16BEz__Pyx_PyUnicode_Decode%srþ   r  zPyUnicode_Decode%s)r_   r<  rÿ  Fr   zStringTools.c)r—   r¬   rÉ   Zdecode_c_stringr•  r¹  r®   r°   r¤  r¥  rº  Zdecode_cpp_stringZdecode_bytesZdecode_bytearrayz__Pyx_%srá   )2rC   r…  r   r   r¶   r^   r®   r°   r-   rÇ  r   r_   r   r’   Úbytearray_typerª   r   rë   Zis_cpp_stringr®  r\   r£   rŸ   rÏ   r   rÑ   rk   r¯  rÃ  r;  Ú!PyUnicode_DecodeXyz_func_ptr_typer  r…   r   r±   r5   r²   r  r   r   Ú_decode_c_string_func_typer   Ú_decode_cpp_string_func_typer  r”   r  rÎ   Ú_decode_bytes_func_typer¬   r  )r4   r    r™   r—   rç  r±  r®   r°   rm  Zstring_typer³  r¤  r´  rµ  r¶  r·  Zcodec_cnameZdecode_functionrY   Zhelper_func_typeZutility_code_namer÷   r   r   r   Ú"_handle_simple_method_bytes_decodeŠ  s´    











z7OptimizeBuiltinCalls._handle_simple_method_bytes_decodec             C   sj   yt  |¡}W n tk
r"   d S X x@| jD ]6\}}||kr,d|kr^d dd„ | d¡D ƒ¡}|S q,W d S )NrI  r  c             S   s   g | ]}|  ¡ ‘qS r   )r–  )rF   r«   r   r   r   rH     s   zAOptimizeBuiltinCalls._find_special_codec_name.<locals>.<listcomp>)rª  r«  ÚLookupErrorÚ_special_codecsrq  r„  )r4   r¤  Zrequested_codecr   Úcodecr   r   r   r¯    s    
z-OptimizeBuiltinCalls._find_special_codec_namec             C   sŠ   t  |¡}t|ƒdkr6|  |d ¡\}}|d kr>d S nd }|}t|ƒdkrv|  |d ¡\}}|d krhd S |dkr~|}nd}|}||||fS )Nró   r   r   r¬  )r   r  rC   Ú_unpack_string_and_cstring_node)r4   r\   r—   r²  r¤  r´  rµ  r¶  r   r   r   r®    s     
z4OptimizeBuiltinCalls._unpack_encoding_and_error_modec             C   s¶   t |tjƒr|j}t |tjƒr>|j}tj|j| ¡ t	j
d}npt |tjtjfƒrt|j d¡}tj|j|jt	j
d}n:|jtjkr˜d }| t	j
|  ¡ ¡}n|jjr¦d }nd  }}||fS )N)rN   r_   z
ISO-8859-1)r   r   rÇ  r   r"  rN   rÍ   r\   Zas_utf8_stringr   rÎ   r	  r»  r_   r   r’   rÏ   rk   rë   )r4   r    r¤  r   r   r   rÅ  '  s"    z4OptimizeBuiltinCalls._unpack_string_and_cstring_nodec          
   C   s   |   ||||ddtd¡S )NrÐ   rŽ  r   )r  Ústr_tailmatch_utility_code)r4   r    r™   r—   rç  r   r   r   Ú"_handle_simple_method_str_endswith;  s    z7OptimizeBuiltinCalls._handle_simple_method_str_endswithc          
   C   s   |   ||||ddtd¡S )NrÐ   r’  rá   )r  rÆ  )r4   r    r™   r—   rç  r   r   r   Ú$_handle_simple_method_str_startswith@  s    z9OptimizeBuiltinCalls._handle_simple_method_str_startswithc          
   C   s   |   ||||ddtd¡S )NrØ  rŽ  r   )r  Úbytes_tailmatch_utility_code)r4   r    r™   r—   rç  r   r   r   Ú$_handle_simple_method_bytes_endswithE  s    z9OptimizeBuiltinCalls._handle_simple_method_bytes_endswithc          
   C   s   |   ||||ddtd¡S )NrØ  r’  rá   )r  rÉ  )r4   r    r™   r—   rç  r   r   r   Ú&_handle_simple_method_bytes_startswithJ  s    z;OptimizeBuiltinCalls._handle_simple_method_bytes_startswithr   c          
   C   sT   t |ƒ}|r(|r(|  |d |||¡|d< |	d kr6|j}	tj|j||||	||
|jdS )Nr   )r—   r¬   rÉ   r  rÈ   )r2  r(  r¬   r   r²   r\   rÈ   )r4   r    r™   r   r~  ræ  rç  r—   rÉ   r¬   r  rq  r   r   r   r<  ]  s    z,OptimizeBuiltinCalls._substitute_method_callc             C   sR   |j r
|S |r&|jd||jjgd}n(|jd t|ƒdkr>dnd¡d|gd}|S )	Nz@descriptor '%s' requires a '%s' object but received a 'NoneType')r  z*'NoneType' object has no attribute '%{0}s'r  z.30r  r  )r   r  )rÊ   rª   r_   r   r
  rC   )r4   Zself_argr™   rç  ræ  r   r   r   r(  p  s    
z#OptimizeBuiltinCalls._wrap_self_argc             C   sX   t |ƒ|kst‚t |ƒ|kr<| tj|jt|ƒ||d¡ n||  ||  ¡ ¡||< d S )N)rN   r_   r-   )	rC   rå   r5   r   r£   r\   rÐ   rÏ   rk   )r4   r    r—   Ú	arg_indexr_   Údefault_valuer   r   r   r…  ~  s
    z1OptimizeBuiltinCalls._inject_int_default_argumentc             C   sX   t |ƒ|kst‚t |ƒ|kr>t|ƒ}| tj|j||d¡ n||  |  ¡ ¡||< d S )N)rN   r-   )	rC   rå   rü  r5   r   rf   r\   rË  rk   )r4   r    r—   rÌ  rÍ  r   r   r   r  †  s    z2OptimizeBuiltinCalls._inject_bint_default_argument)N)N)F)·r=   r>   r?   r@   rÅ  rÆ  r9   rÌ  r   r  r  r  rÐ  rÒ  r×  rÙ  r   r’   rÑ   rÒ   rÚ  rÖ  r~   Zc_float_typerˆ  Zc_longdouble_typerá  rÕ  r…  rã  rê  rä  r”   rí  rî  rñ  rŠ   rò  r½  r©   r©  r¹  r¨   ró  rô  r‹   rõ  rº  r   r÷  r¸  rø  rŒ  rú  rù  rû  rþ  r  rÎ   r  Zc_const_py_unicode_ptr_typer  r  r¼  rE  r  r  r  r  r  r
  r  rd  r  r  r“  r  r  r   r)  r!  r"  r*  r,  r.  r0  r8  r9  r5  r4  r=  r>  rA  rB  rE  rF  rG  rH  r‘  rr  rO  rQ  rS  rU  rW  rY  rZ  r\  r]  r`  rb  rd  rf  r_  rg  rh  ri  rj  rk  rl  rm  rN  rí   rw  rz  Z%_handle_simple_method_unicode_isalnumZ%_handle_simple_method_unicode_isalphaZ'_handle_simple_method_unicode_isdecimalZ%_handle_simple_method_unicode_isdigitZ%_handle_simple_method_unicode_islowerZ'_handle_simple_method_unicode_isnumericZ%_handle_simple_method_unicode_isspaceZ%_handle_simple_method_unicode_istitleZ%_handle_simple_method_unicode_isupperr{  r|  Z#_handle_simple_method_unicode_lowerZ#_handle_simple_method_unicode_upperZ#_handle_simple_method_unicode_titler€  r  r†  r‡  rŠ  r‹  r—  r‘  r“  r  rž  r›  r  rš  r   r¡  r¢  r£  r­  r°  Z_special_encodingsrÃ  r¸  r  r½  r¾  rÀ  r¿  rÁ  Z&_handle_simple_method_bytearray_decoder¯  r®  rÅ  rÇ  rÈ  rÊ  rË  r   r²   r  r<  r(  r…  r  r   r   r   r   rÄ  ë  sf  (/
,

5D
L?!
D	V 1wrÄ  Zunicode_tailmatchzStringTools.cZbytes_tailmatchZstr_tailmatchc                   s:  e Zd ZdZdE‡ fdd„	Zdd„ Zejejej	ej
gZdd„ Zd	d
„ Zdd„ Zdd„ ZdddddœjZdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(Zd)d*„ Zd+d,„ Zd-d.„ Zd/d0„ Z d1d2„ Z!d3d4„ Z"d5d6„ Z#d7d8„ Z$d9d:„ Z%d;d<„ Z&d=d>„ Z'd?d@„ Z(dAdB„ Z)dCdD„ Z*e+j,j-Z.‡  Z/S )FÚConstantFoldingaF  Calculate the result of constant expressions to store it in
    ``expr_node.constant_result``, and replace trivial cases by their
    constant result.

    General rules:

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

    - We recursively calculate constants from non-literal nodes to
      make them available to the compiler, but we only aggregate
      literal nodes at each step.  Non-literal nodes are never merged
      into a single node.
    Fc                s   t t| ƒ ¡  || _dS )z‡
        The reevaluate argument specifies whether constant values that were
        previously computed should be recomputed.
        N)ÚsuperrÎ  r1   Ú
reevaluate)r4   rÐ  )Ú	__class__r   r   r1   ¦  s    zConstantFolding.__init__c             C   sä   | j s|jtjk	rd S tj}||_|  |¡}xT| ¡ D ]H}t|ƒtkrjx6|D ]}t	|d|ƒ|krLd S qLW q6t	|d|ƒ|kr6d S q6W y| 
¡  W nP ttttttfk
r®   Y n2 tk
rÞ   dd l}dd l}|j|jd Y nX d S )Nr-   r   )Úfile)rÐ  r-   r   Zconstant_value_not_setr   r6   r{   r_   r2  r$  Zcalculate_constant_resultÚ
ValueErrorÚ	TypeErrorrI   Ú
IndexErrorr=  ÚArithmeticErrorrc  Ú	tracebackÚsysÚ	print_excÚstdout)r4   r    r   ÚchildrenZchild_resultÚchildr×  rØ  r   r   r   Ú_calculate_const®  s(    


z ConstantFolding._calculate_constc             G   s8   y| j tt| j jtt|ƒƒƒ S  tk
r2   d S X d S )N)ÚNODE_TYPE_ORDERÚmaxr3  r¼   r_   rÓ  )r4   Znodesr   r   r   Ú_widest_node_classÑ  s
    z"ConstantFolding._widest_node_classc             C   s   t |ƒ}tj|j||dS )N)rN   r-   )rü  r   rf   r\   )r4   r    rN   r   r   r   Ú
_bool_nodeØ  s    zConstantFolding._bool_nodec             C   s   |   |¡ |S )N)rÝ  )r4   r    r   r   r   Úvisit_ExprNodeÜ  s    
zConstantFolding.visit_ExprNodec             C   s®   |   |¡ | ¡ s*|jdkr&|  |¡S |S |jjs6|S |jdkrN|  ||j¡S t|jt	j
ƒr‚t	j|jtt|jƒƒtjt|jƒdS |jdkr–|  |¡S |jdkrª|  |¡S |S )Nú!)rN   r_   r-   râ   rþ   )rÝ  r¤   rK   Ú_handle_NotNoder[   rÊ   rá  r-   r   r   rf   r£   r\   rÐ   rÜ  r   rÒ   Ú_handle_UnaryPlusNodeÚ_handle_UnaryMinusNode)r4   r    r   r   r   Úvisit_UnopNodeà  s$    







zConstantFolding.visit_UnopNoderZ   rX  Úis_notÚis)rX  rZ   ré  rè  c             C   s@   |j }t|tjƒr<|  |j¡}|r<t |¡}||_|  |¡}|S )N)r[   r   r   rc   Ú_negate_operatorrK   Úcopyrr   )r4   r    r[   rK   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rH|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 … } nd|  } | S )Nrþ   r   )r’  )rN   r   r   r   Ú_negate  s    
z7ConstantFolding._handle_UnaryMinusNode.<locals>._negate)rN   r_   r-   )rN   r_   Úlongnessr-   )r[   r_   r   r   r‡  r\   rN   r-   rŸ   r:  r£   r¢   rí  )r4   r    rì  Z	node_typer   r   r   ræ    s    

z&ConstantFolding._handle_UnaryMinusNodec             C   s"   |j  ¡ r|j|j jkr|j S |S )N)r[   r¤   r-   )r4   r    r   r   r   rå    s    
z%ConstantFolding._handle_UnaryPlusNodec             C   sR   |   |¡ |j ¡ s|S |jjr8|jdkr0|jS |jS n|jdkrH|jS |jS d S )Nr  )rÝ  rL   r¤   r-   rK   rM   )r4   r    r   r   r   rQ  !  s    



z#ConstantFolding.visit_BoolBinopNodec          	   C   sÌ  |   |¡ |jtjkr|S t|jtƒr*|S |j|j }}|jrD|jsH|S y&|j	|j	 }}|d ksh|d krl|S W n t
k
r‚   |S X |jrž|jržt ||¡}ntj}|  ||¡}|d kr¼|S |tjkrØ|jdkrØtj}n|tjkrò|jdkròtj}|tjkr–t|ddƒot|ddƒ}dd ttt|ddƒƒtt|ddƒƒƒ… }	tj|j||	tt|jƒƒt|jƒd}
|jsz|
j	jr„tj|
_	nt ||
j	¡|
_	n2|tjkrª|j}n
t|jƒ}||j|||jd}
|
S )	Nz+-//<<%**>>z+-//<<%**>>&|^Úunsignedr  ZLLrí  )r\   rî  rí  rN   r-   )r\   r_   rN   r-   )rÝ  r-   r   r   r   r†  rL   rM   rÊ   r_   r=  rà  r   Zwidest_numeric_typer  rà  rf   rK   r£   r1  r$  rß  rC   r\   rÐ   rÜ  r¢   )r4   r    rL   rM   Ztype1Ztype2Zwidest_typeZtarget_classrî  rí  rq   Z
node_valuer   r   r   Úvisit_BinopNode0  sV    



zConstantFolding.visit_BinopNodec             C   s  |   |¡ |jtjkr|S |jjrú|jjrú|j|j }}t|tjƒr®t|tjƒr®d }|j	d k	rŽ|j	d k	rŽ|j	j
|j	j
krŽt|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)rN   r-   rÜ   )rN   r-   )rÝ  r-   r   r   rL   r-  rM   r   r"  rÜ   r¤  r   r   r\   rÍ   rN   rï  )r4   r    Zstr1Zstr2rÜ   Zstring_valuer   r   r   Úvisit_AddNodej  s(    



zConstantFolding.visit_AddNodec             C   sŠ   |   |¡ |jjr$|  ||j|j¡S t|jtjƒrL|jjrL|  ||j|j¡S |jjrf|  	||j|j¡S |jjr€|  	||j|j¡S |  
|¡S )N)rÝ  rL   rô   Ú_calculate_constant_seqrM   r   r   r£   r-  Ú_multiply_stringrï  )r4   r    r   r   r   Úvisit_MulNodeƒ  s    
zConstantFolding.visit_MulNodec             C   s  |j }t|tƒs|S | ¡ r(t|j tƒs,|S t|j ƒdkr>|S t}t|tjƒrTt	}n€t|tj
ƒr’|jd k	r€t|j| |jjƒ|_|jjrŒtnt	}nBt|tjƒrÀ|jd k	rÔt	|j| |jjƒ|_ndsÔtdt|ƒ ƒ‚||j| |jjƒ|_t|tj
ƒr|jd k	r|j|_ n|j|_ |S )Né   Fzunknown string node type: %s)r-   r   r   r¤   Ú_py_string_typesrC   r	   r   rÍ   r   r	  r’  r¤  rN   Z
is_unicoder"  rÜ   rå   r_   )r4   r    r±  Zmultiplier_nodeÚ
multiplierZbuild_stringr   r   r   rò    s:    



z ConstantFolding._multiply_stringc             C   sž   |j dkrš|jršt|j tƒr:|j dkr:|jd d …= d |_n`|jd k	r”t|j tƒrˆt|jj tƒrˆ|jj |j  }tj|jjt|ƒ|d|_qš|  	|¡S n||_|S )Nr   r   )rN   r-   )
r-   r—   r   r   r'  r   r£   r\   rÐ   rï  )r4   r    Zsequence_nodeÚfactorrN   r   r   r   rñ  ´  s    
z'ConstantFolding._calculate_constant_seqc             C   s^   |   |¡ t|jtjƒrTt|jtjƒrT|jjsT|  |jj	|jj
|jj¡}|d k	rT|S |  |¡S )N)r6   r   rL   r   r"  rM   r^  r'  Ú_build_fstringr\   rN   r—   rï  )r4   r    Zfstringr   r   r   Úvisit_ModNodeÇ  s    
zConstantFolding.visit_ModNodez'(%(?:(?:[-0-9]+|[ ])?(?:[.][0-9]+)?)?.)c             C   s  t |ƒ}g }d}x°t | j|¡D ]œ}|s.q"|dkrR| tj|tdƒdd¡ q"|d dkr¤|d dkrˆt|d|dd …  d	d
 d}| tj|t|ƒ|d¡ q"|d }yt	|ƒ}	W n( t
k
rà   t|dd	d
 d}P Y nX |	jrîd}P |dkrº|d	d … }
d }|dkr"d|
kr"d}nF|dkrZ|
d d… }
|}|
 d¡rhd|
d	d …  }
n|dkrhd}|
 d¡r„d|
d	d …  }
| tj|	j|	||
r®tj|t|
ƒ|
dnd d¡ q"d}P q"W |sÎd S yt	|ƒ W n t
k
rð   Y nX t|dd	d
 d S tj||d}|  |¡S )NTz%%ú%)rN   r-   r   rá   zIncomplete format: '...%s'éýÿÿÿr   )ÚlevelFz)Too few arguments for format placeholdersZasrfdoxXZdoxXro  ZarsrÀ   rÁ   Údrþ   rÂ   )rN   rð  rï  z*Too many arguments for format placeholders)r{   )ÚiterÚrer„  Ú_parse_string_format_regexr5   r   r"  r   r   ÚnextÚStopIterationrY  r’  ZFormattedValueNoder\   ZJoinedStrNodeÚvisit_JoinedStrNode)r4   r\   rx  r  r—   Ú
substringsZcan_be_optimisedr«   Zformat_typer   rï  rð  r    r   r   r   rø  ×  sn    


& zConstantFolding._build_fstringc             C   sÔ   |   |¡ |jpd}t|jtjƒr0|jjs0d |_|jd krpt|jtjƒrpt|jjƒ}| 	¡ rptj|jj
||dS |jd krÐ|dkrÐd }t|jtjƒrž|jj}nt|jtjƒr´|jj}|d k	rÐtj|jj
||dS |S )Nr«   )rN   r-   )r6   rð  r   rï  r   r"  rN   r£   r   Úisdigitr\   r	  r’  )r4   r    rð  rN   r   r   r   rñ    s"    


z(ConstantFolding.visit_FormattedValueNodec                s   |   |¡ tj‰ g }xˆt |j‡ fdd„¡D ]n\}}|rt|ƒ}|d }t|ƒdkr~td 	dd„ |D ƒ¡ƒ}tj|j
||d}|jrš| |¡ q,| |¡ q,W |s¾tdƒ}tj|j
||d}n>t|ƒdkrÔ|d }n(t|ƒd	krötj|j
d
f|žŽ }n||_|S )zø
        Clean up after the parser by discarding empty Unicode strings and merging
        substring sequences.  Empty or single-value join lists are not uncommon
        because f-string format specs are always parsed into JoinedStrNodes.
        c                s
   t | ˆ ƒS )N)r   )Úv)Úunicode_noder   r   Ú<lambda>;  ó    z5ConstantFolding.visit_JoinedStrNode.<locals>.<lambda>r   r   r  c             s   s   | ]}|j V  qd S )N)rN   )rF   rN   r   r   r   rÛ  @  s    z6ConstantFolding.visit_JoinedStrNode.<locals>.<genexpr>)rN   r-   ró   râ   )r6   r   r"  Ú	itertoolsÚgroupbyr{   r2  rC   r   rq  r\   rN   r5   r$  r   )r4   r    r{   Zis_unode_groupr  ZunoderN   r   )r  r   r  1  s,    
 
z#ConstantFolding.visit_JoinedStrNodec                s’   |   |¡ g ‰g ‰‡ ‡‡fdd„‰ x|jD ]}ˆ |ƒ q*W ˆrLˆ ˆd ¡ tˆƒdkrvˆd }|jsrt|tjƒrv|S ˆ|jdd…< |  |¡ |S )z!Unpack **args in place if we can.c                sz   | j r*ˆrˆd j | j¡ qvˆ | ¡ nLt| tjƒrPx>| jD ]}ˆ |ƒ q>W n&ˆrlˆ ˆd ¡ ˆd d …= ˆ | ¡ d S )Nr   )Úis_dict_literalr»  r$  r5   r   r   ÚMergedDictNoderx  )r   Ú	child_arg)r;  r—   r}   r   r   r;  Z  s    
z1ConstantFolding.visit_MergedDictNode.<locals>.addr   r   N)	r6   rx  r5   rC   r  r   r   r  rÝ  )r4   r    r   r   )r;  r—   r}   r   Úvisit_MergedDictNodeT  s    

z$ConstantFolding.visit_MergedDictNodec                s¶   |   |¡ |jtjk‰g ‰g ‰‡ ‡‡‡fdd„‰ x|jD ]}ˆ |ƒ q8W ˆrZˆ ˆd ¡ tˆƒdkršˆd }ˆrx|js–|jrŠ|j|jks–t	|t
jƒrš|S ˆ|jdd…< |  |¡ |S )z Unpack *args in place if we can.c                sŠ   ˆr
| j s| jr:| js:ˆr.ˆd j | j¡ q†ˆ | ¡ nLt| tjƒr`x>| jD ]}ˆ |ƒ qNW n&ˆr|ˆ ˆd ¡ ˆd d …= ˆ | ¡ d S )Nr   )	Úis_set_literalrô   r'  r—   r$  r5   r   r   ÚMergedSequenceNode)r   r  )r;  r—   r  r{   r   r   r;  ~  s    
z5ConstantFolding.visit_MergedSequenceNode.<locals>.addr   r   N)r6   r_   r   r‹   r—   r5   rC   r  rô   r   r   r  rÝ  )r4   r    r   r   )r;  r—   r  r{   r   Úvisit_MergedSequenceNodev  s$    


z(ConstantFolding.visit_MergedSequenceNodec             C   sv   |   |¡ g }xJ|jD ]@}|js,| |¡ q|jjrL|jjsL| |jj¡ q| |¡ qW ||jdd…< |  |¡ |S )z Unpack *args in place if we can.N)	r6   r—   rY  r5   rW   rô   r'  r$  rÝ  )r4   r    r—   r   r   r   r   Úvisit_SequenceNodeœ  s    

z"ConstantFolding.visit_SequenceNodec       	         sÚ  ˆ  |dg¡ |j}|}xr|d k	rŠˆ  |dg¡ |j}t|_| ¡ r~| ¡ r~y| |j¡ W n  ttt	t
ttfk
r|   Y nX |}|j}qW |js¬| ¡ r¨ˆ ||j¡S |S |jgg‰ g ‰‡ ‡‡‡fdd„‰ˆ|ƒ g }xvˆ D ]n}t|ƒdk rðqÞ|d }tj|j|d |j|jtd}| |¡ |}x |dd … D ]}||_|}q2W d |_qÞW ˆrf| ˆd ¡ n|sxˆ |d	¡S |d }t|ƒdkr¨| ¡ rÖˆ ||j¡S n.x,|dd … D ]}tj|j|d
|td}q¶W |S )NrL   rM   c                sV   |   ¡ r4| js$ˆ ˆ | d¡¡ d S ˆ  | jg¡ nˆ d  | ¡ | jrRˆ| jƒ d S )NFrá   )r¤   r-   r5   rá  rM   r   )rp   )ÚcascadesÚfinal_false_resultr4   Úsplit_cascadesr   r   r  Å  s    z<ConstantFolding.visit_PrimaryCmpNode.<locals>.split_cascadesró   r   r   )rL   rK   rM   r-   Tr  )r6   rL   rM   r   r-   r¤   Z"calculate_cascaded_constant_resultrÓ  rÔ  rI   rÕ  r=  rÖ  r   rá  rC   r   rc   r\   rK   r5   r%  )	r4   r    Z	left_noderp   Z
right_nodeZ	cmp_nodesr   Z	pcmp_nodeZlast_cmp_noder   )r  r  r4   r  r   rr   «  sn    







z$ConstantFolding.visit_PrimaryCmpNodec             C   s0   |   |¡ |j ¡ s|S |jjr&|jS |jS d S )N)rÝ  rB  r¤   r-   rM  rN  )r4   r    r   r   r   rO  ý  s    

z"ConstantFolding.visit_CondExprNodec             C   sv   |   |¡ g }x8|jD ].}|j}| ¡ r:|jrD|j|_P q| |¡ qW |rV||_|S |jrb|jS tj	|j
g dS d S )N)rQ   )r6   rT   rR   r¤   r-   rS   rU   r5   r
   rd   r\   )r4   r    rT   rH  rR   r   r   r   rK    s    
z ConstantFolding.visit_IfStatNodec             C   s´   |   |¡ |jd ks |jjd kr,d  }|_n|jj}|jd ksJ|jjd krVd  }|_n|jj}|jtk	r°|j}|jr’|jd kr’|j||… |_|S |j	r°| 
||¡}|d k	r°|S |S )N)rÝ  r®   r-   r°   r   r^   rô   r'  r—   r-  Zas_sliced_node)r4   r    r®   r°   r^   r   r   r   Úvisit_SliceIndexNode  s"    

z$ConstantFolding.visit_SliceIndexNodec             C   s€   |   |¡ t|jtjƒr||jjs||jtjkr>t	j
|jg g dS |jtjkr^t	j|jg tƒ dS |jtjkr|t	j|jg i dS |S )N)r—   r-   )r»  r-   )r6   r   r¦  r
   rd   rQ   r_   r   r©   r   r_  r\   r‹   r`  r  rŠ   r¼  )r4   r    r   r   r   Úvisit_ComprehensionNode4  s    
z'ConstantFolding.visit_ComprehensionNodec             C   s\   |   |¡ |jj}t|tjƒrX|js@|jr0|jS tj	|j
g dS t|tjƒrX| ¡ |j_|S )N)rQ   )r6   rX   rV   r   r   ZSequenceNoder—   rU   r
   rd   r\   r_  r·  )r4   r    rV   r   r   r   rt   C  s    
z#ConstantFolding.visit_ForInStatNodec             C   s:   |   |¡ |jr6|j ¡ r6|jjr0d |_d |_n|jS |S )N)r6   rR   r¤   r-   rU   )r4   r    r   r   r   Úvisit_WhileStatNodeR  s    
z#ConstantFolding.visit_WhileStatNodec             C   s.   |   |¡ t|jtjƒs|S |j ¡ r*d S |S )N)r6   r   r8   r   ZExprNoder¤   )r4   r    r   r   r   r9   \  s    

z"ConstantFolding.visit_ExprStatNode)F)0r=   r>   r?   r@   r1   rÝ  r   rf   r1  r£   r‡  rÞ  rà  rá  râ  rç  rE  rê  rä  ræ  rå  rQ  rï  rð  ró  rò  rñ  rù  r   rø  rñ  r  r  r  r  rr   rO  rK  r  r  rt   r  r9   r   rU  rV  rA   Ú__classcell__r   r   )rÑ  r   rÎ  •  sN    

:$
G#"&R	
rÎ  c               @   sD   e Zd ZdZdZdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
dS )ÚFinalOptimizePhasea!  
    This visitor handles several commuting optimizations, and is run
    just before the C code generation phase.

    The optimizations currently implemented in this class are:
        - eliminate None assignment and refcounting for first assignment.
        - isinstance -> typecheck for cdef types
        - eliminate checks for None and/or types that became redundant after tree changes
        - eliminate useless string formatting steps
        - replace Python function calls that look like method calls by a faster PyMethodCallNode
    Fc             C   s    |   |¡ |jr|j}d|_|S )zaAvoid redundant initialisation of local variables before their
        first assignment.
        T)r6   rR  rO   Zlhs_of_first_assignment)r4   r    rO   r   r   r   Úvisit_SingleAssignmentNodez  s
    
z-FinalOptimizePhase.visit_SingleAssignmentNodec          	      sþ  |   |¡ |j}|jjr |jr |jdkrœt|jƒdkrœ|jd }|jjrœ|jjdkrœ| j	j
}| d¡|_|jj|_t | d¡j¡}t |jd |¡|jd< nZ|jrú|jjrú| j | jsÌ|  ¡ jrÌdnd¡rút|jtjƒrú|jjsú|jjr
t|jjƒdksúd	}|jtjkr"d
}nx|jrD|jrš|jjjršd
}nV|jrš|j}|j sd|jjrjd
}n0|j!rštj"tj#tj$f‰ t%‡ fdd„|j!D ƒƒ}|rú|j&rÚ|jrÚt|j'tj(ƒrÚ|j'j)|j&krÚ|j'j)|_'|  *|tj+j,|||j|jd¡}|S )z¬
        Replace generic calls to isinstance(x, type) by a more efficient type check.
        Replace likely Python method calls by a specialised PyMethodCallNode.
        r   ró   r   r_   ZPyObject_TypeCheckr  z&optimize.unpack_method_calls_in_pyinitzoptimize.unpack_method_callsTFc             3   s"   | ]}|j ot|j ˆ ƒ V  qd S )N)rP   r   )rF   Z
assignment)Únon_method_nodesr   r   rÛ  «  s   z:FinalOptimizePhase.visit_SimpleCallNode.<locals>.<genexpr>)r™   r˜   r_   )-r6   r™   r_   Zis_cfunctionr…   r   rC   r—   rß  r›   r  rz  r‡   r   r  r   rì   r¬   r¢   rD  rE  Úin_looprk   Zis_module_scoper   r˜   r^  r'  rÊ   r   r  r†   rœ   rÀ  rÂ  Z	ClassNodeZPy3ClassNodera  r4   r)   rê   r   rÃ  ZPyMethodCallNodeZ	from_node)r4   r    r™   r  r  r  Zmay_be_a_methodr‡   r   )r  r   rw  „  sL    


&
 
z'FinalOptimizePhase.visit_SimpleCallNodec             C   s   |   |¡ |S )N)r6   )r4   r    r   r   r   Úvisit_NumPyMethodCallNode¶  s    
z,FinalOptimizePhase.visit_NumPyMethodCallNodec             C   s$   |   |¡ |js |j ¡ s d|_|S )z‘Remove tests for alternatively allowed None values from
        type tests when we know that the argument cannot be None
        anyway.
        T)r6   Znotnoner   rì  )r4   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.
        )r6   r   rì  )r4   r    r   r   r   Úvisit_NoneCheckNodeÆ  s    

z&FinalOptimizePhase.visit_NoneCheckNodec             C   s    | j }d| _ |  |¡ || _ |S )zeRemember when we enter a loop as some expensive optimisations might still be worth it there.
        T)r  r6   )r4   r    Úold_valr   r   r   Úvisit_LoopNodeÏ  s
    
z!FinalOptimizePhase.visit_LoopNodeN)r=   r>   r?   r@   r  r  rw  r  rÅ  r   r"  r   r   r   r   r  l  s   
2	r  c               @   s$   e Zd ZdZdZdd„ Zdd„ ZdS )ÚConsolidateOverflowChecka5  
    This class facilitates the sharing of overflow checking among all nodes
    of a nested arithmetic expression.  For example, given the expression
    a*b + c, where a, b, and x are all possibly overflowing ints, the entire
    sequence will be evaluated and the overflow bit checked only at the end.
    Nc             C   s6   | j d k	r(| j }d | _ |  |¡ || _ n
|  |¡ |S )N)Úoverflow_bit_noder6   )r4   r    Zsavedr   r   r   rA   â  s    


z#ConsolidateOverflowCheck.visit_Nodec             C   sT   |j rF|jrF| jd k}|r"|| _n| j|_d|_ |  |¡ |rPd | _n
|  |¡ |S )NF)Zoverflow_checkZoverflow_foldr$  r6   )r4   r    Ztop_level_overflowr   r   r   Úvisit_NumBinopNodeì  s    


z+ConsolidateOverflowCheck.visit_NumBinopNode)r=   r>   r?   r@   r$  rA   r%  r   r   r   r   r#  Ù  s   
r#  )KÚ
__future__r   rÿ  rØ  rë  rª  r
  r  r   r   r   ÚcythonZdeclarer	  Úversion_inforÜ  r   rØ  rÐ   rõ  Úlongrë  r
   r   r   r   r   r   ZCoder   r   ZStringEncodingr   r   r	   ZErrorsr   r   ZParseTreeTransformsr   Ú__builtin__r   ÚImportErrorÚ	functoolsr   r   rÇ  rÏ  r!   r$   r(   r.   r0   r/   rE   rB   ZEnvTransformrJ   r  rU  rW  re  rt  ZNodeRefCleanupMixinr¿  ZMethodDispatcherTransformrÄ  r   r  rÉ  rÆ  rÎ  r  ZCythonTransformr#  r   r   r   r   Ú<module>   s²   



        -  Lt   d!               3     \m