
    ng\j+                     H   S SK r S SKJr  S rS rS rS rS rS rS	 r	0 S
\
_S\
_S\
_S\
_S\
_S\
_S\
_S\
_S\
_S\
_S\
_S\
_S\
_S\
_S\
_S\
_S\
_\
\
\
\
\
\
S.ErSrS rS rS rS  rS! rS" rS# rS$ rS% rS& rS' rS( rS) rS* rS+ rS, rS- rS. rS/ rSS0 jr S1 r!S2 r"S3 r#S4 r$S5 r%S6 r&S7 r'S8 r(S9 r)S: r*S; r+S< r,S= r-S> r.S? r/S@ r0SA r1SB r2SC r3SD r4SE r5SF r6SG r7SH r8SI r9SJ r:SK r;SL r<SM r=SN r>SO r?SP r@SQ rASR rBSS rCST rDSU rESV rFSW rGSX rHSY rISZ rJS[ rKS\ rLS] rMS^ rNS_ rOS` rPSa rQSb rRSc rSSd rTSe rUSf rVSg rWSh rXSi rYSj rZSk r[Sl r\Sm r]Sn r^So r_Sp r`Sq raSr rbSs rcSt rdSu reSv rfSw rgSx rhSy riSz rjS{ rkS| rlS} rmS~ rnS roS rpS rqSSKrJsrsJtrtJuruJvrvJwrwJxrxJyry  g)    Nstr_if_bytesc                     U (       d  g [        U 5      n [        R                  R                  U 5      $ ! [         a     gf = f)z5Converts a unix timestamp to a Python datetime objectN)int
ValueErrordatetimefromtimestampresponses    Q/home/edenadmin/noVNC/venv/lib/python3.13/site-packages/redis/_parsers/helpers.pytimestamp_to_datetimer      sC    x= **844  s   4 
A Ac                     [        U 5      n SU -   n [        S U R                  5        5       5      n SnU H  nX ;   d  M
  [        X   5      X'   M     U $ )zDParse the results of Redis's DEBUG OBJECT command into a Python dictztype:c              3   B   #    U  H  oR                  S 5      v   M     g7f:Nsplit).0kvs     r   	<genexpr>%parse_debug_object.<locals>.<genexpr>   s     =,<bHHSMM,<s   )refcountserializedlengthlrulru_seconds_idle)r   dictr   r   )r   
int_fieldsfields      r   parse_debug_objectr      s\     H%H!H=HNN,<==H MJ!(/2HO  O    c                   ^ 0 n[        U 5      n U4S jmU R                  5        H  nU(       d  M  UR                  S5      (       a  M$  UR                  S5      S:w  ai  UR	                  SS5      u  p4US:X  a  UR                  SS5      u  p4US:X  a)  UR                  S/ 5      R                  T" U5      5        M  T" U5      X'   M  UR                  S	/ 5      R                  U5        M     U$ )
z;Parse the result of Redis's INFO command into a Python dictc                   > SU ;  a#  SU ;  a   SU ;   a  [        U 5      $ [        U 5      $ SU ;  a0  U R                  S5       Vs/ s H  o(       d  M  T" U5      PM     sn$ 0 nU R                  S5       H6  nU(       d  M  SU;   a   UR	                  SS5      u  pAT" U5      X$'   M2  SX#'   M8     U$ ! [         a    U s $ f = fs  snf )N,=.   T)floatr   r   r   rsplit)valuevsub_dictitemk	get_values        r   r.   parse_info.<locals>.get_value(   s    e5 0%< <'u:% */++c*:@*:QaLIaL*:@@HC($;;;sA.DA"+A,HK%)HN ) O   As"   B0 
B0 
CC0B?>B?#r   r&   cmdstat_hostmodulemodules__raw__)r   
splitlines
startswithfindr   r(   
setdefaultappend)r   infolinekeyr)   r.   s        @r   
parse_infor>   #   s    DH%H. ##%4,,yy~# "ZZQ/
.(!%S!!4JC(? OOIr299)E:JK )% 0DI 	2.55d;% &( Kr    c                     [        U SSS9nUR                  5        HA  u  p4UR                  S5      (       d  M  [        U[        5      (       d  M4  [        USSS9X#'   MC     U$ )z!Parse the results of MEMORY STATST)decode_keysdecode_string_valuesdb.pairs_to_dictitemsr7   
isinstancelistr   kwargsstatsr=   r)   s        r   parse_memory_statsrK   V   sW    (4PEkkm
>>%  Zt%<%<&4dEJ $
 Lr    c                     [        U SS9nUR                  5        H@  u  p4UR                  S5      (       d  M  [        U[        5      (       d  M4  [        USS9X#'   MB     U$ )zParse MEMORY STATS for unified RESP2 output.

Unified responses decode structural keys while preserving string-like
values as delivered, matching the approved RESP2/RESP3 unification shape.
Tr@   rB   rC   rH   s        r   parse_memory_stats_unifiedrN   a   sR     (5Ekkm
>>%  Zt%<%<&u$?EJ $ Lr    c                 l   U R                  5        VVs0 s H  u  p#[        U5      U_M     nnnUR                  5        He  u  p#UR                  S5      (       d  M  [        U[        5      (       d  M4  UR                  5        VVs0 s H  u  pV[        U5      U_M     snnXB'   Mg     U$ s  snnf s  snnf )a$  Parse the results of MEMORY STATS on RESP3 wire.

Each entry arrives as a top-level ``dict`` instead of a flat list of
pairs; decode the keys to ``str`` and recurse into the per-database
``db.*`` sub-dicts so the Python shape matches what
:func:`parse_memory_stats` produces from RESP2 wire.
rB   )rE   r   r7   rF   r   )r   rI   r=   r)   rJ   r-   r*   s          r   parse_memory_stats_resp3rP   n   s     9A8HI8H*#\#%8HEIkkm
>>%  Zt%<%<9>G,q/1,GEJ $ L	 J Hs   B*B0c                     U  VVVs/ s H1  o"R                  5        VVs0 s H  u  p4[        U5      U_M     snnPM3     snnn$ s  snnf s  snnnf )zParse list-of-maps responses on RESP3 wire (e.g. ``XINFO`` family).

Each list entry arrives as a ``dict`` with bytes keys; decode the
keys to ``str`` so the Python shape matches what
:func:`parse_list_of_dicts` produces from RESP2 wire.
rE   r   )r   rI   xr=   r)   s        r   parse_list_of_dicts_resp3rT   }   s@     MUUHq	B	*#\#%	BHUUBUs   A
AA
A
zcan-failover-its-masterzconfig-epochzdown-after-millisecondszfailover-timeoutzinfo-refreshzlast-hello-messagezlast-ok-ping-replyzlast-ping-replyzlast-ping-sentzmaster-link-down-timezmaster-portznum-other-sentinelsz
num-slaveszo-down-timezpending-commandszparallel-syncsport)quorumzrole-reported-timezs-down-timezslave-priorityzslave-repl-offsetzvoted-leader-epoch))	is_mastermaster)is_slaveslave)is_sdowns_down)is_odowno_down)is_sentinelsentinel)is_disconnecteddisconnected)is_master_downmaster_downc                 .    [          H  u  p#X1;   X'   M     g)zSet ``is_master`` / ``is_slave`` / ``is_sdown`` / ``is_odown`` /
``is_sentinel`` / ``is_disconnected`` / ``is_master_down`` on
``result`` based on membership in the ``flags`` set.
N)_SENTINEL_DERIVED_BOOLEANS)resultflagsnameflags       r   _add_derived_sentinel_booleansrk      s    
 1
} 1r    c                 v    [        U [        5      n[        US   R                  S5      5      n[	        X5        U$ Nrh   r#   )pairs_to_dict_typedSENTINEL_STATE_TYPESsetr   rk   )r,   rg   rh   s      r   parse_sentinel_staterq      s5     ';<Fw%%c*+E"61Mr    c                 4    [        [        [        U 5      5      $ Nrq   mapr   r   optionss     r   parse_sentinel_masterrx      s    L( ;<<r    c                    0 nU  H-  n[        U5      n [        U   " [        X   5      5      nXRU'   M/     [        US   R	                  S5      5      nXbS'   [        X&5        U$ ! [         a    [        X   5      X$'    M{  f = frm   )r   ro   	Exceptionrp   r   rk   )r   rw   rg   r=   str_keyr)   rh   s          r   parse_sentinel_state_resp3r|      s    Fs#	:(1,x}2MNE#7O	  w%%c*+E7O"61M  	:*8=9FO	:s   A$$B Bc                 \    0 nU  H#  n[        [        [        U5      5      nXBUS   '   M%     U$ Nri   rt   r   rw   rg   r,   states        r   parse_sentinel_mastersr      s5    F$St%<= %uV}  Mr    c                 @    0 nU  H  n[        U5      nXBUS   '   M     U$ r~   r|   r   rw   rg   rX   r   s        r   parse_sentinel_masters_resp3r      s.    F*62 %uV}  Mr    c           	      `    U  Vs/ s H  n[        [        [        U5      5      PM     sn$ s  snf rs   rt   r   rw   r,   s      r   #parse_sentinel_slaves_and_sentinelsr      s'    FNOhd \4!89hOOOs   #+c                 F    U  Vs/ s H  n[        U40 UD6PM     sn$ s  snf rs   r   r   s      r   )parse_sentinel_slaves_and_sentinels_resp3r      s%    DLMHD&t7w7HMMMs   c              #   N   #    U R                  5        H  u  pUv   Uv   M     g7f)zpYield key/value pairs from a RESP3 sentinel-state map as a flat
iterable suitable for ``parse_sentinel_state``.
N)rE   )r   r=   r)   s      r   _flatten_resp3_state_pairsr      s#      kkm
	 $s   #%c                 F    [        [        [        [        U 5      5      5      $ rs   rq   ru   r   r   rv   s     r   +parse_sentinel_master_resp3_to_resp2_legacyr      s    L2LX2V WXXr    c           	      n    0 nU  H,  n[        [        [        [        U5      5      5      nXBUS   '   M.     U$ r~   r   r   s        r   ,parse_sentinel_masters_resp3_to_resp2_legacyr      s@    F$8@A
 !&uV}	 
 Mr    c                 r    U  Vs/ s H%  n[        [        [        [        U5      5      5      PM'     sn$ s  snf rs   r   r   s      r   9parse_sentinel_slaves_and_sentinels_resp3_to_resp2_legacyr      s;     D 	S/I$/OPQ  s   ,4c                 x    [        [        [        U 5      5      n[        US   R	                  S5      5      US'   U$ rm   rq   ru   r   rp   r   r   rw   r   s      r   parse_sentinel_master_unifiedr     s5     \8!<=Ew--c23E'NLr    c                     0 nU  HC  n[        [        [        U5      5      n[        US   R	                  S5      5      US'   XBUS   '   ME     U$ )Nrh   r#   ri   r   r   s        r   parse_sentinel_masters_unifiedr     sR    F$St%<=U7^11#67g %uV}  Mr    c                     / nU  HM  n[        [        [        U5      5      n[        US   R	                  S5      5      US'   UR                  U5        MO     U$ rm   )rq   ru   r   rp   r   r:   r   rw   outr,   r   s        r   +parse_sentinel_slaves_and_sentinels_unifiedr     sR    
C$St%<=U7^11#67g

5  Jr    c                 :    [        U 40 UD6n[        X"S   5        U$ Nrh   r|   rk   r   s      r   #parse_sentinel_master_unified_resp3r     s"    &x;7;E"5.9Lr    c                 \    0 nU  H#  n[        U5      n[        XDS   5        XBUS   '   M%     U$ )Nrh   ri   r   r   s        r   $parse_sentinel_masters_unified_resp3r   $  s:    F*62&uGn= %uV}  Mr    c                 r    / nU  H.  n[        U40 UD6n[        XDS   5        UR                  U5        M0     U$ r   )r|   rk   r:   r   s        r   1parse_sentinel_slaves_and_sentinels_unified_resp3r   -  s?    
C*4;7;&uGn=

5  Jr    c                 L    U =(       a    U S   [        U S   5      4=(       d    S $ Nr   r&   r   rv   s     r   parse_sentinel_get_masterr   6  s$    7!c(1+&67?4?r    c                 
   U c  0 $ U(       d  U(       aR  U SSS2   nU(       a  [        [        U5      nU SSS2   nU(       a  [        [        U5      n[        [        X45      5      $ [	        U 5      n[        [        XU5      5      $ )z-Create a dict given a list of key/value pairsN   r&   )ru   r   r   zipiter)r   r@   rA   keysvaluesits         r   rD   rD   :  sw    	* !}|T*D!$Q$v.FC%&&(^CK  r    c                     [        U 5      n0 n[        X"5       H  u  pEXA;   a   X   " U5      nXSU'   M     U$ ! [         a     Nf = frs   )r   r   rz   )r   	type_infor   rg   r=   r)   s         r   rn   rn   M  s]    	hBF"k
!u-
 s " M   s   
8
AAc                 *   ^  T [         L a  T $ U 4S jnU$ )a  Wrap score_cast_func to handle scientific notation in RESP2 byte strings.

Redis returns scores as byte strings in RESP2, and large numbers may use
scientific notation (e.g., b'1.7732526297292595e+18'). Python's int() cannot
parse scientific notation directly.  Rather than unconditionally routing
through float() (which would change the input type for every custom
callable), we try the original function first and only fall back to
converting through float() on ValueError.
c                 d   >  T" U 5      $ ! [         [        4 a    T" [        U 5      5      s $ f = frs   )r   	TypeErrorr'   )rS   score_cast_funcs    r   
_safe_cast)_wrap_score_cast_func.<locals>._safe_casti  s6    	-"1%%I& 	-"58,,	-s    !//r'   )r   r   s   ` r   _wrap_score_cast_funcr   \  s      %- r    c           	          U (       a  UR                  S5      (       d  U $ [        UR                  S[        5      5      n[        U 5      n[	        [        U[        X#5      5      5      $ )zf
If ``withscores`` is specified in the options, return the response as
a list of (value, score) pairs

withscoresr   )getr   r'   r   rG   r   ru   r   rw   r   r   s       r   zset_score_pairsr   r  sP    
 7;;|44+GKK8I5,QRO	hBBO0122r    c           	          U (       d  U $ [        UR                  S[        5      5      n[        U 5      n[	        [        U[        X#5      5      5      $ )zRESP2-wire ZPOPMAX/ZPOPMIN -> legacy ``list[(member, score), ...]``.

ZPOPMAX/ZPOPMIN always include scores, so this parser intentionally
does not depend on a ``withscores`` option.
r   )r   r   r'   r   rG   r   ru   r   s       r   zpop_score_pairsr   ~  sB     +GKK8I5,QRO	hBBO0122r    c                     U (       a  UR                  S5      (       d  U $ [        UR                  S[        5      5      nU S   U" U S   5      /$ z]
If ``withscores`` is specified in the options, return the response as
a [value, score] pair
	withscorer   r   r&   r   r   r'   r   rw   r   s      r   zset_score_for_rankr     sH    
 7;;{33+GKK8I5,QROQK!566r    c                     U (       a  UR                  S5      (       d  U $ UR                  S[        5      nU  VVs/ s H  u  p4X2" U5      /PM     snn$ s  snnf )zf
If ``withscores`` is specified in the options, return the response as
a list of [value, score] pairs
r   r   r   r'   r   rw   r   ri   vals        r   zset_score_pairs_resp3r     sO    
 7;;|44kk"3U;O:BC(YTT?3'((CCCs   Ac                     U (       a  UR                  S5      (       d  U $ UR                  S[        5      nU S   U" U S   5      /$ r   r   r   s      r   zset_score_for_rank_resp3r     sC    
 7;;{33kk"3U;OQK!566r    c                     [        U [        5      (       a  U $ [        U [        5      (       a  U R                  5       $ [        U [        5      (       a  U (       a  S$ S$ [        [        U 5      S5      R                  5       $ )a  Re-encode a score back to the bytes form Redis returns on the RESP2
wire so that custom ``score_cast_func`` callables observe the same
input type they would receive on a RESP2 connection when the wire
protocol is RESP3 but legacy response shapes are requested.
   1   0z.17g)rF   bytesstrencodeboolformatr'   )r)   s    r   _score_to_resp2_bytesr     sc     %%||~%t&$&%,'..00r    c           
          U (       a  UR                  S5      (       d  U $ [        UR                  S[        5      5      nU  VVs/ s H  u  p4X2" [        U5      5      4PM     snn$ s  snnf )zConvert RESP3 nested ``[[member, score], ...]`` to today's RESP2
``list[(member, score)]`` shape: tuples instead of lists, scores
re-encoded to bytes before being passed to ``score_cast_func`` so the
cast receives the same input as on a RESP2 connection.
r   r   r   r   r'   r   r   rw   r   memberscores        r   &zset_score_pairs_resp3_to_resp2_legacyr     si     7;;|44+GKK8I5,QRO &%MF 
!6u!=>?%  s   A&c                     U (       a  UR                  S5      (       d  U $ / nU  H0  u  p4UR                  U5        UR                  [        U5      5        M2     U$ )a  Convert RESP3 nested ``[[member, score], ...]`` to the flat raw RESP2
wire shape ``[member, score_bytes, ...]`` used by ZDIFF in v8.0.0b1.

ZDIFF historically did not propagate ``withscores`` to the response
callback, so the legacy RESP2 callback was a no-op and the raw flat
wire response was returned to the user. This helper reproduces that
shape on RESP3 wires so ``legacy_responses=True`` keeps emitting the
same Python value regardless of the underlying protocol.
r   )r   r:   r   )r   rw   flatr   r   s        r   +zset_score_pairs_resp3_to_resp2_legacy_flatr     sP     7;;|44D!F)%01 " Kr    c                     U (       a  UR                  S5      (       d  U $ [        UR                  S[        5      5      nU S   U" [        U S   5      5      /$ )u%  RESP3-wire ZRANK/ZREVRANK WITHSCORE → legacy RESP2 ``[rank, score]``.

The shape ``[rank, score]`` is identical between RESP2 and RESP3; only
the score is re-encoded to bytes before being passed to
``score_cast_func`` so the cast observes the same input type it would
on a RESP2 connection.
r   r   r   r&   r   r   s      r   )zset_score_for_rank_resp3_to_resp2_legacyr     sN     7;;{33+GKK8I5,QROQK)>x{)KLMMr    c           
          U (       a  UR                  S5      (       d  U $ [        UR                  S[        5      5      n[        U 5      n[	        X35       VVs/ s H  u  pEXB" [        U5      5      /PM     snn$ s  snnf )u   RESP2-wire WITHSCORES → unified ``list[[member, score], ...]``.

Normalises RESP2 byte-string scores through ``float`` before applying
``score_cast_func`` so the cast receives the same input type as on a
RESP3 connection.
r   r   )r   r   r'   r   r   r   rw   r   r   r   r   s         r   zset_score_pairs_unifiedr     se     7;;|44+GKK8I5,QRO	hBCFr;O;ZSS/%,/0;OOOs   A:c                     U (       a  UR                  S5      (       d  U $ [        UR                  S[        5      5      nU S   U" [        U S   5      5      /$ )u   RESP2-wire ZRANK/ZREVRANK WITHSCORE → unified ``[rank, score]``.

Normalises the RESP2 byte-string score through ``float`` before
applying ``score_cast_func`` so the cast receives the same input type
as on a RESP3 connection.
r   r   r   r&   r   r   s      r   zset_score_for_rank_unifiedr     sM     7;;{33+GKK8I5,QROQKx{);<==r    c           
          U (       d  U $ [        UR                  S[        5      5      n[        U 5      n[	        X35       VVs/ s H  u  pEXB" [        U5      5      /PM     snn$ s  snnf )u   RESP2-wire ZPOPMAX/ZPOPMIN → unified ``list[[member, score], ...]``.

ZPOPMAX/ZPOPMIN always include scores; no ``withscores`` gate is
required. Scores are normalised through ``float`` before applying
``score_cast_func`` for parity with RESP3.
r   )r   r   r'   r   r   r   s         r   zpop_score_pairs_unifiedr     sW     +GKK8I5,QRO	hBCFr;O;ZSS/%,/0;OOOs   A$c                     U (       d  U $ UR                  S[        5      n[        U S   [        5      (       a  U  VVs/ s H  u  p4X2" U5      /PM     snn$ U S   U" U S   5      //$ s  snnf )u  RESP3-wire ZPOPMAX/ZPOPMIN → unified ``list[[member, score], ...]``.

Without ``count`` RESP3 returns a flat ``[member, score]``; with
``count`` it returns a nested ``[[member, score], ...]``. Both shapes
are normalised to a nested list with ``score_cast_func`` applied.
r   r   r&   )r   r'   rF   rG   r   s        r   zpop_score_pairs_resp3_unifiedr     sp     kk"3U;O(1+t$$>FGhs+,hGGa[/(1+6788 Hs   A'c           
         U (       d  U $ [        UR                  S[        5      5      n[        U S   [        5      (       a'  U  VVs/ s H  u  p4X2" [        U5      5      4PM     snn$ U S   U" [        U S   5      5      4/$ s  snnf )uE  RESP3-wire ZPOPMAX/ZPOPMIN → legacy RESP2 ``list[(member, score), ...]``.

Both RESP3 shapes (flat without ``count``; nested with ``count``) are
converted to a list of tuples. Scores are re-encoded to bytes before
being passed to ``score_cast_func`` so the cast observes the same
input type it would on a RESP2 connection.
r   r   r&   )r   r   r'   rF   rG   r   r   s        r   &zpop_score_pairs_resp3_to_resp2_legacyr   #  s     +GKK8I5,QRO(1+t$$ "*
!) _%:5%ABC!)
 	
 a[/*?*LMNOO	
s   Bc                 @    U (       d  gU S   U S   [        U S   5      /$ )u   BZPOPMAX/BZPOPMIN → unified ``[key, member, score]``.

Works for both RESP2 (bytes score) and RESP3 (float score) wire shapes.
Nr   r&   r   r   rv   s     r   bzpop_score_unifiedr   6  (    
 QK!eHQK&899r    c                 @    U (       d  gU S   U S   [        U S   5      4$ )u   RESP3-wire BZPOPMAX/BZPOPMIN → legacy RESP2 ``(key, member, score)``.

Matches the v8.0.0b1 RESP2-wire callback shape (tuple, ``float`` score).
Nr   r&   r   r   rv   s     r   !bzpop_score_resp3_to_resp2_legacyr   @  r   r    c           	      t    U (       d  U $ U S   U S    VVs/ s H  u  p#U[        U5      /PM     snn/$ s  snnf )u   RESP3-wire ZMPOP/BZMPOP → legacy RESP2 ``[name, [[member, b"score"], ...]]``.

Re-encodes RESP3 native float scores back to the bytes form Redis
returns on the RESP2 wire so callers observe today's RESP2 raw shape.
r   r&   )r   r   rw   r   r   s       r   zmpop_resp3_to_resp2_legacyr   J  sC     EMa[Q[MF&'.	/[Q Q   4c           	      t    U (       d  U $ U S   U S    VVs/ s H  u  p#U[        U5      /PM     snn/$ s  snnf )u   ZMPOP/BZMPOP → unified ``[name, [[member, float_score], ...]]``.

Used for the ``legacy_responses=False`` overlay on RESP2 wire to mirror
RESP3's native float-score shape.
r   r&   r   r   s       r   zmpop_unifiedr   X  sA     5=a[A[MF&%,	[A Ar   c                     U (       a  UR                  S5      (       d  U $ [        U S   [        5      (       a  U $ [        U 5      n[	        X"5       VVs/ s H  u  p4X4/PM
     snn$ s  snnf )u  RESP2-wire HRANDFIELD WITHVALUES → unified ``list[[field, value], ...]``.

Plain (no-values) responses — flat list of fields — pass through.
The ``withvalues`` option (forwarded by the command method) selects the
pairing branch so the no-values flat result is never misread.

withvaluesr   )r   rF   rG   r   r   )r   rw   r   r   r)   s        r   hrandfield_unifiedr   f  sY     7;;|44(1+t$$	hB/22{;{|uUN{;;;s   A&c                     U (       a  UR                  S5      (       d  U $ [        U S   [        5      (       d  U $ / nU  H'  u  p4UR                  U5        UR                  U5        M)     U$ )u   RESP3-wire HRANDFIELD WITHVALUES → legacy RESP2 flat ``[field, value, ...]``.

Plain (no-values) responses — flat list of fields — pass through.
r   r   )r   rF   rG   r:   )r   rw   r   r   r)   s        r    hrandfield_resp3_to_resp2_legacyr   u  s`    
 7;;|44hqk4((D EE ! Kr    c                 n    U  Vs/ s H#  o"b  [        US   5      [        US   5      /OSPM%     sn$ s  snf )u   GEOPOS → unified ``list[list[float, float] | None]``.

Used for the ``legacy_responses=False`` overlay on RESP2 wire to mirror
RESP3's native ``list[list]`` shape.
Nr   r&   r   r   rw   lls      r   parse_geopos_unifiedr    s:     PXXxNU2a5\5A<(DxXXX   *2c                 n    U  Vs/ s H#  o"b  [        US   5      [        US   5      4OSPM%     sn$ s  snf )u   RESP3-wire GEOPOS → legacy RESP2 ``list[tuple(float, float) | None]``.

Matches today's RESP2-wire callback shape (tuple coordinates).
Nr   r&   r   r   s      r   "parse_geopos_resp3_to_resp2_legacyr    s:    
 PXXxNU2a5\5A<(DxXXXr  c                 :   [        U [        5      (       a5  [        U 5      n[        X"5       VVs0 s H  u  p4[	        U5      U_M     snn$ [        U [
        5      (       a/  U R                  5        VVs0 s H  u  p4[	        U5      U_M     snn$ U $ s  snnf s  snnf )u   LCS with IDX → unified ``dict``.

Used for the ``legacy_responses=False`` overlay on RESP2 wire to mirror
RESP3's native ``dict`` shape. Non-IDX responses (``bytes`` / ``int``)
pass through unchanged.
)rF   rG   r   r   r   r   rE   )r   rw   r   r=   r)   s        r   parse_lcs_idx_unifiedr    s     (D!!(^;>r;G;ZSS!5(;GG(D!!;C>>;KL;KZSS!5(;KLLO HLs   B3Bc                     [        U [        5      (       d  U $ / nU R                  5        H'  u  p4UR                  U5        UR                  U5        M)     U$ )u   RESP3-wire LCS with IDX → legacy RESP2 flat list shape.

Reproduces today's RESP2 raw output (``[b"matches", [...], b"len", n]``).
Non-IDX responses pass through unchanged.
)rF   r   rE   r:   r   rw   r   r=   r)   s        r   #parse_lcs_idx_resp3_to_resp2_legacyr	    sL     h%%Cnn&


3

5 ' Jr    c                    [        U [        5      (       a/  U R                  5        VVs0 s H  u  p#[        U5      U_M     nnnO6[	        U SSS2   U SSS2   5       VVs0 s H  u  p#[        U5      U_M     nnnSU;   a"  US    Vs/ s H  n[        U5      PM     snUS'   SU;   a"  US    Vs/ s H  n[        U5      PM     snUS'   U$ s  snnf s  snnf s  snf s  snf )u   CLIENT TRACKINGINFO → unified ``dict[str, Any]``.

Accepts either RESP2's flat ``[label, value, ...]`` list or RESP3's
native ``dict`` and returns a ``dict`` with ``str`` keys.
Nr   r&   rh   prefixes)rF   r   rE   r   r   )r   rw   r=   r)   datarj   prefixs          r   !parse_client_trackinginfo_unifiedr    s     (D!!;C>>;KL;KZSS!5(;KL "(3Q3-!$Q$@
@
 u$@ 	 
 $8<WFd+FWT?CJ?OP?OVL0?OPZK M

 GPs   C CC0Cc                     [        U [        5      (       d  [        [        [        U 5      5      $ / nU R                  5        H0  u  p4UR                  [	        U5      5        UR                  U5        M2     U$ )u   RESP3-wire CLIENT TRACKINGINFO → legacy RESP2 flat ``list``.

Mirrors today's RESP2-wire callback (``list(map(str_if_bytes, r))``):
labels are decoded to ``str`` while values are preserved as-is.
)rF   r   rG   ru   r   rE   r:   r  s        r   /parse_client_trackinginfo_resp3_to_resp2_legacyr    s_     h%%Ch/00Cnn&


<$%

5 ' Jr    c                     U (       a  UR                  S5      (       d  U $ US   n[        [        [        U5       Vs/ s H
  o0USU2   PM     sn6 5      $ s  snf )z
If ``groups`` is specified, return the response as a list of
n-element tuples with n being the value found in options['groups']
groupsN)r   rG   r   range)r   rw   nis       r   sort_return_tuplesr    sR    
 7;;x00AeAh7hqt!tnh78997s   Ac                     U c  g / nU  Hk  nUbT  SU;   a*  UR                  US   [        US   5      /USS  Q75        M6  UR                  US   [        US   5      45        MZ  UR                  S5        Mm     U$ )Nclaim_min_idle_timer   r&   r   )NN)r:   rD   )r   rw   r  rs       r   parse_stream_listr    s    D=$/QqT=1#6?12?@QqT=1#678KK%  Kr    c                     [        U SS9$ NTrM   )rD   r
   s    r   pairs_to_dict_with_str_keysr    s    t44r    c                 4    [        [        [        U 5      5      $ rs   )rG   ru   r  r
   s    r   parse_list_of_dictsr    s    /:;;r    c                 J    UR                  SS5      (       a  U $ [        U 5      $ )Nparse_justidFr   r  rv   s     r   parse_xclaimr#    s#    {{>5))X&&r    c                 `    UR                  SS5      (       a  U S   $ [        U S   5      U S'   U $ )Nr!  Fr&   r"  rv   s     r   parse_xautoclaimr%    s4    {{>5)){#HQK0HQKOr    c                     [        U [        5      (       a
  [        U SS9$ U R                  5        VVs0 s H  u  p#[	        U5      U_M     snn$ s  snnf r  )rF   rG   rD   rE   r   )r   rw   r-   r*   s       r   parse_arinfor'    sH    (D!!X488+3>>+;<+;41LOQ+;<<<s   Ac                    [        U [        5      (       a  [        U SS9nO.U R                  5        VVs0 s H  u  p4[	        U5      U_M     nnnUR                  SS5      (       dV  UR                  S5      nUb  US   b  US   [        US   5      4US'   US   nUb  US   b  US   [        US   5      4US'   U$ US	    VVs0 s H  u  pxU[        U5      _M     snnUS	'   [        US
   5      S:  a  [        US
   S   [        5      (       ag  US
    V	s/ s H  n	[        U	SS9PM     sn	US
'   US
    H;  n
U
S   (       d  M  U
S   S   c  M  U
S    Vs/ s H  n[        USS9PM     snU
S'   M=     U$ US
    V	VVs/ s H2  n	U	R                  5        VVs0 s H  u  p4[	        U5      U_M     snnPM4     snnn	US
'   U$ s  snnf s  snnf s  sn	f s  snf s  snnf s  snnn	f )NTrM   fullFzfirst-entryr   r&   z
last-entryentriesr  	consumers)rF   rG   rD   rE   r   r   len)r   rw   r  r-   r*   firstlast_identrygroupgcs               r   parse_xinfo_streamr4    s   (D!!X48/7~~/?@/?tqQ"/?@;;vu%%'q!5#(8]58-D"EDL!Q 3"&q'=a+A!BD" K HLIW3e 44WYtH~"z$x.2CT'J'JDHNDR5e6NDN (^[>>anQ&7&CDEkN&DRqaT:N&AkN $ K "(^+E 16>a!#>+DN K1 A X
&
 ?s/   GG	GG GG1GGc           	      ^    U c  / $ U  Vs/ s H  o"S   [        US   40 UD6/PM     sn$ s  snf r   )r  )r   rw   r  s      r   parse_xreadr6  +  s;    	@HI1qT$QqT5W56IIIs   *c           
      z    U c  0 $ U R                  5        VVs0 s H  u  p#U[        U40 UD6/_M     snn$ s  snnf rs   rE   r  r   rw   r=   r)   s       r   parse_xread_resp3r:  1  sK    	EM^^EUEUzs1122EU  s   7c           
          U (       d  0 $ [        U [        5      (       a0  U R                  5        VVs0 s H  u  p#U[        U40 UD6_M     snn$ U  VVs0 s H  u  pEU[        U40 UD6_M     snn$ s  snnf s  snnf )u   XREAD/XREADGROUP → unified ``dict[stream, list[tuple[id, dict]]]``.

Accepts either RESP2 (``list[[stream, entries]]``) or RESP3
(``dict[stream, entries]``) wire shape. Empty result is ``{}``.
)rF   r   rE   r  )r   rw   r=   r)   streamr*  s         r   parse_xread_unifiedr=  9  s     	(D!!GO~~GW
GWC"54G44GW
 	
 NVMU/&!'5W55X 
s   A1A7c           
          U (       d  / $ U R                  5        VVs/ s H  u  p#U[        U40 UD6/PM     snn$ s  snnf )u   RESP3-wire XREAD/XREADGROUP → legacy RESP2 ``list[[stream, entries]]``.

Empty result ``{}`` is converted to ``[]`` to match today's RESP2 shape.
r8  r9  s       r   !parse_xread_resp3_to_resp2_legacyr?  J  sG    
 	EM^^EUEUzs112EU  s   ;c                     UR                  SS5      (       a  [        U 5      $ U S   =(       d    /  VVs/ s H  u  p#U[        U5      S.PM     nnnU S   U S   U S   US.$ s  snnf )	Nparse_detailF   )ri   pendingr   r&   r   )rC  minmaxr+  )r   parse_xpending_ranger   )r   rw   r  pr+  s        r   parse_xpendingrH  V  ss    {{>5))#H--<DQK<M2<MN<MDA!A/<MINA;{{	  Os   A!c           	      Z    SnU  Vs/ s H  n[        [        X5      5      PM     sn$ s  snf )N)
message_idconsumertime_since_deliveredtimes_delivered)r   r   )r   r-   r  s      r   rF  rF  b  s'    MA%-.XDQOX...s   (c                      U c  g [        U 5      $ rs   r   r
   s    r   float_or_nonerO  g  s    ?r    c                     [        U 5      S:H  $ NOKr   rv   s     r   bool_okrS  m  s    !T))r    c                 b    U c  g UR                  S5      (       a  [        U 5      $ [        U 5      $ )Nas_score)r   r'   r   rv   s     r   
parse_zaddrV  q  s.    {{:Xx=r    c                    / n[        U 5      R                  5        Hl  n0 nUR                  S5      nS nU H4  nSU;   a  UR                  SS5      u  pXU'   UnM%  XF==   SU-   -  ss'   M6     U(       d  M[  UR                  U5        Mn     U$ )N r$   r&   )r   r6   r   r:   )
r   rw   clientsr3  client_dicttokenslast_keytokenr=   r)   s
             r   parse_client_listr^  y  s    G(#..0Ee|"[[a0
#(C  %u4%  ;NN;'! 1" Nr    c                     U  Vs/ s H  o"b  [        U5      OS PM     n nU =(       a    [        U 5      =(       d    0 $ s  snf rs   )r   rD   )r   rw   r  s      r   parse_config_getr`    s<    DLMHq=Qd:HHM/h/525 Ns   =c                     U (       d  0 $ U R                  5        VVs0 s H$  u  p#Ub  [        U5      OSUb  [        U5      OS_M&     snn$ s  snnf )u  RESP3-wire CONFIG GET → today's RESP2 ``dict[str, str]`` shape.

On RESP3 the server returns a map; convert both keys and values via
``str_if_bytes`` so callers using ``r.config_get()["timeout"]``
keep working when the wire is RESP3 with ``legacy_responses=True``.
NrR   r9  s       r   &parse_config_get_resp3_to_resp2_legacyrb    s_     	
 #..*	 +JC !_S$#(#4L$	? +	  s   +Ac                 $    U u  p#[        U5      U4$ rs   r   )r   rw   cursorr  s       r   
parse_scanre    s    IFv;>r    c                     U u  p#UR                  SS5      nU(       a  U=(       d    / nOU=(       a    [        U5      =(       d    0 n[        U5      U4$ )N	no_valuesF)r   rD   r   )r   rw   rd  r  rg  payloads         r   parse_hscanri    sH    IFK/I'r(a(.Bv;r    c           
          [        UR                  S[        5      5      nU u  p4[        U5      n[	        U5      [        [        U[        X%5      5      5      4$ Nr   )r   r   r'   r   r   rG   r   ru   )r   rw   r   rd  r  r   s         r   parse_zscanrl    sH    +GKK8I5,QROIF	aBv;SS%=>???r    c                     [        UR                  S[        5      5      nU u  p4[        U5      n[	        U5      [        XU5       VVs/ s H  u  pgXb" [        U5      5      /PM     snn4$ s  snnf rk  )r   r   r'   r   r   r   )r   rw   r   rd  r  r   r)   r   s           r   parse_zscan_unifiedrn    si    +GKK8I5,QROIF	aBv;CFr;CN<5e-.;   s   A*c                 L    U  Vs/ s H  o"b  [        U5      OS PM     sn$ s  snf rs   r   )r   rw   r   s      r   parse_zmscorerp    s&    EMNXE-E%L47XNNNs   !c                    ^ UR                  SS5      (       a  SOSmU4S jnU  Vs/ s H
  o2" U5      PM     sn$ s  snf )Ndecode_responsesFrX      c                 f  > U S   [        U S   5      [        U S   5      S.n[        U S   [        5      (       a8  TR                  U S   5      US'   [	        U 5      S:  a  U S   US	'   U S
   US'   U$ U S   US'   TR                  U S   5      US'   [	        U 5      S:  a  U S
   US	'   U S   US'   U$ )Nr   r&   r   )id
start_timedurationrB  command      client_address   client_name
complexity   )r   rF   rG   joinr,  )r,   rg   spaces     r   
parse_item%parse_slowlog_get.<locals>.parse_item  s    Qs47|TRSWV d1gt$$ %

47 3F9 4yA~+/7'((,Q}%  $(7F<  %

47 3F9 4yA~+/7'((,Q}%r    )r   )r   rw   r  r,   r  s       @r   parse_slowlog_getr    s?    ;;1599CtE. *22Jt222s   ;c                    UR                  SS5      (       a  [        U 5      $ UR                  SS5      (       a  UR                  SS5      (       a@  U S    Vs/ s H/  n[        US   5      /[        [        [        USS 5      5      -   PM1     nnO,U S    Vs/ s H  n[        [        [        U5      5      PM     nn[        U S   5      U[        U S	   5      [        U S
   5      0$ [        U 5      $ s  snf s  snf )a  
Parse the response from `STRALGO` command.
Without modifiers the returned value is string.
When LEN is given the command returns the length of the result
(i.e integer).
When IDX is given the command returns a dictionary with the LCS
length and all the ranges in both the strings, start and end
offset for each string, where there are matches.
When WITHMATCHLEN is given, each array representing a match will
also have the length of the match at the beginning of the array.
r,  Fidxwithmatchlenr&   r1   Nr   r   rB  )r   r   rG   ru   tupler   )r   rw   matchmatchess       r   parse_stralgor    s     {{5%  8}{{5%  ;;~u-- &a[(E eBi."T#eU3BZ*@%AA(  G
 =EQKHK5tCu-.KGH!%w!%s8A;'7
 	
 !!
 Is   6C2#C7c                 "   UR                  SS5      (       a  [        U 5      $ UR                  SS5      (       a  UR                  SS5      (       aE  U S    VVs/ s H2  n[        US   5      /USS  Vs/ s H  n[        U5      PM     sn-   PM4     nnnO0U S    VVs/ s H  o" Vs/ s H  n[        U5      PM     snPM      nnn[        U S   5      U[        U S	   5      [        U S
   5      0$ [        U 5      $ s  snf s  snnf s  snf s  snnf )z
Parse STRALGO into the approved unified shape.

The legacy parser returns tuple ranges for IDX responses. Unified
responses use list ranges so RESP2 and RESP3 produce the same value.
r,  Fr  r  r&   r1   Nr   r   rB  )r   r   rG   r   )r   rw   r  mr  s        r   parse_stralgo_unifiedr    s    {{5%  8}{{5%  ;;~u-- &a[(E U2Y U3BZ#@ZDGZ#@@(  G
 >Fa[I[E/AQ/[GI!%w!%s8A;'7
 	
 !! $A
 0Is0   D 4C;		D 	D'D<D;D Dc                    UR                  SS5      (       a  [        U 5      $ UR                  SS5      (       a  [        U [        5      (       d  [	        U 5      $ U R                  SU R                  S/ 5      5      nU R                  SU R                  SS5      5      nUR                  SS5      (       aB  U VVs/ s H2  n[        US	   5      /US
S	  Vs/ s H  n[        U5      PM     sn-   PM4     nnnO-U VVs/ s H  oD Vs/ s H  n[        U5      PM     snPM      nnnU[        U5      S.$ [	        U 5      $ s  snf s  snnf s  snf s  snnf )zEParse RESP3 STRALGO into the same value as ``parse_stralgo_unified``.r,  Fr  r  s   matchess   lenr   r  r1   N)r  r,  )r   r   rF   r   r   rG   )r   rw   raw_matchesraw_lenr  r  r  s          r   parse_stralgo_resp3_unifiedr    s1   {{5%  8}{{5%  (D))))ll9hll:r.JK,,uhll61&=>;;~u-- )(E U2Y U3BZ#@ZDGZ#@@(  G
 >II[E/AQ/[GI"3w<88!! $A
 0Is0   :ED=*	E<	EEE=EEc                 X    [        U 5      n [        S U R                  5        5       5      $ )Nc              3   T   #    U  H  o(       d  M  UR                  S 5      v   M      g7fr   r   )r   r<   s     r   r   %parse_cluster_info.<locals>.<genexpr>1  s      J,ADT

3,As   
(()r   r   r6   rv   s     r   parse_cluster_infor  /  s&    H%HJH,?,?,AJJJr    c                 h   U R                  S5      nU R                  S5      S S u  p#pEpgpUR                  S5      S   n
SU;   a,  SU;   a&  UR                  S5      S   R                  S5      S   OSnUUUUUUU/ / U	S:X  a  S	OS
S.
n[        U5      S:  a  [        USS  5      u  pXsUS'   US'   X4$ )NrX     @r   r#   r&    	connectedTF)
node_idhostnamerh   	master_idlast_ping_sentlast_pong_rcvdepochslots
migrationsr  	   r  r  )r   r,  _parse_slots)r<   
line_itemsr  addrrh   r  pingpongr  r  ipr  	node_dictr  r  s                  r   _parse_node_liner  4  s    CJDHJJsOTVUVDWAG5T	C	B36$;3$;tzz#q!'',Q/TVH&+5T5I :!(AB86;3	'Il3=r    c                 X   / / p!U  H  nSU;   a-  USS R                  SS5      u  pEUR                  XESS.5        M6  SU;   a-  USS R                  SS5      u  pFUR                  XFSS.5        Mi  UR                  S5       Vs/ s H  owPM     nnUR                  U5        M     X4$ s  snf )	Nz->-r&   r1   	migrating)slotr  r   z-<-	importing-)r   r:   )slot_rangesr  r  s_rangeslot_iddst_node_idsrc_node_idsls           r   r  r  K  s    B:G#*1R=#6#6ua#@ G ;O g#*1R=#6#6ua#@ G ;O %,MM#$67$6br$6G7LL!   8s   B'c                 |    [        U [        [        45      (       a  U R                  5       n [	        S U  5       5      $ )z
@see: https://redis.io/commands/cluster-nodes  # string / bytes
@see: https://redis.io/commands/cluster-replicas # list of string / bytes
c              3   J   #    U  H  n[        [        U5      5      v   M     g 7frs   )r  r   )r   nodes     r   r   &parse_cluster_nodes.<locals>.<genexpr>f  s     J d!344s   !#)rF   r   r   r6   r   rv   s     r   parse_cluster_nodesr  _  s4    
 (S%L))&&(JJJJr    c                     US   (       d
  US   (       a  U $  [        U [        5      (       d  U /nOU nUS   (       d  US   (       d  US   (       d  U$ [        S [        S.nS /nUS	 Vs/ s H  oQU   (       d  M  X5   PM     sn-  nU Vs/ s H"  n[        [        S
 [        XF5      5      5      PM$     sn$ ! [          a    U s $ f = fs  snf s  snf )z
Parse the response of 'GEOSEARCH', GEORADIUS' and 'GEORADIUSBYMEMBER'
commands according to 'withdist', 'withhash' and 'withcoord' labels.
store
store_distwithdist	withcoordwithhashc                 :    [        U S   5      [        U S   5      4$ r   r   r   s    r   <lambda>)parse_geosearch_generic.<locals>.<lambda>      r!uuRU| <r    r  r  r  c                     U $ rs    rS   s    r   r  r    s    1r    r  r  r  c                     U S   " U S   5      $ r   r  fvs    r   r  r        1ber    KeyErrorrF   rG   r'   r   ru   r   )r   rw   response_listcastfor  s          r   parse_geosearch_genericr  i  s    
7w|4 O	  5 h%%!
 :w{';GJDW <D 
A@	O@aAJ'$'@	OOACPQ=aD,c!i89=QQ-  * 
PQs#   B: ,C=C)C:C	C	c                     US   (       d
  US   (       a  U $  [        U [        5      (       a  U OU /nUS   (       d  US   (       d  US   (       d  U$ [        S [        S.nS /nUS	 Vs/ s H  oQU   (       d  M  X5   PM     sn-  nU Vs/ s H"  n[        [        S
 [        XF5      5      5      PM$     sn$ ! [          a    U s $ f = fs  snf s  snf )z>
Parse GEOSEARCH/GEORADIUS responses using tuple coordinates.
r  r  r  r  r  c                 :    [        U S   5      [        U S   5      4$ r   r   r  s    r   r  1parse_geosearch_generic_unified.<locals>.<lambda>  r  r    r  c                     U $ rs   r  r  s    r   r  r    s    qr    r  c                     U S   " U S   5      $ r   r  r  s    r   r  r    r  r    r  )r   rw   r  r  funcsr  r  s          r   parse_geosearch_generic_unifiedr    s    7w|4O  5
 !+8T : :H
M:w{';GJDW <D
 ME	DSD!PQ
gdgDSSEGTU}!D,c%m<=}UU   TUs#   B9 +C<C)C9CCc                    0 nU  H  n0 n[        US   5      nXTS'   [        US   5      US'   US    Vs/ s H  n[        U5      PM     snUS'   US   US'   US	   US
'   US   US'   [        U5      S:  a"  US    Vs/ s H  n[        U5      PM     snUS'   [        U5      S:  a  US   US'   US   US'   US   US'   XBU'   M     U$ s  snf s  snf Nr   ri   r&   arityr   rh   rB  first_key_posrz  last_key_posr|  
step_country  acl_categoriesr  tipsr  key_specificationsr  subcommandsr   r   r,  )r   rw   commandsrx  cmd_dictcmd_namerj   categorys           r   parse_commandr    s   H
+#
O<CAJGJD\$/JG$+AJ!#*1: !(w<!7>qz*7A8X&z*H%& w<!&qzHV-4QZH)*&-ajH]#%# $ O H
*   C	=Cc                    0 nU  H  n0 n[        US   5      nXTS'   [        US   5      US'   US    Vs1 s H  n[        U5      iM     snUS'   US   US'   US	   US
'   US   US'   [        U5      S:  a"  US    Vs1 s H  n[        U5      iM     snUS'   [        U5      S:  a  US   US'   US   US'   US   US'   XBU'   M     U$ s  snf s  snf r  r  )r   rw   r  rx  r  r  rj   r3  s           r   parse_command_unifiedr    s
   H
+#
O<CAJGJD\$/JG$+AJ!#*1: !(w<!CJ1:)N:a,q/:)NH%&w<!&qzHV-4QZH)*&-ajH]#%   O H
 *Or  c                 8   0 nU  H  n0 n[        US   5      nXTS'   US   US'   US    Vs1 s H  n[        U5      iM     snUS'   US   US'   US	   US
'   US   US'   US   US'   [        U5      S:  a  US   US'   US   US'   US   US'   XBU'   M     U$ s  snf r  )r   r,  )r   rw   r  rx  r  r  rj   s          r   parse_command_resp3r    s    H
+##AJ<CAJGJD\$/JG$+AJ!#*1: !(%,QZ!"w<!&qzHV-4QZH)*&-ajH]#%   O Hs   Bc           	      D    [        [        U SS S2   U SS S2   5      5      $ )Nr   r   r&   )rG   r   rv   s     r   parse_pubsub_numsubr    s(    HQTTNHQTTN344r    c                 L    [        U [        5      (       a  U $ [        U 5      S:H  $ rQ  )rF   r   r   rv   s     r   parse_client_killr    s$    (C  !T))r    c                 H   U c  g [        U [        5      (       a  [        U SS9nO.U R                  5        VVs0 s H  u  p4[	        U5      U_M     nnn[        [        [        US   5      5      US'   [        [        [        US   5      5      US'   [	        US   5      US'   [        US   [        5      (       d  [        US   [        5      (       a)  [        [	        US   5      R                  S5      5      US'   US   S/:X  a  / US'   S	U;   ah  [        US	   [        5      (       d  [        US	   [        5      (       a)  [        [	        US	   5      R                  S5      5      US	'   US	   S/:X  a  / US	'   S
U;   a  US
   / :w  aL  [        US
   S   [        5      (       a1  US
    Vs/ s H  n[        [        [        U5      5      PM     snUS
'   O\US
   / :w  aS  US
    VVVs/ s H;  nUR                  5        VVs0 s H  u  pg[	        U5      [	        U5      _M     snnPM=     snnnUS
'   / / pUS   R                  S5       H-  n
SU
;   a  U	R                  U
5        M  UR                  U
5        M/     XS'   XS'   SUS   ;   US'   U$ s  snnf s  snf s  snnf s  snnnf )NTrM   rh   	passwordsr  r   rX  r  channels	selectorsr   r  
categoriesonenabled)
rF   rG   rD   rE   r   ru   r   r   r   r:   )r   rw   r  r=   r)   selectorr-   r*   r  r  rx  s              r   parse_acl_getuserr     s   (D!!X48;C>>;KL;KZSS!5(;KL \4=9:DMStK/@ABD#D$45D$v,$$
4<(G(GLf6<<SABVF|tVTd:&,,
4
;KU0S0S#Lj1A$B$H$H$MND
t#!Dd"z${2CA2F'M'MBF{BS!BShSx01BS!D +"$ !%[ 1! 1H ?Gnn>NO>Ndaa,q/1>NO 1!D rj
#))#.&)Wn
'"(//':R /  #d7m+DOKE M"!
 P!s#   J)#J%J>!JJJc                    U c  g [        U [        5      (       a\  / nU  HR  n[        USS5      nUR                  SS5      n[	        U5      US'   [        US   5      US'   UR                  U5        MT     U$ [        U 5      nU$ )NTclient-infor  age-seconds)rF   rG   rD   r   parse_client_infor'   r:   rS  )r   rw   r  loglog_dataclient_infos         r   parse_acl_logr    s    (D!!C$S$5H",,}b9K&7&DH]# ',H],C&DH]#KK!  K x Kr    c                    U c  g[        U [        5      (       d  [        U 5      $ / nU  H  n[        U[        5      (       a/  UR	                  5        VVs0 s H  u  pE[        U5      U_M     nnnO[        USS5      nUR                  SS5      n[        U5      US'   [        US   5      US'   UR                  U5        M     U$ s  snnf )u  RESP3-wire ACL LOG → today's RESP2 parsed shape.

Each log entry arrives as a ``dict`` on RESP3 wire instead of a flat
list of pairs; convert ``client-info`` from a string blob into the
parsed ``dict`` and ``age-seconds`` to ``float`` so the Python shape
matches what :func:`parse_acl_log` produces from RESP2 wire.

Also used as the unified callback (Set D): the legacy and unified
shapes coincide for ACL LOG.
NTr  r  r  )rF   rG   rS  r   rE   r   rD   r   r  r'   r:   )r   rw   r  r  r-   r*   r  r  s           r   #parse_acl_log_resp3_to_resp2_legacyr
  .  s     h%%x  Dc4  7:yy{C{tqQ*{HCH$S$5Hll="5"3K"@"'(?"@H  K Ds   Cc                    U c  g[        U [        5      (       d  [        U 5      $ / nU  H  n[        U[        5      (       a/  UR	                  5        VVs0 s H  u  pE[        U5      U_M     nnnO[        USS5      nSU;   a  [        US   5      US'   SU;   a  [        US   5      US'   [        UR	                  5       5       H  u  pxUS;  d  M  [        U5      Xg'   M     UR                  U5        M     U$ s  snnf )z4Parse RESP3 ACL LOG into the approved unified shape.NTr  r  )r  r  )
rF   rG   rS  r   rE   r   rD   r'   r  r:   )	r   rw   r  r0  r-   r*   r  r=   r)   s	            r   parse_acl_log_resp3_unifiedr  J  s    h%%x  DeT""7<{{}E}tqQ*}HEH$UD$7HH$&+H],C&DH]#H$&78O&PH]#x~~/0JC88 ,U 3 1 	H  K Fs   C9c                     [        U 40 UD6nUc  U$ UR                  S5      nU(       aM  [        US   [        5      (       a5  U Vs/ s H$  n[	        [        USSS2   USSS2   5      5      PM&     snUS'   U$ s  snf )u   ACL GETUSER → unified shape with selectors as ``list[dict]``.

On RESP2 wire each selector arrives as a flat ``[k, v, k, v, …]``
list; pair them into dicts to match the RESP3 wire shape.
Nr  r   r   r&   )r   r   rF   rG   r   r   )r   rw   r  r  r  s        r   parse_acl_getuser_unifiedr  a  s     X11D|%IZ	!d33FO
FO(DXadd^Xadd^45i
[ K
s   +A9c                 &   [        U 40 UD6nUc  U$ UR                  S5      nU(       aZ  [        US   [        5      (       aB  U VVVs/ s H-  oDR	                  5        VVs/ s H  oU  H  ofPM     M     snnPM/     snnnUS'   U$ s  snnf s  snnnf )u   RESP3-wire ACL GETUSER → today's RESP2 selectors as flat lists.

Each selector arrives as a ``dict`` on RESP3 wire; flatten back to
the interleaved ``[k, v, k, v, …]`` form produced by RESP2 wire.
r  r   )r   r   rF   r   rE   )r   rw   r  r  r  r   r,   s          r   'parse_acl_getuser_resp3_to_resp2_legacyr  r  s     X11D|%IZ	!d33MV
MVNN,<,bTT,<Y
[ K =
s   B B4BBc                     0 n[        U 5      R                  5       R                  5        H  nUR                  S5      u  p0XU'   M     S H  nXA;   d  M
  [        X   5      X'   M     U$ )z[
Parsing client-info in ACL Log in following format.
"key1=value1 key2=value2 key3=value3"
r$   >   dbru  ageoblollsubidleomempsubqbufmultitot-memargv-mem	qbuf-free)r   stripr   r   )r)   r  r;   r=   int_keys        r   r  r    sm    
 KU#))+113ZZ_
 C 4
  !#&{';#<K #$ r    c                 `    UR                  S5      (       a  U $ U =(       a    [        U 5      S:H  $ )z
Handle SET result since GET argument is available since Redis 6.2.
Parsing SET result into:
- BOOL
- String when GET argument is used
r   rR  )r   r   rv   s     r   parse_set_resultr"    s/     {{5 6X.$66r    c                 F   U c  g/ nU  H  n[        U[        5      (       a  UR                  U5        M+  [        U5      nSU;   a  SOSnXT;   a9  XE   nU Vs/ s H%  n[        U[        5      (       a  UO
[        U5      PM'     snXE'   UR                  U5        M     U$ s  snf )u3  FUNCTION LIST → unified ``list[dict]`` with bytes keys.

Accepts either RESP2 wire (``list[list]`` of flat ``[k, v, k, v, …]``
pairs, with the nested ``b"functions"`` value also a flat list of
flat lists) or RESP3 wire (``list[dict]`` already in nested-map
form). Both are normalised to ``list[dict]``.
N	   functions	functions)rF   r   r:   rD   )r   rw   rg   liblib_dictfunc_keyr%  funcs           r   parse_function_list_unifiedr*    s     Fc4  MM# %#/8#;< *I &"%D #4..M$4GG%"H 	h  M"s   ,Bc                    U c  g/ nU  H  n[        U[        5      (       d  UR                  U5        M+  / nUR                  5        H  u  pVUR                  U5        US:X  d  US:X  ah  UR                  U VVV	s/ s HE  n[        U[        5      (       a+  UR                  5        VV	s/ s H  o  H  oPM     M     sn	nOUPMG     sn	nn5        M  UR                  U5        M     UR                  U5        M     U$ s  sn	nf s  sn	nnf )u   RESP3-wire FUNCTION LIST → today's RESP2 ``list[list]`` shape.

Each library and each nested function arrives as a ``dict``; flatten
them back to interleaved ``[k, v, k, v, …]`` lists so the Python
shape matches what RESP2 wire produces natively.
Nr$  r%  )rF   r   r:   rE   )
r   rw   rg   r&  r   r=   r)   r)  r   r,   s
             r   )parse_function_list_resp3_to_resp2_legacyr,    s     F#t$$MM#))+JCKKl"c[&8
 %*	 %*D &dD11 )-

D"D!" %*	 E" & 	d% & M Es   9.D'C<;
D<Dc                     U c  gU  VVVs/ s HQ  n[        U[        5      (       a/  UR                  5        VVs0 s H  u  p4[        U5      U_M     snnO	[	        USS9PMS     snnn$ s  snnf s  snnnf )u   CLUSTER LINKS → unified ``list[dict]`` with string keys.

Accepts either RESP2 wire (``list[list]`` of flat pairs) or RESP3
wire (``list[dict]``). Both are normalised to ``list[dict]``.
NTrM   )rF   r   rE   r   rD   )r   rw   r,   r-   r*   s        r   parse_cluster_links_unifiedr.    sy     
 	 D dD!! )-

5a!	54T2	3 	 5s   .A.A(A.(A.c                     U c  gU  VVVs/ s HE  n[        U[        5      (       a+  UR                  5        VVs/ s H  o3  H  oDPM     M     snnOUPMG     snnn$ s  snnf s  snnnf )u   RESP3-wire CLUSTER LINKS → today's RESP2 ``list[list]`` shape.

Each link arrives as a ``dict`` with bytes keys; flatten back to
interleaved ``[k, v, k, v, …]`` lists so the Python shape matches
what RESP2 wire produces natively.
N)rF   r   rE   )r   rw   linkr   r,   s        r   )parse_cluster_links_resp3_to_resp2_legacyr1    sg      D 9C48N8N

4"4TXX 4s   .A"A
A"A"c                 J    [         R                  U R                  5       U5      $ rs   )r   fromkeysr   )
key_stringcallbacks     r   string_keys_to_dictr6    s    ==))+X66r    r&   )_RedisCallbacks_RedisCallbacksRESP2_RedisCallbacksRESP2Unified_RedisCallbacksRESP3_RedisCallbacksRESP3Unified!_RedisCallbacksRESP3toRESP2Legacyget_response_callbacks)FF)zr   redis.utilsr   r   r   r>   rK   rN   rP   rT   r   ro   rf   rk   rq   rx   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rD   rn   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  r  r  r  r  r  r#  r%  r'  r4  r6  r:  r=  r?  rH  rF  rO  rS  rV  r^  r`  rb  re  ri  rl  rn  rp  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.  r1  r6  response_callbacksr7  r8  r9  r:  r;  r<  r=  r  r    r   <module>r@     s?    $5$0f
VsC s 	
 C # # s c S 3 3 # 3   c!" C#$ / 6 %=PNY@!&,	3
37D71&NP
>P9P&::< YY(:5<'=>J"		/
*,6
"
 @O
3:":"0"(K
.(K!RHV2.**5*(V$8.""@76@ 7  r    