U
    d                     @   sR   d dl mZmZmZmZmZmZ d dlmZm	Z	 er@d dl
mZ G dd dZdS )    )TYPE_CHECKINGAnyDictOptionalTupleUnion)
RedisErrorResponseError)ClusterNodec                   @   sp   e Zd ZdZdZddddZded ddd	d
Zeee	e
df  dddZeee	e
df  dddZdS )CommandsParsera%  
    Parses Redis commands to get command keys.

    COMMAND output is used to determine key locations.
    Commands that do not have a predefined key location are flagged with 'movablekeys',
    and these commands' keys are determined by the command 'COMMAND GETKEYS'.

    NOTE: Due to a bug in redis<7.0, this does not work properly
    for EVAL or EVALSHA when the `numkeys` arg is 0.
     - issue: https://github.com/redis/redis/issues/9493
     - fix: https://github.com/redis/redis/pull/9733

    So, don't use this with EVAL or EVALSHA.
    )commandsnodeN)returnc                 C   s
   i | _ d S )N)r   )self r   8/tmp/pip-unpacked-wheel-xj5sloo9/redis/asyncio/parser.py__init__   s    zCommandsParser.__init__r
   )r   r   c                    s   |r
|| _ | j dI d H }| D ]`\}}d|d krBd||< q$|d dkrd|d dkrdd||< q$|d dkr$|d dkr$d||< q$d	d
 | D | _d S )NZCOMMANDZmovablekeysflagsfirst_key_posr   last_key_pos   c                 S   s   i | ]\}}|  |qS r   )upper).0cmdcommandr   r   r   
<dictcomp>*   s      z-CommandsParser.initialize.<locals>.<dictcomp>)r   execute_commanditemsr   )r   r   r   r   r   r   r   r   
initialize   s    


zCommandsParser.initialize.)argsr   c                    s  t |dk rd S z| j|d  }W nv tk
r   |d  t|dd   }|d  }|| jkr|  I d H  || jkrt| d| j| }Y nX |dkr|d fS |dkrd S |dkr| j| I d H S |d }|dk rt || }||d |d |d  S )	N   r   r   z( command doesn't exist in Redis commandsr   r   r   Z
step_count)	lenr   KeyErrorsplitlistr   r   r   _get_moveable_keys)r   r    r   cmd_namer   r   r   r   get_keys/   s0    


zCommandsParser.get_keysc              
      sh   z| j jd| I d H }W nH tk
rb } z*| }d|ksDd|krNW Y d S |W 5 d }~X Y nX |S )NCOMMAND GETKEYSzInvalid argumentsz The command has no key arguments)r)   )r   r   r	   __str__)r   r    keysemessager   r   r   r&   R   s    
z!CommandsParser._get_moveable_keys)N)__name__
__module____qualname____doc__	__slots__r   r   r   r   r   strr(   r&   r   r   r   r   r   	   s   #r   N)typingr   r   r   r   r   r   Zredis.exceptionsr   r	   Zredis.asyncio.clusterr
   r   r   r   r   r   <module>   s    