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

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,
        fields: Mapping[bytes | memoryview | str | float, bytes | memoryview | str | float],
        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,
        fields: Mapping[bytes | memoryview | str | float, bytes | memoryview | str | float],
        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(
        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(
        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(
        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(
        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(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(
        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(
        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(
        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(
        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(
        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(
        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(
        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(
        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(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(
        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(
        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(
        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(
        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: ...  # type: ignore[override]

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],
    Generic[_StrType],
): ...
class AsyncDataAccessCommands(
    AsyncBasicKeyCommands[_StrType],
    AsyncHyperlogCommands,
    AsyncHashCommands[_StrType],
    AsyncGeoCommands,
    AsyncListCommands[_StrType],
    AsyncScanCommands[_StrType],
    AsyncSetCommands[_StrType],
    AsyncStreamCommands,
    AsyncSortedSetCommands[_StrType],
    Generic[_StrType],
): ...
class CoreCommands(
    ACLCommands[_StrType],
    ClusterCommands,
    DataAccessCommands[_StrType],
    ManagementCommands,
    ModuleCommands,
    PubSubCommands,
    ScriptCommands[_StrType],
    Generic[_StrType],
): ...
class AsyncCoreCommands(
    AsyncACLCommands[_StrType],
    AsyncClusterCommands,
    AsyncDataAccessCommands[_StrType],
    AsyncManagementCommands,
    AsyncModuleCommands,
    AsyncPubSubCommands,
    AsyncScriptCommands[_StrType],
    AsyncFunctionCommands,
    Generic[_StrType],
): ...
