o
    Š¨Êh,+  ã                   @   s~   d dl mZmZmZmZmZmZ d dlmZm	Z	 d dl
mZ er&d dlmZ G dd„ dƒZG dd„ deƒZG d	d
„ d
eƒZdS )é    )ÚTYPE_CHECKINGÚAnyÚDictÚOptionalÚTupleÚUnion)Ú
RedisErrorÚResponseError©Ústr_if_bytes)ÚClusterNodec                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚAbstractCommandsParserc                 G   sŒ   t |ƒdk rdS dd„ |D ƒ}|d  ¡ }d}|dkr-|d  ¡ }|dv r+|dd… }|S |d	v r;t|dd… ƒ}|S |d
v rD|d g}|S )zé
        Get the keys from pubsub command.
        Although PubSub commands have predetermined key locations, they are not
        supported in the 'COMMAND's output, so the key positions are hardcoded
        in this method
        é   Nc                 S   ó   g | ]}t |ƒ‘qS © r
   )Ú.0Úargr   r   úI/var/www/html/env/lib/python3.10/site-packages/redis/_parsers/commands.pyÚ
<listcomp>   ó    z;AbstractCommandsParser._get_pubsub_keys.<locals>.<listcomp>r   ÚPUBSUBé   )ÚCHANNELSÚNUMSUBÚSHARDCHANNELSÚSHARDNUMSUB)Ú	SUBSCRIBEÚ
PSUBSCRIBEÚUNSUBSCRIBEÚPUNSUBSCRIBE)ÚPUBLISHÚSPUBLISH)ÚlenÚupperÚlist)ÚselfÚargsÚcommandÚkeysÚpubsub_typer   r   r   Ú_get_pubsub_keys   s    	øü
z'AbstractCommandsParser._get_pubsub_keysc                 K   s–   i }t |d ƒ}||d< t|d ƒ|d< dd„ |d D ƒ|d< |d	 |d
< |d |d< |d |d< t|ƒdkrI|d |d< |d |d< |d |d< |S )Nr   Únamer   Úarityc                 S   r   r   r
   )r   Úflagr   r   r   r   -   r   z;AbstractCommandsParser.parse_subcommand.<locals>.<listcomp>r   Úflagsé   Úfirst_key_posé   Úlast_key_posé   Ú
step_counté   Útipsé   Úkey_specificationsé	   Úsubcommands)r   Úintr"   )r%   r'   ÚoptionsÚcmd_dictÚcmd_namer   r   r   Úparse_subcommand(   s   z'AbstractCommandsParser.parse_subcommandN)Ú__name__Ú
__module__Ú__qualname__r*   r?   r   r   r   r   r   
   s    r   c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Z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'.
    c                 C   s   i | _ |  |¡ d S ©N)ÚcommandsÚ
initialize)r%   Úredis_connectionr   r   r   Ú__init__A   s   zCommandsParser.__init__c                 C   sX   |  ¡ }g }|D ]}tdd„ |D ƒƒr| |¡ q|D ]}| |¡|| ¡ < q|| _d S )Nc                 s   s   � | ]}|  ¡ V  qd S rD   )Úisupper)r   Úxr   r   r   Ú	<genexpr>I   s   € z,CommandsParser.initialize.<locals>.<genexpr>)r'   ÚanyÚappendÚpopÚlowerrE   )r%   ÚrrE   Úuppercase_commandsÚcmdr   r   r   rF   E   s   
€
zCommandsParser.initializec                    sœ  t ˆ ƒdk rdS ˆ d  ¡ }|| jvr>| ¡ }|d }|| jv r+|tˆ dd… ƒ ‰ n|  |¡ || jvr>t| ¡ › d�ƒ‚| j |¡}d|d v rU| j	|gˆ ¢R Ž }|S d|d v sa|d	 dkrh| j
ˆ Ž }|S |d
 dkr¥|d dkr¥|d dkr¥d}d|v r¡|› dˆ d  ¡ › �}|d D ]}	t|	d ƒ|kr |  |	¡}d}q�|s¥dS |d }
|
dk rµt ˆ ƒt|
ƒ }
tt|d |
d |d
 ƒƒ}‡ fdd„|D ƒ}|S )áp  
        Get the keys from the passed command.

        NOTE: Due to a bug in redis<7.0, this function 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 function with EVAL or EVALSHA.
        r   Nr   r   ú( command doesn't exist in Redis commandsÚmovablekeysr.   Úpubsubr+   r4   r0   r2   Fr:   ú|Tc                    ó   g | ]}ˆ | ‘qS r   r   ©r   Úpos©r&   r   r   r   �   r   z+CommandsParser.get_keys.<locals>.<listcomp>©r"   rO   rE   Úsplitr$   rF   r   r#   ÚgetÚ_get_moveable_keysr*   r   r?   ÚabsÚrange)r%   Ú
redis_connr&   r>   Úcmd_name_splitr'   r(   Ú	is_subcmdÚsubcmd_nameÚsubcmdr2   Úkeys_posr   r[   r   Úget_keysR   sR   



ÿå
é
€ÿzCommandsParser.get_keysc              
   G   sx   |d   ¡ t|dd… ƒ }z|jdg|¢R Ž }W |S  ty; } z| ¡ }d|v s.d|v r5W Y d}~dS |‚d}~ww )aA  
        NOTE: Due to a bug in redis<7.0, this function 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 function with EVAL or EVALSHA.
        r   r   NúCOMMAND GETKEYSúInvalid argumentsú The command has no key arguments)r]   r$   Úexecute_commandr	   Ú__str__)r%   rb   r&   Úpiecesr(   ÚeÚmessager   r   r   r_   “   s   
÷€øz!CommandsParser._get_moveable_keysN)r@   rA   rB   Ú__doc__rH   rF   rh   r_   r   r   r   r   rC   8   s    ArC   c                   @   sr   e Zd ZdZdZddd„Zdded ddfd	d
„Zdedee	e
df  fdd„Zdedee	e
df  fdd„ZdS )ÚAsyncCommandsParsera%  
    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.
    )rE   ÚnodeÚreturnNc                 C   s
   i | _ d S rD   )rE   )r%   r   r   r   rH   ¿   s   
zAsyncCommandsParser.__init__rs   r   c                 Ã   s6   �|r|| _ | j  d¡I d H }dd„ | ¡ D ƒ| _d S )NÚCOMMANDc                 S   s   i | ]	\}}|  ¡ |“qS r   )rO   )r   rR   r'   r   r   r   Ú
<dictcomp>Ç   s    z2AsyncCommandsParser.initialize.<locals>.<dictcomp>)rs   rl   ÚitemsrE   )r%   rs   rE   r   r   r   rF   Â   s
   €zAsyncCommandsParser.initializer&   .c                 ‡   s   �t ˆ ƒdk r	dS ˆ d  ¡ }|| jvrA| ¡ }|d }|| jv r,|tˆ dd… ƒ ‰ n|  ¡ I dH  || jvrAt| ¡ › d�ƒ‚| j |¡}d|d v rW| j	ˆ Ž I dH }|S d|d v sc|d	 dkrj| j
ˆ Ž }|S |d
 dkr§|d dkr§|d dkr§d}d|v r£|› dˆ d  ¡ › �}|d D ]}t|d ƒ|kr¢|  |¡}d}q‘|s§dS |d }	|	dk r·t ˆ ƒt|	ƒ }	tt|d |	d |d
 ƒƒ}
‡ fdd„|
D ƒ}|S )rS   r   Nr   r   rT   rU   r.   rV   r+   r4   r0   r2   Fr:   rW   Tc                    rX   r   r   rY   r[   r   r   r   	  r   z0AsyncCommandsParser.get_keys.<locals>.<listcomp>r\   )r%   r&   r>   rc   r'   r(   rd   re   rf   r2   rg   r   r[   r   rh   Ì   sT   €


ÿå
é
€ÿzAsyncCommandsParser.get_keysc              
   Ç   sf   �z| j jdg|¢R Ž I d H }W |S  ty2 } z| ¡ }d|v s%d|v r,W Y d }~d S |‚d }~ww )Nri   rj   rk   )rs   rl   r	   rm   )r%   r&   r(   ro   rp   r   r   r   r_     s   €
÷€øz&AsyncCommandsParser._get_moveable_keys)rt   NrD   )r@   rA   rB   rq   Ú	__slots__rH   r   rF   r   r   Ústrrh   r_   r   r   r   r   rr   ­   s    

"Arr   N)Útypingr   r   r   r   r   r   Úredis.exceptionsr   r	   Úredis.utilsr   Úredis.asyncio.clusterr   r   rC   rr   r   r   r   r   Ú<module>   s     .u