
     !g-                     H   d dl mZmZ d dlZd dlZd dlZd dlZd dlZd dlZdZ	d dl
mZmZmZ d dlmZ ej                   Zej                   Zej"                  Zej&                  Zdddd	d
ddddZdddddddddd	ZedededededededediZej:                  Zej<                  Zeej>                     Z  e!ejE                               Z#g dZ$ G d d      Z%d Z&d Z'd Z( G d d      Z) G d  d!e)      Z*d"Z+d#Z,d$Z- ej\                  e+ d%e, d%e-       Z/dLd'efd(Z0d) Z1dMd*Z2d+ Z3d, Z4d- Z5d. Z6d/ Z7d0 Z8d1 Z9d2 Z:d3 Z;d4 Z<d5 Z=d6d7gZ>dNd8Z?d9i d&fd'efd:Z@dOd'efd;ZAd< ZBd= ZCdLd'efd>ZDdPd?eEfd@ZF edA      ZG edA      ZHi aI ej                         ZK	 	 	 	 	 	 	 dQdBedCee   dDee   dEej                  dFedGed?eEd'ee   dHeeM   fdIZN	 	 	 	 	 	 	 dRdBedCee   dDee   dEej                  dFedGed'ee   d?eEdHej                  fdJZO	 	 	 dPdCee   dDee   d?eEdHej                  fdKZPy)S    )OptionalDictNF)interpreterexpressionsuse_vml)	CacheDictboolintlongfloatdoublecomplexnonestr)bilfdcnsr   r   r   r   r   r   r   r   )	r	   r
   r   r   r   r   bytesr   r   )divinvpowsqrtsincostanarcsinarccosarctansinhcoshtanharcsinharccosharctanhloglog1plog10expexpm1absolute	conjugatearctan2fmodceilfloorc                   V    e Zd ZdZg dZddZd Zd Zd Zd Z	d	 Z
d
 Zd Zd Zd Zy)ASTNodea  Abstract Syntax Tree node.

    Members:

    astType      -- type of node (op, constant, variable, raw, or alias)
    astKind      -- the type of the result (bool, float, etc.)
    value        -- value associated with this node.
                    An opcode, numerical value, a variable name, etc.
    children     -- the children below this node
    reg          -- the register assigned to the result for this node.
    astTypeastKindvaluechildrenNc                 \    || _         || _        || _        t        |      | _        d | _        y N)r8   r9   r:   tupler;   reg)selfr8   r9   r:   r;   s        2lib/python3.12/site-packages/numexpr/necompiler.py__init__zASTNode.__init__Y   s)    
h    c                     | j                   dk(  r| j                  } |j                   dk(  r|j                  }t        |t              sy| j                  D ]  }t        | |      t        ||      k7  s y y)NaliasFT)r8   r:   
isinstancer6   cmpnamesgetattr)r@   othernames      rA   __eq__zASTNode.__eq__`   se    <<7"::D==G#KKE%)MMDtT"geT&:: " rC   c                 2   | j                   dk(  rq| j                  |j                  k(  r?t        j                  | j                        t        j                  |j                        k  S | j                  |j                  k  S t        d| j                   z        )Nconstantz'Sorting not implemented for astType: %s)r8   r9   numpyarrayr:   	TypeError)r@   rI   s     rA   __lt__zASTNode.__lt__l   sm    
 <<:%||u}},{{4::.U[[1III<<%--//EdllRSSrC   c                     | j                   dk(  r| j                  } t        | j                   | j                  | j                  | j                  f      S )NrE   )r8   r:   hashr9   r;   r@   s    rA   __hash__zASTNode.__hash__x   s;    <<7"::DT\\4<<T]]KLLrC   c                     d| j                   d| j                  d| j                  d| j                  d| j                  dS )NzAST(, ))r8   r9   r:   r;   r?   rT   s    rA   __str__zASTNode.__str__}   s.    ,0LL$,,,0JJtxxQ 	QrC   c                     dt        |       z  S )Nz<AST object at %s>)idrT   s    rA   __repr__zASTNode.__repr__   s    #bh..rC   c                 ^    | j                   | j                  | j                  | j                  fS r=   r7   rT   s    rA   keyzASTNode.key   s!    dllDJJFFrC   c                 (    t         | j                     S r=   )kind_to_typecoder9   rT   s    rA   typecodezASTNode.typecode   s    --rC   c              #   h   K   | j                   D ]  }|j                         D ]  }|   |  y wr=   )r;   postorderWalk)r@   r   ws      rA   rc   zASTNode.postorderWalk   s1     A__& '  
s   02c              '   r   K   t        |      }| j                         D ]  }|j                  |v s|  y wr=   )setrc   r8   )r@   astTypesrd   s      rA   allOfzASTNode.allOf   s3     x=##%AyyH$ &s   -77)genericunknownN )__name__
__module____qualname____doc__rG   rB   rK   rQ   rU   rY   r\   r^   ra   rc   rh   rk   rC   rA   r6   r6   K   sD    
 ;H

TM
Q/G.rC   r6   c                     t        | j                  | j                  | j                  | j                  D cg c]  }t        |       c}      S c c}w )zTake an expression tree made out of expressions.ExpressionNode,
    and convert to an AST tree.

    This is necessary as ExpressionNode overrides many methods to act
    like a number.
    )r6   r8   r9   r:   r;   expressionToAST)exr   s     rA   rq   rq      sA     2::rzz28802<1OA&<> ><s   Ac              #      K   d}| sd y| d   |v r9|j                  | d         }||d D ]  }t        | dd       D ]	  }||z      y| d   dk(  rt        | dd       D ]	  }d|z     y|  yw)zSGenerate all possible signatures derived by upcasting the given
    signature.
    bilfdc r   N   r   )indexsigPerms)r   codesstartxys        rA   rx   rx      s      E	
1AaD!uvAae_!e %  
1!AB%A'M ! s   A2A4c                 0   t        | j                        }| j                  dk(  r| j                         }dj	                  d t        | j                        D              }t        |      D ]:  }| j                  dz   |z   |z   j                  d      }|t        j                  v s: n t        |      D ]s  }| j                  dz   |z   |z   j                  d      }|t        j                  v s:d||z   z  j                  d      }|t        ddt        j                  |         gz  } n" t        d	| j                  dz   |z   |z   z        t        t        ||            D ]^  \  }\  }}	||	k7  st        |	   }
||   j                  d
k(  rt        d
|
||   j                        ||<   Hd}t        d|
|||   g      ||<   ` n| j                  }| j                  }t        | j                  | j                   ||D cg c]  }t#        |       c}      S c c}w )zAssign appropriate types to each node in the AST.

    Will convert opcodes and functions to appropriate upcast version,
    and add "cast" ops if needed.
    opru   c              3   <   K   | ]  }|j                           y wr=   )ra   ).0r{   s     rA   	<genexpr>z!typeCompileAst.<locals>.<genexpr>   s     C0B1!**,0Bs   _asciizfunc_%snrawr   z&couldn't find matching opcode for '%s'rM   cast)listr;   r8   ra   joinrx   r:   encoder   opcodes	funccodesr6   NotImplementedError	enumerateziptypecode_to_kindr9   typeCompileAst)astr;   retsigbasesigsigr:   funcnamer   havewantkindopnamer   s                rA   r   r      s    CLL!H
{{d''CS\\0BCCG$CYY_v-3;;GDE+++ %
  (IIOf4s:BB7K{444'6C<8@@IE)4)>)>x)H"J !K KH ) *<yy3/'9;< <  )Wc):;OA|dt|'-A;&&*4")*dHQK<M<M"NHQK#F")$fx{m"LHQK  < 		<<3;;U/78x!N1%x8: :8s   :Hc                   $    e Zd ZdZddZd Zd Zy)RegisteraM  Abstraction for a register in the VM.

    Members:
    node          -- the AST node this corresponds to
    temporary     -- True if this isn't an input or output
    immediate     -- not a register, but an immediate value
    n             -- the physical register number.
                     None if no number assigned yet.
    c                 <    || _         || _        d| _        d | _        y )NF)node	temporary	immediater   )r@   astnoder   s      rA   rB   zRegister.__init__   s    	"rC   c                     | j                   rd}nd}|d| j                  j                  d| j                  j                  d| j                  dS )N	Temporaryr   (rW   rX   )r   r   r8   r9   r   )r@   rJ   s     rA   rY   zRegister.__str__   s?    >>DD#'):):#'99#4#4dff? 	?rC   c                 "    | j                         S r=   )rY   rT   s    rA   r\   zRegister.__repr__   s    ||~rC   N)F)rl   rm   rn   ro   rB   rY   r\   rk   rC   rA   r   r      s    ?rC   r   c                       e Zd ZdZd Zd Zy)	ImmediatezQRepresentation of an immediate (integer) operand, instead of
    a register.
    c                 >    t         j                  | |       d| _        y )NT)r   rB   r   )r@   r   s     rA   rB   zImmediate.__init__  s    $(rC   c                 6    d| j                   j                  fz  S )NzImmediate(%d))r   r:   rT   s    rA   rY   zImmediate.__str__  s    $))//!333rC   N)rl   rm   rn   ro   rB   rY   rk   rC   rA   r   r      s    4rC   r   z[\;\[\:]z(^|[^\w])__[\w]+__($|[^\w])z-\.\b(?!(real|imag|(\d*[eE]?[+-]?\d+)|\d*j)\b)|Tsanitizec                 4   |rRt        j                  dd|       }t        j                  dd|      }t        j                  |      t	        d|  d      t
        j                  j                         }	 t
        j                  j                  |       |j                  dd      rt        j                  j                  }nd	}t        | d
d|      }i }	|j                  D ]Y  }
|
dk(  rd|	|
<   |
dk(  rd|	|
<   |
dk(  rd|	|
<   $|j                  |
t              }t        j                   |
t"        |         |	|
<   [ |	j%                  t
        j&                         t)        ||	      }t        j*                  |      r*t        j,                  |t        j.                  |            }n1t1        |t
        j2                        st5        dt7        |      z        t
        j                  j                  |       |S # t
        j                  j                  |       w xY w)z>Given a string, convert it to a tree of ExpressionNode's.
    z\s+ru   z(\'[^\']*\')NzExpression z" has forbidden control characters.truedivFr   z<expr>evalNoneTrueTFalsezunsupported expression type: %s)resub_blacklist_research
ValueErrorr   _contextget_current_contextset_new_contextget
__future__divisioncompiler_flagcompileco_namesdefault_typeVariableNodetype_to_kindupdate	functionsr   
isConstantConstantNodegetKindrF   ExpressionNoderP   type)r   typescontextr   no_whitespaceskip_quotesold_ctxflagsr   namesrJ   trr   s                rA   stringToExpressionr     s    vr1-ff_b-@,8{1#-OPQQ""668G6,,W5;;y%(''55EEAx/JJDv~"d"d#dIIdL1)66t\!_Md  	[**+ !U^!!"%))"k.A.A".EFBB : :;=RHII,,W5I 	,,W5s   4E!G6 6!Hc                 0     d}t         fd|D              S )N)s   sum_s   prod_s   min_s   max_c              3   T   K   | ]  }j                   j                  |       ! y wr=   )r:   
startswith)r   pr   s     rA   r   zisReduction.<locals>.<genexpr>B  s!     91syy##A&s   %()any)r   prefixess   ` rA   isReductionr   @  s    4H9999rC   c                 4   i }| j                  d      D ]  }|||j                  <    t        |j                               }|r#|t        |      k7  rt	        d|d|d      |}nt        |      }|j                          |D cg c]  }||   	 }}|S c c}w )zC
    Derive the input order of the variables in an expression.
    variablezinput names (z)) don't match those found in expression (rX   )rh   r:   rf   keysr   r   sort)r   input_order	variablesavariable_namesordered_namesvordered_variabless           rA   getInputOrderr   E  s     IYYz"	!'' #)*NS--01 1 $^,/<=}!1}= >s   Bc                     |dk(  rt        j                  |       S t        | t              r| j	                  d      S t        |   |       S )Nr   r   )rN   float32rF   r   r   kind_to_type)r{   r   s     rA   convertConstantToKindr   \  sA    w}}Q	Ac	xx  a  rC   c                 ,   t        | j                  d      D cg c]  }|j                   c}      }t        |D cg c]  }|j                   c}      }|D cg c]"  }t        |j                  |j                        $ }}||fS c c}w c c}w c c}w )z
    RAM: implemented magic method __lt__ for ASTNode to fix issues
    #88 and #209. The following test code works now, as does the test suite.

        import numexpr as ne
        a = 1 + 3j; b = 5.0
        ne.evaluate('a*2 + 15j - b')
    rM   )rf   rh   r?   sortedr   r   r:   r9   )r   r   constant_registersrconstants_orderr   	constantss          rA   getConstantsr   e  s     399Z3HI3H4dhh3HIJ.@A.@aff.@ABO)+)Q 'qww		:)  +I%%	 JA+s   BB'Bc                     i }t        |      D ]  \  }\  }}}|||<    | D cg c]  }||j                     |f }}|j                          |D cg c]  }|d   	 c}S c c}w c c}w )Nrv   )r   r:   r   )	nodesorder	order_mapr   r   r   r   	dec_nodesr   s	            rA   sortNodesByOrderr   u  sv    I!%(9Aq!	! )278%Q)AGG$a(%I8NN#$)QAaD)$$ 9$s   A A%c                 x    i }| D ]3  }|j                         }||v r||   |_        " ||      x|_        ||<   5 y)z9
    Assign new registers to each of the leaf nodes.
    N)r^   r?   )inodesregisterMakerleafRegistersr   r^   s        rA   assignLeafRegistersr   ~  sH     Mhhj-$S)DH,9$,??DH}S) rC   c                 0    | D ]  } ||d      |_          y)zA
    Assign temporary registers to each of the branch nodes.
    T)r   Nr?   )r   r   r   s      rA   assignBranchRegistersr     s      6 rC   c                 P   i }g }| j                  d      D ]7  }||v r,||   }d|_        ||_        d|_        |j	                  |       3|||<   9 |D ]Q  }|j                  j                  dk(  s|j                  j                  |_        |j                  j                  dk(  r5S |S )z+
    Common subexpression elimination.
    r~   rE   rk   )rh   r8   r:   r;   append)r   seenaliasesr   targets        rA   collapseDuplicateSubtreesr    s     DGYYt_9!WFAIAGAJNN1DG  ggoo(ggmmAG ggoo(  NrC   c                 D   | j                         D cg c]  }|j                  j                  s| }}t        d |D              }t        d |D              }|r|d   | ur|| gz   }n|}|D ]H  }|j                  D ]7  }|j                  j                  s||j                     j                  |       9 J t        t        D cg c]  }|t               f c}      }|D ]  }|j                  D ]\  }|j                  }	|	j                  s||	   }
|
j                  |       |
r5||	j                  j                     j                  |	       ^ ||j                     s~||j                     j                         }	||j                     ||	<   |	|_         yc c}w c c}w )zT
    Attempt to minimize the number of temporaries needed, by reusing old ones.
    c              3   H   K   | ]  }|j                   t               f  y wr=   )r?   rf   r   r   s     rA   r   z0optimizeTemporariesAllocation.<locals>.<genexpr>  s     2EqQUUCENEs    "c              3   X   K   | ]"  }|t        d  |j                  D              f $ yw)c              3   b   K   | ]'  }|j                   j                  s|j                    ) y wr=   )r?   r   )r   r   s     rA   r   z:optimizeTemporariesAllocation.<locals>.<genexpr>.<genexpr>  s     JJq!%%//QUUJs   //N)rf   r;   r  s     rA   r   z0optimizeTemporariesAllocation.<locals>.<genexpr>  s,      %# JAJJJJK#s   (*N)rc   r?   r   dictr;   addscalar_constant_kindsrf   discardr   r9   pop)r   r   r   users_of	node_regsnodes_to_checkr   tcunusedr?   userss              rA   optimizeTemporariesAllocationr    su    ))+?+1quuQ+E?2E22H %#% %Ir#%#Auu##A&  
 )>?)>2B;)>?@FA%%C}} a 388++,005  !))#'')C$QUUOHSMAE  @ @s   FFFc                 l    t        |       D ]  \  }}||z   |j                  _         |t        |       z   S )z;
    Given an order of nodes, assign register numbers.
    )r   r?   r   len)r   rz   r   r   s       rA   setOrderedRegisterNumbersr    s5     U#4QY
 $3u:rC   c                    d}d}g }| j                         D ]  }|j                  dk(  r|j                  |       |j                  }|j                  j
                  r|j                  |j                  _        a|j                  }|j                  z||z   |_        |dz  }||j                  j                         z  } |D ]  }|j                  j                  |_         ||z   |fS )zx
    Assign register numbers for temporary registers, keeping track of
    aliases and handling immediate operands.
    r   ru   rE   rv   )	rc   r8   r   r:   r?   r   r   r   ra   )r   rz   r   	signaturer   r   r?   s          rA    setRegisterNumbersForTemporariesr    s    
 DIG!!#<<7"NN4 ::D88DHHJhh55=DLCEAID**,,I $ ::>> 4<""rC   c                     | j                  d      D cg c]H  }|j                  |j                  ft        |j                  D cg c]  }|j                   c}      z   J c}}S c c}w c c}}w )a  
    Convert an AST to a three address form.

    Three address form is (op, reg1, reg2, reg3), where reg1 is the
    destination of the result of the instruction.

    I suppose this should be called three register form, but three
    address form is found in compiler theory.
    r~   )rh   r:   r?   r>   r;   )r   r   r   s      rA   convertASTtoThreeAddrFormr    sb     		$)' ZZ"U4==+I=aAEE=+I%JJ') )+I )s   /A+A&A+&A+c                 z    d dfd	fd}dj                  | D cg c]
  } ||       c}      }|S c c}w )ze
    Given a three address form of the program, compile it a string that
    the VM understands.
    c                     | y| j                   dk  rt        d| j                   z        t        | j                   g      S )N   r   z%negative value for register number %s)r   r   r   r   s    rA   nToChrz$compileThreeAddrForm.<locals>.nToChr  s:    ;UUQYDsuuLMM#%%>!rC   c                     t        t        j                  |          j                  d      } |      } |      } |      }||z   |z   |z   S )Nr   )chrr   r   r   )	opcodestorea1a2copcsca1ca2r   s	           rA   quadrupleToStringz/compileThreeAddrForm.<locals>.quadrupleToString	  sQ    +%%f-.55g>E]RjRjRx#~##rC   c                     t        |       dk  r| dz  } t        |       dk  r| d d \  }}}} ||||      }|g}| dd  } | r% dg| d d  }|j                  |       | dd  } | r%dj                  |      S )N   r=   s   noop   rC   )r  r   r   )argsr#  r$  r%  r&  r   r   r+  s          rA   toStringz&compileThreeAddrForm.<locals>.toString  s    $i!mGOD $i!m $Rar2feR4CABx!'5D!H5AHHQK8D  xx{rC   rC   )NN)r   )programr0  r   prog_strr   r+  s       @@rA   compileThreeAddrFormr3    s?    "$ xxg6g!g67HO 7s   8)optimization)r   moderate
aggressiver6  )r   )FTautor7  c                    | j                         }i }t        D ]2  \  }}}|j                  ||      }||v r|||<   #t        d|d|       |rt        d|j	                         d   z        |d   dk(  rHt        j                  |dz         j                  }|j                  dd       t        j                  k(  |d<   |S )	N'z' must be one of zUnknown keyword argument '%s'r   r   r7  rv   r   )copycontext_infor  r   popitemsys	_getframe	f_globalsr   r   r   )	kwargs_frame_depthr   r   rJ   alloweddefaultr:   caller_globalss	            rA   
getContextrE  '  s    AG".gwdG$G!GDMwGHH #/ 	8199;q>IJJyV#|a'78BB+//
DAZEXEXX	NrC   rk   c                    t        |      |D cg c]  \  }}|	 }}}t        | t              rt        | ||      } t	        |       }| j
                  dk7  rt        dd| j                  |f      }t        |      }t        |      }t        |j                  d      t               t        |j                  dd      t               t        |j                  d      t               |D ]  }	|	j                  j                   |	_         t#        ||      }t%        |      \  }
}t'        |      rd|j                   _        t+        |       d|j                   _        d}d|j                   _        |d	z   }t/        ||      }t/        |
|      }t1        ||      \  }}t3        |      }t5        |D 	cg c]  }	|	j                   c}	      }d
j7                  fd|D              }|||||fS c c}}w c c}	w )z9
    Compile the expression to an intermediate form.
    r~   r:  )r:   r9   r;   r   r   rM   Fr   rv   ru   c              3   X   K   | ]!  }t         j                  |t                  # y wr=   )type_to_typecoder   r   )r   r{   r   s     rA   r   zprecompile.<locals>.<genexpr>k  s)      .!,A )1l)CD!,s   '*)r	  rF   r   r   rq   r8   r6   r9   r   r  r   rh   r   r   r   r:   r?   r   r   r   r   r  r   r  r  r  r>   r   )rr   r  r   r   rJ   type_r   r   r   r   r   r   r_outputr_inputsr_constantsr_tempsr_endtempsigthreeAddrPrograminput_namesr   s                       @rA   
precompilerR  :  s    OE-67YMT54YK7"cE7H=
 "
C	zzTd&"**vN

C',G		%()4		*j98D#))D/84    [1K!-c!2OY3!!#&CGGHCGGI!|H+KBK'EG5c7CNE705+6+Q+67K .!,. .IYKGG] 8V 7s   G).G/c                     d}t        ||      }t        | |||      \  }}}}	}
t        |      }t        j                  |j                  d      |j                  d      ||	|
      S )aY  
    Compile an expression built using E.<variable> variables to a function.

    ex can also be specified as a string "2*a+3*b".

    The order of the input variables and their types can be specified using the
    signature parameter, which is a list of (name, type) pairs.

    Returns a `NumExpr` object containing the compiled function.
    rv   rA  r   r   )rE  rR  r3  r   NumExprr   )rr   r  r   r@  rA  r   rP  inputsigrO  r   rQ  r1  s               rA   rV  rV  p  sr     Ll;GBLRQZ\cnvBw?hK"#34Gxw7&~~g6&	;@ @rC   c           	      n   	
 i t         j                  D ]  }|t         j                  |   <    dt         j                        z   

t         j                        z   d 	 	
fd}g }t        dt         j                        d      D ]  }j                   j                  |         } 	|      \  }}|g}t        t        |            D ]  }|j                   ||d|z                 t        |      dk  r |j                  d       t        |      dk  r |j                  |        |S )zR
    Given a NumExpr object, return a list which is the program disassembled.
    rv   c                 B    g | j                  dd      dd d \  }}||fS )N   _rv   ru      )rsplit)r~   rJ   r   s      rA   parseOpzdisassemble.<locals>.parseOp  s1    -biia(-"-bq1	cSyrC   c                    j                   | |dk  r|n|dz   z      } 
j                  j                   |                \  }}	 ||dz
     }t        |g      }|dk(  ry |dk7  rq|dk(  ry|k  r&d|j                  |dz
     fz  j                  d      S |	k  r&d	|j                  |z
     fz  j                  d      S d
|fz  j                  d      S |S # t        $ r Y y w xY w)Nr-  rv         nr   s   r0zr%d[%s]r   zc%d[%s]zt%d)r1  r   
IndexErrorr   rQ  r   r   )pcoffsetargr   r   codenexr]  rL  rM  rev_opcodess         rA   getArgzdisassemble.<locals>.getArg  s   kk"&1*&(CDR9:3	vz?D dV}#:4<ax{"!S#//#'*B$CCKKGTTw!S#--k8I*J$KKSST[\\..w77J#  		s   C 	C$#C$r   r-  N)	r   r   r  r  r   ranger1  r   r   )rf  r~   rh  sourcerb  r   r   parsedr   r]  rL  rM  rg  s   `        @@@@rA   disassemblerl    s    K!!/1K''+, "c#--((KC..G 0 FAs3;;'+__S[[_-3s3xAMM&QU+, !&kAoMM$ &kAof , MrC   c                    | j                   j                  }|dk(  rt        S |dv rI| j                   j                  dkD  rt        S |dk(  r| j                   j                  dk(  rt        S t
        S |dk(  r%| j                   j                  dkD  rt        S t        S |dk(  rt        S |dk(  rt        S |dk(  rt        d	      t        d
| j                   j                  z        )Nr   iur-  ur   r   SUz.NumExpr 2 does not support Unicode as a dtype.zunknown type %s)dtyper   r	   itemsizelong_int_r   r   r   r   r   rJ   )r   r   s     rA   getTyperv    s    77<<Ds{t|77aL3;177++q0Ls{77aMs{s{s{IJJ
&5
66rC   c                    t        | i ||      }t        |      }t        |d       }t        sd}n=|j	                         D ](  }|j
                  dk(  s|j                  t        v s&d} n d}|D cg c]  }|j                   c}|fS c c}w )NFr~   T)r   rq   r   r   rc   r8   r:   vml_functions)	textr   r   rr   r   r   ex_uses_vmlr   r   s	            rA   getExprNamesr{    s    	D"gx	8B
"
CT*K%%'D||t#

m(C" (
  K()[AGG[);66)s   0BrA  c                    t        j                  |      }d}||j                  }d}	 |j                  }||}|xr ||u}g }| D ],  }	 ||   }	|j                  t        j                  |	             . 	 |rt        |d      r|j                          |S # t        $ r ||   }	Y Ww xY w# |rt        |d      r|j                          w w w xY w)z/
    Get the arguments based on the names.
    FTclear)
r=  r>  f_localsr?  KeyErrorr   rN   asarrayhasattrr}  )
r   
local_dictglobal_dictrA  
call_frameclear_local_dictframe_globals	argumentsrJ   r   s
             rA   getArgumentsr    s     |,J((
",,'K ,OMZ4O	D&t$ U]]1-.  
G <  &%& 
G < !=s/   B) 	B&B) B&#B) %B&&B) )"C   rr   r  r  outr   castingreturnc                    	 t        | t              st        d      |:dt        j                  v r&t        t        t        j                  d               }nd}t        |      }	| t        t        |	j                                     f}
|
t        vrt        | |	|      t        |
<   t        |
   \  }}t        ||||      }t        ||      D cg c]  \  }}|t        |      f }}}|
t        |      fz   }	 t         |   }||||d}t'        |||	      ayc c}}w # t"        $ r t%        | |fd|i|	x}t         |<   Y ?w xY w# t*        $ r}|cY d}~S d}~ww xY w)
a  
    Validate a NumExpr expression with the given `local_dict` or `locals()`.
    Returns `None` on success and the Exception object if one occurs. Note that 
    you can proceed directly to call `re_evaluate()` if you use `validate()`
    to sanitize your expressions and variables in advance.

    Parameters
    ----------
    ex: str
        a string forming an expression, like "2*a+3*b". The values for "a"
        and "b" will by default be taken from the calling function's frame
        (through use of sys._getframe()). Alternatively, they can be specified
        using the 'local_dict' or 'global_dict' arguments.

    local_dict: dictionary, optional
        A dictionary that replaces the local operands in current frame.

    global_dict: dictionary, optional
        A dictionary that replaces the global operands in current frame.

    out: NumPy array, optional
        An existing array where the outcome is going to be stored.  Care is
        required so that this array has the same shape and type than the
        actual outcome of the computation.  Useful for avoiding unnecessary
        new array allocations.

    order: {'C', 'F', 'A', or 'K'}, optional
        Controls the iteration order for operands. 'C' means C order, 'F'
        means Fortran order, 'A' means 'F' order if all the arrays are
        Fortran contiguous, 'C' order otherwise, and 'K' means as close to
        the order the array elements appear in memory as possible.  For
        efficient computations, typically 'K'eep order (the default) is
        desired.

    casting: {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
        Controls what kind of data casting may occur when making a copy or
        buffering.  Setting this to 'unsafe' is not recommended, as it can
        adversely affect accumulations.

          * 'no' means the data types should not be cast at all.
          * 'equiv' means only byte-order changes are allowed.
          * 'safe' means only casts which can preserve values are allowed.
          * 'same_kind' means only safe casts or casts within a kind,
            like float64 to float32, are allowed.
          * 'unsafe' means any data conversions may be done.

    sanitize: Optional[bool]
        Both `validate` and by extension `evaluate` call `eval(ex)`, which is 
        potentially dangerous on unsanitized inputs. As such, NumExpr by default 
        performs simple sanitization, banning the character ':;[', the 
        dunder '__[\w+]__', and attribute access to all but '.real' and '.imag'.
        
        Using `None` defaults to `True` unless the environment variable 
        `NUMEXPR_SANITIZE=0` is set, in which case the default is `False`. 
        Nominally this can be set via `os.environ` before `import numexpr`.

    _frame_depth: int
        The calling frame depth. Unless you are a NumExpr developer you should 
        not set this value.

    Note
    ----
    
    z#must specify expression as a stringNNUMEXPR_SANITIZETrU  rT  r   )r  r   r  rz  )rr   argnamesr@  )rF   r   r   osenvironr	   r
   rE  r>   r   items_names_cacher{  r  r   rv  _numexpr_cacher  rV  r	  _numexpr_last	Exception)rr   r  r  r  r   r  rA  r   r@  r   expr_keyr   rz  r  rJ   rd  r  numexpr_keycompiled_exes                       rA   validater    s~   V!"c"BCC!RZZ/BJJ/A$B CD V$fW]]_567<'%1"g%QL")(3{ 
Kl[	 y)+) /:tSdGCL)) 	 + %	"2!44	m(5K u*,eFK +  	m8?I8lX`8ldk8llK.5	m
  sT   CE D&E 9	D E E !E?E EE 	EEEEc                 N    t        | f|||||||d|}	|	t        |||      S |	)a  
    Evaluate a simple array expression element-wise using the virtual machine.

    Parameters
    ----------
    ex: str
        a string forming an expression, like "2*a+3*b". The values for "a"
        and "b" will by default be taken from the calling function's frame
        (through use of sys._getframe()). Alternatively, they can be specified
        using the 'local_dict' or 'global_dict' arguments.

    local_dict: dictionary, optional
        A dictionary that replaces the local operands in current frame.

    global_dict: dictionary, optional
        A dictionary that replaces the global operands in current frame.

    out: NumPy array, optional
        An existing array where the outcome is going to be stored.  Care is
        required so that this array has the same shape and type than the
        actual outcome of the computation.  Useful for avoiding unnecessary
        new array allocations.

    order: {'C', 'F', 'A', or 'K'}, optional
        Controls the iteration order for operands. 'C' means C order, 'F'
        means Fortran order, 'A' means 'F' order if all the arrays are
        Fortran contiguous, 'C' order otherwise, and 'K' means as close to
        the order the array elements appear in memory as possible.  For
        efficient computations, typically 'K'eep order (the default) is
        desired.

    casting: {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
        Controls what kind of data casting may occur when making a copy or
        buffering.  Setting this to 'unsafe' is not recommended, as it can
        adversely affect accumulations.

          * 'no' means the data types should not be cast at all.
          * 'equiv' means only byte-order changes are allowed.
          * 'safe' means only casts which can preserve values are allowed.
          * 'same_kind' means only safe casts or casts within a kind,
            like float64 to float32, are allowed.
          * 'unsafe' means any data conversions may be done.

    sanitize: bool
        Both `validate` and by extension `evaluate` call `eval(ex)`, which is 
        potentially dangerous on unsanitized inputs. As such, NumExpr by default 
        performs simple sanitization, banning the character ':;[', the 
        dunder '__[\w+]__', and attribute access to all but '.real' and '.imag'.

        Using `None` defaults to `True` unless the environment variable 
        `NUMEXPR_SANITIZE=0` is set, in which case the default is `False`. 
        Nominally this can be set via `os.environ` before `import numexpr`.

    _frame_depth: int
        The calling frame depth. Unless you are a NumExpr developer you should 
        not set this value.

    Note
    ----
    Both `validate` and by extension `evaluate` call `eval(ex)`, which is 
    potentially dangerous on unsanitized inputs. As such, NumExpr does some 
    sanitization, banning the character ':;[', the dunder '__', and attribute
    access to all but '.r' for real and '.i' for imag access to complex numbers.
    )r  r  r  r   r  rA  r   )r  r  rA  )r  re_evaluate)
rr   r  r  r  r   r  r   rA  r@  r  s
             rA   evaluater    sM    X 	 	I
w*X	IAG	IA 	yjkXdeerC   c                     	 t         d   }t         d   }t        || ||      }t         d   }t        5   ||i |cddd       S # t        $ r t        d      w xY w# 1 sw Y   yxY w)a!  
    Re-evaluate the previous executed array expression without any check.

    This is meant for accelerating loops that are re-evaluating the same
    expression repeatedly without changing anything else than the operands.
    If unsure, use evaluate() which is safer.

    Parameters
    ----------
    local_dict: dictionary, optional
        A dictionary that replaces the local operands in current frame.
    _frame_depth: int
        The calling frame depth. Unless you are a NumExpr developer you should 
        not set this value.
    rr   zmA previous evaluate() execution was not found, please call `validate` or `evaluate` once before `re_evaluate`r  rT  r@  N)r  r  RuntimeErrorr  evaluate_lock)r  r  rA  r  r  r/  r@  s          rA   r  r    s    (L#D) Z(H*kUD8$F	D+F+ 
  L  K  L  	LL
 
s   	A AAA%)Tr=   )rv   )rk   T)NNr[  )NNNKsafer[  N)NNNr  r  Nr.  )Qtypingr   r   r   r=  r  	threadingr   rN   is_cpu_amd_intelnumexprr   r   r   numexpr.utilsr   r   int32ru  int64rt  r   r`   r	   r   r   r   r   rH  r   r   default_kindr   r   r   r  rx  r6   rq   rx   r   r   r   	_flow_pat_dunder_pat	_attr_patr   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r3  r;  rE  rR  rV  rl  rv  r{  r
   r  r  r  r  Lockr  ndarrayr  r  r  r  rk   rC   rA   <module>r     s   "  
 	  	   5 5 # 
	{{e&wX"e= S3RU"ScK #tS%eSC#uc3E ''''K445-2245 @I IX>&(:V :
4 
4 	,<	

i[+a	{CD.D .b:
.!& %
@7.B#2)#N G.&  D 3Ht 3Hl@ @00f7.7$ 7$! !J ~3	 
 +/+/"&"!"(,m m!$m"4.m --m 	m
 m m  ~m #9-m` +/+/"&"(,!"R R!$R"4.R --R 	R
 R  ~R R  --Rh .2.2"#,HTN ,%d^,!,(-,rC   