o
    2gAr                     @  sT  U d Z ddlmZ ddlmZmZ ddlmZmZm	Z	m
Z
mZmZmZmZmZmZmZmZmZ ddlmZmZ ddlmZmZmZmZmZmZmZmZ ddl m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9 ddl:m;Z; dd	l<m=Z=m>Z>m?Z?m@Z@ dd
lAmBZBmCZCmDZDmEZE ddlFmGZGmHZHmIZImJZJ ddlKmLZL ddlMmNZN ede	egee f ZOi ZPdeQd< 	ddddZRddd ZS	ddd"d#ZT	ddd&d'ZUeUd(dd)d*ZVeUd+eUd,eUd-eUd.eUd/eUd0eUd1eUd2dd3d4ZWeUd5dd6d7ZXeUd8dd9d:ZYeUd8dd;d<ZZeUd=dd>d?Z[eUd@ddAdBZ\eUdCeUdDddEdFZ]eUd=eUdGeUdHeUdCeUdDeUdIeUdJeUdKe8eUdLe6eUdMe'eUdMe7ddNdOZ^eUdPddQdRZ_eUdSddTdUZ`dd^d_ZaeUd`ddadbZbeUdceUddeUdeeUdfddgdhZceUdiddjdkZdeUdlddmdnZeeUdoe'ddpdqZfeUdre8ddsdtZgeUdKe8ddudvZheUd/ddwdxZieUd0ddydzZjeUd1dd{d|ZkeUd2dd}d~ZldddZmeUd,dddZneUddddZoeUd-dddZpdS )a0  Special case IR generation of calls to specific builtin functions.

Most special cases should be handled using the data driven "primitive
ops" system, but certain operations require special handling that has
access to the AST/IR directly and can make decisions/optimizations
based on it. These special cases can be implemented here.

For example, we use specializers to statically emit the length of a
fixed length tuple and to emit optimized code for any()/all() calls with
generator comprehensions as the argument.

See comment below for more documentation.
    )annotations)CallableOptional)	ARG_NAMEDARG_POSCallExprDictExpr
ExpressionGeneratorExprIntExprListExpr
MemberExprNameExprRefExprStrExpr	TupleExpr)AnyType	TypeOfAny)
BasicBlockExtendIntegerRaiseStandardErrorRegisterTruncateUnreachableValue)	RInstance
RPrimitiveRTupleRTypebool_rprimitivec_int_rprimitivedict_rprimitiveint16_rprimitiveint32_rprimitiveint64_rprimitiveint_rprimitiveis_bool_rprimitiveis_dict_rprimitiveis_fixed_width_rtypeis_float_rprimitiveis_int16_rprimitiveis_int32_rprimitiveis_int64_rprimitiveis_int_rprimitiveis_list_rprimitiveis_uint8_rprimitivelist_rprimitiveset_rprimitivestr_rprimitiveuint8_rprimitive)	IRBuilder)comprehension_helper*sequence_from_generator_preallocate_helpertranslate_list_comprehensiontranslate_set_comprehension)FormatOpconvert_format_expr_to_strjoin_formatted_stringstokenizer_format_call)dict_items_opdict_keys_opdict_setdefault_spec_init_opdict_values_op)new_list_set_item_op)new_tuple_set_item_opr5   z1dict[tuple[str, RType | None], list[Specializer]]specializersNbuilderexprr   calleer   name
str | NonetypRType | NonereturnValue | Nonec                 C  sB   |r||ft v rt ||f D ]}|| ||}|d ur|  S qd S N)rD   )rE   rF   rG   rH   rJ   specializerval rQ   P/home/garg/my-data/venv/lib/python3.10/site-packages/mypyc/irbuild/specialize.py_apply_specializationn   s   rS   c                 C  s   t | |||jS )zIInvoke the Specializer callback for a function if one has been registered)rS   fullnamerE   rF   rG   rQ   rQ   rR   apply_function_specialization~   s   rV   r   c                 C  s$   |du r|j n|j}t| ||||S )zGInvoke the Specializer callback for a method if one has been registeredN)rT   rH   rS   )rE   rF   rG   rJ   rH   rQ   rQ   rR   apply_method_specialization   s   rW   str$Callable[[Specializer], Specializer]c                   s   d fdd}|S )zDecorator to register a function as being a specializer.

    There may exist multiple specializers for one function. When
    translating method calls, the earlier appended specializer has
    higher priority.
    fSpecializerrL   c                   s   t  fg |  | S rN   )rD   
setdefaultappend)rZ   rH   rJ   rQ   rR   wrapper   s   z$specialize_function.<locals>.wrapperN)rZ   r[   rL   r[   rQ   )rH   rJ   r_   rQ   r^   rR   specialize_function   s   
r`   zbuiltins.globalsc                 C  s   t |jdkr|  S d S )Nr   )lenargsload_globals_dictrU   rQ   rQ   rR   translate_globals   s   rd   zbuiltins.abszbuiltins.intzbuiltins.floatzbuiltins.complexzmypy_extensions.i64zmypy_extensions.i32zmypy_extensions.i16zmypy_extensions.u8c                 C  s   t |jdkrK|jtgkrKt|trK|jd }| |}|jdd }|dv r+d}nd| d}t|t	rK|j
|rK| |}| ||g d|jS dS )zSpecialize calls on native classes that implement the associated dunder.

    E.g. i64(x) gets specialized to x.__int__() if x is a native instance.
       r   .)i64i32i16u8__int____N)ra   rb   	arg_kindsr   
isinstancer   	node_typerT   splitr   class_ir
has_methodacceptgen_method_callline)rE   rF   rG   argarg_typ	shortnamemethodobjrQ   rQ   rR   $translate_builtins_with_unary_dunder   s   $


r{   zbuiltins.lenc                 C  s   t |jdkrB|jtgkrB|jd }| |}t|tr(| | tt |j	S t
| |r2d}nd}| j||d}| ||jS d S )Nre   r   TF
can_borrow)ra   rb   rm   r   ro   rn   r   rs   r   typesr/   builtin_lenru   )rE   rF   rG   rv   
expr_rtypeborrowrz   rQ   rQ   rR   translate_len   s   



r   zbuiltins.listc                 C  s   t |jdkr|jtgksdS |jd }t|tr"|js"t|jts$dS |jj}|jj	}| 
|}t|r9|dv s;dS | |}|dkrM| t|g|jS |dkrZ| t|g|jS | t|g|jS )zSpecialize a common case when list() is called on a dictionary
    view method call.

    For example:
        foo = list(bar.keys())
    re   Nr   )keysvaluesitemsr   r   )ra   rb   rm   r   rn   r   rG   r   rF   rH   ro   r(   rs   call_cr?   ru   rA   r>   )rE   rF   rG   rv   baseattrrtyperz   rQ   rQ   rR   dict_methods_fast_path   s    


r   c                 C  J   t |jdkr#|jd tkr#t|jd tr#t| |jd | jjt	dS dS )zSpecial case for simplest list comprehension.

    For example:
        list(f(x) for x in some_list/some_tuple/some_str)
    'translate_list_comprehension()' would take care of other cases
    if this fails.
    re   r   empty_op_llbuilderset_item_opN)
ra   rb   rm   r   rn   r
   r7   rE   new_list_op_with_lengthrB   rU   rQ   rQ   rR   "translate_list_from_generator_call      r   zbuiltins.tuplec                 C  r   )zSpecial case for simplest tuple creation from a generator.

    For example:
        tuple(f(x) for x in some_list/some_tuple/some_str)
    'translate_safe_generator_call()' would take care of other cases
    if this fails.
    re   r   r   N)
ra   rb   rm   r   rn   r
   r7   rE   new_tuple_with_lengthrC   rU   rQ   rQ   rR   #translate_tuple_from_generator_call  r   r   builtins.setc                 C  s@   t |jdkr|jd tkrt|jd trt| |jd S dS )zSpecial case for set creation from a generator.

    For example:
        set(f(...) for ... in iterator/nested_generators...)
    re   r   N)ra   rb   rm   r   rn   r
   r9   rU   rQ   rQ   rR   !translate_set_from_generator_call(  s   
r   builtins.minzbuiltins.maxc           
      C  s  |j ttgkr| |jd | |jd }}t| |}|jdkr.| ||d|j}n	| ||d|j}t	 t	 t	 }}}	| 
||| | | | || ||j|j|j | |	 | | | || ||j|j|j | |	 | |	 |S d S )Nr   re   r   <>)rm   r   rs   rb   r   ro   rT   	binary_opru   r   add_bool_branchactivate_blockassigncoercetypegoto)
rE   rF   rG   xyresult
comparison
true_blockfalse_block
next_blockrQ   rQ   rR   faster_min_max:  s"   "





r   zbuiltins.frozensetzbuiltins.dictzbuiltins.sortedzcollections.OrderedDictjoinextendupdatec              	     s   t |jdkrb|jd tkrbt|jd trbt|trF  |j	|j
t |jd g fdd|jdd D   ||j|j|jS  ||t |jd g fdd|jdd D  S dS )zuSpecial cases for things that consume iterators where we know we
    can safely compile a generator into a list.
    r   c                      g | ]}  |qS rQ   rs   .0rv   rE   rQ   rR   
<listcomp>r      z1translate_safe_generator_call.<locals>.<listcomp>re   Nc                   r   rQ   r   r   r   rQ   rR   r     r   )ra   rb   rm   r   rn   r
   r   rt   rs   rF   rH   r8   ro   ru   	arg_namescall_refexpr_with_argsrU   rQ   r   rR   translate_safe_generator_callV  s0   

r   zbuiltins.anyc                 C  sL   t |jdkr$|jtgkr$t|jd tr$t| |jd | jdd | jS d S )Nre   r   c                 S  s   | S rN   rQ   r   rQ   rQ   rR   <lambda>  s    z$translate_any_call.<locals>.<lambda>)	ra   rb   rm   r   rn   r
   any_all_helperfalsetruerU   rQ   rQ   rR   translate_any_call  s   r   zbuiltins.allc                   sR   t jdkr'jtgkr'tjd tr't jd  j fdd jS d S )Nre   r   c                   s     | djS )Nnot)unary_opru   r   rE   rF   rQ   rR   r     s    z$translate_all_call.<locals>.<lambda>)	ra   rb   rm   r   rn   r
   r   r   r   rU   rQ   r   rR   translate_all_call  s   r   genr
   initial_valueCallable[[], Value]modifyCallable[[Value], Value]	new_valuer   c              	     s   t t | d ttjjjj}t	 t	 t	 d fdd}t
 ||j   S )NrL   Nonec                    sP     j}  |      d     d S )Nr   )rs   	left_exprr   r   r   r   )r   rE   
exit_blockr   r   r   r   retvalr   rQ   rR   gen_inner_stmts  s   

z'any_all_helper.<locals>.gen_inner_stmtsrL   r   )r   r    r   listzipindices	sequences	condlistsis_asyncr   r6   ru   goto_and_activate)rE   r   r   r   r   loop_paramsr   rQ   r   rR   r     s   
r   zbuiltins.sumc                   s   t |jdv r|jd tkrt|jd tsd S t |jdkr0|jd ttfvr*d S |jd }ntd}|jd  |}t	| 
  ||dd d
 fdd	}ttjjjj}t ||j S )N)re      r   r   re   r   rL   r   c               	     s*     j}   | ddd d S )N+r   )rs   r   r   r   )	call_exprrE   gen_exprr   rQ   rR   r     s   z+translate_sum_call.<locals>.gen_inner_stmtsr   )ra   rb   rm   r   rn   r
   r   r   ro   r   r   r   rs   r   r   r   r   r   r   r6   ru   )rE   rF   rG   
start_exprtarget_typer   r   rQ   r   rR   translate_sum_call  s(   

r   zdataclasses.fieldzattr.ibzattr.attribzattr.Factoryc                 C  s   t tj| j|< dS )a,  Special case for 'dataclasses.field', 'attr.attrib', and 'attr.Factory'
    function calls because the results of such calls are type-checked
    by mypy using the types of the arguments to their respective
    functions, resulting in attempted coercions by mypyc that throw a
    runtime error.
    N)r   r   
from_errorr~   rU   rQ   rQ   rR    translate_dataclasses_field_call  s   r   zbuiltins.nextc                   s   |j tgttgfv rt|jd tsdS |jd t |t|jdkr/ |jd nd}t	 d fdd}t
tjjjj}t ||j |rd |jj   n ttjd|j  t    S )	a6  Special case for calling next() on a generator expression, an
    idiom that shows up some in mypy.

    For example, next(x for x in l if x.id == 12, None) will
    generate code that searches l for an element where x.id == 12
    and produce the first such object, or None if no such element
    exists.
    r   Nre   rL   r   c                     s(      jjj   d S rN   )r   rs   r   ru   r   rQ   rE   r   r   r   rQ   rR   r     s   z,translate_next_call.<locals>.gen_inner_stmtsr   )rm   r   rn   rb   r
   r   ro   ra   rs   r   r   r   r   r   r   r   r6   ru   r   r   r   addr   STOP_ITERATIONr   r   )rE   rF   rG   default_valr   r   rQ   r   rR   translate_next_call  s$   
"
r   zbuiltins.isinstancec                 C  s   t |jdkrK|jttgkrKt|jd ttfrKttj	| j
|jd < | |jd }|durKtdd |D }| j|jd |d}| j|||jS dS )zSpecial case for builtins.isinstance.

    Prevent coercions on the thing we are checking the instance of -
    there is no need to coerce something to a new type before checking
    what type it is, and the coercion could lead to bugs.
    r   re   r   Nc                 s  s&    | ]}|j o|j o|j V  qd S rN   )is_ext_classinherits_pythonallow_interpreted_subclasses)r   irrQ   rQ   rR   	<genexpr>0  s
    
z'translate_isinstance.<locals>.<genexpr>r|   )ra   rb   rm   r   rn   r   r   r   r   r   r~   flatten_classesallrs   rE   isinstance_helperru   )rE   rF   rG   irsr}   rz   rQ   rQ   rR   translate_isinstance  s   	r   r\   c                 C  s   t |jdkr{|jttgkr{t|tr{|jd }t|tr,t |jr$dS tdt	|j
}n6t|tr@t |jr8dS tdt	|j
}n"t|tr`t|jtr`|jjdkr`t |jrXdS tdt	|j
}ndS | |j}| |jd }| t|||g|j
S dS )a  Special case for 'dict.setdefault' which would only construct
    default empty collection when needed.

    The dict_setdefault_spec_init_op checks whether the dict contains
    the key and would construct the empty collection only once.

    For example, this specializer works for the following cases:
         d.setdefault(key, set()).add(value)
         d.setdefault(key, []).append(value)
         d.setdefault(key, {})[inner_key] = inner_val
    r   re   Nr      r   )ra   rb   rm   r   rn   r   r   r   r   r!   ru   r   r   rG   r   rT   rs   rF   r   r@   )rE   rF   rG   rv   	data_typecallee_dictkey_valrQ   rQ   rR   translate_dict_setdefault9  s8   






r   formatc                 C  s   t |tr?t |jtr?|jtt|jkr?|jj}t	|}|d u r$d S |\}}t
| ||j|j}|d u r7d S t| |||jS d S rN   )rn   r   rF   r   rm   countr   ra   valuer=   r;   rb   ru   r<   )rE   rF   rG   
format_strtokensliterals
format_opssubstitutionsrQ   rQ   rR   translate_str_formatg  s   
r   c                 C  sn  t |trt |jtr|jjdkr|jtgkrt |jd tr|jd j	D ]C}t |tr-q%t |t
rft |jtr>|jjdkrA dS t |jjtrO|jjjdkrR dS t |jd trb|jd jdkre dS q% dS g }g }|jd j	D ]+}t |tr|jdkr|tj || qst |t
r|tj ||jd  qst| |||j}|du rdS t| d||jS dS )zSpecial case for f-string, which is translated into str.join()
    in mypy AST.

    This specializer optimizes simplest f-strings which don't contain
    any format operation.
     r   r   Nz{:{}}re   )rn   r   rF   r   r   rm   r   rb   r   r   r   rG   rH   r]   r:   STRr;   ru   r<   )rE   rF   rG   itemr   exprsr   rQ   rQ   rR   translate_fstring{  sJ   	


 
r   c                 C  s   t |jdks|jd tkrd S |jd }| |}t|r#| |S t|s+t|r<| |}| 	t
|td|jdS t|rQ| |}| 	t
|td|jdS t|sYt|rf| |}| |t|jS d S )Nre   r   Tsignedru   F)ra   rb   rm   r   ro   r-   rs   r,   r+   r   r   r%   ru   r0   r.   r'   r   rE   rF   rG   rv   arg_typerP   rQ   rQ   rR   translate_i64  s    





r  c                 C  s   t |jdks|jd tkrd S |jd }| |}t|r#| |S t|r7| |}| t	|t
|jdS t|rL| |}| t|t
d|jdS t|ra| |}| t|t
d|jdS t|sit|r{| |}t|t
}| |t
|jS d S )Nre   r   ru   Tr  F)ra   rb   rm   r   ro   r,   rs   r-   r   r   r$   ru   r+   r   r0   r.   r'   truncate_literalr   r  rQ   rQ   rR   translate_i32  s(   







r  c                 C  s   t |jdks|jd tkrd S |jd }| |}t|r#| |S t|s+t|r;| |}| 	t
|t|jdS t|rP| |}| 	t|td|jdS t|sXt|rj| |}t|t}| |t|jS d S )Nre   r   r  Fr  )ra   rb   rm   r   ro   r+   rs   r,   r-   r   r   r#   ru   r0   r   r.   r'   r  r   r  rQ   rQ   rR   translate_i16  s"   






r	  c                 C  s   t |jdks|jd tkrd S |jd }| |}t|r#| |S t|s/t|s/t	|r?| |}| 
t|t|jdS t|sGt|rY| |}t|t}| |t|jS d S )Nre   r   r  )ra   rb   rm   r   ro   r0   rs   r+   r,   r-   r   r   r4   ru   r.   r'   r  r   r  rQ   rQ   rR   translate_u8  s&   





r
  r   r   r   c                 C  s\   t | ts| S |  }d|jd > d }||@ }|jr)||d d kr)||d 8 }t||S )zIf value is an integer literal value, truncate it to given native int rtype.

    For example, truncate 256 into 0 if rtype is u8.
    re      r   )rn   r   numeric_valuesize	is_signed)r   r   r   max_unsignedrQ   rQ   rR   r    s   

r  c                 C  sj   t |jdks|jd tkrd S |jd }| |}t|s&t|s&t|r3| |}| 	|t
|jS d S Nre   r   )ra   rb   rm   r   ro   r'   r.   r)   rs   r   r&   ru   )rE   rF   rG   rv   r  srcrQ   rQ   rR   translate_int  s   


r  zbuiltins.boolc                 C  s@   t |jdks|jd tkrd S |jd }| |}| j|S r  )ra   rb   rm   r   rs   rE   
bool_value)rE   rF   rG   rv   r  rQ   rQ   rR   translate_bool$  s
   

r  c                 C  sJ   t |jdks|jd tkrd S |jd }| |}t|r#| |S d S r  )ra   rb   rm   r   ro   r*   rs   )rE   rF   rG   rv   r  rQ   rQ   rR   translate_float-  s   


r  rN   )rE   r5   rF   r   rG   r   rH   rI   rJ   rK   rL   rM   )rE   r5   rF   r   rG   r   rL   rM   )
rE   r5   rF   r   rG   r   rJ   rK   rL   rM   )rH   rX   rJ   rK   rL   rY   )rE   r5   r   r
   r   r   r   r   r   r   rL   r   )r   r   r   r   rL   r   )q__doc__
__future__r   typingr   r   
mypy.nodesr   r   r   r   r	   r
   r   r   r   r   r   r   r   
mypy.typesr   r   mypyc.ir.opsr   r   r   r   r   r   r   r   mypyc.ir.rtypesr   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   mypyc.irbuild.builderr5   mypyc.irbuild.for_helpersr6   r7   r8   r9   "mypyc.irbuild.format_str_tokenizerr:   r;   r<   r=   mypyc.primitives.dict_opsr>   r?   r@   rA   mypyc.primitives.list_opsrB   mypyc.primitives.tuple_opsrC   r[   rD   __annotations__rS   rV   rW   r`   rd   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  rQ   rQ   rQ   rR   <module>   s    <(l
	
	 $

&+-1
