o
    Niq{                    @   s  d dl Z e jdRi dededededededed	ed
ededededededededede d dlZd dlZd dlZd dlZd dlmZm	Z	 d dl
mZ ddlmZ ddlmZmZ eefZddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ dd lmZmZ dd!lmZmZm Z  dd"l!m"Z"m#Z# dd#l$m%Z% d$d%lm&Z& d&d' Z'ej(ej)ffd(d)Z*d*d+ Z+d,d- Z,d.d/ Z-d0e.fd1d2Z/G d3d4 d4ej0Z1d5d6 Z2d7d8 Z3G d9d: d:ej4Z5G d;d< d<ej4Z6G d=d> d>ej7e%Z8G d?d@ d@ej7Z9G dAdB dBej4Z:G dCdD dDej;ej4Z<G dEdF dFej;ej=Z>dGdH Z?e@dIdJZAe@dKdJZBG dLdM dMej7e%ZCG dNdO dOej4ej;ZDG dPdQ dQejEZFdS )S    NUtilityCodeEncodedStringbytes_literalencoded_stringNodes	ExprNodes
PyrexTypesBuiltin	UtilNodesOptionsUtilsrecopycodecs	itertools
attrgetterpartialreduce)r   r   )r      )	TypeSlots)UnicodeNodenot_a_constant)r   )r   )r   )Visitor)r	   )r
   )r   )r   TempitaUtilityCode)r   r   r   )errorwarning)SkipDeclarations   )r   c                 C   s   t | dS )N
Optimize.c)r   load_cached)name r!   L/home/ubuntu/.local/lib/python3.10/site-packages/Cython/Compiler/Optimize.pyload_c_utility%   s   r#   c                 C   s   t | |r| jS | S N)
isinstancearg)nodecoercion_nodesr!   r!   r"   unwrap_coerced_node)   s   
r)   c                 C   s"   t | tjr| j} t | tjs| S r$   )r%   r
   ResultRefNode
expressionr'   r!   r!   r"   unwrap_node/   s   r-   c                 C   sr   t | } t |}t| tjrt|tjr| j|jkS t| tjr7t|tjr7| j o6t| j|jo6| j	|j	kS dS NF)
r-   r%   r   NameNoder    AttributeNode
is_py_attris_common_valueobj	attribute)abr!   r!   r"   r2   5   s   "r2   c                 C   s   | d ur| j d u rd S | S r$   )constant_resultr,   r!   r!   r"   filter_none_node?   s   r8   union_type_nodesc                    s   t j  fddg }d }| d d d }|r_| }t| rXt|}t|dkrX| tju rX|jj	r?|d u r>|j}n|
|j |jj	rQ|d u rP|j}n|
|j q|
| |s||fS )Nc                 3   sF    t |  r| jE d H  | jE d H  d S | js!| jV  d S d S r$   )r%   operand1operand2is_nonetype)	tree_nodeBitwiseOrNodecollect_tree_typesr!   r"   rA   I   s   
z4_unpack_union_type_nodes.<locals>.collect_tree_typesr   )r   r@   popr%   setlenr	   	type_typer;   r<   appendr:   )r9   typesallowed_none_node
type_stacktptype_setr!   r?   r"   _unpack_union_type_nodesE   s0   

rM   c                   @   sH   e Zd ZdZdd ZejjZdd Z	dd Z
dd	 Zd
d Zdd ZdS )_YieldNodeCollectorz9
    YieldExprNode finder for generator expressions.
    c                 C   s   t j|  i | _g | _d S r$   )r   TreeVisitor__init__yield_stat_nodesyield_nodes)selfr!   r!   r"   rP   o   s   
z_YieldNodeCollector.__init__c                 C   s   | j | | | d S r$   )rR   rG   visitchildrenrS   r'   r!   r!   r"   visit_YieldExprNodev   s   z'_YieldNodeCollector.visit_YieldExprNodec                 C   s*   |  | |j| jv r|| j|j< d S d S r$   )rT   exprrR   rQ   rU   r!   r!   r"   visit_ExprStatNodez   s   
z&_YieldNodeCollector.visit_ExprStatNodec                 C      d S r$   r!   rU   r!   r!   r"   visit_GeneratorExpressionNode      z1_YieldNodeCollector.visit_GeneratorExpressionNodec                 C   rY   r$   r!   rU   r!   r!   r"   visit_LambdaNode   r[   z$_YieldNodeCollector.visit_LambdaNodec                 C   rY   r$   r!   rU   r!   r!   r"   visit_FuncDefNode   r[   z%_YieldNodeCollector.visit_FuncDefNodeN)__name__
__module____qualname____doc__rP   r   rO   rT   
visit_NoderV   rX   rZ   r\   r]   r!   r!   r!   r"   rN   k   s    rN   c                 C   s    t | }t|dkrdS |d S )Nr   )NNr   )_find_yield_statementsrE   r'   yield_statementsr!   r!   r"   _find_single_yield_expression   s   rf   c                    sD   t    |  z fdd jD }W |S  ty!   g }Y |S w )Nc                    s   g | ]
}|j  j| fqS r!   )r&   rQ   ).0
yield_node	collectorr!   r"   
<listcomp>   s    z*_find_yield_statements.<locals>.<listcomp>)rN   rT   rR   KeyErrorrd   r!   ri   r"   rc      s   

rc   c                   @   s  e Zd ZdZdd Zdd Zd0ddZd	d
 Zd0ddZe	j
e	je	dejdgddZe	j
e	je	dejdgddZd0d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d0ddZd0ddZdd Zdd Zd0d 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 )1IterationTransforma   Transform some common for-in loop patterns into efficient C loops:

    - for-in-dict loop becomes a while loop calling PyDict_Next()
    - for-in-enumerate is replaced by an external counter variable
    - for-in-range loop becomes a plain C for loop
    c                 C   sB  |  r|j}t|}|jjr|jjjj}n|jjj}t	|}|
|}tj|d|j|d}tj|tj||tj|dddt|gd}tj|tj|||dgd d}	tj||gtj||tj|jj|jd	|	tj||tj|d
dddd}
|
|  }
| |
}
t||
}|jdkrtj||d}|S | | |S )N==operatorr:   r;   Tvaluelhsrhsstats	conditionbody
if_clauseselse_clause)sequenceF)targetiteratorrz   r}   tempsrz   not_inoperand)is_ptr_containsposr
   r*   r;   is_subscriptbaser=   	base_type
TempHandlerefr   PrimaryCmpNoder:   r   StatListNodeSingleAssignmentNodeBoolNodeBreakStatNode
IfStatNodeIfClauseNodeTempsBlockNodeForInStatNodeIteratorNodeanalyse_expressionscurrent_envvisitTempResultFromStatNoderp   NotNoderT   )rS   r'   r   
result_refr   target_handler   cmp_nodeif_bodyif_nodefor_loopnew_noder!   r!   r"   visit_PrimaryCmpNode   sV   	








z'IterationTransform.visit_PrimaryCmpNodec                 C   s   |  | | ||jjS r$   )rT   _optimise_for_loopr   r~   rU   r!   r!   r"   visit_ForInStatNode   s   
z&IterationTransform.visit_ForInStatNodeFc                    s@  |j }d }|js|jr|jr|jjr|jjj}|jr|j}tj	||fv r2|r(|S | j
||d dddS tj||fv s@tj||fv rJ|rD|S | ||S |  }|jsT|jr\| j|||dS |jr|jstj|||d}|r|jstdd |jD stj|j|jd|t|t|j|}| j|||dS |j r|js|tj!u rtj"}t#t$|j%}	ntj&}|j%}	t'tj(j)|j|d	 tj|j fd
d|	D d}||t|t|j|}| j|||dS |tj*u r|jr| j+||d|dS | j,|||dS |tj!u r| j-|||dS |tj.u r| j+||d|dS t/|tj0r1|j1j j2r1| j+||j1d|dS t/|tj3s:|S |jd u rN|j4rKt|j4jpLd}
nt|j}
|
r`|j5d ur`|
d8 }
|j6}|jr|s|
s|j5ps|j7}|j8}| 9 j:j;dk}|s|dv rt/|tj<r|j6}|jr|j=dkr|jr|jj>rd}d }}|dks|r|dkrd}n!|dks|r|dkrd}n|dks|r|dkrd }}|s|r| 
|||||S |j5d u r|jr|jr|jj>r|j=dkr|r|S | ?||S |j=dkr|r|S | @||S tAjBrd|
  kr/dkrn |S |j5d u r|jr|j=dv r|jr|jj>r|jCj jDsW|jCj jEr_| jF|||dS |jCj jr|jd u ro|j4jn|jD ]#}t/|tj(r|G rd|jH  krdk rn  |S qr |S | jF|||dS |S )NTF)dict_objmethodkeysvaluesreversed)seq_typec                 s       | ]}|j V  qd S r$   
is_starred)rg   itemr!   r!   r"   	<genexpr>       z8IterationTransform._optimise_for_loop.<locals>.<genexpr>argsr=   c                       g | ]} |qS r!   r!   )rg   chas_int_noder!   r"   rk         z9IterationTransform._optimise_for_loop.<locals>.<listcomp>)
is_mutabler   r   r      )r   r   itemsdictiterkeysr   
itervaluesr   	iteritemsr   	enumerater   )rangexrange      @)Ir=   is_nameis_attributeentry
annotationrW   r   r   r	   	dict_type_transform_dict_iterationset_typefrozenset_type_transform_set_iterationr   is_ptris_array_transform_carray_iterationis_sequence_constructoris_generator_scoper   infer_sequence_item_typeis_pyobjectanyr   ListNoder   analyse_types	coerce_tor   c_array_typerE   is_string_literalunicode_typec_py_ucs4_typemapordrr   c_uchar_typer   IntNodefor_int
bytes_type_transform_indexable_iteration_transform_bytes_iteration_transform_unicode_iterationbytearray_typer%   CoerceToPyTypeNoder&   is_memoryviewsliceSimpleCallNode	arg_tuplerS   functionr3   r4   global_scopecontextlanguage_levelCallNoder    
is_builtin_transform_enumerate_iteration_transform_reversed_iterationr   convert_ranger   is_intis_enum_transform_range_iterationhas_constant_resultr7   )rS   r'   iterabler   	iter_typeannotation_typer   env	item_typer   	arg_countr   base_objr   is_safe_iterinner_functionr   r   r&   r!   r   r"   r      s   


 


"&z%IterationTransform._optimise_for_loopc                 C   s   |j j}t|dkrt|jd |S t|dkr t|jd |S |d }|jtjtjfv r:|	d|j
_d|j
_|S | j||ddS )Nr   z(reversed() requires an iterable argumentr   z#reversed() takes exactly 1 argument!'NoneType' object is not iterableTr   )r   r   rE   r   r   r=   r	   
tuple_type	list_typeas_none_safe_noder   r~   r   r   )rS   r'   reversed_functionr   r&   r!   r!   r"   r   h  s"   z0IterationTransform._transform_reversed_iterationc                 C   s  g }t j|dddd}|| tj|jtj|jdtj	
dd|gd}|r,|}nt j|tjd}|| t tj|jdd	}	||	 |rZ|}
tj|jd
}d\}}ntj|jd}
d\}}t|
}t j|
tjd}|| tj|j|||d}|r|rtj|jd|tj|j|||dd}tj|jtj|j|	tj|jdd	dt|jgd}tj|j||d}tj|jj|j|d}|  }tj|jddd}tj|j||d}tj|jtj|j||dg|d}|r	|j j!sJ |j tj"|j|g|d}|#| tj|jtj|j|tj$|j|rdndd|tj|jddd|gd}tj%|j|	||j&d}|}|ddd D ]	}t '||}qB|(|}|j)|j* |S )zUIteration over iterables that Cython has a len() for and knows how to index.
        'NoneType' is not iterableFT)may_hold_noneis_temprE   )r    r   r   r   r   rq   r   >>=rB   <=<ro   andrs   rv   )r   indexr   rt   ru   )boundscheck
wraparound)
directivesrz   rx   r{   )r   rz   -+r   )rp   inplacer:   r;   ry   rz   r}   N)+r
   
LetRefNoder  rG   r   r   r   r/   r	   builtin_scopelookupr   c_py_ssize_t_typer   r   for_sizer   r   BoolBinopNoder   r   r   ContinueStatNode	IndexNoder   r   r   copy_inherited_directivesr  CompilerDirectivesNoder   r   r=   r   CriticalSectionStatNodeanalyse_declarations
binop_nodeWhileStatNoder}   LetNoder   rw   rz   )rS   r'   
slice_noder   r   
temp_nodesunpack_temp_nodelength_call_nodeend_nodekeep_going_ref
start_node	relation1	relation2start_check_nodecounter_ref	test_nodefailed_test_bodytarget_valuetarget_assignr   new_directiveslength_check_and_target_assignrz   	loop_noderetlet_ref_noder!   r!   r"   r   |  s   

	







z1IterationTransform._transform_indexable_iterationsNNULLexception_valuerB   c                 C   s   |j j}|js|tjur|S t|d}tj	|j
d| j|gdd}tj	|j
d| j|gdd}t|| j|tj|j
|d d ||jdd|dS )Nr  __Pyx_PyBytes_AsWritableStringr   r   r
  __Pyx_PyBytes_GET_SIZE)r   startstepstopr=   r
  r   )r   r=   r   r	   r   r
   r  r  r   PythonCapiCallNoder   PyBytes_AS_STRING_func_typePyBytes_GET_SIZE_func_typer*  r   SliceIndexNode)rS   r'   r+  r   target_typer-  slice_base_nodelen_noder!   r!   r"   r   *  sD   	z-IterationTransform._transform_bytes_iterationkinddatar  lengthc                 C   sl  |   }|jrH|jsHzt|jdd}W n	 ty   Y n*w tj|j	tj
|j	||tjdtj|d tj|j	t|tjd}| |||S t|d}tj|j	d}ttj}	|	|j	}
|rpd\}}|
|}}
nd\}}ttj}ttj}ttj}tj|j	d	| j||j	||j	||jj	gd
d}|j |jj kr||jj |}t!j"|jj	|j|d}t!j#|j	||j$gd}t!j%|j	||||jj	||
d ||j&dd
}t!j'|j	tj|j	d| j(|tj)|j	|	|j	tj*dtj)|j	||j	tj+dtj)|j	||j	tj,dgdd
t-.dddd}t/|tj0|j	||	||gt!j#|j	||gddS )Nlatin1z	iso8859-1rr   r7   r=   )r   rF  rH  r=   r  r   r  r  __Pyx_PyUnicode_READFrD  r  rv   T	bound1r2  r   r3  bound2rG  rz   r}   
from_range__Pyx_init_unicode_iterationr   r=   unicode_iterr   )r   r
  result_is_usedutility_code)rW   r   )1r   
is_literalr   r   rr   encodeUnicodeEncodeErrorr   rL  r   	BytesNoder   c_const_char_ptr_typer   c_const_uchar_ptr_typer   r   rE   r	   r   r   r
   r  r  r   r  r   
c_int_typec_void_ptr_typerI  PyUnicode_READ_func_typer   r=   r   r   r   rz   ForFromStatNoder}   ExprStatNode init_unicode_iteration_func_typeAmpersandNodec_py_ssize_t_ptr_typec_void_ptr_ptr_typec_int_ptr_typer   r   r*  r   )rS   r'   r+  r   r   bytes_valuebytes_slicer-  r1  length_tempr/  r2  r3  	kind_temp	data_tempcounter_tempr8  r9  rz   r<  
setup_noder!   r!   r"   r   a  s   

	
z/IterationTransform._transform_unicode_iterationc                 C   s   d}t |tjr&|j}t|j}t|j}d }|s%|jjs#t	|j
d |S n|jrt |jtjs2J |j}|j}	t|	j}t|	j}t|	j}|rt |jtrb|jdksb|jdkr[|rb|jdk rn|sn|jjslt	|j
d |S |j}
|rv|
 }
|
dk }tj|j
t|
}n/|jjr|jjd u rt	|j
d |S |}d  }}tj|j
|jj}n|jjst	|j
d |S |r|tj|  }|r|tj|  }|d u r|rtj|j
d}nt	|j
d |S |r|stj|j
d}||}}|j}|jr| }||  }|r|jdkrtj|j
|d||d}n|}|r7|jdkr7tj|j
t|d||d|  }nt|}t|}| |j!j
}|jj"r|j!jjr|jt#j$u rst%tj&|j!j
||j'dtj(|j!j|  }nBtj|j!j
tj)|j!j
dtj)|j!j
d	|t#j*d	d
}n%|j!jj+r|j!j,|j's|}ntj-|j!j
tj)|j!j
d||j'd}|j|j!jkr||j!j|  }t.j/|j!j
|j!|d}t.j0|j
||j1gd}| 2||\}}t.j3|j
||||||||j4dd
}tj5|j
|g|dS )NFz*C array iteration requires known end indexr   z8C array iteration requires known step size and end indexrB   r  r:   rp   r;   r=   r[  r   )rF  rH  r   r=   r
  )r  r   r=   r  rv   TrV  r   )6r%   r   rL  r   r8   rF  rH  r=   r   r   r   r   r  	SliceNoderG  r7   intr   r   absr   sizer   r   r  r   element_ptr_typecoerce_to_simpleAddNode	CloneNoder
   r   r   r   	is_stringr	   r   CastNodeDereferenceNoder   r   r   r   r   assignable_fromr#  r   r   r   rz   _find_for_from_node_relationsrh  r}   r   )rS   r'   r+  r   neg_step
slice_baserF  rH  rG  r  
step_valueptr_type
carray_ptrstart_ptr_nodestop_ptr_nodecounterrt  r8  r9  rz   r2  r3  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s&|S |jj}t|dkr2|S |\}}|j}|jsA|j	sA|S t|dkrTt
|d ||  }n
tjj|jd|d}t|}	tj|j|	tjj|jd|dd||jd}
tj|j||	d	tj|j|	|
d	g}t|jtjr||jj |j_n||j tj|jj|d
|_||_|j|j|  |_|d |j_t|	| ||jjS )Nr   z)enumerate() requires an iterable argumentr   z%enumerate() takes at most 2 argumentsr   r   r  )r:   r;   rp   r=   r
  r  rv   )r   r   rE   r   r   r   r   r=   r   r   r)   r   r   r   r   r   r
   r  r}  r   r   r%   rz   r   rw   rG   r   r   r~   r*  r   )rS   r'   enumerate_functionr   targetsenumerate_targetiterable_targetcounter_typerF  tempinc_expression	loop_bodyr!   r!   r"   r   P  sl   
z1IterationTransform._transform_enumerate_iterationc                 C   s   |r|rdS dS |rdS dS )N)r  r  r  )r  r  r  r!   )rS   neg_step_valuer   r!   r!   r"   r    s   z0IterationTransform._find_for_from_node_relationsc                 C   s8  |j j}t|dk r|j}d}tj|d}n|d }|j}t|jt	s&|S |j}|dkr/|S tj||}t|dkrNtj|jd}|d 
|  }	n|d 
|  }|d 
|  }	| |dk |\}
}d }|r|	|}}	t|}|dkrt|jt	rt|	jt	r|dk r|	j}|j}|||| d |   d }n|j}|	j}|||| d |   d }tjj|j|t|j|	jd}nt|	}| ||||}|dk r| }t||_||_|
|  }|	jsd}|pt|	}	nd}tj|j|j||
||	||j|jdd
}||   |rt|	|}|S )	Nr   r   r   r   r   TF)	r   rW  r2  r3  rX  rG  rz   r}   rY  )r   r   rE   r   r   r   r   r%   r7   rx  coerce_to_indexr   r  ry  r   r   spanning_typer=   r
   r  _build_range_step_calculationstrrr   r_  r   rh  r   rz   r}   set_up_loopr*  )rS   r'   range_functionr   r   step_posr  rG  rW  rX  r2  r3  bound2_ref_nodeabs_stepbegin_value	end_valuebound1_valuebound2_is_tempr  r!   r!   r"   r     s   



z-IterationTransform._transform_range_iterationc                 C   s  t |}t|j|j}|jjr|dk rt|tj}nt||j}|dk r.|}|}	d}
n|}|}	d}
tj|jtj|j||
tj	|jtj
j|j||ddtj|jtj|jtj|j|d|	|ddtj
|jd|dd	tj
j|j||d|d|d|d|
tj
|jd|d}|S )
Ni  r   r  r  r   *rv  r   z//)ry  r   r  r=   r   re  r   r(  r   MulNoder   r   DivNodeSubNode)rS   rW  r  rG  r  r  r  spanning_step_typer  r  final_opstep_calculation_noder!   r!   r"   r    sd   z0IterationTransform._build_range_step_calculationc                 C   sv  g }t tj}|| ||j}t tj}|| ||j}	d  }
 }}|rG|rG|jj	rCt
|jjdkrA|jj\}
}n|S |j}n	|rM|j}
n|j}t|jtjr[|j}ntj|jj|jgd}t tj}|| tj|j||jt|jd}t tj}|| ||j}tj|j|t|jd}t|||j|	|
|||}||  }|g|jdd< |rtj|j|d}|jdt
|dkrdnd	d
|gd}nt|j}|d}tj|jt|jt j!u }tj"|j|	tj#|jddtj"|j|tj$|jd| j%t&'dd|||||gdddtj(|jd ||j)dg}t j*|j|tj|j|ddS )Nr   r   rw   r[  r   rq   )'NoneType' object has no attribute '%{}s'   .30 PyExc_AttributeErrorr   format_argsr  rs   __Pyx_dict_iterator	dict_iterr   Tr^  r   r
  r  rv   r   )+r
   r   r   py_object_typerG   r   r   r  r   r   rE   r   r%   rz   r   r   r   rk  
c_ptr_typer=   re  DictIterationNextNoder   r   rw   IdentifierStringNoder  formatNullNoder   r   rx  r	   r   r   r   rI  PyDict_Iterator_func_typer   r   r)  r}   r   )rS   r'   r   r   r   r   r   r  	dict_temppos_temp
key_targetvalue_targettuple_targetrz   dict_len_tempdict_len_temp_addris_dict_tempis_dict_temp_addriter_next_nodemethod_nodeis_dictresult_coder!   r!   r"   r   #  s   








z,IterationTransform._transform_dict_iterationr   r  method_namep_orig_length	p_is_dictrD   is_setp_is_setc                 C   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< tj|jt|jtju }t
j|j|tj|jddt
j|j|tj|jd| jt dd|||	|gdd	dt
j!|jd ||j"d
g}t j#|j|t
j|j|ddS )Nr  r[  r   rs   __Pyx_set_iteratorset_iterr   Tr  r  rv   r   )$r
   r   r   r  rG   r   r   r  r%   rz   r   r   r   rk  r  r=   re  r   SetIterationNextNoder   r   rw   r   r   rx  r	   r   r   r   rI  PySet_Iterator_func_typer   r   r)  r}   r   )rS   r'   set_objr   r  set_tempr  rz   set_len_tempset_len_temp_addris_set_tempis_set_temp_addrr  r  r  r  r!   r!   r"   r     s~   








z+IterationTransform._transform_set_iterationF)&r^   r_   r`   ra   r   r   r   r   r   r   	CFuncTypec_char_ptr_typeCFuncTypeArgr	   r   rJ  r  rK  r   r   re  rf  rg  r  rl  rm  rn  rj  r   r   r   r  r   r  r   r  r  r   r!   r!   r!   r"   rm      s    2
 
 $
'
	
X D
Q2^	rm   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   s2  	 t |tjtjfr|j}n t |tjr|jj}nt |tjr#|j}nt |tj	r-|j
}nnqt |tjr|jd ur=| jS | rat |jtjtjfra|jdk}|rW|sW| jS ||j| |jfS | s|jdkrmd}n|rw|jdkrwd}n| jS t|j|jr|jjr||j|jgfS t|jdd r|jjjr||j|jgfS t|j|jr|jjr||j|jgfS t|jdd r|jjjr||j|jgfS | jS t |tjr|jdks|r|jdkr|jdk}| |j|\}}}| |j|\}}}	|d ur||krt||r|r|r||||	 fS | jS )	NTr   rn   F!=r   orr  )r%   r   CoerceToTempNodeCoerceToBooleanNoder&   BoolBinopResultNoder
   EvalWithTempExprNodesubexpressionTypecastNoder   r   cascadeNO_MATCHis_c_string_containsr;   r   rb  rp   r:   extract_in_string_conditionsis_python_comparisonr2   r_  getattrr   is_constr!  extract_conditions)
rS   condallow_not_inr   not_in_1t1c1not_in_2t2c2r!   r!   r"   r    sj   



	
 z"SwitchTransform.extract_conditionsc                    s   t tjr!ttttj}ttj	j
jfdd|D S j  jt fddtt D  fdd D S )Nc                    r   r!   r!   )rg   charval)node_for_charr!   r"   rk     r   z@SwitchTransform.extract_in_string_conditions.<locals>.<listcomp>c                    s   h | ]
} ||d   qS )r   r!   )rg   i)
charactersr!   r"   	<setcomp>  s    z?SwitchTransform.extract_in_string_conditions.<locals>.<setcomp>c                    s$   g | ]}t jjt| |d qS )rr   r7   )r   CharNoder   r   )rg   	character)encodingstring_literalr!   r"   rk      s
    
)r%   r   r   sortedrD   r   r   rr   r   r   r   r   r  r   rE   )rS   r  charvalsr!   )r  r  r  r  r"   r    s   z,SwitchTransform.extract_in_string_conditionsc                 C   sj   |  ||\}}}|d u r| jS |d urt||s| jS |jjs$|jjr-tdd |D r0| jS |||fS )Nc                 S   s   g | ]}|j jp|j j qS r!   )r=   r   r   )rg   r  r!   r!   r"   rk   +  s    z=SwitchTransform.extract_common_conditions.<locals>.<listcomp>)r  r  r2   r=   r   r   r   )rS   
common_varry   r  r   var
conditionsr!   r!   r"   extract_common_conditions$  s   
z)SwitchTransform.extract_common_conditionsc              	   C   s   t  }|D ]F}| r|j|v r dS ||j qz|j}|jjs&|jjr/|jd ur/|j}n|j	}W n t
y>   Y  dS w ||v rF dS || qdS )NTF)rD   r   r7   addr   r=   r   is_cpp_enumenum_int_valuecnameAttributeError)rS   condition_valuesseenrr   value_entryvalue_for_seenr!   r!   r"   has_duplicate_values/  s(   

z$SwitchTransform.has_duplicate_valuesc           
      C   s   | j ds| | |S d }g }|jD ]'}| ||jd\}}}|d u r.| | |  S |tj|j	||j
d qdd |D }t|dk rP| | |S | |r\| | |S | |d |D ]}| |d qdt|}tj|j	|||jd	}	|	S )
Noptimize.use_switchFr   r  rz   c                 S   s   g | ]
}|j D ]}|qqS r!   )r  )rg   caser  r!   r!   r"   rk   Y  s
    z4SwitchTransform.visit_IfStatNode.<locals>.<listcomp>r   r}   rz   r   testcasesr}   )current_directivesgetrT   r|   r  ry   rG   r   SwitchCaseNoder   rz   rE   r  r-   SwitchStatNoder}   )
rS   r'   r  r  	if_clause_r  r
  r  switch_noder!   r!   r"   visit_IfStatNodeH  sF   







z SwitchTransform.visit_IfStatNodec                 C   st   | j ds| | |S | d |jd\}}}|d u s't|dk s'| |r.| | |S | |||||j|j	S )Nr  Tr   )
r  r  rT   r  r  rE   r  build_simple_switch_statementtrue_val	false_valrS   r'   r   r  r  r!   r!   r"   visit_CondExprNoden  s    


z"SwitchTransform.visit_CondExprNodec                 C   s   | j ds| | |S | d |d\}}}|d u s&t|dk s&| |r4| | ||   |S | ||||t	j
|jddt	j
|jddS Nr  Tr   rq   F)r  r  rT   r  rE   r  wrap_operandsr   r  r   r   r   r   r!   r!   r"   visit_BoolBinopNode  s$   


z#SwitchTransform.visit_BoolBinopNodec                 C   s   | j ds| | |S | d |d\}}}|d u s&t|dk s&| |r-| | |S | ||||tj|j	ddtj|j	ddS r"  )
r  r  rT   r  rE   r  r  r   r   r   r   r!   r!   r"   r     s"   


z$SwitchTransform.visit_PrimaryCmpNodec                 C   s   t |}tj|j|||j|  dd}tj|j|||j|  dd}	|r.|	|}}	tj|j||dg}
t	|}tj
|j||
|	d}t ||}|S )NTrt   ru   firstr  r  )r
   r*   r   r   r   r   r=   r   r  r-   r  r   )rS   r'   r  r  r   r  r  r   	true_body
false_bodyr  r  replacementr!   r!   r"   r    s6   

z-SwitchTransform.build_simple_switch_statementc                 C   sR   | j ds| | |S |j}|j}| | |j|ur't|j|s'|jS |S )Nr  )r  r  rT   r  	lazy_tempr   tree_contains)rS   r'   	orig_exprtemp_refr!   r!   r"   visit_EvalWithTempExprNode  s   


z*SwitchTransform.visit_EvalWithTempExprNodeN)r^   r_   r`   ra   r  r  r  r  r  r  r!  r$  r   r  r.  r   VisitorTransformrecurse_to_childrenrb   r!   r!   r!   r"   r    s    7&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                    sf  |   jd urS jdkrd d}njdkr d d}nS tjtjtjtjfs0S j	}jj
}t|dkrP| rNjdk}tjj|dS S td	d
 |D r[S t|}g }g }|D ](}| svt|}|| tjj|||d d}	|tjj|	tjd qf fdd}
t|
|}t||}|d d d D ]}t||}q|S )Ninr  rn   r   r  r  r   rq   c                 S      g | ]}|j qS r!   r   rg   r&   r!   r!   r"   rk         z?FlattenInListTransform.visit_PrimaryCmpNode.<locals>.<listcomp>)r   r:   rp   r;   r  )r   r   r=   c                    s   t jj | |dS )N)r   rp   r:   r;   )r   r!  r   )leftrightconjunctionr'   r!   r"   concat  s   z;FlattenInListTransform.visit_PrimaryCmpNode.<locals>.concatrB   )rT   r  rp   r%   r;   r   	TupleNoder   SetNoder:   r   rE   try_is_simpler   r   r   r
   r*   r  rG   r   r  r   c_bint_typer   r  )rS   r'   	eq_or_neqrt   r   r7   condsr   r&   r  r:  ry   r   r  r!   r8  r"   r     sb   










z+FlattenInListTransform.visit_PrimaryCmpNodeN)	r^   r_   r`   ra   r   r   r/  r0  rb   r!   r!   r!   r"   r1    s    @r1  c                   @   s0   e Zd ZdZejjZdd Zdd Z	dd Z
dS )	DropRefcountingTransformz&Drop ref-counting in safe places.
    c                 C   s  g g }}g g }}g }|j D ]0}t|tjr2| |j|||s$|  S | |j|||s1|  S qt|tjr<|  S |  S |sD|rhdd |D }dd |D }	t|t|	kr\|S t	t|t	|krh|S |sl|rg }
|D ]}| 
|}|s}|  S |
| qpg }|D ]}| 
|}|s|  S || qt|
t|kr|S t	t|
t	|kr|S |S dd |D }|D ]}d|_q|| D ]\}}||vrd|_q|| D ]}d|_q|S )zF
        Parallel swap assignments like 'a,b = b,a' are safe.
        c                 S      g | ]\}}|qS r!   r!   rg   pathnr!   r!   r"   rk   9  r   zIDropRefcountingTransform.visit_ParallelAssignmentNode.<locals>.<listcomp>c                 S   rB  r!   r!   rC  r!   r!   r"   rk   :  r   c                 S   r3  r!   r&   )rg   tr!   r!   r"   rk   Y  r5  F)rw   r%   r   r   _extract_operandrt   ru   CascadedAssignmentNoderD   rE   _extract_index_idrG   use_managed_ref)rS   r'   
left_namesright_namesleft_indicesright_indicesr   statlnamesrnameslindiceslhs_nodeindex_idrindicesrhs_node	temp_argsr  r  	name_node
index_noder!   r!   r"   visit_ParallelAssignmentNode!  sh   






z5DropRefcountingTransform.visit_ParallelAssignmentNodec                 C   s   t |}|jjs
dS t|tjr|| |j}g }|}|jr0|j	r$dS ||j
 |j}|js|jrJ||j |d|d d d |f dS |jrj|jjtjkrVdS |jjjs]dS |jjscdS || dS dS )NF.rB   T)r-   r=   r   r%   r   r  rG   r&   r   r1   memberr3   r   r    joinr   r   r	   r  r  r   )rS   r'   namesindicesr   	name_pathobj_noder!   r!   r"   rH  f  s8   


z)DropRefcountingTransform._extract_operandc                 C   s>   |j }|j}t|tjr|j}n
t|tjrd S d S |j|fS r$   )r   r  r%   r   r/   r    	ConstNode)rS   rZ  r   r  	index_valr!   r!   r"   rJ    s   
z*DropRefcountingTransform._extract_index_idN)r^   r_   r`   ra   r   r/  r0  rb   r[  rH  rJ  r!   r!   r!   r"   rA    s    ErA  c                   @   s   e Zd ZdZejjZdd Zdd Z	dd Z
d4d	d
Zd4ddZd4ddZdd Zdd Zdd Zdd Zdd Zdd ZeejedejdgZdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Z d(d) Z!d*d+ Z"d,d- Z#d.d/ Z$d0d1 Z%d2d3 Z&dS )5EarlyReplaceBuiltinCallsa  Optimize some common calls to builtin types *before* the type
    analysis phase and *after* the declarations analysis phase.

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

    Introducing C function calls here may not be a good idea.  Move
    them to the OptimizeBuiltinCalls transform instead, which runs
    after type analysis.
    c                 C   s.   |  | |j}| |s|S | |||jS r$   )rT   r   _function_is_builtin_name_dispatch_to_handlerr   )rS   r'   r   r!   r!   r"   visit_SimpleCallNode  s
   

z-EarlyReplaceBuiltinCalls.visit_SimpleCallNodec                 C   sL   |  | |j}| |s|S |j}t|tjs|S |j}| ||||j	S r$   )
rT   r   rf  positional_argsr%   r   r;  r   rg  keyword_args)rS   r'   r   r   r   r!   r!   r"   visit_GeneralCallNode  s   


z.EarlyReplaceBuiltinCalls.visit_GeneralCallNodec                 C   s:   |j sdS |  }||j}|| |jurdS dS )NFT)r   r   r  r    r  lookup_here)rS   r   r   r   r!   r!   r"   rf    s   z2EarlyReplaceBuiltinCalls._function_is_builtin_nameNc                 C   sT   |d u r
d|j  }nd|j  }t| |d }|d ur(|d u r"|||S ||||S |S )Nz_handle_simple_function_%sz_handle_general_function_%s)r    r  )rS   r'   r   r   kwargshandler_namehandle_callr!   r!   r"   rg    s   

z-EarlyReplaceBuiltinCalls._dispatch_to_handlerc                 C   s"   t j|jj|jj|||d|_d S )Nr^  )r   PythonCapiFunctionNoder   r   r    )rS   r'   r  	func_typer^  r!   r!   r"   _inject_capi_function  s   z.EarlyReplaceBuiltinCalls._inject_capi_functionc                 C   j   |sd}nt |ts|dkrd}n	|dkrd}nd}|d ur#d| }nd}t|jd|||t|f  d S Nr  r   z...xzexpected %s, z3%s(%s) called with wrong number of args, %sfound %dr%   r  r   r   rE   rS   function_namer'   r   expectedarg_strexpected_strr!   r!   r"   _error_wrong_arg_count     
z/EarlyReplaceBuiltinCalls._error_wrong_arg_countc                 C   s\   |s
t j|jddS t|dkr| d||d t|d dd }|tjtj	fv r,|d S |S )N0.0rq   r   floatr   r=   )
r   	FloatNoder   rE   r}  r  r   c_double_typer	   
float_type)rS   r'   pos_argsarg_typer!   r!   r"   _handle_simple_function_float  s   z6EarlyReplaceBuiltinCalls._handle_simple_function_floatc                 C   s   t |}d  }}|dkr|\}n|dkr|\}}n|dkr#|\}}}n	| d|| |S tj|j|p7t|j||p?t|jdS )Nr   r   r   slice)rF  rH  rG  )rE   r}  r   rw  r   NoneNode)rS   r'   r  r   rF  rG  rH  r!   r!   r"   _handle_simple_function_slice  s    
z6EarlyReplaceBuiltinCalls._handle_simple_function_slicec                 C   sX   t |dkr|S |d }t|tjtjfr*t |jdkr*tjj|jt	|jt
jdS |S )zUnpack ord('X').
        r   r   r   )rE   r%   r   r   rb  rr   r   r   r   r   r   c_long_type)rS   r'   r  r&   r!   r!   r"   _handle_simple_function_ord  s   z4EarlyReplaceBuiltinCalls._handle_simple_function_ordc                 C      |  ||dS )zTransform

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

        into

        for L in LL:
            for x in L:
                if not p(x):
                    return False
        else:
            return True
        F_transform_any_allrS   r'   r  r!   r!   r"   _handle_simple_function_all	     z4EarlyReplaceBuiltinCalls._handle_simple_function_allc                 C   r  )zTransform

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

        into

        for L in LL:
            for x in L:
                if p(x):
                    return True
        else:
            return False
        Tr  r  r!   r!   r"   _handle_simple_function_any  r  z4EarlyReplaceBuiltinCalls._handle_simple_function_anyc                 C   s   t |dkr|S t|d tjs|S |d }|jj}|j}t|\}}|d u r)|S |r.|}	ntj|j	|d}	t
j|j	d t
j|j	|	t
j|j	tj|j	|dddgd}
t
j|j	tj|j	| dd|_t|||
 tj|j	||rudd	S dd	S )
Nr   r   r   rq   rx   )r}   r|   r   all)gen	orig_func)rE   r%   r   GeneratorExpressionNodedef_nodegbodyrz   rf   r   r   r   r   r   ReturnStatNoder   r}   r   recursively_replace_nodeInlinedGeneratorExpressionNode)rS   r'   r  is_anygen_expr_nodegenerator_bodyr<  yield_expressionyield_stat_nodery   r6  r!   r!   r"   r  )  sF   
z+EarlyReplaceBuiltinCalls._transform_any_allitc           
      C   s   t |dkr|S |d }t|tjr|jtju r|}nXt|tjrP|}t|j	}|s,|S tj
|j|dtjd}|D ]\}}tj|j||jd}	t|||	 q9n#|jrX| }ntj|j| rk|jtjtjfv rkdnd| j|dd	}t|j|S )
a  Transform sorted(genexpr) and sorted([listcomp]) into
        [listcomp].sort().  CPython just reads the iterable into a
        list and calls .sort() on it.  Expanding the iterable in a
        listcomp is still faster and the result can be sorted in
        place.
        r   r   r  r  comprehension_typerW   r   __Pyx_PySequence_ListKeepNewPySequence_ListTrD  )rE   r%   r   ComprehensionNoder=   r	   r  r  rc   loopr  r   ComprehensionAppendNoder   r   r  r   as_listrI  result_in_tempr   r  PySequence_List_func_typeSortedListNode)
rS   r'   r  r&   	list_noder  re   r  r  append_noder!   r!   r"   _handle_simple_function_sortedQ  sF   

z7EarlyReplaceBuiltinCalls._handle_simple_function_sortedc              	   C   sP  t |dvr|S t|d tjtjfs|S |d }|j}t|tjr1t|\}}d}|du r0|S n|j}|j}z|j	r?|j
jsB|W S W n tyN   | Y S w t |dkr^tj|jd}n|d }tj|jtjd}tj|j|t|jd||d}	t|||	 tj|jtj|jtj|j|d|d	d
|gd}
tj|j|
||jd|jdS )zLTransform sum(genexpr) into an equivalent inlined aggregation loop.
        r   r   r   Nr   )r   r=   r  rs   )r   r+   Tr%  rv   sum)r  result_node
expr_scoper  has_local_scope)rE   r%   r   r  r  r  rf   rG   rW   r_  r=   r   r	  r   r   r   r
   r*   r   r  r   r   r(  r   r  r   r  r  r  )rS   r'   r  r  r<  r  r  rF  r   add_node	exec_coder!   r!   r"   __handle_simple_function_sum  sb   z5EarlyReplaceBuiltinCalls.__handle_simple_function_sumc                 C   r  )Nr  _optimise_min_maxr  r!   r!   r"   _handle_simple_function_min     z4EarlyReplaceBuiltinCalls._handle_simple_function_minc                 C   r  )Nr  r  r  r!   r!   r"   _handle_simple_function_max  r  z4EarlyReplaceBuiltinCalls._handle_simple_function_maxc           	      C   s   t |dkrt |dkr|d jr|d j}t |dkr|S tttj|dd }|d }|D ]}t|}tj|j	||tj
|j	|||dd}t||}q0|ddd D ]}t||}qW|S )zKReplace min(a,b,...) and max(a,b,...) by explicit comparison code.
        r   r   Nr:   rp   r;   )r  r  r  rB   )rE   r   r   listr   r
   r*   r   CondExprNoder   r   r  )	rS   r'   r   rp   cascaded_nodeslast_resultarg_noder   ref_noder!   r!   r"   r    s0   

z*EarlyReplaceBuiltinCalls._optimise_min_maxc                 C   sB   |st j|jg ddS | ||tj}||urt j|j|dS |S )Nr!   r   r7   rF  )r   r;  r   _transform_list_set_genexprr	   r  AsTupleNode)rS   r'   r  resultr!   r!   r"   &_DISABLED_handle_simple_function_tuple  s   z?EarlyReplaceBuiltinCalls._DISABLED_handle_simple_function_tuplec                 C   sR   t |dkr|S |d jr|d js|d= |S t|d tjr'|d  |d< |S )zSReplace frozenset([...]) by frozenset((...)) as tuples are more efficient.
        r   r   )rE   r   r   r%   r   r   as_tupler  r!   r!   r"   !_handle_simple_function_frozenset  s   z:EarlyReplaceBuiltinCalls._handle_simple_function_frozensetc                 C   s&   |st j|jg g dS | ||tjS Nr  )r   r   r   r  r	   r  r  r!   r!   r"   _handle_simple_function_list  s   z5EarlyReplaceBuiltinCalls._handle_simple_function_listc                 C   s(   |st j|jg t dS | ||tjS r  )r   r<  r   rD   r  r	   r   r  r!   r!   r"   _handle_simple_function_set  s   z4EarlyReplaceBuiltinCalls._handle_simple_function_setc                 C   s   t |dkr|S t|d tjs|S |d }|j}t|}|s!|S tj|j||tj	u r-dnd|d}|D ]\}}	tj
|j||jd}
t||	|
 q4|S )zLReplace set(genexpr) and list(genexpr) by an inlined comprehension.
        r   r   rD   r  r  r  )rE   r%   r   r  r  rc   r  r   r	   r   r  r   r   r  )rS   r'   r  rM  r  r<  re   r  r  r  r  r!   r!   r"   r  	  s,   z4EarlyReplaceBuiltinCalls._transform_list_set_genexprc                 C   s   t |dkrtj|jg i dS t |dkr|S t|d tjs!|S |d }|j}t|}|s0|S |D ]\}}t|tjs@|  S t |j	dkrK|  S q2tj
|j|dtjd}|D ]\}}	tj|j|j	d |j	d |jd}
t||	|
 qY|S )zDReplace dict( (a,b) for ... ) by an inlined { a:b for ... }
        r   key_value_pairsr7   r   r   r   r  )key_expr
value_exprr   )rE   r   DictNoder   r%   r  r  rc   r;  r   r  r	   r   DictComprehensionAppendNoder   r   r  )rS   r'   r  r  r<  re   r  r  r  r  r  r!   r!   r"   _handle_simple_function_dict%  s<   z5EarlyReplaceBuiltinCalls._handle_simple_function_dictc                 C   s$   t |dkr|S t|tjs|S |S )zlReplace dict(a=b,c=d,...) by the underlying keyword dict
        construction which is done anyway.
        r   )rE   r%   r   r  )rS   r'   r  rm  r!   r!   r"   _handle_general_function_dictK  s
   z6EarlyReplaceBuiltinCalls._handle_general_function_dictr$   )'r^   r_   r`   ra   r   r/  r0  rb   rh  rk  rf  rg  rs  r}  r  r  r  r  r  r  r   r  r	   r  r  r  r  r  5_EarlyReplaceBuiltinCalls__handle_simple_function_sumr  r  r  r  r  r  r  r  r  r  r!   r!   r!   r"   re    s>    




$1:#&re  c                   @   s$   e Zd ZejjZdd Zdd ZdS )InlineDefNodeCallsc                 C   sR   |j d u rd S |j jrd S |  |j}|r!|jr!t|jdkr#d S |jd jS Nr   r   )cf_state
cf_is_nullr   r  r    cf_assignmentsrE   ru   )rS   rY  r   r!   r!   r"   get_constant_value_nodeY  s   

z*InlineDefNodeCalls.get_constant_value_nodec                 C   sv   |  | | jds|S |j}|js|S | |}t|tjs"|S tj	|j
|||j|jd}| r9| ||S |S )Nzoptimize.inline_defnode_calls)ry  r   r   generator_arg_tag)rT   r  r  r   r   r  r%   r   PyCFunctionNodeInlinedDefNodeCallNoder   r   r  can_be_inlinedreplace)rS   r'   ry  r   inlinedr!   r!   r"   rh  e  s"   

z'InlineDefNodeCalls.visit_SimpleCallNodeN)	r^   r_   r`   r   r/  r0  rb   r  rh  r!   r!   r!   r"   r  V  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dd ejejejfD Zdd Zej	ejedejdgddZej	ejedejdgddZdd ZdddZdd Zdd Zd d! Ze	ejed"ej
dgZd#d$ Z e Z!d%d& Z"e	ej#ed'ej#dgZ$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Z0d2d3 Z1ej	ejed"ej
dgd4d5d6Z2d7d8 Z3e	ej4ed
ej
dgZ5e	ej4ed9ejdgZ6d:d; Z7d<d= Z8e	ej9ed9ej
dgZ:e	ej9ed9ej;dgZ<d>d? Z=ej	ej>ed@ej?dgddZ@ej	ej>edAejAdgddZBej	ej>ed"ej
dgddZCejdBejDdCejEdDej&dEej)dFej,dGej/dGej#dHijFZGdIhZHdJdK ZIe	ejJedLej
dgZKdMdN ZLe	ejMedej
dgZNdOdP ZOdQdR ZPe	ej
edSej
dedTej)dgZQe	ej
edSej
dedTej)dedUej#dgZR	ddVdWZS	ddXdYZTej	ejUed-ej
dedZej
dgddZVd[d\ ZWd]d^ ZXej	ejUed_ej
ded9ejdgddZYej	ejUed_ej
ded9ej
dgddZZd`da Z[e	ej
ed-ej
dgZ\ej	ej
ed-ej
dedbej
dedcej>deddejdgd5deZ]dfdg Z^ddidjZ_ej	ejUed"ej
dgddZ`dkdl Zae	ej
ed'ej
dedmej
dednej
dgZbdodp Zce	ej
ed'ej
dedmej
dednej
dedqejdgZddrds Zee	ej
ed'ej
dedmej
dednej
dgZfej	ejed'ej
dedmej
dednej
dgejjgdZhdtdu Zidvd ejjejfD Zkdwdx Zldydz Zmd{d| Znd}d~ Zodd Zpdd Zqdd Zrdd Zsdd Ztdd Zudd Zvdd Zwdd Zxdd ZyelZzemZ{enZ|eoZ}epZ~eqZerZesZetZeuZevZewZexZdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Ze	ejMedejdgZdd ZeZeZeZeZeZeZeZeZeZeZe	ejedejdgZ	 e	ej&edejdedejMdgZdd Ze	ej&edejdedej
dedej>dgZdd Ze	ejedejdedej
dgZdd Zej	ejMedej
dedej
dedej>dedej>dedejdgddZdd Zdd Zdd Zej	ej>edejdedej
dedej>dedej>dedejdgddZdd Zdd ZddÄ Zej	ej>edejdedej
dedej>dedej>dgddZddń Ze	ejedejdedej
dedej
dedej>dgZddɄ Ze	ejDed"ejdedej?dedej?dgZe	ejDed"ejdgZg d̢Zdd΄ eD ZddЄ Zee	ejedej?dedej>dedej?dgZe	ejedej?dedej>dedej>dedej?dedej?dededgZe	ejedej
dedej>dedej>dedej?dedej?dededgZdZddք ZeZdd؄ Zddڄ Zdd܄ Zddބ Zdd Z	 dddejjd5fddZdd Ze	ej
ed"ej
dgZdd Zdd Zdd ZdS )OptimizeBuiltinCallsa<  Optimize some common methods calls and instantiation patterns
    for builtin types *after* the type analysis phase.

    Running after type analysis, this transform can only perform
    function replacements that do not alter the function return type
    in a way that was not anticipated by the type analysis.
    c                 C   s   |  | | S )z:Flatten redundant type checks after tree changes.
        )rT   	reanalyserU   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.
        )rT   r=   r   rU   r!   r!   r"   _visit_TypecastNode  s   
z(OptimizeBuiltinCalls._visit_TypecastNodec                 C   sd   |  | t|jtjr|jj|_|j}|du s|js|jr dS |jr0|j	r0|j	j
s.|j	jr0dS |S )z7
        Drop dead code and useless coercions.
        N)rT   r%   rW   r   r   r&   r<   r_  r   r   is_localis_arg)rS   r'   rW   r!   r!   r"   rX     s   

z'OptimizeBuiltinCalls.visit_ExprStatNodec                 C   sT   |  | |j}t|tjr|j}t|tjr(|jtjt	j
fv r(|j|  S |S )z<Drop redundant conversion nodes after tree changes.
        )rT   r&   r%   r   PyTypeTestNoder   r=   r   r  r	   	bool_typecoerce_to_booleanr   rS   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u r4|dS |j
jr[|jjdkr[tj|jd| j|gd|jtdd|jd	|j
|  S |S )
z3Drop redundant conversion nodes after tree changes.r  r   r   =float() argument must be a string or a number, not 'NoneType'__Pyx_PyObject_AsDouble__Pyx_PyNumber_Floatpynumber_floatzTypeConversion.c)r   py_namer
  r^  r]  )rT   r&   r%   r   CoerceFromPyTypeNoderI  r   r    rE   r   r=   r	   r  r  r   r  r   PyNumber_Float_func_typer
  r   r   r]  r   r   )rS   r'   r&   func_argr!   r!   r"   visit_CoerceToPyTypeNode  s*   




z-OptimizeBuiltinCalls.visit_CoerceToPyTypeNodec                 C   sF  |  | |j}|jjs|j|jkr||j|  }|S t|tjr&|j}|j	rR|jj
r3t|tjsG|jjr=t|tjsG|jj
rPt|tjrP||j|  S |S t|tjr|jtju rr|j|jjrp|j|j|  S |S |jtju r|jjjr|jjr|j|j|  S |S t|tjr|jj
s|jjr| ||S |S )zDrop redundant conversion nodes after tree changes.

        Also, optimise away calls to Python's builtin int() and
        float() if the result is going to be coerced back into a C
        type anyway.
        )rT   r&   r=   r   r   r   r%   r   r  r_  r   r   is_floatr  r   r   r   r  r  r	   r   is_unicode_charr   _optimise_numeric_cast_callr  r!   r!   r"   visit_CoerceFromPyTypeNode  sB   


z/OptimizeBuiltinCalls.visit_CoerceFromPyTypeNodec                 C   s&   i | ]}|t |t d |dgqS )r&   N)r   r  r  )rg   r  r!   r!   r"   
<dictcomp>  s    zOptimizeBuiltinCalls.<dictcomp>c              	   C   s  |j }d }t|tjr|j}nt|tjr$|jjr$t|jtj	r$|jj}|d u s.t
|dkr0|S |d }t|tjr>|j}n|jjrD|S |jdkr|jjsQ|jjr|j|jkrY|S |jtjtjfv rj| ||j|S |j|jsu|jjrtj|j||jdS |S |jjr|jjr|jjdkrd}nd|jj }tj|j|| j|j |gd|j|jd|j|  S |S |jd	kr|jjs|jjr|j|jkr|S |jtjtjfv r| ||j|S |j|js|jjrtj|j||jdS |S )
Nr   r   rx  r[  l__Pyx_truncltrunc)rr  r   r  r
  r]  r  )r   r%   r   rI  r   r/   r=   is_builtin_typer   r;  rE   r   r&   r   r    r   r   r   c_py_unicode_type_pyucs4_to_numberr  r  r  r   
is_numericmath_h_modifierfloat_float_func_typesr
  r]  r   r   )rS   r'   r&   r   r   r  trunclr!   r!   r"   r    sb   



z0OptimizeBuiltinCalls._optimise_numeric_cast_callr&   rB   rA  g      c                 C   sl   |dv sJ t j|j|dkrdnd|dkr| jn| j|g||j|jt|dkr)dnddd	|j
|  S )	N)rx  r  rx  __Pyx_int_from_UCS4__Pyx_double_from_UCS4
int_pyucs4float_pyucs4
Builtins.c)rr  r   r  r
  r]  r^  )r   rI  r   pyucs4_int_func_typepyucs4_double_func_typer
  r]  r   r   r   r=   r   )rS   r'   py_type_namer  r!   r!   r"   r  7	  s   z&OptimizeBuiltinCalls._pyucs4_to_numberc                 C   rt  ru  rw  rx  r!   r!   r"   r}  C	  r~  z+OptimizeBuiltinCalls._error_wrong_arg_countc                 C      |S r$   r!   )rS   r'   ry  r   arg_listrm  r!   r!   r"   _handle_functionU	  r[   z%OptimizeBuiltinCalls._handle_functionc                 C   s   |r|S |r|j r|jjs|S |  |}|s|S tj|jjtj	|j|||j
d|dd|  }	|	du r@| |||||S |j}
|
du rN|jrN|jj}
tj|j|	|
d}|s]|j|_||   d|_||j
|  S )a  
        Try to inject C-API calls for unbound method calls to builtin types.
        While the method declarations in Builtin.py already handle this, we
        can additionally resolve bound and unbound methods here that were
        assigned to variables ahead of time.
        )r    r   r=   T)r3   r4   	is_calledNr  )r   r3   r   r   r  r   r0   r   r   r/   r=   analyse_as_type_attribute%_optimise_generic_builtin_method_callr   r   r   rS   analyse_c_function_callanalysedr   )rS   r'   	type_name	attr_namer   r  is_unbound_methodrm  
type_entryr   r   	call_noder!   r!   r"   _handle_methodX	  sJ   
	
z#OptimizeBuiltinCalls._handle_methodc                 C   sV   t |}|s|dks|jr|js|S |jjjs|S |jjtju r"|S t	||j||S )z
        Try to inject an unbound method call for a call to a method of a known builtin type.
        This enables caching the underlying C function of the method at runtime.
        r   )
rE   r   r1   r3   r=   r  r	   rF   r   CachedBuiltinMethodCallNode)rS   r'   r  r   r  r  r   r!   r!   r"   r  	  s   

z:OptimizeBuiltinCalls._optimise_generic_builtin_method_callr3   c              	   C   s   t |dkrt |dkrtj|jt dS |S |d }|jtju r0| s'|S d}t	
dd}nd}t	
dd}tj|j|| j||j|d	d
S )z5Optimise single argument calls to unicode().
        r   r   rq   __Pyx_PyUnicode_UnicodePyUnicode_UnicodeStringTools.c__Pyx_PyObject_UnicodePyObject_Unicodeunicoder   r
  r^  r  )rE   r   r   r   r   r=   r	   r   may_be_noner   r   rI  PyObject_Unicode_func_typer
  )rS   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u r#|js#|js#|jr|jdkr#| |d|jgS |S )zSimplify or avoid plain string formatting of a unicode value.
        This seems misplaced here, but plain unicode formatting is essentially
        a call to the unicode() builtin, which is optimised right above.
        r?  N)	rT   rr   r=   r	   r   c_format_specformat_specconversion_charr(  rU   r!   r!   r"   visit_FormattedValueNode	  s
   
z-OptimizeBuiltinCalls.visit_FormattedValueNoder   c                 C   sN   t |dkr|S |d }|jtju r%|d}tj|jd| j|g|j	dS |S )z;Replace dict(some_dict) by PyDict_Copy(some_dict).
        r   r   r  PyDict_CopyrD  )
rE   r=   r	   r   r  r   rI  r   PyDict_Copy_func_typer
  rS   r'   r   r  r&   r!   r!   r"   r  	  s   

z1OptimizeBuiltinCalls._handle_simple_function_dictr  c                 C   sX   t |dkr|S |d }tj|j| r#| r#|jtjtj	fv r#dnd| j
||jdS )z0Turn list(ob) into PySequence_List(ob).
        r   r   r  r  rD  )rE   r   rI  r   r  r=   r   r  r	   r  r  r
  r/  r!   r!   r"   r  	  s    z1OptimizeBuiltinCalls._handle_simple_function_listr  c                 C   s~   t |dks
| s|S |d }|jtju r| s|S |jtju r5|d|d< tj	|j
d| j|ddS tj|j
|tjdS )zDReplace tuple([...]) by PyList_AsTuple or PySequence_Tuple.
        r   r   r  PyList_AsTupleTrD  )r&   r=   )rE   r  r=   r	   r  r&  r  r  r   rI  r   PyList_AsTuple_func_typer  r/  r!   r!   r"   _handle_simple_function_tuple	  s   
z2OptimizeBuiltinCalls._handle_simple_function_tuplec           	      C   s   t |dkr|S |d jrMg }g }|d jD ]}| s&t|}|| || qtj|j	d|d}| 
|| |d d d D ]}t||}qB|S | 
|tj|j	d| j||jddS )Nr   r   )r
  r   rB   	PySet_NewrD   r   r
  r  )rE   r   r   	is_simpler
   r  rG   r   r<  r   r  r  rI  PySet_New_func_typer
  )	rS   r'   r   r  r   r   r&   r  r  r!   r!   r"   r  
  s,   



z0OptimizeBuiltinCalls._handle_simple_function_setc              
   C   sn   |s
t |jg}nt|dkr|S |d jtju r$|d  s$|d S t j|jd| j	||j
tddddS )Nr   r   __Pyx_PyFrozenSet_Newpyfrozenset_newr  	frozensetr%  )r   r  r   rE   r=   r	   r   r&  rI  PyFrozenSet_New_func_typer
  r   r   rS   r'   r   r  r!   r!   r"   r  &
  s   
z6OptimizeBuiltinCalls._handle_simple_function_frozensetz((double)-1)T)rB  exception_checkc              	   C   sh  t |dkrtj|dddtj|  S t |dkr%| d||d |S |d }t|tj	r2|j
}|jtju r:|S |jtjtjfv rK| ||j|S |j|jsV|jjr`tj|j||jdS |d d	}|jtju rrd
}d}n)|jtju r}d}d}n|jtju rd}d}n|jtju rd}d}n|d }d}d}tj|j|| j|g|j|rt|ddS dddS )zYTransform float() into either a C type cast or a faster C
        function call.
        r   r  g        r  r   r  0 or 1r[  r  __Pyx_PyBytes_AsDoublepybytes_as_double__Pyx_PyByteArray_AsDouble__Pyx_PyUnicode_AsDoublepyunicode_as_doublePyLong_AsDoubleNr  pyobject_as_doubler%  )rE   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   int_typerI  PyObject_AsDouble_func_typer
  r#   )rS   r'   r   r  r  r&   
cfunc_nameutility_code_namer!   r!   r"   r  =
  sb   

z2OptimizeBuiltinCalls._handle_simple_function_floatrr   c                 C   s   t |dkrtjj|jdtjdS t |dkr|S |d }t|tjr9|j	j
jr7tj|jd| j|j	gdddS |S |j
jrN|j
jrNtj|jd| j|dddS |S )	z7Transform int() into a faster C function call.
        r   r   r   PyLong_FromDoubleTrx  r4  __Pyx_PyNumber_Int)rE   r   r   r   r   r	   rE  r%   r   r&   r=   r  rI  PyLong_FromDouble_func_typer   PyNumber_Int_func_type)rS   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tjdS t |dkr | d||d |S |d |  }tj	|j|d}tj	|j|d}|
|  S )z=Transform bool(x) into a type coercion to a boolean.
        r   Frr   r=   r   boolr=  r   )rE   r   r   r   r	   r  r}  r  r   r   coerce_to_pyobject)rS   r'   r   r  r   r!   r!   r"   _handle_simple_function_bool
  s   z1OptimizeBuiltinCalls._handle_simple_function_boolc                 C   s   t |dkr| d||d |S |d jjr'tj|jd| j|d g|jddS |d jj	rF|d j
tju rFtj|jd| j|d g|jddS |S )Nr   
memoryview1r   PyMemoryView_FromObjectr4  PyMemoryView_FromBuffer)rE   r}  r=   r   r   rI  r   !PyMemoryView_FromObject_func_typer
  r   r   r	   py_buffer_type!PyMemoryView_FromBuffer_func_typer;  r!   r!   r"   "_handle_simple_function_memoryview
  s(   z7OptimizeBuiltinCalls._handle_simple_function_memoryviewbytesr$  __Pyx_PyUnicode_GET_LENGTHrE  __Pyx_PyByteArray_GET_SIZE__Pyx_PyList_GET_SIZE__Pyx_PyTuple_GET_SIZE__Pyx_PySet_GET_SIZEPyDict_Sizezcpython.array.arrayc           	   
   C   s  t |dkr| d||d |S |d }t|tjr|j}|jjr0tj|j	d| j
|g|jd}n|jjrHtj|j	d| j|g|jtddd	}nj|jjrjtjtjtd
|jdgdd}tj|j	d||g|jd}nH|jjr| |j}|du r|j}|js|jr|jj| jv rd}n|S |d}tj|j	|| j|g|jd}n|jjrtjj |j	d|jdS |S |jtj!tjfvr|"|j| # }|S )zReplace len(char*) by the equivalent call to strlen(),
        len(Py_UNICODE) by the equivalent Py_UNICODE_strlen() and
        len(known_builtin_type) by an equivalent C-API call.
        r   rE   r   __Pyx_ssize_strlenrD  __Pyx_Py_UNICODE_ssize_strlenssize_pyunicode_strlenr!  r   r
  r^  memoryviewsliceNT)nogil__Pyx_MemoryView_LenPy_SIZEz&object of type 'NoneType' has no len()r   )$rE   r}  r%   r   r   r&   r=   r  rI  r   Pyx_ssize_strlen_func_typer
  is_pyunicode_ptrPyx_Py_UNICODE_strlen_func_typer   r   r   r   r  r  r  r   _map_to_capi_len_functionis_extension_typer  r   qualified_name_ext_types_with_pysizer  PyObject_Size_func_typer  r   r   c_size_t_typer   r   )	rS   r'   r   r  r&   r   rr  rG  r  r!   r!   r"   _handle_simple_function_len
  sf   



z0OptimizeBuiltinCalls._handle_simple_function_lenobjectc                 C   s6   t |dkr|S tj|jd| j|dd}t|tjS )z7Replace type(o) by a macro call to Py_TYPE(o).
        r   Py_TYPEFrD  )rE   r   rI  r   Pyx_Type_func_typer  r   r  r;  r!   r!   r"   _handle_simple_function_type  s   
z1OptimizeBuiltinCalls._handle_simple_function_typec                    s0  t |dkrS |\}}g }t|tjr|j}n|jtju s$t|tjr(|g}nS t	|\}}|rK|s:t |dkrK|j
sA| sKt|}|| g }	|   |durj|	tj|j|d|d tj  t }
|D ]}d }}|jr|jr |jj}|r|jr|jjr|j}|tju r|jdks|jr|jjsd}|dur|jdd}||
v rqo|
| |g}n |jtju rd	}||g}n|j st|}|| d
}||g}|	tj!|j|| j"||dur|j#nddd qotj$f fdd	}t%||	j }|ddd D ]	}t&||}q|S )zcReplace isinstance() checks against builtin types by the
        corresponding C-API call.
        r   r   Nisr  r=   F)exact__Pyx_TypeCheckPyObject_IsInstanceTr   r^  r
  c                    s&   |j d| |}tj|_|  |S )Nr  )r   r   r>  r=   r#  )r5   r6   make_binop_nodeor_noder   r'   r!   r"   join_with_orx  s   
zMOptimizeBuiltinCalls._handle_simple_function_isinstance.<locals>.join_with_orrB   )'rE   r%   r   r;  r   r=   r	   rF   r@   rM   r   r5  r
   r*   rG   r   r   r   r   r   r   r>  rD   r   r   r  r    r  scopeis_builtin_scopetype_check_functionr  r_  rI  Py_type_check_func_typer^  r(  r   r  )rS   r'   r   r  r&   
type_nodesr   rH   rI   
test_nodesbuiltin_teststest_type_nodebuiltin_typer   r  type_check_argsr  r6  r  r!   r~  r"   "_handle_simple_function_isinstance/  s   








z7OptimizeBuiltinCalls._handle_simple_function_isinstancec                 C   s   t |dkr|S |d }t|tjr+|jjjr)tj|j|jt	j
d|j|  S |S t|tjtjfrMt |jdkrMtj|jt|j|j|  S |S )z-Unpack ord(Py_UNICODE) and ord('X').
        r   r   r[  )rE   r%   r   r   r&   r=   r  r  r   r   r  r   r   r   rb  rr   r   r   r   r/  r!   r!   r"   r    s   
$z0OptimizeBuiltinCalls._handle_simple_function_ordr=   r   rm  c              
   C   s  |j }|rt|dk r|S |d }|jr|js|S |jtjks%|jtjkr'|S |jr-|js6|j|jkr5|S n|j|jkr>|S tj	|j
|dd d}|j|  dd}|jr|jj}	|	jr|	jr|	j |   krtdd}
t|	j|
}|r| jj}t|d	j}t|	td
|dtdtjdtdtjdg}t||}|stj|j
tjd}tj|j
|||||gdddS n|d}t !dd}|rtj|j
d| j"|||g||j#dS tj|j
d| j$||g||j#dS )zOReplace 'exttype.__new__(exttype, ...)' by a call to exttype->tp_new()
        r   r   Nr   Tskip_childrentp_new__new__PyTypeObjectr=   r   rm  r   F)r   may_return_noner
  z4object.__new__(X): X is not a type object (NoneType)zObjectHandling.c__Pyx_tp_new_kwargsr{  __Pyx_tp_new)%r3   rE   r   r=   r	   rF   r  r    r   r;  r   r   r   rm  typeobj_cnamer  r   r   ConstructorSlotget_slot_functionr   cython_scoper   CPtrTyper  r  r  r  r  r  rI  r  r   r   Pyx_tp_new_kwargs_func_typer
  Pyx_tp_new_func_type)rS   r'   r   r   r  rm  r3   type_arg
args_tupleext_typetp_slotslot_func_cnamer  PyTypeObjectPtrpyx_tp_new_kwargs_func_typer^  r!   r!   r"   _handle_any_slot__new__  s   


z,OptimizeBuiltinCalls._handle_any_slot__new__c                 C   r  r$   r!   )rS   r'   r   r   r  rm  r!   r!   r"   _handle_any_slot__class__  s   z.OptimizeBuiltinCalls._handle_any_slot__class__r   c              
   C   sB   t |dks|js|jjr|S tj|jd| j|d|jdt	ddS )z\Optimistic optimisation as X.append() is almost always
        referring to a list.
        r   __Pyx_PyObject_AppendFrG   )r   r  r
  r]  r^  )
rE   r]  r   r   r   rI  r   PyObject_Append_func_typer
  r#   rS   r'   r   r   r  r!   r!   r"   #_handle_simple_method_object_append  s   
z8OptimizeBuiltinCalls._handle_simple_method_object_appendc                 C   s|  t |dkr|S |\}}|js|S t|j}|jdus!t |dkr$	 |S | |||d}	|s4|j|	_|	S |	 }
}t |dkrG| sGt|}
g }|d	 }| s[t|}|| tj|jd
| j|
|gdtdd}|ddd	 D ],}| st|}|| tj|jdtj|jd| j|
|gddtdd|tjd}qs|j|_|
|ur||
 |D ]}t||}|j|_q|S )zReplace list.extend([...]) for short sequence literals values by sequential appends
        to avoid creating an intermediate sequence argument.
        r   N   Fr   Tr  extendrB   __Pyx_PyList_Append
ListAppendrd  |__Pyx_ListComp_AppendListCompAppend)r   r  r
  r^  r   )rE   r   r  r   mult_factorr%   r   r   r  r   r   r   r  _wrap_self_argr]  r5  r
   r  rG   rI  r   r  r#   r(  r   c_returncode_typer  )rS   r'   r   r   r  r3   rr   r   
tuple_nodewrapped_obj
cloned_objr   r&   r   r  r!   r!   r"   !_handle_simple_method_list_extend  sb   










z6OptimizeBuiltinCalls._handle_simple_method_list_extend	bytearrayc           
   	   C   s   t |dkr|S d}| j}t|d }|jjst|tjr-|t	j
|  }tdd}n+|jrF| s6|S |t	j|  }tdd}n|jjrVd}| j}tdd}n|S tj|j|||d |gd	|j|d
}	|jrv|	|j|  }	|	S )Nr   __Pyx_PyByteArray_Appendr   ByteArrayAppendr!  __Pyx_PyByteArray_AppendObjectByteArrayAppendObjectr   Fr   r  r
  r^  )rE   PyByteArray_Append_func_typer)   r=   r   r%   r   r   r   r   re  r   r   r   r   can_coerce_to_char_literalc_char_typer   "PyByteArray_AppendObject_func_typerI  r   r
  r]  )
rS   r'   r   r   r  	func_namerr  rr   r^  r   r!   r!   r"   &_handle_simple_method_bytearray_appendX  s8   
z;OptimizeBuiltinCalls._handle_simple_method_bytearray_appendpy_indexc_index	is_signed)has_varargsc                 C   s   | j ||||ddS )NT)is_list) _handle_simple_method_object_popr  r!   r!   r"   _handle_simple_method_list_pop  s   
z3OptimizeBuiltinCalls._handle_simple_method_list_popFc                 C   s  |s|S |d }|rd}|j dddgd}nd}t|dkr2tj|jd	| | j|gd
|jtddS t|dkrt|d }t	|j}	|j
}
|j
jst|tjrb||  }	|tj|  }n5|r~|j
jrt||  }	t|	}|tj|  }n|S t|j
tjs|S t|tjr||  }	|
js|j
}
|
|  s|S |
j}ttjtd|
dg}tj|jd| | j||	|tj|j|
jrdndt|jtj |
! t|j||gd
|jtddS |S )z\Optimistic optimisation as X.pop([n]) is almost always
        referring to a list.
        r   List*'NoneType' object has no attribute '%.30s'r  rC   r  Objectr   z__Pyx_Py%s_PopTr  r   intvalNz__Pyx_Py%s_PopIndex	pop_index)"r  rE   r   rI  r   PyObject_Pop_func_typer
  r#   r)   r  r=   r   r%   r   rP  r   r   r   r  r   r|  r~  numeric_type_fitscreate_to_py_utility_codeto_py_functionr  r  r  PyObject_PopIndex_func_typer   signedRawCNameExprNodec_void_typeempty_declaration_code)rS   r'   r   r   r  r  r3   r  r  r  orig_index_typeconvert_funcconversion_typer!   r!   r"   r    sz   


z5OptimizeBuiltinCalls._handle_simple_method_object_popc              	   C   s4   t |dkr|S | ||d| jd|||j| jS )z?Call PyList_Sort() instead of the 0-argument l.sort().
        r   PyList_Sortsort)rE   _substitute_method_callsingle_param_func_typer   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.get2 or 3__Pyx_PyDict_GetItemDefaultr  Tdict_getitem_defaultr  r^  )	rE   rG   r   r  r   r}  r  Pyx_PyDict_GetItem_func_typer#   r  r!   r!   r"   _handle_simple_method_dict_get  s   z3OptimizeBuiltinCalls._handle_simple_method_dict_getis_safe_typec                 C   sf   t |dkr|t|j nt |dkr | d||d |S | j||d| jd||dt	dd	d
	S )zUReplace dict.setdefault() by calls to PyDict_GetItem() and PyDict_SetItem().
        r   r   zdict.setdefaultr  __Pyx_PyDict_SetDefault
setdefaultTdict_setdefaultr  r  )
rE   rG   r   r  r   r}  r  Pyx_PyDict_SetDefault_func_typer   r   r  r!   r!   r"   %_handle_simple_method_dict_setdefault  s   
z:OptimizeBuiltinCalls._handle_simple_method_dict_setdefaultc                 C   s   d}d}| j }t|dkr|t|j nt|dkr(|js'd}d}| j}n
| d||d |S | j	||||d	||d
t
|d	S )z7Replace dict.pop() by a call to _PyDict_Pop().
        __Pyx_PyDict_Poppy_dict_popr   r   __Pyx_PyDict_Pop_ignorepy_dict_pop_ignorezdict.popr  rC   Tr  )PyDict_Pop_func_typerE   rG   r   r  r   r]  PyDict_Pop_ignore_func_typer}  r  r#   )rS   r'   r   r   r  	capi_funcrH  rr  r!   r!   r"   _handle_simple_method_dict_pop  s(   z3OptimizeBuiltinCalls._handle_simple_method_dict_popc                 C   s   i | ]>}t jt jfD ]5}||ft j|t d t jdt dt jdt d|dt dt jdt dt jdg|jr:dn|jdq
qS )op1Nop2cvalr  zerodiv_checkrA  )r   r  r>  r  r  r   rB  )rg   ctyperet_typer!   r!   r"   r  5  s     	


c                 C      |  d||||S NAdd_optimise_num_binopr  r!   r!   r"   $_handle_simple_method_object___add__B     z9OptimizeBuiltinCalls._handle_simple_method_object___add__c                 C   r  NSubtractr  r  r!   r!   r"   $_handle_simple_method_object___sub__E  r  z9OptimizeBuiltinCalls._handle_simple_method_object___sub__c                 C   r  )NMultiplyr  r  r!   r!   r"   $_handle_simple_method_object___mul__H  r  z9OptimizeBuiltinCalls._handle_simple_method_object___mul__c                 C   r  NEqr  r  r!   r!   r"   #_handle_simple_method_object___eq__K  r  z8OptimizeBuiltinCalls._handle_simple_method_object___eq__c                 C   r  NNer  r  r!   r!   r"   #_handle_simple_method_object___ne__N  r  z8OptimizeBuiltinCalls._handle_simple_method_object___ne__c                 C   r  )NAndr  r  r!   r!   r"   $_handle_simple_method_object___and__Q  r  z9OptimizeBuiltinCalls._handle_simple_method_object___and__c                 C   r  )NOrr  r  r!   r!   r"   #_handle_simple_method_object___or__T  r  z8OptimizeBuiltinCalls._handle_simple_method_object___or__c                 C   r  )NXorr  r  r!   r!   r"   $_handle_simple_method_object___xor__W  r  z9OptimizeBuiltinCalls._handle_simple_method_object___xor__c                 C   `   t |dkst|d tjs|S |d  r%d|d j  kr$dks'|S  |S | d||||S )Nr   r   ?   RshiftrE   r%   r   r   r   r7   r  r  r!   r!   r"   '_handle_simple_method_object___rshift__Z     $z<OptimizeBuiltinCalls._handle_simple_method_object___rshift__c                 C   r  )Nr   r   r  Lshiftr  r  r!   r!   r"   '_handle_simple_method_object___lshift__a  r  z<OptimizeBuiltinCalls._handle_simple_method_object___lshift__c                 C   r  N	Remainder_optimise_num_divr  r!   r!   r"   $_handle_simple_method_object___mod__h  r  z9OptimizeBuiltinCalls._handle_simple_method_object___mod__c                 C   r  )NFloorDivider  r  r!   r!   r"   )_handle_simple_method_object___floordiv__k  r  z>OptimizeBuiltinCalls._handle_simple_method_object___floordiv__c                 C   r  N
TrueDivider  r  r!   r!   r"   (_handle_simple_method_object___truediv__n  r  z=OptimizeBuiltinCalls._handle_simple_method_object___truediv__c                 C   r  NDivider  r  r!   r!   r"   $_handle_simple_method_object___div__q  r  z9OptimizeBuiltinCalls._handle_simple_method_object___div__c                 C   s   t |dks|d  r|d jdkr|S t|d tjr/d|d j  kr+dks.|S  |S nt|d tjrId|d j  krEdksH|S  |S n|S | |||||S )Nr   r   r   r   r   l       l          )rE   r   r7   r%   r   r   r  r  )rS   rp   r'   r   r   r  r!   r!   r"   r    s    &z&OptimizeBuiltinCalls._optimise_num_divc                 C   r  r  r  r  r!   r!   r"   #_handle_simple_method_float___add__  r  z8OptimizeBuiltinCalls._handle_simple_method_float___add__c                 C   r  r  r  r  r!   r!   r"   #_handle_simple_method_float___sub__  r  z8OptimizeBuiltinCalls._handle_simple_method_float___sub__c                 C   r  r"  r  r  r!   r!   r"   '_handle_simple_method_float___truediv__  r  z<OptimizeBuiltinCalls._handle_simple_method_float___truediv__c                 C   r  r%  r  r  r!   r!   r"   #_handle_simple_method_float___div__  r  z8OptimizeBuiltinCalls._handle_simple_method_float___div__c                 C   r  r  r  r  r!   r!   r"   #_handle_simple_method_float___mod__  r  z8OptimizeBuiltinCalls._handle_simple_method_float___mod__c                 C   r  r  r  r  r!   r!   r"   "_handle_simple_method_float___eq__  r  z7OptimizeBuiltinCalls._handle_simple_method_float___eq__c                 C   r  r
  r  r  r!   r!   r"   "_handle_simple_method_float___ne__  r  z7OptimizeBuiltinCalls._handle_simple_method_float___ne__c                 C   s   t |ddr|S t|dkr|S |jjrtj}n|jtju r&|dv r&tj}n|S t||||d |d }|s8|S |\}}	}
}tdd |D sIJ t	||
 }| j
|||| j||f d	|dd
   ||dd|	d
}|jjr||js|t||  |j}|S )zY
        Optimise math operators for (likely) float or small integer operations.
        special_bool_cmp_functionNr   r  r  r   r   c                 S   s   g | ]}|j jqS r!   )r=   r   r4  r!   r!   r"   rk     r   z<OptimizeBuiltinCalls._optimise_num_binop.<locals>.<listcomp>z__%s__r   TF)r  with_none_checkr^  )r  rE   r=   r   r   r  r>  optimise_numeric_binopr  r  r  Pyx_BinopInt_func_typeslowerr   r   r   )rS   rp   r'   r   r   r  r  r  
func_cnamer^  
extra_argsnum_typer  r!   r!   r"   r    s6   	z(OptimizeBuiltinCalls._optimise_num_binopucharc              
   C   s   |st |dkr
|S |d }t|tjr|jjjs|S |j}|j}tj	ddt
|dd}d|  }	| j|||	| j|||g|d}
|jjrK|
| j}
|
S )	Nr   r   py_unicode_predicater!  )r  r   z__Pyx_Py_UNICODE_%srp  )rE   r%   r   r   r&   r=   r  r4   r   r   r   upperr  #PyUnicode_uchar_predicate_func_typer   rP  r   )rS   r'   r   r   r  ustringr8  r  r^  ry  	func_callr!   r!   r"   _inject_unicode_predicate  s.   z.OptimizeBuiltinCalls._inject_unicode_predicater  keependsc              	   C   sH   t |dvr| d||d |S | ||dd | ||d| jd||S )zfReplace unicode.splitlines(...) by a direct call to the
        corresponding C-API function.
        r  zunicode.splitlinesz1 or 2r   FPyUnicode_Splitlines
splitlines)rE   r}  _inject_bint_default_argumentr  PyUnicode_Splitlines_func_typer  r!   r!   r"   (_handle_simple_method_unicode_splitlines  s   z=OptimizeBuiltinCalls._handle_simple_method_unicode_splitlinessepmaxsplitc              	   C   sx   t |dvr| d||d |S t |dk r |t|j n| |d | ||dtj	d | 
||d| jd||S )	zaReplace unicode.split(...) by a direct call to the
        corresponding C-API function.
        )r   r   r   zunicode.split1-3r   r   -1PyUnicode_Splitsplit)rE   r}  rG   r   r  r   _inject_null_for_none_inject_int_default_argumentr   r  r  PyUnicode_Split_func_typer  r!   r!   r"   #_handle_simple_method_unicode_split-  s   z8OptimizeBuiltinCalls._handle_simple_method_unicode_splitseqc              	   C   s   t |dkr| d||d |S t|d tjrL|d }|j}t|}|rLtj|j|dt	j
d}|D ]\}	}
tj|	j|	|jd}t||
| q2||d< | ||d| jd	||S )
z^
        unicode.join() builds a list first => see if we can do this more efficiently
        r   zunicode.join2r   r  r  r  PyUnicode_Joinr^  )rE   r}  r%   r   r  r  rc   r  r   r	   r  r  r   r   r  r  PyUnicode_Join_func_type)rS   r'   r   r   r  r  r<  re   inlined_genexprr  r  r  r!   r!   r"   "_handle_simple_method_unicode_joinF  s2   z7OptimizeBuiltinCalls._handle_simple_method_unicode_join	substringrF  end	directionc              
   C      |  ||||ddtdS )Nr  endswithr   _inject_tailmatchunicode_tailmatch_utility_coder  r!   r!   r"   &_handle_simple_method_unicode_endswithp     z;OptimizeBuiltinCalls._handle_simple_method_unicode_endswithc              
   C   rY  )Nr  
startswithrB   r[  r  r!   r!   r"   (_handle_simple_method_unicode_startswithu  r_  z=OptimizeBuiltinCalls._handle_simple_method_unicode_startswithc	              
   C   s   t |dvr| | d| ||d |S | ||dtjd | ||dtjd |tj|j	| |dkr;d	}	nd
|
  d}	| j|||	| j||||d}
|
tj|  S )zReplace unicode.startswith(...) and unicode.endswith(...)
        by a direct call to the corresponding C-API function.
        r   r      r\  2-4r   0r   PY_SSIZE_T_MAXr  __Pyx_PyUnicode_Tailmatch__Pyx_Py
_Tailmatchrp  )rE   r}  rM  r   r  rG   r   r   r   r   
capitalizer  PyString_Tailmatch_func_typer   r	   r  r   )rS   r'   r   r   r  r  r  r^  rX  r  method_callr!   r!   r"   r\  z  s(   z&OptimizeBuiltinCalls._inject_tailmatchr  c                 C      |  ||||ddS )Nfindr   _inject_unicode_findr  r!   r!   r"   "_handle_simple_method_unicode_find     z7OptimizeBuiltinCalls._handle_simple_method_unicode_findc                 C   rm  )NrfindrB   ro  r  r!   r!   r"   #_handle_simple_method_unicode_rfind  rr  z8OptimizeBuiltinCalls._handle_simple_method_unicode_rfindc              	   C   s   t |dvr| d| ||d |S | ||dtjd | ||dtjd |tj|j	| | 
||d| j|||}||  S )	zwReplace unicode.find(...) and unicode.rfind(...) by a
        direct call to the corresponding C-API function.
        rb  z
unicode.%srd  r   re  r   rf  PyUnicode_Find)rE   r}  rM  r   r  rG   r   r   r   r   r  PyUnicode_Find_func_typerP  r   )rS   r'   r   r   r  r  rX  rl  r!   r!   r"   rp    s   
z)OptimizeBuiltinCalls._inject_unicode_findc              	   C   sn   t |dvr| d||d |S | ||dtjd | ||dtjd | ||d| jd	||}||  S )
zaReplace unicode.count(...) by a direct call to the
        corresponding C-API function.
        rb  zunicode.countrd  r   re  r   rf  PyUnicode_Countcount)	rE   r}  rM  r   r  r  PyUnicode_Count_func_typerP  r   )rS   r'   r   r   r  rl  r!   r!   r"   #_handle_simple_method_unicode_count  s   
z8OptimizeBuiltinCalls._handle_simple_method_unicode_countreplstrmaxcountc              	   C   sL   t |dvr| d||d |S | ||dtjd | ||d| jd||S )zcReplace unicode.replace(...) by a direct call to the
        corresponding C-API function.
        )r   rc  zunicode.replacez3-4r   rI  PyUnicode_Replacer  )rE   r}  rM  r   r  r  PyUnicode_Replace_func_typer  r!   r!   r"   %_handle_simple_method_unicode_replace  s   
z:OptimizeBuiltinCalls._handle_simple_method_unicode_replacer  errors)UTF8UTF16UTF-16LEUTF-16BELatin1ASCIIunicode_escaperaw_unicode_escapec                 C   s   g | ]	}|t |fqS r!   )r   
getencoder)rg   r    r!   r!   r"   rk     s    zOptimizeBuiltinCalls.<listcomp>c                 C   s>  t |dk st |dkr| d||d |S |d }| |j|}|du r'|S |\}}}	}
| rQz	|j||	}W n   Y nt||pEd}tj	|j|t
jdS t |dkrlt|j}| ||d	| jd
||||gS |r|	dkr| |}|durd|vrd| }| |||| jd
||gS | ||d	| jd
||||
gS )z_Replace unicode.encode(...) by a direct C-API call to the
        corresponding codec.
        r   r   zunicode.encoderH  r   NzUTF-8rN  PyUnicode_AsEncodedStringr`  strictr  zPyUnicode_As%sString)rE   r}  _unpack_encoding_and_error_moder   r   r7   r`  r   r   rb  r	   r   r  r  #PyUnicode_AsEncodedString_func_type_find_special_codec_namePyUnicode_AsXyzString_func_type)rS   r'   r   r   r  string_node
parametersr  encoding_nodeerror_handlingerror_handling_noderr   	null_node
codec_nameencode_functionr!   r!   r"   $_handle_simple_method_unicode_encode  sJ   
z9OptimizeBuiltinCalls._handle_simple_method_unicode_encodestringrz  rH  decode_funcc                 C   s  dt |  krdksn | d||d |S |d }| |j|}|du r(|S |\}}}	}
| rSz	|j||	}W n ttt	fyG   Y nw t
|jt||jdS d }}t|tjrr|}|j}|j|j}}|rp|jdkrrd}t|tjr{|j}|j}|tjtjfv r|r|jdd	|jgd
}n|jddd	gd}n|js|js|S |stj|jd}n|jjs|t j!| " }|r|jjs|t j!| " }d}|dur| #|}|dur|dv rd|$dd }nd| }tj%|j| j&|d}t'|j}nt'|j}g }|jr-|s'|j(st)*|}|+| tj,|jd| j-|gdd}| j.}d}nm|jr|s>tj|jdtj/d}| j0du rut 1tj2t 3d|dt 3dt j!dt 3dt j!dt 3dt j4dt 3dt j4dt 3d| j&dg| _0| j0}d |j }n|stj|jdtj/d}| j5}|tju rd!}nd"}tj,|jd#| ||||||
|g|j6t78|d$d%}|ddd& D ]	}t)9||}q|S )'zReplace char*.decode() by a direct C-API call to the
        corresponding codec, possibly resolving a slice on the char*.
        r   r   zbytes.decoderH  r   Nrr   ro  @descriptor '%s' requires a '%s' object but received a 'NoneType'decoder  r  r  r  )r  r  r  z__Pyx_PyUnicode_Decode%sr  r  zPyUnicode_Decode%s)r=   r  ra  TrD  decode_c_stringrf  r  r  rF  rH  r  r  r  decode_cpp_decode_bytesdecode_bytearrayz__Pyx_%sr!  rd  rB   ):rE   r}  r  r   r   r7   r  r	  
ValueErrorUnicodeDecodeErrorr   r   r%   r   rL  r   rF  rH  r   r&   r=   r	   r   r   r  r    r  is_cpp_stringr   r   r   r   r   r  r   r  r  r  !PyUnicode_DecodeXyz_func_ptr_typer  r   r
   r  rG   rI  ri  _decode_c_string_func_typer   _decode_cpp_string_func_typer  r   r  rc  _decode_bytes_func_typer
  r   r   r  )rS   r'   r   r   r  r  r  r  r  r  r  r7   rF  rH  rZ  string_typer  codec_cnamedecode_functionr   helper_func_typerH  r  r!   r!   r"   "_handle_simple_method_bytes_decodeI  s   





	

z7OptimizeBuiltinCalls._handle_simple_method_bytes_decodec                 C   sj   zt |}W n
 ty   Y d S w | jD ]\}}||kr2d|v r.ddd |dD }|  S qd S )Nr  r  c                 S   s   g | ]}|  qS r!   )rj  )rg   r?  r!   r!   r"   rk     s    zAOptimizeBuiltinCalls._find_special_codec_name.<locals>.<listcomp>)r   r  LookupError_special_codecsr^  rK  )rS   r  requested_codecr    codecr!   r!   r"   r    s   
z-OptimizeBuiltinCalls._find_special_codec_namec                 C   s   t |}t|dkr| |d \}}|d u rd S nd }|}t|dkr;| |d \}}|d u r4d S |dkr:|}nd}|}||||fS )Nr   r   r   r  )r   r  rE   _unpack_string_and_cstring_node)rS   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}||fS t |tjr=|jd}tj|j|jt	j
d}||fS |jtju rRd }|t	j
|  }||fS |jjr\d }||fS d  }}||fS )NrN  z
ISO-8859-1)r%   r   r   r&   r   rr   rb  r   as_utf8_stringr   rc  r  r=   r	   r   r   r   r  )rS   r'   r  r!   r!   r"   r    s.   	z4OptimizeBuiltinCalls._unpack_string_and_cstring_nodec              
   C   rY  )NrZ  rZ  r   r\  bytes_tailmatch_utility_coder  r!   r!   r"   $_handle_simple_method_bytes_endswith  r_  z9OptimizeBuiltinCalls._handle_simple_method_bytes_endswithc              
   C   rY  )NrZ  r`  rB   r  r  r!   r!   r"   &_handle_simple_method_bytes_startswith  r_  z;OptimizeBuiltinCalls._handle_simple_method_bytes_startswithr!   c              
   C   sT   t |}|r|r| |d ||||d< |	d u r|j}	tj|j||||	||
|jdS )Nr   )r   r
  r^  r  r]  )r  r  r
  r   rI  r   r]  )rS   r'   r   r    rr  r  r  r   r^  r
  r  r1  r!   r!   r"   r    s   z,OptimizeBuiltinCalls._substitute_method_callc                 C   sT   |j r|S |r|jd||jjgd}|S |jdt|dkr dndd|gd}|S )	Nr  r  r  r  r  r  r  r  )r_  r  r=   r    r  rE   )rS   self_argr   r  r  r!   r!   r"   r  1  s   
z#OptimizeBuiltinCalls._wrap_self_argc                 C   sb   t ||krd S || }| sd S |jrt|jntj|jd| j|| 	 gdd||< d S )N__Pyx_NoneAsNullr   rD  )
rE   r&  r<   r   r  r   rI  obj_to_obj_func_typer|  r   )rS   r   r  r&   r!   r!   r"   rL  D  s   z*OptimizeBuiltinCalls._inject_null_for_nonec                 C   s   t ||ksJ t ||ks|| jr>t|ts!t|d r,tj	|j
t|}ntj|j
t||d}|| d S || ||  }t|tjrSt||_|||< d S )Nz+-rN  )rE   r<   r%   rx  r  lstrip	isdecimalr   r   r   r   rG   r   r   r  special_none_cvalue)rS   r'   r   	arg_indexr=   default_valueint_noder&   r!   r!   r"   rM  S  s   
z1OptimizeBuiltinCalls._inject_int_default_argumentc                 C   sT   t ||ksJ t ||kr|tj|jt|d d S || |  ||< d S Nrq   )rE   rG   r   r   r   rO  r  r   )rS   r'   r   r  r  r!   r!   r"   rC  d  s   z2OptimizeBuiltinCalls._inject_bint_default_argumentr$   r  )r^   r_   r`   ra   r  r  rX   r  r   r  r  r  r  r  r  c_float_typer  c_longdouble_typer  r  re  r   r  r  r  r}  r  r  r  r	   r   r'  r(  _handle_simple_function_strr,  r   r.  r  r  r  r  r  r1  r2  r   r6  r  r   r:  r  rF  r  rE  rL  rK  rM  rQ  memoryview_typerV  rW  rX  rY  r  rc  ri  c_const_py_unicode_ptr_typerk  rp  r   r   r  rl  ro  rr  rF   ru  rv  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  rB  r  r  r  r3  r   r  r  r	  r  r  r  r  r  r  r  r!  r$  r'  !_handle_simple_method_int___add__!_handle_simple_method_int___sub__!_handle_simple_method_int___mul__ _handle_simple_method_int___eq__ _handle_simple_method_int___ne__!_handle_simple_method_int___and__ _handle_simple_method_int___or__!_handle_simple_method_int___xor__$_handle_simple_method_int___rshift__$_handle_simple_method_int___lshift__!_handle_simple_method_int___mod__&_handle_simple_method_int___floordiv__%_handle_simple_method_int___truediv__r  r(  r)  r*  r+  r,  r-  r.  r  r<  r?  %_handle_simple_method_unicode_isalnum%_handle_simple_method_unicode_isalpha'_handle_simple_method_unicode_isdecimal%_handle_simple_method_unicode_isdigit%_handle_simple_method_unicode_islower'_handle_simple_method_unicode_isnumeric%_handle_simple_method_unicode_isspace%_handle_simple_method_unicode_istitle%_handle_simple_method_unicode_isupper)_handle_simple_method_unicode_isprintable$PyUnicode_uchar_conversion_func_typerD  rE  rN  rO  rS  rU  rk  r^  ra  r\  rv  rq  rt  rp  ry  rz  r~  r  r  r  _special_encodingsr  r  r  r  r  r  r  r  &_handle_simple_method_bytearray_decoder  r  r  r  r  r   rI  r  r  r  r  rL  rM  rC  r!   r!   r!   r"   r  x  sn   	"5
,6	4T
J
	?!	
B		
	' 

	1

 
r  c                 C   s  t jt jf}t||r|jtjur|jtjurdS |}d}nt||r6|jtjur1|jtjur1dS |}d}ndS |	 s>dS t|t j}|rItj
ntj}	|rU| dvrTdS n| dkr[dS t|jdkrddS | dv ro|jdkrodS g }
|
|rxt jnt j|j|j|j|	d	 t|t jr|jnd
}|
t j|j|d |s| dvr|dkot|t jr|j nd
}|
t j|j|d tj|rdn| dv rdnddt| ||dd}d|rdnd|jrdnd| |f }|||
|	fS )zQ
    Optimise math operators for (likely) float or small integer operations.
    NObjCCObj)r  r  r  r#  r&  r  r  r&  r   )r#  r   r&  r  r   rT  Frq   r0  PyFloatBinopPyLongComparePyLongBinopr   )oporderr  r:  z__Pyx_Py%s_%s%s%sFloatLongr  Bool)r   r   r  r%   r=   r   r  r	   rE  r   r  r  ry  r7   rG   r   rr   NumBinopNoder  r   r  	cdivisionr   r   r   r   )rp   r'   r  arg0arg1	num_nodesnumval	arg_orderr  r7  r6  r  zerodivision_checkr^  r5  r!   r!   r"   r2  l  sf   



r2  unicode_tailmatchr!  bytes_tailmatchc                       sJ  e Zd ZdZdI fdd	Zdd Zejejej	ej
gZdd Zd	d
 Zdd Zdd ZdddddjZdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(Zd)d* Zd+d, Zd-d. Zd/d0 Z d1d2 Z!d3d4 Z"d5d6 Z#d7d8 Z$d9d: Z%d;d< Z&d=d> Z'd?d@ Z(dAdB Z)dCdD Z*dEdF Z+dGdH Z,e-j.j/Z0  Z1S )JConstantFoldingaF  Calculate the result of constant expressions to store it in
    ``expr_node.constant_result``, and replace trivial cases by their
    constant result.

    General rules:

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

    - We recursively calculate constants from non-literal nodes to
      make them available to the compiler, but we only aggregate
      literal nodes at each step.  Non-literal nodes are never merged
      into a single node.
    Fc                    s   t    || _dS )z
        The reevaluate argument specifies whether constant values that were
        previously computed should be recomputed.
        N)superrP   
reevaluate)rS   r  	__class__r!   r"   rP     s   

zConstantFolding.__init__c                 C   s   | j s|jtjurd S tj}||_| |}| D ]%}t|tu r4|D ]}t	|d||u r2  d S q$qt	|d||u r? d S qz|
  W d S  ttttttfyW   Y d S  tyo   dd l}dd l}|j|jd Y d S w )Nr7   r   )file)r  r7   r   constant_value_not_setr   rT   r   r=   r  r  calculate_constant_resultr  	TypeErrorrl   
IndexErrorr	  ArithmeticError	Exception	tracebacksys	print_excstdout)rS   r'   r   childrenchild_resultchildr  r  r!   r!   r"   _calculate_const  s0   
z ConstantFolding._calculate_constc                 G   s6   z| j tt| j jtt| W S  ty   Y d S w r$   )NODE_TYPE_ORDERmaxr   r  r=   r  )rS   nodesr!   r!   r"   _widest_node_class  s   z"ConstantFolding._widest_node_classc                 C   s   t j|jt|dS r  )r   r   r   rO  )rS   r'   rr   r!   r!   r"   
_bool_node  s   zConstantFolding._bool_nodec                 C      |  | |S r$   )r	  rU   r!   r!   r"   visit_ExprNode  s   
zConstantFolding.visit_ExprNodec                 C   s   |  | | s|jdkr| |S |S |jjs|S |jdkr'| ||jS t|jt	j
r9t	j|jt|jS |jdkrC| |S |jdkrM| |S |S )N!r  r  )r	  r   rp   _handle_NotNoder   r_  r  r7   r%   r   r   r   r   r   rx  _handle_UnaryPlusNode_handle_UnaryMinusNoderU   r!   r!   r"   visit_UnopNode  s    







zConstantFolding.visit_UnopNoder   r2  is_notrw  )r2  r   rw  r  c                 C   s@   |j }t|tjr| |j}|rt|}||_| |}|S r$   )r   r%   r   r   _negate_operatorrp   r   r   )rS   r'   r   rp   r!   r!   r"   r    s   

zConstantFolding._handle_NotNodec                 C   s   dd }|j j}t|j tjrtj|j||j j||jdS |jr$|j	s.t|j tj
r@|jr@tj
|j||j j||j j|jdS |S )Nc                 S   s&   |  dr| dd  } | S d|  } | S )Nr  r   )r`  rq   r!   r!   r"   _negate#  s
   
z7ConstantFolding._handle_UnaryMinusNode.<locals>._negate)rr   r=   r7   )rr   r=   longnessr7   )r   r=   r%   r   r  r   rr   r7   r   r  r   r   r  )rS   r'   r  	node_typer!   r!   r"   r  "  s$   z&ConstantFolding._handle_UnaryMinusNodec                 C   s"   |j  r|j|j jkr|j S |S r$   )r   r   r7   rU   r!   r!   r"   r  8  s   
z%ConstantFolding._handle_UnaryPlusNodec                 C   sL   |  | |j s|S |jjr|jdkr|jS |jS |jdkr#|jS |jS )Nr  )r	  r:   r   r7   rp   r;   rU   r!   r!   r"   r$  >  s   



z#ConstantFolding.visit_BoolBinopNodec              	   C   s  |  | |jtju r|S t|jtr|S |j|j}}|jr"|js$|S z|j	|j	}}|d u s4|d u r7|W S W n t
yC   | Y S w |jrQ|jrQt||}ntj}| ||}|d u r`|S |tju rn|jdv rntj}n|tju r{|jdv r{tj}|tju rt|ddot|dd}dd ttt|ddtt|dd }	tt|j}
t|
}
tj|j||	|
t|jd}|js|j	jrtj|_	|S t||j	|_	|S |tju rtj|j|j|d}|S ||j|t|j|jd	}|S )
Nz+-//<<%**>>z+-//<<%**>>&|^unsignedr  LLr  )r   r  r  rr   r7   rN  )r   r=   rr   r7   )r	  r7   r   r   r%   r  r:   r;   r_  r=   r	  r  r   widest_numeric_typer  r  r   rp   r   r  r  r  rE   hexrx  r   strip_py2_long_suffixr   r   r  )rS   r'   r:   r;   type1type2widest_typetarget_classr  r  rr   r   r!   r!   r"   visit_BinopNodeM  sj   



	
zConstantFolding.visit_BinopNodec                 C   s  |  | t|jtrtj|jjt|jdS |j|j	}}t|tj
rdt|tj
r:|j|j tj|_| |S t|jtrc|jsE|S t|tjsTtj|j|jd}|j| tj|_| |S n0t|tj
rt|jtr|jsu|S t|tjstj|j|jd}|jd| tj|_| |S |jtju r|S |jr|jrt|tjrt|tjrd }|jd ur|jd ur|jj|jjkrt|j|j |jj}t|j}tj|j||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 )Nrq   r   r  r  )r	  r%   r7   r  r   r   r:   r   r   r;   JoinedStrNoder   r  r  simplify_JoinedStrNoderG   insertr   r   ro  r  r   rb  rr   r$  )rS   r'   r:   r;   ro  string_valuer!   r!   r"   visit_AddNode  sf   


	



zConstantFolding.visit_AddNodec                 C   s   |  | |jjr| ||j|jS t|jtjr&|jjr&| ||j|jS |jjr3| 	||j|jS |jjr@| 	||j|jS | 
|S r$   )r	  r:   r   _calculate_constant_seqr;   r%   r   r   r   _multiply_stringr$  rU   r!   r!   r"   visit_MulNode  s   

zConstantFolding.visit_MulNodec                 C   s   |j }t|ts
|S | rt|j ts|S t|j dkr|S t|tjr(t}n!t|tj	rAt
}|jd ur@t|j| |jj|_nJ dt| ||j| |jj|_|j|_ |S )N   Fzunknown string node type: %s)r7   r%   rx  r   _py_string_typesrE   r   rb  r   r   r   ro  r  r=   rr   )rS   r'   r  multiplier_node
multiplierbuild_stringr!   r!   r"   r+    s0   

z ConstantFolding._multiply_stringc                 C   s   |j dkrK|jrKt|j tr|j dkr|jd d = d |_|S |jd urHt|j trCt|jj trC|jj |j  }tj|jj||_|S | 	|S ||_|S r  )
r7   r   r%   rx  r  r   r   r   r   r$  )rS   r'   sequence_nodefactorrr   r!   r!   r"   r*    s   

z'ConstantFolding._calculate_constant_seqc                 C   s^   |  | t|jtjr*t|jtjr*|jjs*| |jj	|jj
|jj}|d ur*|S | |S r$   )rT   r%   r:   r   r   r;   r;  r  _build_fstringr   rr   r   r$  )rS   r'   fstringr!   r!   r"   visit_ModNode  s   

zConstantFolding.visit_ModNodez'(%(?:(?:[-0-9]+|[ ])?(?:[.][0-9]+)?)?.)c                 C   s  t |}g }d}t| j|D ]}|sq|dkr%|tj|tdd q|d dkrO|d dkrBt|d|dd   d	d
d d}|tj|t|d q|d }zt	|}	W n t
yl   t|dd
d d}Y  nhw |	jrtd} n`|dv r|d
d  }
d }|dv rd|
v rd}n |dv r|
d d }
|}|
drd|
d
d   }
n|dkrd}|
drd|
d
d   }
|tj|	j|	||
rtj|t|
dnd d qd} |sd S zt	| W n	 t
y   Y n
w t|dd
d d S tj||d}| |S )NTz%%%rq   r   rB   zIncomplete format: '...'r   )levelFz)Too few arguments for format placeholdersasrfdoxXdoxXr\  arsre  r  dr  r  )rr   r+  r*  z*Too many arguments for format placeholders)r   )iterr   rK  _parse_string_format_regexrG   r   r   r   r   nextStopIterationr   r`  FormattedValueNoder   r%  visit_JoinedStrNode)rS   r   r=  r  r   
substringscan_be_optimisedr?  format_typer&   r*  r+  r'   r!   r!   r"   r4    sv   



zConstantFolding._build_fstringc                 C   s   |  | |jp	d}|jd ur|jjr|jjsd |_|jd u r<|j r<t|jjtr<t	t
|jj}tj|jj|dS |jd u rL|dkrL|jjrL|jS |S )Nr?  rq   )rT   r+  r*  r   rr   r   r%   r7   rx  r   r  r   r   r   )rS   r'   r+  rr   r!   r!   r"   r,  M  s   

"z(ConstantFolding.visit_FormattedValueNodec                 C   s   |  | | |S r$   )rT   r&  rU   r!   r!   r"   rD  Z  s   

z#ConstantFolding.visit_JoinedStrNodec                 C   s   g }t j|jtddD ]6\}}|r=t|}|d }t|dkr4tddd |D }tj	|j
|d}|jr<|| q|| q|sQtj	|j
tdd}|S t|dkr]|d }|S t|d	krptj|j
d
g|R  }|S ||_|S )z
        Clean up after the parser by discarding empty Unicode strings and merging
        substring sequences.  Empty or single-value join lists are not uncommon
        because f-string format specs are always parsed into JoinedStrNodes.
        r   )r  r   r   r  c                 s   r   r$   rq   )rg   rr   r!   r!   r"   r   j  r   z9ConstantFolding.simplify_JoinedStrNode.<locals>.<genexpr>rq   r   r  )r   groupbyr   r   r  rE   r   r^  r   r   r   rr   rG   r  r(  )rS   r'   r   is_unode_grouprE  unoderr   r!   r!   r"   r&  ^  s.   
z&ConstantFolding.simplify_JoinedStrNodec                    s   |  | g g  fdd |jD ]} || qr# tdkr8d }|js6t|tjr8|S |jdd< | | |S )z!Unpack **args in place if we can.c                    s   |j rrd j|jkrd j|j d S | d S t|tjr8| j|jkr8|jD ]} || q.d S rD d d = | d S )NrB   )	is_dict_literalreject_duplicatesr  r  rG   r%   r   MergedDictNoderj  )parentr&   	child_argr  r   r   r!   r"   r    s   


z1ConstantFolding.visit_MergedDictNode.<locals>.addr   r   N)	rT   rj  r  rE   rK  r%   r   rM  r	  r  r!   rP  r"   visit_MergedDictNode}  s   



z$ConstantFolding.visit_MergedDictNodec                    s   |  | |jtju g g  fdd |jD ]} | qr+d  tdkrKd }r:|jsI|jrC|j|ju sIt	|t
jrK|S |jdd< | | |S ) Unpack *args in place if we can.c                    s   r| j s| jr| jsrd j| j d S |  d S t| tjr1| jD ]} | q(d S r?d  d d = |  d S )Nr   )	is_set_literalr   r  r   r  rG   r%   r   MergedSequenceNode)r&   rO  r  r   r  r   r!   r"   r    s   


z5ConstantFolding.visit_MergedSequenceNode.<locals>.addr   r   N)rT   r=   r	   r   r   rG   rE   rS  r   r%   r   rT  r	  r  r!   rU  r"   visit_MergedSequenceNode  s*   





z(ConstantFolding.visit_MergedSequenceNodec                 C   sr   |  | g }|jD ] }|js|| q
|jjr%|jjs%||jj q
|| q
||jdd< | | |S )rR  N)	rT   r   r   rG   r   r   r  r  r	  )rS   r'   r   r&   r!   r!   r"   visit_SequenceNode  s   


z"ConstantFolding.visit_SequenceNodec                 C   s  |  |dg |j}|}|d urF|  |dg |j}t|_| r=| r=z||j W n ttt	t
ttfy<   Y nw |}|j}|d us|jsV| rT| ||jS |S |jgg}g }|}|d ur| r||jst|| |d n||jg n|d | |j}|d uscg }|D ]4}t|dk rq|d }tj|j|d |j|jtd}	||	 |	}
|dd  D ]}||
_|}
qd |
_q|r||d  n|s| |d	S |d }t|dkr| r| ||jS |S |dd  D ]}tj|j|d
|td}q|S )Nr:   r;   FrB   r   r   r   )r:   rp   r;   r7   Tr  )rT   r:   r;   r   r7   r   "calculate_cascaded_constant_resultr  r  rl   r  r	  r   r  r  rG   rE   r   r   r   rp   r!  )rS   r'   	left_noder   
right_nodecascadesfinal_false_result	cmp_nodesr  	pcmp_nodelast_cmp_noder!   r!   r"   r     s   

	z$ConstantFolding.visit_PrimaryCmpNodec                 C   s,   |  | |j s|S |jjr|jS |jS r$   )r	  r  r   r7   r  r  rU   r!   r!   r"   r!  $  s   

z"ConstantFolding.visit_CondExprNodec                 C   sp   |  | g }|jD ]}|j}| r|jr|j|_ nq
|| q
|r*||_|S |jr0|jS tj	|j
g dS Nrv   )rT   r|   ry   r   r7   rz   r}   rG   r   r   r   )rS   r'   r|   r  ry   r!   r!   r"   r  -  s    

z ConstantFolding.visit_IfStatNodec                 C   s   |  | |jd u s|jjd u rd  }|_n|jj}|jd u s%|jjd u r+d  }|_n|jj}|jturX|j}|jrI|jd u rI|j|| |_|S |j	rX|
||}|d urX|S |S r$   )r	  rF  r7   rH  r   r   r   r  r   r   as_sliced_node)rS   r'   rF  rH  r   r!   r!   r"   visit_SliceIndexNodeD  s"   

z$ConstantFolding.visit_SliceIndexNodec                 C   s   |  | t|jtjr>|jjs>|jtju rt	j
|jg g dS |jtju r/t	j|jg t dS |jtju r>t	j|jg i dS |S )Nr  r  )rT   r%   r  r   r   rw   r=   r	   r  r   r   r   r   r<  rD   r   r  rU   r!   r!   r"   visit_ComprehensionNode[  s   

z'ConstantFolding.visit_ComprehensionNodec                 C   s\   |  | |jj}t|tjr,|js |jr|jS tj	|j
g dS t|tjr,| |j_|S r`  )rT   r   r~   r%   r   SequenceNoder   r}   r   r   r   r   r  )rS   r'   r~   r!   r!   r"   r   j  s   
z#ConstantFolding.visit_ForInStatNodec                 C   s<   |  | |jr|j r|jjrd |_d |_|S |jS |S r$   )rT   ry   r   r7   r}   rU   r!   r!   r"   visit_WhileStatNodey  s   
z#ConstantFolding.visit_WhileStatNodec                 C   s.   |  | t|jtjs|S |j rd S |S r$   )rT   r%   rW   r   ExprNoder   rU   r!   r!   r"   rX     s   

z"ConstantFolding.visit_ExprStatNodec                 C   s>   |  | |jd u r|S |j r|jjrd |_|S |jS |S r$   )rT   ry   r   r7   rz   rU   r!   r!   r"   visit_GILStatNode  s   


z!ConstantFolding.visit_GILStatNoder  )2r^   r_   r`   ra   rP   r	  r   r   r  r   r  r
  r  r  r  r  r  r  r  r  r  r$  r$  r)  r,  r+  r*  r6  r@  r4  r,  rD  r&  rQ  rV  rW  r   r!  r  rb  rc  r   re  rX   rg  r   r/  r0  rb   __classcell__r!   r!   r  r"   r    s^     
:7
F"&P	

r  c                   @   sv   e Zd ZdZdZdd Zdd Zdd Zd	d
 Zdd Z	dd Z
dd Zdd Zdd ZdddZdejfddZdS )FinalOptimizePhasea  
    This visitor handles several commuting optimizations, and is run
    just before the C code generation phase.

    The optimizations currently implemented in this class are:
        - eliminate None assignment and refcounting for first assignment.
        - isinstance -> typecheck for cdef types
        - eliminate checks for None and/or types that became redundant after tree changes
        - eliminate useless string formatting steps
        - inject branch hints for unlikely if-cases that only raise exceptions
        - replace Python function calls that look like method calls by a faster PyMethodCallNode
        - replace duplicate FormattedValueNodes in f-strings with CloneNodes
    Fc                 C   s    |  | |jr|j}d|_|S )zaAvoid redundant initialisation of local variables before their
        first assignment.
        T)rT   r&  rt   lhs_of_first_assignment)rS   r'   rt   r!   r!   r"   visit_SingleAssignmentNode  s
   
z-FinalOptimizePhase.visit_SingleAssignmentNodec                 C   s   |j }|j}|js|jr|jnd }|  }|jp!|jp!|jo!|j	j}|
 o@|jo@|tjuo@|o2|j o@| j| js>|r>dndS )Nz&optimize.unpack_method_calls_in_pyinitzoptimize.unpack_method_calls)r   r=   r   r   r   r   is_module_scopeis_c_class_scopeis_py_class_scopeouter_scoper  r   r	   rF   r   r  r  in_loop)rS   r'   r   function_typer   r   in_global_scoper!   r!   r"   _check_optimize_method_calls  s0   
z/FinalOptimizePhase._check_optimize_method_callsc                 C   s  |  | |j}|jjrP|jrP|jdkrNt|jdkrN|jd }|jjrN|jjdkrN| j	j
}|d|_|jj|_t|dj}t|jd ||jd< |S tjj|jddrtj|r|jrx|jrxt|jtjrx|jj|ju rx|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=   PyObject_TypeCheckr  F)
has_kwargs)r   r   r=   unpack)rT   r   r=   is_cfunctionr   r    rE   r   r  r   r  r  r   r   r  r   r  PyMethodCallNodecan_be_used_for_posargsr   can_be_used_for_functionrS   r   r%   r3   r~  r&   r  	from_noders  )rS   r'   r   r  r  r  r!   r!   r"   rh    s0   



z'FinalOptimizePhase.visit_SimpleCallNodec                 C   s   |  | t|j}t|jtj}tjj|j||ds|S |j	}tj
|s(|S | |tjj|||j|j|j| |d}|S )zW
        Replace likely Python method calls by a specialised PyMethodCallNode.
        )ru  has_explicit_kwargs)r   r   kwdictr=   rv  )rT   rO  rj  r%   r   r  rx  ry  ri  r   rz  r  r{  r=   rs  )rS   r'   ru  r|  r   r!   r!   r"   rk    s   

z(FinalOptimizePhase.visit_GeneralCallNodec                 C   r  r$   )rT   rU   r!   r!   r"   visit_NumPyMethodCallNode  s   
z,FinalOptimizePhase.visit_NumPyMethodCallNodec                 C   s$   |  | |js|j sd|_|S )zRemove tests for alternatively allowed None values from
        type tests when we know that the argument cannot be None
        anyway.
        T)rT   notnoner&   r&  rU   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.
        )rT   r&   r&  rU   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)rp  rT   )rS   r'   old_valr!   r!   r"   visit_LoopNode$  s
   
z!FinalOptimizePhase.visit_LoopNodec                 C   sZ   |  | d}t|jD ]\}}| ||j |js|}q|jr+|r+| j||jdd |S )zQAssign 'unlikely' branch hints to if-clauses that only raise exceptions.
        NT)inverse)rT   r   r|   _set_ifclause_branch_hintrz   branch_hintr}   )rS   r'   last_non_unlikely_clauser  r  r!   r!   r"   r  -  s   

z#FinalOptimizePhase.visit_IfStatNodec                 C   s   |j sdS tjtjtjtjtjtjf}|g}t|dD ]>\}}t	|tj
r-|||j qt	|tjr;|j|||< qt	||sY|t|krVt	|tjtjfrV|rSdnd|_ dS qdS )z\Inject a branch hint if the if-clause unconditionally leads to a 'raise' statement.
        Nr   likelyunlikely)is_terminatorr   ri  AssignmentNodeAssertStatNodeDelStatNode
GlobalNodeNonlocalNoder   r%   GILStatNoder'  rz   r   rw   rE   RaiseStatNodeReraiseStatNoder  )rS   clausestatements_noder  non_branch_nodes
statementsnext_node_posr'   r!   r!   r"   r  ;  s.   
z,FinalOptimizePhase._set_ifclause_branch_hintr'   c                 C   s   t j}t j}i }|jdd }t|jD ]O\}}t||sq|j}t|j|r+|j}n|jdur1n|j	j
r6nq|jr>| s?q|j|j|j|jpIdf}	||	|}
|
|u rVqt |
}|j|_|||< q||jdd< |S )a  
        Deduplicate repeatedly formatted (C) values by replacing them with CloneNodes.
        It's not uncommon for a formatting expression to appear multiple times in an f-string.

        Note that this is somewhat handwavy since it's potentially possible even for simple
        expressions to change their value while processing an f-string, e.g. by modifying the
        world in a ".__format__" method.  However, this seems unlikely enough to appear in
        real-world code that we ignore the case here.
        Nr?  )r   rC  r   r   r   r%   rr   r&   r)  r=   r  r   r5  r    r*  r+  r  r~  r   )rS   r'   rC  r   r  r   r  fnodefnode_value_noder  
seen_fnodededup_fnoder!   r!   r"   rD  W  s4   




z&FinalOptimizePhase.visit_JoinedStrNodeNr  )r^   r_   r`   ra   rp  rk  rs  rh  rk  r~  r  r  r  r  r  r   r%  rD  r!   r!   r!   r"   ri    s    
		
ri  c                   @   s$   e Zd ZdZdZdd Zdd ZdS )ConsolidateOverflowChecka5  
    This class facilitates the sharing of overflow checking among all nodes
    of a nested arithmetic expression.  For example, given the expression
    a*b + c, where a, b, and x are all possibly overflowing ints, the entire
    sequence will be evaluated and the overflow bit checked only at the end.
    Nc                 C   s8   | j d ur| j }d | _ | | || _ |S | | |S r$   )overflow_bit_noderT   )rS   r'   savedr!   r!   r"   rb     s   


z#ConsolidateOverflowCheck.visit_Nodec                 C   sV   |j r$|jr$| jd u }|r|| _n| j|_d|_ | | |r"d | _|S | | |S r.   )overflow_checkoverflow_foldr  rT   )rS   r'   top_level_overflowr!   r!   r"   visit_NumBinopNode  s   


z+ConsolidateOverflowCheck.visit_NumBinopNode)r^   r_   r`   ra   r  rb   r  r!   r!   r!   r"   r    s
    
r  r!   )Gcythondeclarers  r   r   r   r   	functoolsr   r   rp   r   r  r   r   r   r   rZ  r  r.  r   r   r   r	   r
   r   Coder   r   StringEncodingr   r   r   Errorsr   r   ParseTreeTransformsr   r   r#   r   r  r)   r-   r2   r8   r  rM   rO   rN   rf   rc   EnvTransformrm   r  r/  r1  rA  re  NodeRefCleanupMixinr  MethodDispatcherTransformr  r2  r   r]  r  r  ri  CythonTransformr  r!   r!   r!   r"   <module>   s    "
&         ? }It   I"                E     { d