U
    MZf~?                     @  sx  d Z ddlmZ ddlmZ ddlmZ ddlZddlmZm	Z	m
Z
mZ ddlZddlmZ ddlmZmZ ddlm  mZ dd	lmZmZ dd
lmZ ddlmZmZ dZdZ dZ!e e! Z"dZ#G dd dZ$G dd de$Z%ddddZ&G dd dZ'dd Z(dd Z)dZ*ej+ej,ej-ej.ej/ej0e(e)fZ1e2e3e*e1Z4dZ5ej6ej7ej6ej7fZ8e2e3e5e8Z9d Z:ej;ej<ej=ej>ej?ej@ejAfZBe2e3e:eBZCd!ZDej?ej@ejAfZEe2e3eDeEZFi ZGe4e9eCfD ]ZHeGIeH qd"d#d$d%ZJd&d#d'd(ZKG d)d* d*e'ZLd&d#d+d,ZMG d-d. d.eLZNd/ZOejPejQejRejRfZSe2e3eOeSZTG d0d1 d1e'ZUG d2d3 d3e'ZVG d4d5 d5ZWdS )6z
Operator classes for eval.
    )annotations)datetime)partialN)CallableIterableIteratorLiteral)	Timestamp)is_list_like	is_scalar)ensure_decodedresult_type_many)DEFAULT_GLOBALS)pprint_thingpprint_thing_encoded)sumprodminmax)sincosexplogexpm1log1psqrtsinhcoshtanhZarcsinZarccosZarctanZarccoshZarcsinhZarctanhabslog10floorceil)Zarctan2Z__pd_eval_local_c                      s  e Zd ZU d' fdd	Zded< d(dddd	Zed
dddZd
dddZdd Z	d dddZ
dd ZddddZeddddZedd ZeZed
dddZeddddZedd  Zejddd!d Zed"d# Zed$dd%d&Z  ZS ))TermNc                   s&   t |tstn| }tt|j}||S N)
isinstancestrConstantsuperr#   __new__)clsnameenvsideencodingklassZsupr_new	__class__ ?/tmp/pip-unpacked-wheel-nbcvw55c/pandas/core/computation/ops.pyr)   G   s    zTerm.__new__boolis_localNonereturnc                 C  sB   || _ || _|| _t|}|tp*|tk| _|  | _	|| _
d S r$   )_namer,   r-   r&   
startswith	LOCAL_TAGr   r5   _resolve_name_valuer.   )selfr+   r,   r-   r.   Ztnamer2   r2   r3   __init__O   s    
zTerm.__init__r&   c                 C  s   | j tdS )N )r+   replacer;   r>   r2   r2   r3   
local_nameY   s    zTerm.local_namec                 C  s
   t | jS r$   )r   r+   rB   r2   r2   r3   __repr__]   s    zTerm.__repr__c                 O  s   | j S r$   valuer>   argskwargsr2   r2   r3   __call__`   s    zTerm.__call__c                 O  s   | S r$   r2   rG   r2   r2   r3   evaluatec   s    zTerm.evaluatec                 C  sl   t | j}| j}|| jjkr2t| jj| tr2d}| jj||d}| | t	|drh|j
dkrhtd|S )NF)r5   ndim   z?N-dimensional objects, where N > 2, are not supported with eval)r&   rC   r5   r,   Zscoper%   typeresolveupdatehasattrrL   NotImplementedError)r>   rC   r5   resr2   r2   r3   r<   f   s    

 
zTerm._resolve_namec                 C  s.   | j }t|tr$| jj| j||d || _dS )z
        search order for local (i.e., @variable) variables:

        scope, key_variable
        [('locals', 'local_name'),
         ('globals', 'local_name'),
         ('locals', 'key'),
         ('globals', 'key')]
        )	new_valueN)r+   r%   r&   r,   ZswapkeyrC   rF   )r>   rF   keyr2   r2   r3   rP   w   s    

zTerm.updatec                 C  s
   t | jS r$   )r   r=   rB   r2   r2   r3   r      s    zTerm.is_scalarc                 C  sX   z| j jjW S  tk
rR   z| j jW  Y S  tk
rL   t| j  Y  Y S X Y nX d S r$   )r=   valuesdtypeAttributeErrorrN   rB   r2   r2   r3   rN      s    z	Term.typec                 C  s$   t | j dt| j d| j  dS )Nz(name=z, type=))rN   __name__reprr+   rB   r2   r2   r3   raw   s    zTerm.rawc                 C  s8   z| j j }W n tk
r&   | j }Y nX t|ttjfS r$   )rN   rX   
issubclassr   np
datetime64r>   tr2   r2   r3   is_datetime   s
    zTerm.is_datetimec                 C  s   | j S r$   r=   rB   r2   r2   r3   rF      s    z
Term.valuec                 C  s
   || _ d S r$   rc   )r>   rT   r2   r2   r3   rF      s    c                 C  s   | j S r$   r9   rB   r2   r2   r3   r+      s    z	Term.nameintc                 C  s   | j jS r$   )r=   rL   rB   r2   r2   r3   rL      s    z	Term.ndim)NN)NN)rZ   
__module____qualname__r)   __annotations__r?   propertyrC   rD   rJ   rK   r<   rP   r   rN   return_typer\   rb   rF   setterr+   rL   __classcell__r2   r2   r0   r3   r#   F   s6   




r#   c                      sF   e Zd Zddd fddZdd Zedd	 Zd
dddZ  ZS )r'   Nr6   r7   c                   s   t  j||||d d S )N)r-   r.   )r(   r?   )r>   rF   r,   r-   r.   r0   r2   r3   r?      s    zConstant.__init__c                 C  s   | j S r$   rd   rB   r2   r2   r3   r<      s    zConstant._resolve_namec                 C  s   | j S r$   rE   rB   r2   r2   r3   r+      s    zConstant.namer&   c                 C  s
   t | jS r$   )r[   r+   rB   r2   r2   r3   rD      s    zConstant.__repr__)NN)	rZ   rf   rg   r?   r<   ri   r+   rD   rl   r2   r2   r0   r3   r'      s
   
r'   ~&|)notandorc                   @  s   e Zd ZU dZded< ddddddd	Zd
dddZddddZedd Z	eddddZ
edd ZeddddZeddddZdS )Opz.
    Hold an operator of arbitrary arity.
    r&   opNzIterable[Term | Op]r6   )rt   operandsr8   c                 C  s   t ||| _|| _|| _d S r$   )_bool_op_mapgetrt   ru   r.   )r>   rt   ru   r.   r2   r2   r3   r?      s    zOp.__init__r   r7   c                 C  s
   t | jS r$   )iterru   rB   r2   r2   r3   __iter__   s    zOp.__iter__c                 C  s(   dd | j D }td| j d|S )zW
        Print a generic n-ary operator and its operands using infix notation.
        c                 s  s   | ]}d t | dV  qdS )(rY   N)r   ).0Zoprr2   r2   r3   	<genexpr>   s     zOp.__repr__.<locals>.<genexpr> )ru   r   rt   join)r>   Zparenedr2   r2   r3   rD      s    zOp.__repr__c                 C  s,   | j tt krtjS tdd t| D  S )Nc                 s  s   | ]}|j V  qd S r$   rN   r{   termr2   r2   r3   r|      s     z!Op.return_type.<locals>.<genexpr>)rt   CMP_OPS_SYMSBOOL_OPS_SYMSr^   bool_r   comflattenrB   r2   r2   r3   rj      s    zOp.return_typer4   c                 C  s(   | j }ttdg}| jtko&|| S )Nobject)operand_types	frozensetr^   rW   rj   r   )r>   typesZobj_dtype_setr2   r2   r3   has_invalid_return_type   s    zOp.has_invalid_return_typec                 C  s   t dd t| D S )Nc                 s  s   | ]}|j V  qd S r$   r   r   r2   r2   r3   r|      s     z#Op.operand_types.<locals>.<genexpr>)r   r   r   rB   r2   r2   r3   r      s    zOp.operand_typesc                 C  s   t dd | jD S )Nc                 s  s   | ]}|j V  qd S r$   )r   )r{   operandr2   r2   r3   r|      s     zOp.is_scalar.<locals>.<genexpr>)allru   rB   r2   r2   r3   r      s    zOp.is_scalarc                 C  s8   z| j j}W n tk
r&   | j }Y nX t|ttjfS r$   )rj   rN   rX   r]   r   r^   r_   r`   r2   r2   r3   rb      s
    zOp.is_datetime)N)rZ   rf   rg   __doc__rh   r?   ry   rD   ri   rj   r   r   r   rb   r2   r2   r2   r3   rs      s   


rs   c                 C  s\   z|  |W S  tk
rV   t| rJz| | W  Y S  tk
rH   Y nX | |k Y S X dS )z`
    Compute the vectorized membership of ``x in y`` if possible, otherwise
    use Python.
    NisinrX   r
   xyr2   r2   r3   _in  s    r   c                 C  s`   z|  | W S  tk
rZ   t| rNz| |  W  Y S  tk
rL   Y nX | |k Y S X dS )zd
    Compute the vectorized membership of ``x not in y`` if possible,
    otherwise use Python.
    Nr   r   r2   r2   r3   _not_in  s    r   )><z>=z<=z==z!=inznot in)rn   ro   rq   rr   )+-*/**//%)r   r   r   r6   r7   c              	   C  s`   t |}| D ]L}|j|krqz|j|}W n  tk
rN   ||j}Y nX || qdS )a$  
    Cast an expression inplace.

    Parameters
    ----------
    terms : Op
        The expression that should cast.
    acceptable_dtypes : list of acceptable numpy.dtype
        Will not cast if term's dtype in this list.
    dtype : str or numpy.dtype
        The dtype to cast to.
    N)r^   rW   rN   rF   ZastyperX   rP   )Ztermsacceptable_dtypesrW   dtr   rT   r2   r2   r3   _cast_inplaceM  s    

r   r4   c                 C  s
   t | tS r$   )r%   r#   )objr2   r2   r3   is_termf  s    r   c                      sT   e Zd ZdZddd fddZdd Zdd	d
dZddddZdd Z  Z	S )BinOpz
    Hold a binary operator and its operands.

    Parameters
    ----------
    op : str
    lhs : Term or Op
    rhs : Term or Op
    r&   r6   rt   r8   c              
     s   t  |||f || _|| _|   |   zt| | _W nH tk
r } z*t	t
 }tdt| d| |W 5 d }~X Y nX d S )NzInvalid binary operator , valid operators are )r(   r?   lhsrhs_disallow_scalar_only_bool_opsconvert_values_binary_ops_dictfuncKeyErrorlistkeys
ValueErrorr[   )r>   rt   r   r   errr   r0   r2   r3   r?   u  s    zBinOp.__init__c                 C  s    |  |}| |}| ||S )z
        Recursively evaluate an expression in Python space.

        Parameters
        ----------
        env : Scope

        Returns
        -------
        object
            The result of an evaluated expression.
        )r   r   r   )r>   r,   leftrightr2   r2   r3   rJ     s    

zBinOp.__call__)enginec                 C  s   |dkr| |}nd| j j|||||d}| jj|||||d}| j|krZ| |j|j}nddlm}	 |	| |||d}||}
||
|dS )al  
        Evaluate a binary operation *before* being passed to the engine.

        Parameters
        ----------
        env : Scope
        engine : str
        parser : str
        term_type : type
        eval_in_python : list

        Returns
        -------
        term_type
            The "pre-evaluated" expression as an instance of ``term_type``
        python)r   parser	term_typeeval_in_pythonr   )eval)Z
local_dictr   r   r,   )	r   rK   r   rt   r   rF   Zpandas.core.computation.evalr   Zadd_tmp)r>   r,   r   r   r   r   rS   r   r   r   r+   r2   r2   r3   rK     s,    
	

zBinOp.evaluater7   c                   s    fdd} j  j }}t|r~|jr~t|r~|jr~|j}t|ttfrR||}t	t
|}|jdk	rr|d} j| t|r|jrt|r|jr|j}t|ttfr||}t	t
|}|jdk	r|d} j | dS )zK
        Convert datetimes to a comparable value in an expression.
        c                   s&    j d k	rtt j d}nt}|| S )N)r.   )r.   r   r   r   )rF   encoderrB   r2   r3   	stringify  s    
z'BinOp.convert_values.<locals>.stringifyNUTC)r   r   r   rb   r   rF   r%   re   floatr	   r   tzZ
tz_convertrP   )r>   r   r   r   vr2   rB   r3   r     s$    



zBinOp.convert_valuesc                 C  sr   | j }| j}|j}t|d|}|j}t|d|}|js<|jrn| jtkrnt|tt	j
frft|tt	j
fsntdd S )NrN   z$cannot evaluate scalar only bool ops)r   r   rj   getattrr   rt   _bool_ops_dictr]   r4   r^   r   rR   )r>   r   r   Zrhs_rtZlhs_rtr2   r2   r3   r     s"    
z$BinOp._disallow_scalar_only_bool_ops)
rZ   rf   rg   r   r?   rJ   rK   r   r   rl   r2   r2   r0   r3   r   j  s   
1!r   c                 C  s   t t| jtjS r$   )r]   r^   rW   rN   number)rW   r2   r2   r3   	isnumeric  s    r   c                      s&   e Zd ZdZdd fddZ  ZS )Divz
    Div operator to special case casting.

    Parameters
    ----------
    lhs, rhs : Term or Op
        The Terms or Ops in the ``/`` expression.
    r6   r7   c                   sj   t  d|| t|jr$t|jsFtd| j d|j d|j dtjtjg}t	t
| |tj d S )Nr   z unsupported operand type(s) for z: 'z' and '')r(   r?   r   rj   	TypeErrorrt   r^   Zfloat32Zfloat_r   r   r   )r>   r   r   r   r0   r2   r3   r?     s    zDiv.__init__)rZ   rf   rg   r   r?   rl   r2   r2   r0   r3   r     s   	r   )r   r   rm   rp   c                      sV   e Zd ZdZddd fddZddd	d
ZddddZeddddZ  Z	S )UnaryOpaK  
    Hold a unary operator and its operands.

    Parameters
    ----------
    op : str
        The token used to represent the operator.
    operand : Term or Op
        The Term or Op operand to the operator.

    Raises
    ------
    ValueError
        * If no function associated with the passed operator token is found.
    zLiteral[('+', '-', '~', 'not')]r6   r   c              
     sf   t  ||f || _zt| | _W n< tk
r` } ztdt| dt |W 5 d }~X Y nX d S )NzInvalid unary operator r   )	r(   r?   r   _unary_ops_dictr   r   r   r[   UNARY_OPS_SYMS)r>   rt   r   r   r0   r2   r3   r?   4  s    zUnaryOp.__init__MathCallr7   c                 C  s   |  |}| |S r$   )r   r   )r>   r,   r   r2   r2   r3   rJ   @  s    
zUnaryOp.__call__r&   c                 C  s   t | j d| j dS )Nrz   rY   )r   rt   r   rB   r2   r2   r3   rD   E  s    zUnaryOp.__repr__znp.dtypec                 C  sR   | j }|jtdkr tdS t|trH|jtks>|jtkrHtdS tdS )Nr4   re   )	r   rj   r^   rW   r%   rs   rt   _cmp_ops_dictr   )r>   r   r2   r2   r3   rj   H  s    


zUnaryOp.return_type)
rZ   rf   rg   r   r?   rJ   rD   ri   rj   rl   r2   r2   r0   r3   r   #  s   r   c                      s8   e Zd Zdd fddZdd Zdddd	Z  ZS )
r   r6   r7   c                   s   t  |j| || _d S r$   )r(   r?   r+   r   )r>   r   rH   r0   r2   r3   r?   U  s    zMathCall.__init__c              
     sD    fdd| j D }tjdd | jj| W  5 Q R  S Q R X d S )Nc                   s   g | ]}| qS r2   r2   )r{   rt   r   r2   r3   
<listcomp>[  s     z%MathCall.__call__.<locals>.<listcomp>ignore)r   )ru   r^   Zerrstater   )r>   r,   ru   r2   r   r3   rJ   Y  s    zMathCall.__call__r&   c                 C  s(   t t| j}t| j dd| dS )Nrz   ,rY   )mapr&   ru   r   rt   r~   )r>   ru   r2   r2   r3   rD   _  s    zMathCall.__repr__)rZ   rf   rg   r?   rJ   rD   rl   r2   r2   r0   r3   r   T  s   r   c                   @  s$   e Zd ZdddddZdd ZdS )	FuncNoder&   r6   )r+   r8   c                 C  s.   |t krtd| d|| _tt|| _d S )N"z" is not a supported function)MATHOPSr   r+   r   r^   r   )r>   r+   r2   r2   r3   r?   e  s    zFuncNode.__init__c                 G  s
   t | |S r$   )r   )r>   rH   r2   r2   r3   rJ   k  s    zFuncNode.__call__N)rZ   rf   rg   r?   rJ   r2   r2   r2   r3   r   d  s   r   )Xr   
__future__r   r   	functoolsr   operatortypingr   r   r   r   Znumpyr^   Zpandas._libs.tslibsr	   Zpandas.core.dtypes.commonr
   r   Zpandas.core.commoncorecommonr   Zpandas.core.computation.commonr   r   Zpandas.core.computation.scoper   Zpandas.io.formats.printingr   r   Z
REDUCTIONSZ_unary_math_opsZ_binary_math_opsr   r;   r#   r'   rv   rs   r   r   r   gtltgeleeqneZ_cmp_ops_funcsdictzipr   r   and_or_Z_bool_ops_funcsr   ZARITH_OPS_SYMSaddsubmultruedivpowfloordivmodZ_arith_ops_funcsZ_arith_ops_dictZSPECIAL_CASE_ARITH_OPS_SYMSZ_special_case_arith_ops_funcsZ_special_case_arith_ops_dictr   drP   r   r   r   r   r   r   posneginvertZ_unary_ops_funcsr   r   r   r   r2   r2   r2   r3   <module>   s   t6
	 1