import builtins
from _typeshed import Incomplete, SupportsItems
from collections.abc import AsyncIterator, Awaitable, Callable, Iterable, Iterator, Mapping, Sequence
from datetime import datetime, timedelta
from typing import Any, Generic, Literal, TypeVar, overload

from ..asyncio.client import Redis as AsyncRedis
from ..client import _CommandOptions, _Key, _Value
from ..typing import ChannelT, EncodableT, KeyT, PatternT, ScriptTextT, StreamIdT

_ScoreCastFuncReturn = TypeVar("_ScoreCastFuncReturn")
_StrType = TypeVar("_StrType", bound=str | bytes)

class ACLCommands(Generic[_StrType]):
    def acl_cat(self, category: str | None = None, **kwargs: _CommandOptions) -> list[str]: ...
    def acl_deluser(self, *username: str, **kwargs: _CommandOptions) -> int: ...
    def acl_genpass(self, bits: int | None = None, **kwargs: _CommandOptions) -> str: ...
    def acl_getuser(self, username: str, **kwargs: _CommandOptions) -> Any | None: ...
    def acl_help(self, **kwargs: _CommandOptions): ...
    def acl_list(self, **kwargs: _CommandOptions) -> list[str]: ...
    def acl_log(self, count: int | None = None, **kwargs: _CommandOptions): ...
    def acl_log_reset(self, **kwargs: _CommandOptions): ...
    def acl_load(self, **kwargs: _CommandOptions) -> bool: ...
    def acl_save(self, **kwargs: _CommandOptions): ...
    def acl_setuser(
        self,
        username: str,
        enabled: bool = False,
        nopass: bool = False,
        passwords: Sequence[str] | None = None,
        hashed_passwords: Sequence[str] | None = None,
        categories: Sequence[str] | None = None,
        commands: Sequence[str] | None = None,
        keys: Sequence[str] | None = None,
        channels: Iterable[ChannelT] | None = None,
        selectors: Iterable[tuple[str, KeyT]] | None = None,
        reset: bool = False,
        reset_keys: bool = False,
        reset_channels: bool = False,
        reset_passwords: bool = False,
        **kwargs: _CommandOptions,
    ) -> bool: ...
    def acl_users(self, **kwargs: _CommandOptions) -> list[str]: ...
    def acl_whoami(self, **kwargs: _CommandOptions) -> str: ...

class AsyncACLCommands(Generic[_StrType]):
    async def acl_cat(self, category: str | None = None, **kwargs: _CommandOptions) -> list[str]: ...
    async def acl_deluser(self, *username: str, **kwargs: _CommandOptions) -> int: ...
    async def acl_genpass(self, bits: int | None = None, **kwargs: _CommandOptions) -> str: ...
    async def acl_getuser(self, username: str, **kwargs: _CommandOptions) -> Any | None: ...
    async def acl_help(self, **kwargs: _CommandOptions): ...
    async def acl_list(self, **kwargs: _CommandOptions) -> list[str]: ...
    async def acl_log(self, count: int | None = None, **kwargs: _CommandOptions): ...
    async def acl_log_reset(self, **kwargs: _CommandOptions): ...
    async def acl_load(self, **kwargs: _CommandOptions) -> bool: ...
    async def acl_save(self, **kwargs: _CommandOptions): ...
    async def acl_setuser(
        self,
        username: str,
        enabled: bool = False,
        nopass: bool = False,
        passwords: Sequence[str] | None = None,
        hashed_passwords: Sequence[str] | None = None,
        categories: Sequence[str] | None = None,
        commands: Sequence[str] | None = None,
        keys: Sequence[str] | None = None,
        channels: Iterable[ChannelT] | None = None,
        selectors: Iterable[tuple[str, KeyT]] | None = None,
        reset: bool = False,
        reset_keys: bool = False,
        reset_channels: bool = False,
        reset_passwords: bool = False,
        **kwargs: _CommandOptions,
    ) -> bool: ...
    async def acl_users(self, **kwargs: _CommandOptions) -> list[str]: ...
    async def acl_whoami(self, **kwargs: _CommandOptions) -> str: ...

class ManagementCommands:
    def bgrewriteaof(self, **kwargs: _CommandOptions): ...
    def bgsave(self, schedule: bool = True, **kwargs: _CommandOptions): ...
    def role(self): ...
    def client_kill(self, address: str, **kwargs: _CommandOptions) -> bool: ...
    def client_kill_filter(
        self,
        _id: Incomplete | None = None,
        _type: Incomplete | None = None,
        addr: Incomplete | None = None,
        skipme: Incomplete | None = None,
        laddr: Incomplete | None = None,
        user: Incomplete | None = None,
        **kwargs: _CommandOptions,
    ): ...
    def client_info(self, **kwargs: _CommandOptions): ...
    def client_list(
        self, _type: str | None = None, client_id: list[str] = [], **kwargs: _CommandOptions
    ) -> list[dict[str, str]]: ...
    def client_getname(self, **kwargs: _CommandOptions) -> str | None: ...
    def client_getredir(self, **kwargs: _CommandOptions): ...
    def client_reply(self, reply, **kwargs: _CommandOptions): ...
    def client_id(self, **kwargs: _CommandOptions) -> int: ...
    def client_tracking_on(
        self,
        clientid: Incomplete | None = None,
        prefix=[],
        bcast: bool = False,
        optin: bool = False,
        optout: bool = False,
        noloop: bool = False,
    ): ...
    def client_tracking_off(
        self,
        clientid: Incomplete | None = None,
        prefix=[],
        bcast: bool = False,
        optin: bool = False,
        optout: bool = False,
        noloop: bool = False,
    ): ...
    def client_tracking(
        self,
        on: bool = True,
        clientid: Incomplete | None = None,
        prefix=[],
        bcast: bool = False,
        optin: bool = False,
        optout: bool = False,
        noloop: bool = False,
        **kwargs: _CommandOptions,
    ): ...
    def client_trackinginfo(self, **kwargs: _CommandOptions): ...
    def client_setname(self, name: str, **kwargs: _CommandOptions) -> bool: ...
    def client_unblock(self, client_id, error: bool = False, **kwargs: _CommandOptions): ...
    def client_pause(self, timeout, all: bool = True, **kwargs: _CommandOptions): ...
    def client_unpause(self, **kwargs: _CommandOptions): ...
    def client_no_evict(self, mode: str): ...
    def client_no_touch(self, mode: str): ...
    def command(self, **kwargs: _CommandOptions): ...
    def command_info(self, **kwargs: _CommandOptions): ...
    def command_count(self, **kwargs: _CommandOptions): ...
    def config_get(self, pattern: PatternT = "*", *args: PatternT, **kwargs: _CommandOptions): ...
    def config_set(self, name: KeyT, value: EncodableT, *args: KeyT | EncodableT, **kwargs: _CommandOptions): ...
    def config_resetstat(self, **kwargs: _CommandOptions): ...
    def config_rewrite(self, **kwargs: _CommandOptions): ...
    def dbsize(self, **kwargs: _CommandOptions) -> int: ...
    def debug_object(self, key, **kwargs: _CommandOptions): ...
    def debug_segfault(self, **kwargs: _CommandOptions): ...
    def echo(self, value: _Value, **kwargs: _CommandOptions) -> bytes: ...
    def flushall(self, asynchronous: bool = False, **kwargs: _CommandOptions) -> bool: ...
    def flushdb(self, asynchronous: bool = False, **kwargs: _CommandOptions) -> bool: ...
    def sync(self): ...
    def psync(self, replicationid, offset): ...
    def swapdb(self, first, second, **kwargs: _CommandOptions): ...
    def select(self, index, **kwargs: _CommandOptions): ...
    def info(self, section: _Key | None = None, *args: _Key, **kwargs: _CommandOptions) -> Mapping[str, Any]: ...
    def lastsave(self, **kwargs: _CommandOptions): ...
    def lolwut(self, *version_numbers: _Value, **kwargs: _CommandOptions) -> bytes: ...
    def reset(self) -> None: ...
    def migrate(
        self,
        host,
        port,
        keys,
        destination_db,
        timeout,
        copy: bool = False,
        replace: bool = False,
        auth: Incomplete | None = None,
        **kwargs: _CommandOptions,
    ): ...
    def object(self, infotype, key, **kwargs: _CommandOptions): ...
    def memory_doctor(self, **kwargs: _CommandOptions): ...
    def memory_help(self, **kwargs: _CommandOptions): ...
    def memory_stats(self, **kwargs: _CommandOptions) -> dict[str, Any]: ...
    def memory_malloc_stats(self, **kwargs: _CommandOptions): ...
    def memory_usage(self, key, samples: Incomplete | None = None, **kwargs: _CommandOptions): ...
    def memory_purge(self, **kwargs: _CommandOptions): ...
    def ping(self, **kwargs: _CommandOptions) -> bool: ...
    def quit(self, **kwargs: _CommandOptions): ...
    def replicaof(self, *args, **kwargs: _CommandOptions): ...
    def save(self, **kwargs: _CommandOptions) -> bool: ...
    def shutdown(
        self,
        save: bool = False,
        nosave: bool = False,
        now: bool = False,
        force: bool = False,
        abort: bool = False,
        **kwargs: _CommandOptions,
    ) -> None: ...
    def slaveof(self, host: Incomplete | None = None, port: Incomplete | None = None, **kwargs: _CommandOptions): ...
    def slowlog_get(self, num: Incomplete | None = None, **kwargs: _CommandOptions): ...
    def slowlog_len(self, **kwargs: _CommandOptions): ...
    def slowlog_reset(self, **kwargs: _CommandOptions): ...
    def time(self, **kwargs: _CommandOptions): ...
    def wait(self, num_replicas, timeout, **kwargs: _CommandOptions): ...

class AsyncManagementCommands:
    async def bgrewriteaof(self, **kwargs: _CommandOptions): ...
    async def bgsave(self, schedule: bool = True, **kwargs: _CommandOptions): ...
    async def role(self): ...
    async def client_kill(self, address: str, **kwargs: _CommandOptions) -> bool: ...
    async def client_kill_filter(
        self,
        _id: Incomplete | None = None,
        _type: Incomplete | None = None,
        addr: Incomplete | None = None,
        skipme: Incomplete | None = None,
        laddr: Incomplete | None = None,
        user: Incomplete | None = None,
        **kwargs: _CommandOptions,
    ): ...
    async def client_info(self, **kwargs: _CommandOptions): ...
    async def client_list(
        self, _type: str | None = None, client_id: list[str] = [], **kwargs: _CommandOptions
    ) -> list[dict[str, str]]: ...
    async def client_getname(self, **kwargs: _CommandOptions) -> str | None: ...
    async def client_getredir(self, **kwargs: _CommandOptions): ...
    async def client_reply(self, reply, **kwargs: _CommandOptions): ...
    async def client_id(self, **kwargs: _CommandOptions) -> int: ...
    async def client_tracking_on(
        self,
        clientid: Incomplete | None = None,
        prefix=[],
        bcast: bool = False,
        optin: bool = False,
        optout: bool = False,
        noloop: bool = False,
    ): ...
    async def client_tracking_off(
        self,
        clientid: Incomplete | None = None,
        prefix=[],
        bcast: bool = False,
        optin: bool = False,
        optout: bool = False,
        noloop: bool = False,
    ): ...
    async def client_tracking(
        self,
        on: bool = True,
        clientid: Incomplete | None = None,
        prefix=[],
        bcast: bool = False,
        optin: bool = False,
        optout: bool = False,
        noloop: bool = False,
        **kwargs: _CommandOptions,
    ): ...
    async def client_trackinginfo(self, **kwargs: _CommandOptions): ...
    async def client_setname(self, name: str, **kwargs: _CommandOptions) -> bool: ...
    async def client_unblock(self, client_id, error: bool = False, **kwargs: _CommandOptions): ...
    async def client_pause(self, timeout, all: bool = True, **kwargs: _CommandOptions): ...
    async def client_unpause(self, **kwargs: _CommandOptions): ...
    async def command(self, **kwargs: _CommandOptions): ...
    async def command_info(self, **kwargs: _CommandOptions): ...
    async def command_count(self, **kwargs: _CommandOptions): ...
    async def config_get(self, pattern: PatternT = "*", *args: PatternT, **kwargs: _CommandOptions): ...
    async def config_set(self, name: KeyT, value: EncodableT, *args: KeyT | EncodableT, **kwargs: _CommandOptions): ...
    async def config_resetstat(self, **kwargs: _CommandOptions): ...
    async def config_rewrite(self, **kwargs: _CommandOptions): ...
    async def dbsize(self, **kwargs: _CommandOptions) -> int: ...
    async def debug_object(self, key, **kwargs: _CommandOptions): ...
    async def debug_segfault(self, **kwargs: _CommandOptions): ...
    async def echo(self, value: _Value, **kwargs: _CommandOptions) -> bytes: ...
    async def flushall(self, asynchronous: bool = False, **kwargs: _CommandOptions) -> bool: ...
    async def flushdb(self, asynchronous: bool = False, **kwargs: _CommandOptions) -> bool: ...
    async def sync(self): ...
    async def psync(self, replicationid, offset): ...
    async def swapdb(self, first, second, **kwargs: _CommandOptions): ...
    async def select(self, index, **kwargs: _CommandOptions): ...
    async def info(self, section: _Key | None = None, *args: _Key, **kwargs: _CommandOptions) -> Mapping[str, Any]: ...
    async def lastsave(self, **kwargs: _CommandOptions): ...
    async def lolwut(self, *version_numbers: _Value, **kwargs: _CommandOptions) -> bytes: ...
    async def reset(self) -> None: ...
    async def migrate(
        self,
        host,
        port,
        keys,
        destination_db,
        timeout,
        copy: bool = False,
        replace: bool = False,
        auth: Incomplete | None = None,
        **kwargs: _CommandOptions,
    ): ...
    async def object(self, infotype, key, **kwargs: _CommandOptions): ...
    async def memory_doctor(self, **kwargs: _CommandOptions): ...
    async def memory_help(self, **kwargs: _CommandOptions): ...
    async def memory_stats(self, **kwargs: _CommandOptions) -> dict[str, Any]: ...
    async def memory_malloc_stats(self, **kwargs: _CommandOptions): ...
    async def memory_usage(self, key, samples: Incomplete | None = None, **kwargs: _CommandOptions): ...
    async def memory_purge(self, **kwargs: _CommandOptions): ...
    async def ping(self, **kwargs: _CommandOptions) -> bool: ...
    async def quit(self, **kwargs: _CommandOptions): ...
    async def replicaof(self, *args, **kwargs: _CommandOptions): ...
    async def save(self, **kwargs: _CommandOptions) -> bool: ...
    async def shutdown(
        self,
        save: bool = False,
        nosave: bool = False,
        now: bool = False,
        force: bool = False,
        abort: bool = False,
        **kwargs: _CommandOptions,
    ) -> None: ...
    async def slaveof(self, host: Incomplete | None = None, port: Incomplete | None = None, **kwargs: _CommandOptions): ...
    async def slowlog_get(self, num: Incomplete | None = None, **kwargs: _CommandOptions): ...
    async def slowlog_len(self, **kwargs: _CommandOptions): ...
    async def slowlog_reset(self, **kwargs: _CommandOptions): ...
    async def time(self, **kwargs: _CommandOptions): ...
    async def wait(self, num_replicas, timeout, **kwargs: _CommandOptions): ...

class BasicKeyCommands(Generic[_StrType]):
    def append(self, key, value): ...
    def bitcount(self, key: _Key, start: int | None = None, end: int | None = None, mode: str | None = None) -> int: ...
    def bitfield(self, key, default_overflow: Incomplete | None = None): ...
    def bitop(self, operation, dest, *keys): ...
    def bitpos(self, key: _Key, bit: int, start: int | None = None, end: int | None = None, mode: str | None = None): ...
    def copy(self, source, destination, destination_db: Incomplete | None = None, replace: bool = False): ...
    def decr(self, name, amount: int = 1) -> int: ...
    def decrby(self, name, amount: int = 1) -> int: ...
    def delete(self, *names: _Key) -> int: ...
    def __delitem__(self, name: _Key) -> None: ...
    def dump(self, name: _Key) -> _StrType | None: ...
    def exists(self, *names: _Key) -> int: ...
    __contains__ = exists
    def expire(
        self, name: _Key, time: int | timedelta, nx: bool = False, xx: bool = False, gt: bool = False, lt: bool = False
    ) -> bool: ...
    def expireat(self, name, when, nx: bool = False, xx: bool = False, gt: bool = False, lt: bool = False): ...
    def get(self, name: _Key) -> _StrType | None: ...
    def getdel(self, name: _Key) -> _StrType | None: ...
    def getex(
        self,
        name,
        ex: Incomplete | None = None,
        px: Incomplete | None = None,
        exat: Incomplete | None = None,
        pxat: Incomplete | None = None,
        persist: bool = False,
    ): ...
    def __getitem__(self, name: str): ...
    def getbit(self, name: _Key, offset: int) -> int: ...
    def getrange(self, key, start, end): ...
    def getset(self, name, value) -> _StrType | None: ...
    def incr(self, name: _Key, amount: int = 1) -> int: ...
    def incrby(self, name: _Key, amount: int = 1) -> int: ...
    def incrbyfloat(self, name: _Key, amount: float = 1.0) -> float: ...
    def keys(self, pattern: _Key = "*", **kwargs: _CommandOptions) -> list[_StrType]: ...
    def lmove(
        self,
        first_list: _Key,
        second_list: _Key,
        src: Literal["LEFT", "RIGHT"] = "LEFT",
        dest: Literal["LEFT", "RIGHT"] = "RIGHT",
    ) -> _Value: ...
    def blmove(
        self,
        first_list: _Key,
        second_list: _Key,
        timeout: float,
        src: Literal["LEFT", "RIGHT"] = "LEFT",
        dest: Literal["LEFT", "RIGHT"] = "RIGHT",
    ) -> _Value | None: ...
    def mget(self, keys: _Key | Iterable[_Key], *args: _Key) -> list[_StrType | None]: ...
    def mset(self, mapping: Mapping[_Key, _Value]) -> Literal[True]: ...
    def msetnx(self, mapping: Mapping[_Key, _Value]) -> bool: ...
    def move(self, name: _Key, db: int) -> bool: ...
    def persist(self, name: _Key) -> bool: ...
    def pexpire(
        self, name: _Key, time: int | timedelta, nx: bool = False, xx: bool = False, gt: bool = False, lt: bool = False
    ) -> Literal[1, 0]: ...
    def pexpireat(
        self, name: _Key, when: int | datetime, nx: bool = False, xx: bool = False, gt: bool = False, lt: bool = False
    ) -> Literal[1, 0]: ...
    def psetex(self, name, time_ms, value): ...
    def pttl(self, name: _Key) -> int: ...
    def hrandfield(self, key, count: Incomplete | None = None, withvalues: bool = False): ...
    def randomkey(self, **kwargs: _CommandOptions): ...
    def rename(self, src, dst): ...
    def renamenx(self, src, dst): ...
    def restore(
        self,
        name,
        ttl,
        value,
        replace: bool = False,
        absttl: bool = False,
        idletime: Incomplete | None = None,
        frequency: Incomplete | None = None,
    ): ...
    def set(
        self,
        name: _Key,
        value: _Value,
        ex: None | float | timedelta = None,
        px: None | float | timedelta = None,
        nx: bool = False,
        xx: bool = False,
        keepttl: bool = False,
        get: bool = False,
        exat: Incomplete | None = None,
        pxat: Incomplete | None = None,
    ) -> bool | None: ...
    def __setitem__(self, name, value) -> None: ...
    def setbit(self, name: _Key, offset: int, value: int) -> int: ...
    def setex(self, name: _Key, time: int | timedelta, value: _Value) -> bool: ...
    def setnx(self, name: _Key, value: _Value) -> bool: ...
    def setrange(self, name, offset, value): ...
    def stralgo(
        self,
        algo,
        value1,
        value2,
        specific_argument: str = "strings",
        len: bool = False,
        idx: bool = False,
        minmatchlen: Incomplete | None = None,
        withmatchlen: bool = False,
        **kwargs: _CommandOptions,
    ): ...
    def strlen(self, name): ...
    def substr(self, name, start, end: int = -1): ...
    def touch(self, *args): ...
    def ttl(self, name: _Key) -> int: ...
    def type(self, name): ...
    def watch(self, *names): ...
    def unwatch(self): ...
    def unlink(self, *names: _Key) -> int: ...

class AsyncBasicKeyCommands(Generic[_StrType]):
    async def append(self, key, value): ...
    async def bitcount(self, key: _Key, start: int | None = None, end: int | None = None, mode: str | None = None) -> int: ...
    async def bitfield(self, key, default_overflow: Incomplete | None = None): ...
    async def bitop(self, operation, dest, *keys): ...
    async def bitpos(self, key: _Key, bit: int, start: int | None = None, end: int | None = None, mode: str | None = None): ...
    async def copy(self, source, destination, destination_db: Incomplete | None = None, replace: bool = False): ...
    async def decr(self, name, amount: int = 1) -> int: ...
    async def decrby(self, name, amount: int = 1) -> int: ...
    async def delete(self, *names: _Key) -> int: ...
    async def dump(self, name: _Key) -> _StrType | None: ...
    async def exists(self, *names: _Key) -> int: ...
    async def expire(
        self, name: _Key, time: int | timedelta, nx: bool = False, xx: bool = False, gt: bool = False, lt: bool = False
    ) -> bool: ...
    async def expireat(self, name, when, nx: bool = False, xx: bool = False, gt: bool = False, lt: bool = False): ...
    async def get(self, name: _Key) -> _StrType | None: ...
    async def getdel(self, name: _Key) -> _StrType | None: ...
    async def getex(
        self,
        name,
        ex: Incomplete | None = None,
        px: Incomplete | None = None,
        exat: Incomplete | None = None,
        pxat: Incomplete | None = None,
        persist: bool = False,
    ): ...
    async def getbit(self, name: _Key, offset: int) -> int: ...
    async def getrange(self, key, start, end): ...
    async def getset(self, name, value) -> _StrType | None: ...
    async def incr(self, name: _Key, amount: int = 1) -> int: ...
    async def incrby(self, name: _Key, amount: int = 1) -> int: ...
    async def incrbyfloat(self, name: _Key, amount: float = 1.0) -> float: ...
    async def keys(self, pattern: _Key = "*", **kwargs: _CommandOptions) -> list[_StrType]: ...
    async def lmove(
        self,
        first_list: _Key,
        second_list: _Key,
        src: Literal["LEFT", "RIGHT"] = "LEFT",
        dest: Literal["LEFT", "RIGHT"] = "RIGHT",
    ) -> _Value: ...
    async def blmove(
        self,
        first_list: _Key,
        second_list: _Key,
        timeout: float,
        src: Literal["LEFT", "RIGHT"] = "LEFT",
        dest: Literal["LEFT", "RIGHT"] = "RIGHT",
    ) -> _Value | None: ...
    async def mget(self, keys: _Key | Iterable[_Key], *args: _Key) -> list[_StrType | None]: ...
    async def mset(self, mapping: Mapping[_Key, _Value]) -> Literal[True]: ...
    async def msetnx(self, mapping: Mapping[_Key, _Value]) -> bool: ...
    async def move(self, name: _Key, db: int) -> bool: ...
    async def persist(self, name: _Key) -> bool: ...
    async def pexpire(
        self, name: _Key, time: int | timedelta, nx: bool = False, xx: bool = False, gt: bool = False, lt: bool = False
    ) -> Literal[1, 0]: ...
    async def pexpireat(
        self, name: _Key, when: int | datetime, nx: bool = False, xx: bool = False, gt: bool = False, lt: bool = False
    ) -> Literal[1, 0]: ...
    async def psetex(self, name, time_ms, value): ...
    async def pttl(self, name: _Key) -> int: ...
    async def hrandfield(self, key, count: Incomplete | None = None, withvalues: bool = False): ...
    async def randomkey(self, **kwargs: _CommandOptions): ...
    async def rename(self, src, dst): ...
    async def renamenx(self, src, dst): ...
    async def restore(
        self,
        name,
        ttl,
        value,
        replace: bool = False,
        absttl: bool = False,
        idletime: Incomplete | None = None,
        frequency: Incomplete | None = None,
    ): ...
    async def set(
        self,
        name: _Key,
        value: _Value,
        ex: None | float | timedelta = None,
        px: None | float | timedelta = None,
        nx: bool = False,
        xx: bool = False,
        keepttl: bool = False,
        get: bool = False,
        exat: Incomplete | None = None,
        pxat: Incomplete | None = None,
    ) -> bool | None: ...
    async def setbit(self, name: _Key, offset: int, value: int) -> int: ...
    async def setex(self, name: _Key, time: int | timedelta, value: _Value) -> bool: ...
    async def setnx(self, name: _Key, value: _Value) -> bool: ...
    async def setrange(self, name, offset, value): ...
    async def stralgo(
        self,
        algo,
        value1,
        value2,
        specific_argument: str = "strings",
        len: bool = False,
        idx: bool = False,
        minmatchlen: Incomplete | None = None,
        withmatchlen: bool = False,
        **kwargs: _CommandOptions,
    ): ...
    async def strlen(self, name): ...
    async def substr(self, name, start, end: int = -1): ...
    async def touch(self, *args): ...
    async def ttl(self, name: _Key) -> int: ...
    async def type(self, name): ...
    async def watch(self, *names): ...
    async def unwatch(self): ...
    async def unlink(self, *names: _Key) -> int: ...
    def __getitem__(self, name: str): ...
    def __setitem__(self, name, value) -> None: ...
    def __delitem__(self, name: _Key) -> None: ...
    def __contains__(self, name: _Key) -> None: ...

class ListCommands(Generic[_StrType]):
    @overload
    def blpop(self, keys: _Value | Iterable[_Value], timeout: Literal[0] | None = 0) -> tuple[_StrType, _StrType]: ...
    @overload
    def blpop(self, keys: _Value | Iterable[_Value], timeout: float) -> tuple[_StrType, _StrType] | None: ...
    @overload
    def brpop(self, keys: _Value | Iterable[_Value], timeout: Literal[0] | None = 0) -> tuple[_StrType, _StrType]: ...
    @overload
    def brpop(self, keys: _Value | Iterable[_Value], timeout: float) -> tuple[_StrType, _StrType] | None: ...
    def brpoplpush(self, src, dst, timeout: int | None = 0): ...
    def lindex(self, name: _Key, index: int) -> _StrType | None: ...
    def linsert(
        self, name: _Key, where: Literal["BEFORE", "AFTER", "before", "after"], refvalue: _Value, value: _Value
    ) -> int: ...
    def llen(self, name: _Key) -> int: ...
    def lpop(self, name, count: int | None = None): ...
    def lpush(self, name: _Value, *values: _Value) -> int: ...
    def lpushx(self, name, value): ...
    def lrange(self, name: _Key, start: int, end: int) -> list[_StrType]: ...
    def lrem(self, name: _Key, count: int, value: _Value) -> int: ...
    def lset(self, name: _Key, index: int, value: _Value) -> bool: ...
    def ltrim(self, name: _Key, start: int, end: int) -> bool: ...
    def rpop(self, name, count: int | None = None): ...
    def rpoplpush(self, src, dst): ...
    def rpush(self, name: _Value, *values: _Value) -> int: ...
    def rpushx(self, name, value): ...
    def lpos(
        self, name, value, rank: Incomplete | None = None, count: Incomplete | None = None, maxlen: Incomplete | None = None
    ): ...
    @overload
    def sort(
        self,
        name: _Key,
        start: int | None = None,
        num: int | None = None,
        by: _Key | None = None,
        get: _Key | Sequence[_Key] | None = None,
        desc: bool = False,
        alpha: bool = False,
        store: None = None,
        groups: bool = False,
    ) -> list[_StrType]: ...
    @overload
    def sort(
        self,
        name: _Key,
        start: int | None = None,
        num: int | None = None,
        by: _Key | None = None,
        get: _Key | Sequence[_Key] | None = None,
        desc: bool = False,
        alpha: bool = False,
        *,
        store: _Key,
        groups: bool = False,
    ) -> int: ...
    @overload
    def sort(
        self,
        name: _Key,
        start: int | None,
        num: int | None,
        by: _Key | None,
        get: _Key | Sequence[_Key] | None,
        desc: bool,
        alpha: bool,
        store: _Key,
        groups: bool = False,
    ) -> int: ...

class AsyncListCommands(Generic[_StrType]):
    @overload
    async def blpop(self, keys: _Value | Iterable[_Value], timeout: Literal[0] | None = 0) -> tuple[_StrType, _StrType]: ...
    @overload
    async def blpop(self, keys: _Value | Iterable[_Value], timeout: float) -> tuple[_StrType, _StrType] | None: ...
    @overload
    async def brpop(self, keys: _Value | Iterable[_Value], timeout: Literal[0] | None = 0) -> tuple[_StrType, _StrType]: ...
    @overload
    async def brpop(self, keys: _Value | Iterable[_Value], timeout: float) -> tuple[_StrType, _StrType] | None: ...
    async def brpoplpush(self, src, dst, timeout: int | None = 0): ...
    async def lindex(self, name: _Key, index: int) -> _StrType | None: ...
    async def linsert(
        self, name: _Key, where: Literal["BEFORE", "AFTER", "before", "after"], refvalue: _Value, value: _Value
    ) -> int: ...
    async def llen(self, name: _Key) -> int: ...
    async def lpop(self, name, count: int | None = None): ...
    async def lpush(self, name: _Value, *values: _Value) -> int: ...
    async def lpushx(self, name, value): ...
    async def lrange(self, name: _Key, start: int, end: int) -> list[_StrType]: ...
    async def lrem(self, name: _Key, count: int, value: _Value) -> int: ...
    async def lset(self, name: _Key, index: int, value: _Value) -> bool: ...
    async def ltrim(self, name: _Key, start: int, end: int) -> bool: ...
    async def rpop(self, name, count: int | None = None): ...
    async def rpoplpush(self, src, dst): ...
    async def rpush(self, name: _Value, *values: _Value) -> int: ...
    async def rpushx(self, name, value): ...
    async def lpos(
        self, name, value, rank: Incomplete | None = None, count: Incomplete | None = None, maxlen: Incomplete | None = None
    ): ...
    @overload
    async def sort(
        self,
        name: _Key,
        start: int | None = None,
        num: int | None = None,
        by: _Key | None = None,
        get: _Key | Sequence[_Key] | None = None,
        desc: bool = False,
        alpha: bool = False,
        store: None = None,
        groups: bool = False,
    ) -> list[_StrType]: ...
    @overload
    async def sort(
        self,
        name: _Key,
        start: int | None = None,
        num: int | None = None,
        by: _Key | None = None,
        get: _Key | Sequence[_Key] | None = None,
        desc: bool = False,
        alpha: bool = False,
        *,
        store: _Key,
        groups: bool = False,
    ) -> int: ...
    @overload
    async def sort(
        self,
        name: _Key,
        start: int | None,
        num: int | None,
        by: _Key | None,
        get: _Key | Sequence[_Key] | None,
        desc: bool,
        alpha: bool,
        store: _Key,
        groups: bool = False,
    ) -> int: ...

class ScanCommands(Generic[_StrType]):
    def scan(
        self,
        cursor: int = 0,
        match: _Key | None = None,
        count: int | None = None,
        _type: str | None = None,
        **kwargs: _CommandOptions,
    ) -> tuple[int, list[_StrType]]: ...
    def scan_iter(
        self, match: _Key | None = None, count: int | None = None, _type: str | None = None, **kwargs: _CommandOptions
    ) -> Iterator[_StrType]: ...
    def sscan(
        self, name: _Key, cursor: int = 0, match: _Key | None = None, count: int | None = None
    ) -> tuple[int, list[_StrType]]: ...
    def sscan_iter(self, name: _Key, match: _Key | None = None, count: int | None = None) -> Iterator[_StrType]: ...
    def hscan(
        self, name: _Key, cursor: int = 0, match: _Key | None = None, count: int | None = None
    ) -> tuple[int, dict[_StrType, _StrType]]: ...
    def hscan_iter(
        self, name: _Key, match: _Key | None = None, count: int | None = None
    ) -> Iterator[tuple[_StrType, _StrType]]: ...
    @overload
    def zscan(
        self, name: _Key, cursor: int = 0, match: _Key | None = None, count: int | None = None
    ) -> tuple[int, list[tuple[_StrType, float]]]: ...
    @overload
    def zscan(
        self,
        name: _Key,
        cursor: int = 0,
        match: _Key | None = None,
        count: int | None = None,
        *,
        score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn],
    ) -> tuple[int, list[tuple[_StrType, _ScoreCastFuncReturn]]]: ...
    @overload
    def zscan(
        self,
        name: _Key,
        cursor: int,
        match: _Key | None,
        count: int | None,
        score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn],
    ) -> tuple[int, list[tuple[_StrType, _ScoreCastFuncReturn]]]: ...
    @overload
    def zscan_iter(self, name: _Key, match: _Key | None = None, count: int | None = None) -> Iterator[tuple[_StrType, float]]: ...
    @overload
    def zscan_iter(
        self,
        name: _Key,
        match: _Key | None = None,
        count: int | None = None,
        *,
        score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn],
    ) -> Iterator[tuple[_StrType, _ScoreCastFuncReturn]]: ...
    @overload
    def zscan_iter(
        self, name: _Key, match: _Key | None, count: int | None, score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn]
    ) -> Iterator[tuple[_StrType, _ScoreCastFuncReturn]]: ...

class AsyncScanCommands(Generic[_StrType]):
    async def scan(
        self,
        cursor: int = 0,
        match: _Key | None = None,
        count: int | None = None,
        _type: str | None = None,
        **kwargs: _CommandOptions,
    ) -> tuple[int, list[_StrType]]: ...
    def scan_iter(
        self, match: _Key | None = None, count: int | None = None, _type: str | None = None, **kwargs: _CommandOptions
    ) -> AsyncIterator[_StrType]: ...
    async def sscan(
        self, name: _Key, cursor: int = 0, match: _Key | None = None, count: int | None = None
    ) -> tuple[int, list[_StrType]]: ...
    def sscan_iter(self, name: _Key, match: _Key | None = None, count: int | None = None) -> AsyncIterator[_StrType]: ...
    async def hscan(
        self, name: _Key, cursor: int = 0, match: _Key | None = None, count: int | None = None
    ) -> tuple[int, dict[_StrType, _StrType]]: ...
    def hscan_iter(
        self, name: _Key, match: _Key | None = None, count: int | None = None
    ) -> AsyncIterator[tuple[_StrType, _StrType]]: ...
    @overload
    async def zscan(
        self, name: _Key, cursor: int = 0, match: _Key | None = None, count: int | None = None
    ) -> tuple[int, list[tuple[_StrType, float]]]: ...
    @overload
    async def zscan(
        self,
        name: _Key,
        cursor: int = 0,
        match: _Key | None = None,
        count: int | None = None,
        *,
        score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn],
    ) -> tuple[int, list[tuple[_StrType, _ScoreCastFuncReturn]]]: ...
    @overload
    async def zscan(
        self,
        name: _Key,
        cursor: int,
        match: _Key | None,
        count: int | None,
        score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn],
    ) -> tuple[int, list[tuple[_StrType, _ScoreCastFuncReturn]]]: ...
    @overload
    def zscan_iter(
        self, name: _Key, match: _Key | None = None, count: int | None = None
    ) -> AsyncIterator[tuple[_StrType, float]]: ...
    @overload
    def zscan_iter(
        self,
        name: _Key,
        match: _Key | None = None,
        count: int | None = None,
        *,
        score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn],
    ) -> AsyncIterator[tuple[_StrType, _ScoreCastFuncReturn]]: ...
    @overload
    def zscan_iter(
        self, name: _Key, match: _Key | None, count: int | None, score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn]
    ) -> AsyncIterator[tuple[_StrType, _ScoreCastFuncReturn]]: ...

class SetCommands(Generic[_StrType]):
    def sadd(self, name: _Key, *values: _Value) -> int: ...
    def scard(self, name: _Key) -> int: ...
    def sdiff(self, keys: _Key | Iterable[_Key], *args: _Key) -> builtins.set[_Value]: ...
    def sdiffstore(self, dest: _Key, keys: _Key | Iterable[_Key], *args: _Key) -> int: ...
    def sinter(self, keys: _Key | Iterable[_Key], *args: _Key) -> builtins.set[_Value]: ...
    def sinterstore(self, dest: _Key, keys: _Key | Iterable[_Key], *args: _Key) -> int: ...
    def sismember(self, name: _Key, value: _Value) -> bool: ...
    def smembers(self, name: _Key) -> builtins.set[_StrType]: ...
    def smismember(self, name, values, *args): ...
    def smove(self, src: _Key, dst: _Key, value: _Value) -> bool: ...
    @overload
    def spop(self, name: _Key, count: None = None) -> _Value | None: ...
    @overload
    def spop(self, name: _Key, count: int) -> list[_Value]: ...
    @overload
    def srandmember(self, name: _Key, number: None = None) -> _Value | None: ...
    @overload
    def srandmember(self, name: _Key, number: int) -> list[_Value]: ...
    def srem(self, name: _Key, *values: _Value) -> int: ...
    def sunion(self, keys: _Key | Iterable[_Key], *args: _Key) -> builtins.set[_Value]: ...
    def sunionstore(self, dest: _Key, keys: _Key | Iterable[_Key], *args: _Key) -> int: ...

class AsyncSetCommands(Generic[_StrType]):
    async def sadd(self, name: _Key, *values: _Value) -> int: ...
    async def scard(self, name: _Key) -> int: ...
    async def sdiff(self, keys: _Key | Iterable[_Key], *args: _Key) -> builtins.set[_Value]: ...
    async def sdiffstore(self, dest: _Key, keys: _Key | Iterable[_Key], *args: _Key) -> int: ...
    async def sinter(self, keys: _Key | Iterable[_Key], *args: _Key) -> builtins.set[_Value]: ...
    async def sinterstore(self, dest: _Key, keys: _Key | Iterable[_Key], *args: _Key) -> int: ...
    async def sismember(self, name: _Key, value: _Value) -> bool: ...
    async def smembers(self, name: _Key) -> builtins.set[_StrType]: ...
    async def smismember(self, name, values, *args): ...
    async def smove(self, src: _Key, dst: _Key, value: _Value) -> bool: ...
    @overload
    async def spop(self, name: _Key, count: None = None) -> _Value | None: ...
    @overload
    async def spop(self, name: _Key, count: int) -> list[_Value]: ...
    @overload
    async def srandmember(self, name: _Key, number: None = None) -> _Value | None: ...
    @overload
    async def srandmember(self, name: _Key, number: int) -> list[_Value]: ...
    async def srem(self, name: _Key, *values: _Value) -> int: ...
    async def sunion(self, keys: _Key | Iterable[_Key], *args: _Key) -> builtins.set[_Value]: ...
    async def sunionstore(self, dest: _Key, keys: _Key | Iterable[_Key], *args: _Key) -> int: ...

class StreamCommands:
    def xack(self, name, groupname, *ids): ...
    def xadd(
        self,
        name: KeyT,
        # Only accepts dict objects, but for variance reasons we use a looser annotation
        fields: SupportsItems[bytes | memoryview | str | float, Any],
        id: str | int | bytes | memoryview = "*",
        maxlen=None,
        approximate: bool = True,
        nomkstream: bool = False,
        minid: Incomplete | None = None,
        limit: Incomplete | None = None,
    ): ...
    def xautoclaim(
        self,
        name,
        groupname,
        consumername,
        min_idle_time,
        start_id: StreamIdT = "0-0",
        count: Incomplete | None = None,
        justid: bool = False,
    ): ...
    def xclaim(
        self,
        name,
        groupname,
        consumername,
        min_idle_time,
        message_ids,
        idle=None,
        time=None,
        retrycount=None,
        force=False,
        justid=False,
    ): ...
    def xdel(self, name: KeyT, *ids: str | int | bytes | memoryview): ...
    def xgroup_create(self, name, groupname, id: str = "$", mkstream: bool = False, entries_read: int | None = None): ...
    def xgroup_delconsumer(self, name, groupname, consumername): ...
    def xgroup_destroy(self, name, groupname): ...
    def xgroup_createconsumer(self, name, groupname, consumername): ...
    def xgroup_setid(self, name, groupname, id, entries_read: int | None = None): ...
    def xinfo_consumers(self, name, groupname): ...
    def xinfo_groups(self, name): ...
    def xinfo_stream(self, name, full: bool = False): ...
    def xlen(self, name: _Key) -> int: ...
    def xpending(self, name, groupname): ...
    def xpending_range(
        self, name: _Key, groupname, min, max, count: int, consumername: Incomplete | None = None, idle: int | None = None
    ): ...
    def xrange(self, name, min: str = "-", max: str = "+", count: Incomplete | None = None): ...
    def xread(self, streams, count: Incomplete | None = None, block: Incomplete | None = None): ...
    def xreadgroup(
        self,
        groupname,
        consumername,
        streams,
        count: Incomplete | None = None,
        block: Incomplete | None = None,
        noack: bool = False,
    ): ...
    def xrevrange(self, name, max: str = "+", min: str = "-", count: Incomplete | None = None): ...
    def xtrim(
        self, name, maxlen: int | None = None, approximate: bool = True, minid: Incomplete | None = None, limit: int | None = None
    ): ...

class AsyncStreamCommands:
    async def xack(self, name, groupname, *ids): ...
    async def xadd(
        self,
        name: KeyT,
        # Only accepts dict objects, but for variance reasons we use a looser annotation
        fields: SupportsItems[bytes | memoryview | str | float, Any],
        id: str | int | bytes | memoryview = "*",
        maxlen=None,
        approximate: bool = True,
        nomkstream: bool = False,
        minid: Incomplete | None = None,
        limit: Incomplete | None = None,
    ): ...
    async def xautoclaim(
        self,
        name,
        groupname,
        consumername,
        min_idle_time,
        start_id: StreamIdT = "0-0",
        count: Incomplete | None = None,
        justid: bool = False,
    ): ...
    async def xclaim(
        self,
        name,
        groupname,
        consumername,
        min_idle_time,
        message_ids,
        idle=None,
        time=None,
        retrycount=None,
        force=False,
        justid=False,
    ): ...
    async def xdel(self, name: KeyT, *ids: str | int | bytes | memoryview): ...
    async def xgroup_create(self, name, groupname, id: str = "$", mkstream: bool = False, entries_read: int | None = None): ...
    async def xgroup_delconsumer(self, name, groupname, consumername): ...
    async def xgroup_destroy(self, name, groupname): ...
    async def xgroup_createconsumer(self, name, groupname, consumername): ...
    async def xgroup_setid(self, name, groupname, id, entries_read: int | None = None): ...
    async def xinfo_consumers(self, name, groupname): ...
    async def xinfo_groups(self, name): ...
    async def xinfo_stream(self, name, full: bool = False): ...
    async def xlen(self, name: _Key) -> int: ...
    async def xpending(self, name, groupname): ...
    async def xpending_range(
        self, name: _Key, groupname, min, max, count: int, consumername: Incomplete | None = None, idle: int | None = None
    ): ...
    async def xrange(self, name, min: str = "-", max: str = "+", count: Incomplete | None = None): ...
    async def xread(self, streams, count: Incomplete | None = None, block: Incomplete | None = None): ...
    async def xreadgroup(
        self,
        groupname,
        consumername,
        streams,
        count: Incomplete | None = None,
        block: Incomplete | None = None,
        noack: bool = False,
    ): ...
    async def xrevrange(self, name, max: str = "+", min: str = "-", count: Incomplete | None = None): ...
    async def xtrim(
        self, name, maxlen: int | None = None, approximate: bool = True, minid: Incomplete | None = None, limit: int | None = None
    ): ...

class SortedSetCommands(Generic[_StrType]):
    def zadd(
        self,
        name: _Key,
        mapping: Mapping[_Key, _Value],
        nx: bool = False,
        xx: bool = False,
        ch: bool = False,
        incr: bool = False,
        gt: Incomplete | None = False,
        lt: Incomplete | None = False,
    ) -> int: ...
    def zcard(self, name: _Key) -> int: ...
    def zcount(self, name: _Key, min: _Value, max: _Value) -> int: ...
    def zdiff(self, keys, withscores: bool = False): ...
    def zdiffstore(self, dest, keys): ...
    def zincrby(self, name: _Key, amount: float, value: _Value) -> float: ...
    def zinter(self, keys, aggregate: Incomplete | None = None, withscores: bool = False): ...
    def zinterstore(self, dest: _Key, keys: Iterable[_Key], aggregate: Literal["SUM", "MIN", "MAX"] | None = None) -> int: ...
    def zlexcount(self, name: _Key, min: _Value, max: _Value) -> int: ...
    def zpopmax(self, name: _Key, count: int | None = None) -> list[tuple[_StrType, float]]: ...
    def zpopmin(self, name: _Key, count: int | None = None) -> list[tuple[_StrType, float]]: ...
    def zrandmember(self, key, count: Incomplete | None = None, withscores: bool = False): ...
    @overload
    def bzpopmax(self, keys: _Key | Iterable[_Key], timeout: Literal[0] = 0) -> tuple[_StrType, _StrType, float]: ...
    @overload
    def bzpopmax(self, keys: _Key | Iterable[_Key], timeout: float) -> tuple[_StrType, _StrType, float] | None: ...
    @overload
    def bzpopmin(self, keys: _Key | Iterable[_Key], timeout: Literal[0] = 0) -> tuple[_StrType, _StrType, float]: ...
    @overload
    def bzpopmin(self, keys: _Key | Iterable[_Key], timeout: float) -> tuple[_StrType, _StrType, float] | None: ...
    @overload
    def zrange(  # type: ignore[overload-overlap]
        self,
        name: _Key,
        start: int,
        end: int,
        desc: bool,
        withscores: Literal[True],
        score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn],
        byscore: bool = False,
        bylex: bool = False,
        offset: int | None = None,
        num: int | None = None,
    ) -> list[tuple[_StrType, _ScoreCastFuncReturn]]: ...
    @overload
    def zrange(  # type: ignore[overload-overlap]
        self,
        name: _Key,
        start: int,
        end: int,
        desc: bool,
        withscores: Literal[True],
        score_cast_func: Callable[[_StrType], float] = ...,
        byscore: bool = False,
        bylex: bool = False,
        offset: int | None = None,
        num: int | None = None,
    ) -> list[tuple[_StrType, float]]: ...
    @overload
    def zrange(  # type: ignore[overload-overlap]
        self,
        name: _Key,
        start: int,
        end: int,
        *,
        withscores: Literal[True],
        score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn],
        byscore: bool = False,
        bylex: bool = False,
        offset: int | None = None,
        num: int | None = None,
    ) -> list[tuple[_StrType, _ScoreCastFuncReturn]]: ...
    @overload
    def zrange(  # type: ignore[overload-overlap]
        self,
        name: _Key,
        start: int,
        end: int,
        *,
        withscores: Literal[True],
        score_cast_func: Callable[[_StrType], float] = ...,
        byscore: bool = False,
        bylex: bool = False,
        offset: int | None = None,
        num: int | None = None,
    ) -> list[tuple[_StrType, float]]: ...
    @overload
    def zrange(
        self,
        name: _Key,
        start: int,
        end: int,
        desc: bool = False,
        withscores: bool = False,
        score_cast_func: Callable[[_StrType], Any] = ...,
        byscore: bool = False,
        bylex: bool = False,
        offset: int | None = None,
        num: int | None = None,
    ) -> list[_StrType]: ...
    @overload
    def zrevrange(
        self,
        name: _Key,
        start: int,
        end: int,
        withscores: Literal[True],
        score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn],
    ) -> list[tuple[_StrType, _ScoreCastFuncReturn]]: ...
    @overload
    def zrevrange(  # type: ignore[overload-overlap]
        self, name: _Key, start: int, end: int, withscores: Literal[True]
    ) -> list[tuple[_StrType, float]]: ...
    @overload
    def zrevrange(
        self, name: _Key, start: int, end: int, withscores: bool = False, score_cast_func: Callable[[Any], Any] = ...
    ) -> list[_StrType]: ...
    def zrangestore(
        self,
        dest,
        name,
        start,
        end,
        byscore: bool = False,
        bylex: bool = False,
        desc: bool = False,
        offset: Incomplete | None = None,
        num: Incomplete | None = None,
    ): ...
    def zrangebylex(
        self, name: _Key, min: _Value, max: _Value, start: int | None = None, num: int | None = None
    ) -> list[_StrType]: ...
    def zrevrangebylex(
        self, name: _Key, max: _Value, min: _Value, start: int | None = None, num: int | None = None
    ) -> list[_StrType]: ...
    @overload
    def zrangebyscore(  # type: ignore[overload-overlap]
        self,
        name: _Key,
        min: _Value,
        max: _Value,
        start: int | None = None,
        num: int | None = None,
        *,
        withscores: Literal[True],
        score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn],
    ) -> list[tuple[_StrType, _ScoreCastFuncReturn]]: ...
    @overload
    def zrangebyscore(  # type: ignore[overload-overlap]
        self, name: _Key, min: _Value, max: _Value, start: int | None = None, num: int | None = None, *, withscores: Literal[True]
    ) -> list[tuple[_StrType, float]]: ...
    @overload
    def zrangebyscore(
        self,
        name: _Key,
        min: _Value,
        max: _Value,
        start: int | None = None,
        num: int | None = None,
        withscores: bool = False,
        score_cast_func: Callable[[_StrType], Any] = ...,
    ) -> list[_StrType]: ...
    @overload
    def zrevrangebyscore(  # type: ignore[overload-overlap]
        self,
        name: _Key,
        max: _Value,
        min: _Value,
        start: int | None = None,
        num: int | None = None,
        *,
        withscores: Literal[True],
        score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn],
    ) -> list[tuple[_StrType, _ScoreCastFuncReturn]]: ...
    @overload
    def zrevrangebyscore(  # type: ignore[overload-overlap]
        self, name: _Key, max: _Value, min: _Value, start: int | None = None, num: int | None = None, *, withscores: Literal[True]
    ) -> list[tuple[_StrType, float]]: ...
    @overload
    def zrevrangebyscore(
        self,
        name: _Key,
        max: _Value,
        min: _Value,
        start: int | None = None,
        num: int | None = None,
        withscores: bool = False,
        score_cast_func: Callable[[_StrType], Any] = ...,
    ) -> list[_StrType]: ...
    def zrank(self, name: _Key, value: _Value, withscore: bool = False) -> int | None: ...
    def zrem(self, name: _Key, *values: _Value) -> int: ...
    def zremrangebylex(self, name: _Key, min: _Value, max: _Value) -> int: ...
    def zremrangebyrank(self, name: _Key, min: int, max: int) -> int: ...
    def zremrangebyscore(self, name: _Key, min: _Value, max: _Value) -> int: ...
    def zrevrank(self, name: _Key, value: _Value, withscore: bool = False) -> int | None: ...
    def zscore(self, name: _Key, value: _Value) -> float | None: ...
    def zunion(self, keys, aggregate: Incomplete | None = None, withscores: bool = False): ...
    def zunionstore(self, dest: _Key, keys: Iterable[_Key], aggregate: Literal["SUM", "MIN", "MAX"] | None = None) -> int: ...
    def zmscore(self, key, members): ...

class AsyncSortedSetCommands(Generic[_StrType]):
    async def zadd(
        self,
        name: _Key,
        mapping: Mapping[_Key, _Value],
        nx: bool = False,
        xx: bool = False,
        ch: bool = False,
        incr: bool = False,
        gt: Incomplete | None = False,
        lt: Incomplete | None = False,
    ) -> int: ...
    async def zcard(self, name: _Key) -> int: ...
    async def zcount(self, name: _Key, min: _Value, max: _Value) -> int: ...
    async def zdiff(self, keys, withscores: bool = False): ...
    async def zdiffstore(self, dest, keys): ...
    async def zincrby(self, name: _Key, amount: float, value: _Value) -> float: ...
    async def zinter(self, keys, aggregate: Incomplete | None = None, withscores: bool = False): ...
    async def zinterstore(
        self, dest: _Key, keys: Iterable[_Key], aggregate: Literal["SUM", "MIN", "MAX"] | None = None
    ) -> int: ...
    async def zlexcount(self, name: _Key, min: _Value, max: _Value) -> int: ...
    async def zpopmax(self, name: _Key, count: int | None = None) -> list[tuple[_StrType, float]]: ...
    async def zpopmin(self, name: _Key, count: int | None = None) -> list[tuple[_StrType, float]]: ...
    async def zrandmember(self, key, count: Incomplete | None = None, withscores: bool = False): ...
    @overload
    async def bzpopmax(self, keys: _Key | Iterable[_Key], timeout: Literal[0] = 0) -> tuple[_StrType, _StrType, float]: ...
    @overload
    async def bzpopmax(self, keys: _Key | Iterable[_Key], timeout: float) -> tuple[_StrType, _StrType, float] | None: ...
    @overload
    async def bzpopmin(self, keys: _Key | Iterable[_Key], timeout: Literal[0] = 0) -> tuple[_StrType, _StrType, float]: ...
    @overload
    async def bzpopmin(self, keys: _Key | Iterable[_Key], timeout: float) -> tuple[_StrType, _StrType, float] | None: ...
    @overload
    async def zrange(  # type: ignore[overload-overlap]
        self,
        name: _Key,
        start: int,
        end: int,
        desc: bool,
        withscores: Literal[True],
        score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn],
        byscore: bool = False,
        bylex: bool = False,
        offset: int | None = None,
        num: int | None = None,
    ) -> list[tuple[_StrType, _ScoreCastFuncReturn]]: ...
    @overload
    async def zrange(  # type: ignore[overload-overlap]
        self,
        name: _Key,
        start: int,
        end: int,
        desc: bool,
        withscores: Literal[True],
        score_cast_func: Callable[[_StrType], float] = ...,
        byscore: bool = False,
        bylex: bool = False,
        offset: int | None = None,
        num: int | None = None,
    ) -> list[tuple[_StrType, float]]: ...
    @overload
    async def zrange(  # type: ignore[overload-overlap]
        self,
        name: _Key,
        start: int,
        end: int,
        desc: bool = False,
        *,
        withscores: Literal[True],
        score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn],
        byscore: bool = False,
        bylex: bool = False,
        offset: int | None = None,
        num: int | None = None,
    ) -> list[tuple[_StrType, _ScoreCastFuncReturn]]: ...
    @overload
    async def zrange(  # type: ignore[overload-overlap]
        self,
        name: _Key,
        start: int,
        end: int,
        desc: bool = False,
        *,
        withscores: Literal[True],
        score_cast_func: Callable[[_StrType], float] = ...,
        byscore: bool = False,
        bylex: bool = False,
        offset: int | None = None,
        num: int | None = None,
    ) -> list[tuple[_StrType, float]]: ...
    @overload
    async def zrange(
        self,
        name: _Key,
        start: int,
        end: int,
        desc: bool = False,
        withscores: bool = False,
        score_cast_func: Callable[[_StrType], Any] = ...,
        byscore: bool = False,
        bylex: bool = False,
        offset: int | None = None,
        num: int | None = None,
    ) -> list[_StrType]: ...
    @overload
    async def zrevrange(
        self,
        name: _Key,
        start: int,
        end: int,
        withscores: Literal[True],
        score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn],
    ) -> list[tuple[_StrType, _ScoreCastFuncReturn]]: ...
    @overload
    async def zrevrange(  # type: ignore[overload-overlap]
        self, name: _Key, start: int, end: int, withscores: Literal[True]
    ) -> list[tuple[_StrType, float]]: ...
    @overload
    async def zrevrange(
        self, name: _Key, start: int, end: int, withscores: bool = False, score_cast_func: Callable[[Any], Any] = ...
    ) -> list[_StrType]: ...
    async def zrangestore(
        self,
        dest,
        name,
        start,
        end,
        byscore: bool = False,
        bylex: bool = False,
        desc: bool = False,
        offset: Incomplete | None = None,
        num: Incomplete | None = None,
    ): ...
    async def zrangebylex(
        self, name: _Key, min: _Value, max: _Value, start: int | None = None, num: int | None = None
    ) -> list[_StrType]: ...
    async def zrevrangebylex(
        self, name: _Key, max: _Value, min: _Value, start: int | None = None, num: int | None = None
    ) -> list[_StrType]: ...
    @overload
    async def zrangebyscore(  # type: ignore[overload-overlap]
        self,
        name: _Key,
        min: _Value,
        max: _Value,
        start: int | None = None,
        num: int | None = None,
        *,
        withscores: Literal[True],
        score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn],
    ) -> list[tuple[_StrType, _ScoreCastFuncReturn]]: ...
    @overload
    async def zrangebyscore(  # type: ignore[overload-overlap]
        self, name: _Key, min: _Value, max: _Value, start: int | None = None, num: int | None = None, *, withscores: Literal[True]
    ) -> list[tuple[_StrType, float]]: ...
    @overload
    async def zrangebyscore(
        self,
        name: _Key,
        min: _Value,
        max: _Value,
        start: int | None = None,
        num: int | None = None,
        withscores: bool = False,
        score_cast_func: Callable[[_StrType], Any] = ...,
    ) -> list[_StrType]: ...
    @overload
    async def zrevrangebyscore(  # type: ignore[overload-overlap]
        self,
        name: _Key,
        max: _Value,
        min: _Value,
        start: int | None = None,
        num: int | None = None,
        *,
        withscores: Literal[True],
        score_cast_func: Callable[[_StrType], _ScoreCastFuncReturn],
    ) -> list[tuple[_StrType, _ScoreCastFuncReturn]]: ...
    @overload
    async def zrevrangebyscore(  # type: ignore[overload-overlap]
        self, name: _Key, max: _Value, min: _Value, start: int | None = None, num: int | None = None, *, withscores: Literal[True]
    ) -> list[tuple[_StrType, float]]: ...
    @overload
    async def zrevrangebyscore(
        self,
        name: _Key,
        max: _Value,
        min: _Value,
        start: int | None = None,
        num: int | None = None,
        withscores: bool = False,
        score_cast_func: Callable[[_StrType], Any] = ...,
    ) -> list[_StrType]: ...
    async def zrank(self, name: _Key, value: _Value, withscore: bool = False) -> int | None: ...
    async def zrem(self, name: _Key, *values: _Value) -> int: ...
    async def zremrangebylex(self, name: _Key, min: _Value, max: _Value) -> int: ...
    async def zremrangebyrank(self, name: _Key, min: int, max: int) -> int: ...
    async def zremrangebyscore(self, name: _Key, min: _Value, max: _Value) -> int: ...
    async def zrevrank(self, name: _Key, value: _Value, withscore: bool = False) -> int | None: ...
    async def zscore(self, name: _Key, value: _Value) -> float | None: ...
    async def zunion(self, keys, aggregate: Incomplete | None = None, withscores: bool = False): ...
    async def zunionstore(
        self, dest: _Key, keys: Iterable[_Key], aggregate: Literal["SUM", "MIN", "MAX"] | None = None
    ) -> int: ...
    async def zmscore(self, key, members): ...

class HyperlogCommands:
    def pfadd(self, name: _Key, *values: _Value) -> int: ...
    def pfcount(self, name: _Key) -> int: ...
    def pfmerge(self, dest: _Key, *sources: _Key) -> bool: ...

class AsyncHyperlogCommands:
    async def pfadd(self, name: _Key, *values: _Value) -> int: ...
    async def pfcount(self, name: _Key) -> int: ...
    async def pfmerge(self, dest: _Key, *sources: _Key) -> bool: ...

class HashCommands(Generic[_StrType]):
    def hdel(self, name: _Key, *keys: _Key) -> int: ...
    def hexists(self, name: _Key, key: _Key) -> bool: ...
    def hget(self, name: _Key, key: _Key) -> _StrType | None: ...
    def hgetall(self, name: _Key) -> dict[_StrType, _StrType]: ...
    def hincrby(self, name: _Key, key: _Key, amount: int = 1) -> int: ...
    def hincrbyfloat(self, name: _Key, key: _Key, amount: float = 1.0) -> float: ...
    def hkeys(self, name: _Key) -> list[_StrType]: ...
    def hlen(self, name: _Key) -> int: ...
    @overload
    def hset(
        self, name: _Key, key: _Key, value: _Value, mapping: Mapping[_Key, _Value] | None = None, items: Incomplete | None = None
    ) -> int: ...
    @overload
    def hset(
        self, name: _Key, key: None, value: None, mapping: Mapping[_Key, _Value], items: Incomplete | None = None
    ) -> int: ...
    @overload
    def hset(self, name: _Key, *, mapping: Mapping[_Key, _Value], items: Incomplete | None = None) -> int: ...
    def hsetnx(self, name: _Key, key: _Key, value: _Value) -> int: ...
    def hmset(self, name: _Key, mapping: Mapping[_Key, _Value]) -> bool: ...
    def hmget(self, name: _Key, keys: _Key | Iterable[_Key], *args: _Key) -> list[_StrType | None]: ...
    def hvals(self, name: _Key) -> list[_StrType]: ...
    def hstrlen(self, name, key): ...

class AsyncHashCommands(Generic[_StrType]):
    async def hdel(self, name: _Key, *keys: _Key) -> int: ...
    async def hexists(self, name: _Key, key: _Key) -> bool: ...
    async def hget(self, name: _Key, key: _Key) -> _StrType | None: ...
    async def hgetall(self, name: _Key) -> dict[_StrType, _StrType]: ...
    async def hincrby(self, name: _Key, key: _Key, amount: int = 1) -> int: ...
    async def hincrbyfloat(self, name: _Key, key: _Key, amount: float = 1.0) -> float: ...
    async def hkeys(self, name: _Key) -> list[_StrType]: ...
    async def hlen(self, name: _Key) -> int: ...
    @overload
    async def hset(
        self, name: _Key, key: _Key, value: _Value, mapping: Mapping[_Key, _Value] | None = None, items: Incomplete | None = None
    ) -> int: ...
    @overload
    async def hset(
        self, name: _Key, key: None, value: None, mapping: Mapping[_Key, _Value], items: Incomplete | None = None
    ) -> int: ...
    @overload
    async def hset(self, name: _Key, *, mapping: Mapping[_Key, _Value], items: Incomplete | None = None) -> int: ...
    async def hsetnx(self, name: _Key, key: _Key, value: _Value) -> int: ...
    async def hmset(self, name: _Key, mapping: Mapping[_Key, _Value]) -> bool: ...
    async def hmget(self, name: _Key, keys: _Key | Iterable[_Key], *args: _Key) -> list[_StrType | None]: ...
    async def hvals(self, name: _Key) -> list[_StrType]: ...
    async def hstrlen(self, name, key): ...

class AsyncScript:
    def __init__(self, registered_client: AsyncRedis[Any], script: ScriptTextT) -> None: ...
    async def __call__(
        self, keys: Sequence[KeyT] | None = None, args: Iterable[EncodableT] | None = None, client: AsyncRedis[Any] | None = None
    ): ...

class PubSubCommands:
    def publish(self, channel: _Key, message: _Key, **kwargs: _CommandOptions) -> int: ...
    def pubsub_channels(self, pattern: _Key = "*", **kwargs: _CommandOptions) -> list[str]: ...
    def pubsub_numpat(self, **kwargs: _CommandOptions) -> int: ...
    def pubsub_numsub(self, *args: _Key, **kwargs: _CommandOptions) -> list[tuple[str, int]]: ...

class AsyncPubSubCommands:
    async def publish(self, channel: _Key, message: _Key, **kwargs: _CommandOptions) -> int: ...
    async def pubsub_channels(self, pattern: _Key = "*", **kwargs: _CommandOptions) -> list[str]: ...
    async def pubsub_numpat(self, **kwargs: _CommandOptions) -> int: ...
    async def pubsub_numsub(self, *args: _Key, **kwargs: _CommandOptions) -> list[tuple[str, int]]: ...

class ScriptCommands(Generic[_StrType]):
    def eval(self, script, numkeys, *keys_and_args): ...
    def evalsha(self, sha, numkeys, *keys_and_args): ...
    def script_exists(self, *args): ...
    def script_debug(self, *args): ...
    def script_flush(self, sync_type: Incomplete | None = None): ...
    def script_kill(self): ...
    def script_load(self, script): ...
    def register_script(self, script: str | _StrType) -> Script: ...

class AsyncScriptCommands(Generic[_StrType]):
    async def eval(self, script, numkeys, *keys_and_args): ...
    async def evalsha(self, sha, numkeys, *keys_and_args): ...
    async def script_exists(self, *args): ...
    async def script_debug(self, *args): ...
    async def script_flush(self, sync_type: Incomplete | None = None): ...
    async def script_kill(self): ...
    async def script_load(self, script): ...
    def register_script(self, script: ScriptTextT) -> AsyncScript: ...

class GeoCommands:
    def geoadd(self, name, values, nx: bool = False, xx: bool = False, ch: bool = False): ...
    def geodist(self, name, place1, place2, unit: Incomplete | None = None): ...
    def geohash(self, name, *values): ...
    def geopos(self, name, *values): ...
    def georadius(
        self,
        name,
        longitude,
        latitude,
        radius,
        unit: Incomplete | None = None,
        withdist: bool = False,
        withcoord: bool = False,
        withhash: bool = False,
        count: Incomplete | None = None,
        sort: Incomplete | None = None,
        store: Incomplete | None = None,
        store_dist: Incomplete | None = None,
        any: bool = False,
    ): ...
    def georadiusbymember(
        self,
        name,
        member,
        radius,
        unit: Incomplete | None = None,
        withdist: bool = False,
        withcoord: bool = False,
        withhash: bool = False,
        count: Incomplete | None = None,
        sort: Incomplete | None = None,
        store: Incomplete | None = None,
        store_dist: Incomplete | None = None,
        any: bool = False,
    ): ...
    def geosearch(
        self,
        name,
        member: Incomplete | None = None,
        longitude: Incomplete | None = None,
        latitude: Incomplete | None = None,
        unit: str = "m",
        radius: Incomplete | None = None,
        width: Incomplete | None = None,
        height: Incomplete | None = None,
        sort: Incomplete | None = None,
        count: Incomplete | None = None,
        any: bool = False,
        withcoord: bool = False,
        withdist: bool = False,
        withhash: bool = False,
    ): ...
    def geosearchstore(
        self,
        dest,
        name,
        member: Incomplete | None = None,
        longitude: Incomplete | None = None,
        latitude: Incomplete | None = None,
        unit: str = "m",
        radius: Incomplete | None = None,
        width: Incomplete | None = None,
        height: Incomplete | None = None,
        sort: Incomplete | None = None,
        count: Incomplete | None = None,
        any: bool = False,
        storedist: bool = False,
    ): ...

class AsyncGeoCommands:
    async def geoadd(self, name, values, nx: bool = False, xx: bool = False, ch: bool = False): ...
    async def geodist(self, name, place1, place2, unit: Incomplete | None = None): ...
    async def geohash(self, name, *values): ...
    async def geopos(self, name, *values): ...
    async def georadius(
        self,
        name,
        longitude,
        latitude,
        radius,
        unit: Incomplete | None = None,
        withdist: bool = False,
        withcoord: bool = False,
        withhash: bool = False,
        count: Incomplete | None = None,
        sort: Incomplete | None = None,
        store: Incomplete | None = None,
        store_dist: Incomplete | None = None,
        any: bool = False,
    ): ...
    async def georadiusbymember(
        self,
        name,
        member,
        radius,
        unit: Incomplete | None = None,
        withdist: bool = False,
        withcoord: bool = False,
        withhash: bool = False,
        count: Incomplete | None = None,
        sort: Incomplete | None = None,
        store: Incomplete | None = None,
        store_dist: Incomplete | None = None,
        any: bool = False,
    ): ...
    async def geosearch(
        self,
        name,
        member: Incomplete | None = None,
        longitude: Incomplete | None = None,
        latitude: Incomplete | None = None,
        unit: str = "m",
        radius: Incomplete | None = None,
        width: Incomplete | None = None,
        height: Incomplete | None = None,
        sort: Incomplete | None = None,
        count: Incomplete | None = None,
        any: bool = False,
        withcoord: bool = False,
        withdist: bool = False,
        withhash: bool = False,
    ): ...
    async def geosearchstore(
        self,
        dest,
        name,
        member: Incomplete | None = None,
        longitude: Incomplete | None = None,
        latitude: Incomplete | None = None,
        unit: str = "m",
        radius: Incomplete | None = None,
        width: Incomplete | None = None,
        height: Incomplete | None = None,
        sort: Incomplete | None = None,
        count: Incomplete | None = None,
        any: bool = False,
        storedist: bool = False,
    ): ...

class ModuleCommands:
    def module_load(self, path, *args): ...
    def module_unload(self, name): ...
    def module_list(self): ...
    def command_info(self): ...
    def command_count(self): ...
    def command_getkeys(self, *args): ...
    def command(self): ...

class Script:
    def __init__(self, registered_client, script) -> None: ...
    def __call__(self, keys=[], args=[], client: Incomplete | None = None): ...

class BitFieldOperation:
    def __init__(self, client, key, default_overflow: Incomplete | None = None): ...
    def reset(self) -> None: ...
    def overflow(self, overflow): ...
    def incrby(self, fmt, offset, increment, overflow: Incomplete | None = None): ...
    def get(self, fmt, offset): ...
    def set(self, fmt, offset, value): ...
    @property
    def command(self): ...
    def execute(self): ...

class AsyncModuleCommands(ModuleCommands):
    async def command_info(self) -> None: ...

class ClusterCommands:
    def cluster(self, cluster_arg: str, *args, **kwargs: _CommandOptions): ...
    def readwrite(self, **kwargs: _CommandOptions) -> bool: ...
    def readonly(self, **kwargs: _CommandOptions) -> bool: ...

class AsyncClusterCommands:
    async def cluster(self, cluster_arg: str, *args, **kwargs: _CommandOptions): ...
    async def readwrite(self, **kwargs: _CommandOptions) -> bool: ...
    async def readonly(self, **kwargs: _CommandOptions) -> bool: ...

class FunctionCommands:
    def function_load(self, code: str, replace: bool | None = False) -> Awaitable[str] | str: ...
    def function_delete(self, library: str) -> Awaitable[str] | str: ...
    def function_flush(self, mode: str = "SYNC") -> Awaitable[str] | str: ...
    def function_list(self, library: str | None = "*", withcode: bool | None = False) -> Awaitable[list[Any]] | list[Any]: ...
    def fcall(self, function, numkeys: int, *keys_and_args: list[Any] | None) -> Awaitable[str] | str: ...
    def fcall_ro(self, function, numkeys: int, *keys_and_args: list[Any] | None) -> Awaitable[str] | str: ...
    def function_dump(self) -> Awaitable[str] | str: ...
    def function_restore(self, payload: str, policy: str | None = "APPEND") -> Awaitable[str] | str: ...
    def function_kill(self) -> Awaitable[str] | str: ...
    def function_stats(self) -> Awaitable[list[Any]] | list[Any]: ...

class AsyncFunctionCommands:
    async def function_load(self, code: str, replace: bool | None = False) -> Awaitable[str] | str: ...
    async def function_delete(self, library: str) -> Awaitable[str] | str: ...
    async def function_flush(self, mode: str = "SYNC") -> Awaitable[str] | str: ...
    async def function_list(
        self, library: str | None = "*", withcode: bool | None = False
    ) -> Awaitable[list[Any]] | list[Any]: ...
    async def fcall(self, function, numkeys: int, *keys_and_args: list[Any] | None) -> Awaitable[str] | str: ...
    async def fcall_ro(self, function, numkeys: int, *keys_and_args: list[Any] | None) -> Awaitable[str] | str: ...
    async def function_dump(self) -> Awaitable[str] | str: ...
    async def function_restore(self, payload: str, policy: str | None = "APPEND") -> Awaitable[str] | str: ...
    async def function_kill(self) -> Awaitable[str] | str: ...
    async def function_stats(self) -> Awaitable[list[Any]] | list[Any]: ...

class DataAccessCommands(
    BasicKeyCommands[_StrType],
    HyperlogCommands,
    HashCommands[_StrType],
    GeoCommands,
    ListCommands[_StrType],
    ScanCommands[_StrType],
    SetCommands[_StrType],
    StreamCommands,
    SortedSetCommands[_StrType],
): ...
class AsyncDataAccessCommands(
    AsyncBasicKeyCommands[_StrType],
    AsyncHyperlogCommands,
    AsyncHashCommands[_StrType],
    AsyncGeoCommands,
    AsyncListCommands[_StrType],
    AsyncScanCommands[_StrType],
    AsyncSetCommands[_StrType],
    AsyncStreamCommands,
    AsyncSortedSetCommands[_StrType],
): ...
class CoreCommands(
    ACLCommands[_StrType],
    ClusterCommands,
    DataAccessCommands[_StrType],
    ManagementCommands,
    ModuleCommands,
    PubSubCommands,
    ScriptCommands[_StrType],
): ...
class AsyncCoreCommands(
    AsyncACLCommands[_StrType],
    AsyncClusterCommands,
    AsyncDataAccessCommands[_StrType],
    AsyncManagementCommands,
    AsyncModuleCommands,
    AsyncPubSubCommands,
    AsyncScriptCommands[_StrType],
    AsyncFunctionCommands,
): ...
