Skip to content

Improved type annotations#3619

Open
mahenzon wants to merge 7 commits intoredis:masterfrom
mahenzon:improved-type-annotations
Open

Improved type annotations#3619
mahenzon wants to merge 7 commits intoredis:masterfrom
mahenzon:improved-type-annotations

Conversation

@mahenzon
Copy link

@mahenzon mahenzon commented Apr 27, 2025

Pull Request check-list

Reviewed and checked all of these items:

  • tests and lints pass with this change - checked in my fork: Improved type annotations mahenzon/redis-py#3
  • CI tests pass with this change - I enabled it first in my forked repo and waited for the GitHub action to finish - checked in my fork: Improved type annotations mahenzon/redis-py#3
  • Is the new or changed code fully tested? - example provided below
  • Is a documentation update included (if this change modifies existing APIs, or introduces new ones)? - no API changes
  • Is there an example added to the examples folder (if applicable)? - Do I need to add this checks.py file example to the repo?
  • Was the change added to CHANGES file? - Work in progress.

Description of change

Hello, there're some issues with type annotations: #2399 #3169

Example:

from typing import reveal_type

from redis import Redis

redis = Redis(
    host="localhost",
    port=6379,
    decode_responses=True,
)


res = redis.get("some-key")
reveal_type(res)
# note: Revealed type is "Union[typing.Awaitable[Any], Any]"

We can see that sync redis client may return awaitable result, but it will never do.

This is made for compatibility with async redis, but it introduces some challenges when checking code with static type checkers like mypy.

Also it's Any instead of str or bytes because we can't predict, if decode_responses is True or False - it'll be addressed later.

I'd like to make it work this way:

from typing import reveal_type

from redis import Redis
from redis.asyncio import Redis as AsyncRedis

redis = Redis(
    host="localhost",
    port=6379,
    decode_responses=True,
)

async_redis = AsyncRedis(
    host="localhost",
    port=6379,
    decode_responses=True,
)


res = redis.get("some-key")
reveal_type(res)
# note: Revealed type is "Union[builtins.str, None]"

coro = async_redis.get("some-key")
reveal_type(coro)
# note: Revealed type is "typing.Awaitable[Union[builtins.str, None]]"

I started reworking annotations, so type annotations for sync / async redis work as expected - sync redis doesn't return Awaitable, async redis returns Awaitable.

Important

The goal is not to make the whole redis-py source code mypy-comliant and fully annotated.
The goal is to make usage of redis-py in python projects compatible with mypy - make return type annotations more precise. So devs don't need to add casts and asserts to their code.

Example code. where I checked new typing

File: checks.py:

import random
import string
from typing import Optional, List, reveal_type

from redis import Redis
from redis.asyncio import Redis as AsyncRedis

redis = Redis(
    host="localhost",
    port=6379,
    decode_responses=True,
)

async_redis = AsyncRedis(
    host="localhost",
    port=6379,
    decode_responses=True,
)


def get_string() -> Optional[str]:
    res = redis.get("some-key")
    reveal_type(res)  # checks.py:23: note: Revealed type is "Union[builtins.str, None]"
    return res


async def async_get_string() -> Optional[str]:
    coro = async_redis.get("some-key")
    reveal_type(coro)  # checks.py:29: note: Revealed type is "typing.Awaitable[Union[builtins.str, None]]"
    res = await coro
    reveal_type(res)  # checks.py:31: note: Revealed type is "Union[builtins.str, None]"
    return res


def get_values() -> List[str]:
    vals = redis.hvals(name="name")
    reveal_type(vals)  # checks.py:37: note: Revealed type is "builtins.list[builtins.str]"
    res = [v.lower() for v in vals]
    reveal_type(res)  # checks.py:39: note: Revealed type is "builtins.list[builtins.str]"
    return res


async def async_get_values() -> List[str]:
    coro = async_redis.hvals(name="name")
    reveal_type(coro)  # checks.py:45: note: Revealed type is "typing.Awaitable[builtins.list[builtins.str]]"
    vals = await coro
    reveal_type(vals)  # checks.py:47: note: Revealed type is "builtins.list[builtins.str]"
    res = [v.lower() for v in vals]
    reveal_type(res)  # checks.py:49: note: Revealed type is "builtins.list[builtins.str]"
    return res


def checks() -> None:
    hget_res = redis.hget("hash-name", "key")
    reveal_type(hget_res)  # checks.py:55: note: Revealed type is "Union[builtins.str, None]"
    brpoplpush_res = redis.brpoplpush("src", "dst")
    reveal_type(brpoplpush_res)  # checks.py:57: note: Revealed type is "Union[builtins.str, None]"
    lindex_res = redis.lindex("name", 0)
    reveal_type(lindex_res)  # checks.py:59: note: Revealed type is "Union[builtins.str, None]"
    append_res = redis.append("key", "value")
    reveal_type(append_res)  # checks.py:61: note: Revealed type is "builtins.int"


async def async_checks() -> None:
    hget_res = await async_redis.hget("hash-name", "key")
    reveal_type(hget_res)  # checks.py:67: note: Revealed type is "Union[builtins.str, None]"
    brpoplpush_res = await async_redis.brpoplpush("src", "dst")
    reveal_type(brpoplpush_res)  # checks.py:69: note: Revealed type is "Union[builtins.str, None]"
    lindex_res = await async_redis.lindex("name", 0)
    reveal_type(lindex_res)  # checks.py:71: note: Revealed type is "Union[builtins.str, None]"
    append_res = await async_redis.append("key", "value")
    reveal_type(append_res)  # checks.py:73: note: Revealed type is "builtins.int"


def main() -> None:
    bitop_res = redis.bitop("NOT", "result", "key1")
    print(bitop_res)  # 0
    redis.set("foo", "val")
    bitop_res = redis.bitop("NOT", "res1", "foo")
    print(bitop_res)  # 3
    # decode response: - there's an issue decoding such result - works only with decode_responses=False
    # print(redis.get("res1"))
    res = redis.copy("foo", "bar")
    print("res:", res)  # res: True
    res = redis.copy("foo", "".join(random.choices(string.ascii_letters, k=20)))
    print("res:", res)  # res: True

    list_name = "".join(random.choices(string.ascii_letters, k=10))
    res_rpush = redis.rpush(list_name, "qwerty", "foobar")
    print("res rpush:", res_rpush)  # res rpush: 2
    print("list values", redis.lrange(list_name, 0, -1))  # list values ['qwerty', 'foobar']
    res_lset = redis.lset(list_name, 0, "some-val")
    print("res lset:", res_lset)  # res lset: True
    print("list values", redis.lrange(list_name, 0, -1))  # list values ['some-val', 'foobar']

    res_hsetnx = redis.hsetnx("hash-name", "key", "value")
    print("res hsetnx:", res_hsetnx)  # res hsetnx: True

    set_name = "some-set"
    some_set_value = "".join(random.choices(string.ascii_letters, k=10))
    another_set_value = "".join(random.choices(string.ascii_letters, k=10))
    print("is member", redis.sismember(set_name, some_set_value))  # is member False
    redis.sadd(set_name, some_set_value)
    print("is member", redis.sismember(set_name, some_set_value))  # is member True
    print("are members", redis.smismember(set_name, [some_set_value, another_set_value]))  # are members [True, False]


if __name__ == '__main__':
    main()

I checked it with mypy with strict=True enabled: mypy --strict checks.py, added comments to the code example above.

If these changes are ok for redis-py, I'll continue working on the update.


There's one major issue: these annotations are ok when decode_responses=True, but if not passed, or decode_responses=False, then some methods will return bytes instead of str - I'm working on a solution for this.


Also I fixed parsing for some commands which should return bools: 23ff994

@mahenzon mahenzon force-pushed the improved-type-annotations branch 2 times, most recently from 136b0a2 to b6d4a89 Compare April 27, 2025 08:39
@petyaslavova
Copy link
Collaborator

Hi @mahenzon, thank you for your contribution. We will go over it soon.

@mahenzon mahenzon force-pushed the improved-type-annotations branch 2 times, most recently from 38eb7c3 to de3cd7e Compare April 30, 2025 20:54
@trajano
Copy link

trajano commented May 1, 2025

Would this solve #3574?

@mahenzon
Copy link
Author

mahenzon commented May 1, 2025

Would this solve #3574?

Hi @trajano, thank you for mentioning this issue, I'll check it too.

@petyaslavova petyaslavova requested a review from Copilot May 9, 2025 14:18
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR improves type annotations across the codebase to ensure that both synchronous and asynchronous Redis clients report more precise return types that are compatible with static type checkers. Key changes include the introduction of new type variables in redis/typing.py, refined method return types in redis/commands/core.py (including generic-based command classes), and updates to command parser mappings in redis/_parsers/helpers.py.

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
redis/typing.py Added new type definitions and ResponseType* type variables
redis/commands/helpers.py Updated function signature for list_or_args to support Optional args
redis/commands/core.py Refactored return types for various command methods using generics
redis/_parsers/helpers.py Adjusted SMISMEMBER parser entries

Awaitable[List[Union[Literal[0], Literal[1]]]],
List[Union[Literal[0], Literal[1]]],
]:
def smismember(self, name: str, values: List, *args: List) -> ResponseTypeBoolean:
Copy link

Copilot AI May 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return type for smismember is annotated as ResponseTypeBoolean but the underlying parser returns a list of booleans. Consider defining and using a dedicated type (e.g., ResponseTypeBooleanList) to accurately reflect the returned value.

Copilot uses AI. Check for mistakes.
"SENTINEL SET": bool_ok,
"SLOWLOG GET": parse_slowlog_get,
"SLOWLOG RESET": bool_ok,
"SMISMEMBER": lambda r: list(map(bool, r)),
Copy link

Copilot AI May 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Duplicate entries for the SMISMEMBER key are added in this dictionary. Consolidating these duplicates could improve maintainability and clarity.

Copilot uses AI. Check for mistakes.
@connebs
Copy link

connebs commented May 27, 2025

Would love to see this merged!

redis/typing.py Outdated
BooleanType = bool
IntegerType = int
OptionalStringType = Optional[str]
StringListType = List[str]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
StringListType = List[str]
StringListType = list[str]

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though it won't be a problem for me since I'm on the latest Python, but using the small list version will cause issues with those on 3.8 which means something like this cannot be used with say Kodi

redis/typing.py Outdated

ResponseTypeBoolean = TypeVar(
"ResponseTypeBoolean",
bound=Union[Awaitable[BooleanType], BooleanType],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bound=Union[Awaitable[BooleanType], BooleanType],
bound=Union[Awaitable[bool], bool],

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're not after 3.8 compatibility, then I think it should be

bound=bool  | Awaitable[bool]

ruff has a rule that would do that swap along with removing Optional in place of | None

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're not after 3.8 compatibility, then I think it should be

According to the README, the current version of this project (6.2.0) seems to support Python 3.9+ meaning the list[str] syntax above is usable, but the bool | Awaitable[bool] syntax would not be, as this was introduced in Python 3.10 (source)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right it was just changed recently e5756da it used to say >=3.8 before.

redis/typing.py Outdated
IntegerType = int
OptionalStringType = Optional[str]
StringListType = List[str]
OptionalStringListType = Optional[List[str]]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
OptionalStringListType = Optional[List[str]]
OptionalStringListType = Optional[list[str]]

redis/typing.py Outdated
)
ResponseTypeInteger = TypeVar(
"ResponseTypeInteger",
bound=Union[Awaitable[IntegerType], IntegerType],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bound=Union[Awaitable[IntegerType], IntegerType],
bound=Union[Awaitable[int], int],

return self.execute_command("EXPIRETIME", key)

def get(self, name: KeyT) -> ResponseT:
def get(self, name: KeyT) -> ResponseTypeOptionalString:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get() returns bytes, not str.

>>> import redis
>>> client = redis.Redis()
>>> client.set("foo", b"abcdef")
True
>>> client.get("foo")
b'abcdef'
>>> client.set("bar", "abcdef")
True
>>> client.get("bar")
b'abcdef'

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's a major issue with decode_responses=True or decode_responses=False

If True, then str is returned. Otherwise bytes.

I'm going to try to fix this with overrides and Literals, not sure yet how to implement this. Other way is just to implement types, like in some other libs. Still working on a solution here

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may need to be asserted by the user e.g.

if not isinstance(res, str):
   msg = f"Expected str type got {type(res)}"
   raise TypeError(msg)

But if decodeResponses is False then return bytes
But if decodeResponses is True then return any
that should be doable by @overload right?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other way is just to implement types, like in some other libs. Still working on a solution here

I assume you mean having .pyi files for typing in some of the files? My opinion carries no weight in this project, but I think I'd be a +1 on this approach. Having stub files for these commands seems like a nice balance between several options.

It seems quite difficult to accurately represent the type annotations in a clean way due to the way the command classes are structured. I think the approach taken in this PR is interesting, and works for this scenario, but "feels" quite hacky (I realise this is not necessarily the most constructive criticism), I had to double-take a couple of times to figure out what each generic represents.

Alternative Approaches

Higher-Kinded Generics (Would be nice)

If Python supported higher-kinded TypeVars, it could be semi-cleanly implemented with something like

from collections.abc import Awaitable
from typing import Annotated, Generic, TypeVar

U = TypeVar("U")
A = Annotated[U, ...]
T = TypeVar("T", A, Awaitable)

class Base(Generic[T]):
    def ping(self) -> T[bool]:
        return True

class AsyncClient(Base[Awaitable]):
    pass

class Client(Base[A]):
    pass

Client().ping()  # Should be `bool`
AsyncClient().ping()  # Should be `Awaitable[bool]`

Where A here represents an opaque type designed to be "invisible" to the end-user.

Type Overriding

It is also possible to override the types of the superclass functions in a subclass like

class Superclass:
    def get(self, name: KeyT) -> Any | Awaitable[Any]: ...

class Subclass(Superclass):
    if TYPE_CHECKING:
        def get(self, name: KeyT) -> Awaitable[str | byets]: ...

But this will become very verbose for this project having to re-type all of the functions inside the source code.

Stubs

Which brings me back to the idea of stubs, the stub files provided by typeshed appeared to accurately represent most of the cases for redis-py including overloads for decode_responses which shows how it is possible to represent this behaviour in the stub files.

IMO, this is a nice balance between having a "straightforward" implementation while also not polluting the code with hundreds of lines of typing information.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's best to just leave it as any

You cannot have

redis.Redis(decode_responses: Literal[True]) redis.Redis(decode_responses: Literal[False]) having two different signatures on construction.

I am thinking the use of str | bytes will cause more problems for the users of the library. Ideally there would be a

make_redis(decode_responses: Literal[True]) -> ResponseDecodingRedis
make_redis(decode_responses: Literal[False]-> Redis

Copy link
Author

@mahenzon mahenzon May 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, yes, we can't benefit from overloading __init__ directly since it doesn't return anything. But there're ways around. I see it this way:

protocols

from typing import Protocol


class RedisInterface(Protocol):

    def get(self, key: str) -> str | bytes | None: ...


class RedisDecoded(Protocol):
    def get(self, key: str) -> str | None: ...


class RedisEncoded(Protocol):
    def get(self, key: str) -> bytes | None: ...

implementation

from redis.protocols import RedisInterface

# fake implementation just for example
class RedisImplementation(RedisInterface):

    def __init__(self, decoded: bool = False):
        self.decoded = decoded

    def get(self, key: str) -> str | bytes | None:
        if key == "get-none":
            return None
        if self.decoded:
            return "foo"
        return b"bar"

overloads (for example, stored in redis.typed)

@overload
def Redis() -> RedisEncoded: ...


@overload
def Redis(decoded: Literal[False] = ...) -> RedisEncoded: ...


@overload
def Redis(decoded: Literal[True] = ...) -> RedisDecoded: ...


def Redis(decoded: bool = False) -> RedisEncoded | RedisDecoded | RedisImplementation:
    return RedisImplementation(decoded=decoded)

usage

from redis.typed import Redis

redis = Redis()
redis_decoded = Redis(decoded=True)
redis_encoded = Redis(decoded=False)

reveal_type(redis.get("get-none"))
# MyPy: Revealed type is "Union[builtins.bytes, None]"
# Runtime type is 'NoneType'
reveal_type(redis.get("f"))
# MyPy: Revealed type is "Union[builtins.bytes, None]"
# Runtime type is 'bytes'

reveal_type(redis_encoded.get("get-none"))
# MyPy: Revealed type is "Union[builtins.bytes, None]"
# Runtime type is 'NoneType'
reveal_type(redis_encoded.get("f"))
# MyPy: Revealed type is "Union[builtins.bytes, None]"
# Runtime type is 'bytes'

reveal_type(redis_decoded.get("get-none"))
# MyPy: Revealed type is "Union[builtins.str, None]"
# Runtime type is 'NoneType'
reveal_type(redis_decoded.get("f"))
# MyPy: Revealed type is "Union[builtins.str, None]"
# Runtime type is 'str'

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So basically have a separate .typed package and leave the originals untyped. I guess considering the current state of the code that would be a good way of deferring the debt.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, yes, we can't benefit from overloading __init__ directly since it doesn't return anything.

I think you can. The return type is None, yes; but there's nothing stopping you from typing self, which you could use to narrow the type of the resulting class

toy example: https://mypy-play.net/?mypy=latest&python=3.12&gist=3badd83dc50a9564d24fefa99670ceba

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow, that's great news! Thank you, @Redoubts, I'll take a look at this approach too!

@Graeme22
Copy link

Graeme22 commented Aug 1, 2025

This is desperately needed! Anything I can do to help this along?

@mahenzon
Copy link
Author

mahenzon commented Aug 2, 2025

@Graeme22 hi,
there's no detailed plan for this issue. you can take a look at what's been done with basic commands and work on the next commands class. You'll need to check what redis returns to create proper annotations

owtaylor added a commit to owtaylor/ai-workflows that referenced this pull request Aug 15, 2025
Typing for the asyncio redis client is messed up, and functions
return `T | Awaitable[T]` instead of `T`. Add a workaround
wrapper that asserts that we are in the second case.

See:

  redis/redis-py#3619

for an in-progress upstream fix.
owtaylor added a commit to owtaylor/ai-workflows that referenced this pull request Aug 20, 2025
Typing for the asyncio redis client is messed up, and functions
return `T | Awaitable[T]` instead of `T`. Add a workaround
wrapper that asserts that we are in the second case.

See:

  redis/redis-py#3619

for an in-progress upstream fix.
owtaylor added a commit to packit/ai-workflows that referenced this pull request Aug 20, 2025
Typing for the asyncio redis client is messed up, and functions
return `T | Awaitable[T]` instead of `T`. Add a workaround
wrapper that asserts that we are in the second case.

See:

  redis/redis-py#3619

for an in-progress upstream fix.
owtaylor added a commit to owtaylor/flatpak-indexer that referenced this pull request Nov 19, 2025
redis-py has problematical type annotations - async and sync return types
are mixed together, and there is no representation of the fact that
the client *might* decode the responses from bytes to str, or not,
depending on how it was constructed.

See redis/redis-py#3619

Work around this by adding protocols that represent the types of the
API as we use it, and cast to the protocols as needed.
owtaylor added a commit to owtaylor/flatpak-indexer that referenced this pull request Nov 19, 2025
redis-py has problematical type annotations - async and sync return types
are mixed together, and there is no representation of the fact that
the client *might* decode the responses from bytes to str, or not,
depending on how it was constructed.

See redis/redis-py#3619

Work around this by adding protocols that represent the types of the
API as we use it, and cast to the protocols as needed.
owtaylor added a commit to owtaylor/flatpak-indexer that referenced this pull request Nov 19, 2025
redis-py has problematical type annotations - async and sync return types
are mixed together, and there is no representation of the fact that
the client *might* decode the responses from bytes to str, or not,
depending on how it was constructed.

See redis/redis-py#3619

Work around this by adding protocols that represent the types of the
API as we use it, and cast to the protocols as needed.
owtaylor added a commit to owtaylor/flatpak-indexer that referenced this pull request Nov 19, 2025
redis-py has problematical type annotations - async and sync return types
are mixed together, and there is no representation of the fact that
the client *might* decode the responses from bytes to str, or not,
depending on how it was constructed.

See redis/redis-py#3619

Work around this by adding protocols that represent the types of the
API as we use it, and cast to the protocols as needed.
@mahenzon
Copy link
Author

mahenzon commented Jan 5, 2026

I fiddled around with it, thanks for guys in the discussion above, especially to @Redoubts and his example with overriding __init__.

Here's gist example.
And here's this code at mypy's playground.

This is a real working solution because:

  • it doesn't require any separate fabrics;
  • it will work on the existing codebase - one has to update the package and he'll receive all the annotations;
  • it automatically understands if decode_responses is set to True or False if passed as literal. If passed as a bool variable then the union str | bytes | None will be returned (or Awaitable[str | bytes | None] for async Redis).

Now what I have to do:

  • rebase onto latest master, fix conflicts
  • update sync and async Redis classes, add overloads as in example
  • update commands to have proper annotations
  • add some checks / tests

@mahenzon mahenzon force-pushed the improved-type-annotations branch from de3cd7e to 5d456a1 Compare January 6, 2026 11:53
@mahenzon
Copy link
Author

mahenzon commented Jan 6, 2026

Current implementation works as expected. I checked some basic key commands, PyCharm and mypy resolve types correctly.

Code snippet example
from typing import reveal_type, assert_type, TYPE_CHECKING, Literal

from redis import Redis
from redis import ConnectionPool
from redis.asyncio import Redis as AsyncRedis
from redis.asyncio import ConnectionPool as AsyncConnectionPool

if TYPE_CHECKING:
    from redis.typing import (
        RedisEncoded,
        RedisDecoded, StrAlgoResultType,
    )
    from redis.asyncio.typing import (
        RedisEncoded as AsyncRedisEncoded,
        RedisDecoded as AsyncRedisDecoded,
    )

def main_sync() -> None:
    #  === direct Redis class ===

    # decode_responses=True should return str | None
    redis_decoded = Redis(decode_responses=True)

    value_decoded = redis_decoded.get("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_decoded)
    assert_type(value_decoded, str | None)

    value_decoded_deleted = redis_decoded.getdel("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_decoded_deleted)
    assert_type(value_decoded_deleted, str | None)

    many_values_decoded = redis_decoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None]"
    reveal_type(many_values_decoded)
    assert_type(many_values_decoded, list[str | None])

    dumped_value = redis_decoded.dump("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(dumped_value)
    assert_type(dumped_value, bytes | None)

    decoded_getitem = redis_decoded["key"]
    # Revealed type is "builtins.str"
    reveal_type(decoded_getitem)
    assert_type(decoded_getitem, str)

    inr_float_decoded = redis_decoded.incrbyfloat("key", 1.5)
    # Revealed type is "builtins.float"
    reveal_type(inr_float_decoded)
    assert_type(inr_float_decoded, float)


    # decode_responses=False should return bytes | None
    redis_encoded = Redis(decode_responses=False)
    value_encoded = redis_encoded.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_encoded)
    assert_type(value_encoded, bytes | None)

    value_encoded_deleted = redis_encoded.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_encoded_deleted)
    assert_type(value_encoded_deleted, bytes | None)

    many_values_encoded = redis_encoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_encoded)
    assert_type(many_values_encoded, list[bytes | None])

    # Default (no decode_responses) should return bytes | None
    redis_default = Redis()
    value_default = redis_default.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_default)
    assert_type(value_default, bytes | None)

    value_default_deleted = redis_default.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_default_deleted)
    assert_type(value_default_deleted, bytes | None)

    many_values_default = redis_default.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_default)
    assert_type(many_values_default, list[bytes | None])

    encoded_getitem = redis_default["key"]
    # Revealed type is "builtins.bytes"
    reveal_type(encoded_getitem)
    assert_type(encoded_getitem, bytes)

    inr_float_default = redis_default.incrbyfloat("key", 1.5)
    # Revealed type is "builtins.float"
    reveal_type(inr_float_default)
    assert_type(inr_float_default, float)


    # decode_responses with bool variable should return str | None | bytes
    decode_responses_var = True  # Could be True or False at runtime
    redis_dynamic = Redis(decode_responses=decode_responses_var)
    value_dynamic = redis_dynamic.get("key")
    # Revealed type is "builtins.str | None | builtins.bytes"
    reveal_type(value_dynamic)
    assert_type(value_dynamic, str | bytes | None)

    value_dynamic_deleted = redis_dynamic.getdel("key")
    # Revealed type is "builtins.str | None | builtins.bytes"
    reveal_type(value_dynamic_deleted)
    assert_type(value_dynamic_deleted, str | bytes | None)

    many_values_dynamic = redis_dynamic.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None] | builtins.list[builtins.bytes | None]"
    reveal_type(many_values_dynamic)
    assert_type(many_values_dynamic, list[str | None] | list[bytes | None])

    # decode_responses with static bool variable should act like literal
    decode_responses_static_var: Literal[True] = True  # Could be True or False at runtime
    redis_static_var = Redis(decode_responses=decode_responses_static_var)
    value_static_var = redis_static_var.get("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_static_var)
    assert_type(value_static_var, str | None)

    value_static_var_deleted = redis_static_var.getdel("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_static_var_deleted)
    assert_type(value_static_var_deleted, str | None)

    many_values_static_var = redis_static_var.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None]"
    reveal_type(many_values_static_var)
    assert_type(many_values_static_var, list[str | None])

    # positional decode_responses passed True

    redis_all_positional_decoded = Redis(
        "localhost", # host
        6379, # port
        0, # db
        "pw", # password
        None, # socket_timeout
        None, # socket_connect_timeout
        None, # socket_keepalive
        None, # socket_keepalive_options
        None, # connection_pool
        None, # unix_socket_path
        "utf-8", # encoding
        "strict", # encoding_errors
        True, # decode_responses
    )
    value_all_positional_decoded = redis_all_positional_decoded.get("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_all_positional_decoded)
    assert_type(value_all_positional_decoded, str | None)

    value_all_positional_decoded_deleted = redis_all_positional_decoded.getdel("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_all_positional_decoded_deleted)
    assert_type(value_all_positional_decoded_deleted, str | None)

    many_values_all_positional_decoded = redis_all_positional_decoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None]"
    reveal_type(many_values_all_positional_decoded)
    assert_type(many_values_all_positional_decoded, list[str | None])


    #  === Redis.from_url classmethod ===

    # from_url with decode_responses=True should return str | None
    redis_from_url_decoded = Redis.from_url("redis://localhost", decode_responses=True)
    value_from_url_decoded = redis_from_url_decoded.get("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_from_url_decoded)
    assert_type(value_from_url_decoded, str | None)

    value_from_url_decoded_deleted = redis_from_url_decoded.getdel("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_from_url_decoded_deleted)
    assert_type(value_from_url_decoded_deleted, str | None)

    many_values_from_url_decoded = redis_from_url_decoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None]"
    reveal_type(many_values_from_url_decoded)
    assert_type(many_values_from_url_decoded, list[str | None])

    # from_url with decode_responses=False should return bytes | None
    redis_from_url_encoded = Redis.from_url("redis://localhost", decode_responses=False)
    value_from_url_encoded = redis_from_url_encoded.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_url_encoded)
    assert_type(value_from_url_encoded, bytes | None)

    value_from_url_encoded_deleted = redis_from_url_encoded.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_url_encoded_deleted)
    assert_type(value_from_url_encoded_deleted, bytes | None)

    many_values_from_url_encoded = redis_from_url_encoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_from_url_encoded)
    assert_type(many_values_from_url_encoded, list[bytes | None])

    # from_url without decode_responses should return bytes | None
    redis_from_url_default = Redis.from_url("redis://localhost")
    value_from_url_default = redis_from_url_default.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_url_default)
    assert_type(value_from_url_default, bytes | None)

    value_from_url_default_deleted = redis_from_url_default.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_url_default_deleted)
    assert_type(value_from_url_default_deleted, bytes | None)

    many_values_from_url_default = redis_from_url_default.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_from_url_default)
    assert_type(many_values_from_url_default, list[bytes | None])

    # decode_responses with bool variable should return str | None | bytes
    decode_responses_var = True  # Could be True or False at runtime
    redis_from_url_dynamic = Redis.from_url("redis://localhost", decode_responses=decode_responses_var)
    value_from_url_dynamic = redis_from_url_dynamic.get("key")
    # Revealed type is "builtins.str | None | builtins.bytes"
    reveal_type(value_from_url_dynamic)
    assert_type(value_from_url_dynamic, str | bytes | None)

    value_from_url_dynamic_deleted = redis_from_url_dynamic.getdel("key")
    # Revealed type is "builtins.str | None | builtins.bytes"
    reveal_type(value_from_url_dynamic_deleted)
    assert_type(value_from_url_dynamic_deleted, str | bytes | None)

    many_values_from_url_dynamic = redis_from_url_dynamic.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None] | builtins.list[builtins.bytes | None]"
    reveal_type(many_values_from_url_dynamic)
    assert_type(many_values_from_url_dynamic, list[str | None] | list[bytes | None])


    #  === Redis.from_pool classmethod ===

    conn_pool = ConnectionPool.from_url("redis://localhost")

    redis_from_pool_decoded: "RedisDecoded" = Redis.from_pool(connection_pool=conn_pool)  # type: ignore[assignment]
    value_from_pool_decoded = redis_from_pool_decoded.get("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_from_pool_decoded)
    assert_type(value_from_pool_decoded, str | None)

    value_from_pool_decoded_deleted = redis_from_pool_decoded.getdel("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_from_pool_decoded_deleted)
    assert_type(value_from_pool_decoded_deleted, str | None)

    many_values_from_pool_decoded = redis_from_pool_decoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None]"
    reveal_type(many_values_from_pool_decoded)
    assert_type(many_values_from_pool_decoded, list[str | None])

    redis_from_pool_encoded: "RedisEncoded" = Redis.from_pool(connection_pool=conn_pool)  # type: ignore[assignment]
    value_from_pool_encoded = redis_from_pool_encoded.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_pool_encoded)
    assert_type(value_from_pool_encoded, bytes | None)

    value_from_pool_encoded_deleted = redis_from_pool_encoded.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_pool_encoded_deleted)
    assert_type(value_from_pool_encoded_deleted, bytes | None)

    many_values_from_pool_encoded = redis_from_pool_encoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_from_pool_encoded)
    assert_type(many_values_from_pool_encoded, list[bytes | None])


async def main_async() -> None:
    #  === direct Redis class ===

    # decode_responses=True should return str | None
    async_redis_decoded = AsyncRedis(decode_responses=True)
    value_decoded = await async_redis_decoded.get("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_decoded)
    assert_type(value_decoded, str | None)

    value_decoded_deleted = await async_redis_decoded.getdel("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_decoded_deleted)
    assert_type(value_decoded_deleted, str | None)

    many_values_decoded = await async_redis_decoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None]"
    reveal_type(many_values_decoded)
    assert_type(many_values_decoded, list[str | None])

    dumped_value = await async_redis_decoded.dump("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(dumped_value)
    assert_type(dumped_value, bytes | None)

    inr_float_decoded = await async_redis_decoded.incrbyfloat("key", 1.5)
    # Revealed type is "builtins.float"
    reveal_type(inr_float_decoded)
    assert_type(inr_float_decoded, float)

    stralgo_result = await async_redis_decoded.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings')
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_result)
    assert_type(stralgo_result, StrAlgoResultType)

    # decode_responses=False should return bytes | None
    async_redis_encoded = AsyncRedis(decode_responses=False)
    value_encoded = await async_redis_encoded.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_encoded)
    assert_type(value_encoded, bytes | None)

    value_encoded_deleted = await async_redis_encoded.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_encoded_deleted)
    assert_type(value_encoded_deleted, bytes | None)

    many_values_encoded = await async_redis_encoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_encoded)
    assert_type(many_values_encoded, list[bytes | None])

    # Default (no decode_responses) should return bytes | None
    async_redis_default = AsyncRedis()
    value_default = await async_redis_default.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_default)
    assert_type(value_default, bytes | None)

    value_default_deleted = await async_redis_default.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_default_deleted)
    assert_type(value_default_deleted, bytes | None)

    many_values_default = await async_redis_default.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_default)
    assert_type(many_values_default, list[bytes | None])

    # decode_responses with bool variable should return str | None | bytes
    decode_responses_var = True  # Could be True or False at runtime
    async_redis_dynamic = AsyncRedis(decode_responses=decode_responses_var)
    value_dynamic = await async_redis_dynamic.get("key")
    # Revealed type is "builtins.str | None | builtins.bytes | None"
    reveal_type(value_dynamic)
    assert_type(value_dynamic, str | bytes | None)

    value_dynamic_deleted = await async_redis_dynamic.getdel("key")
    # Revealed type is "builtins.str | None | builtins.bytes | None"
    reveal_type(value_dynamic_deleted)
    assert_type(value_dynamic_deleted, str | bytes | None)

    many_values_dynamic = await async_redis_dynamic.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None] | builtins.list[builtins.bytes | None]"
    reveal_type(many_values_dynamic)
    assert_type(many_values_dynamic, list[str | None] | list[bytes | None])


    #  === AsyncRedis.from_url classmethod ===

    # from_url with decode_responses=True should return str | None
    async_redis_from_url_decoded = AsyncRedis.from_url("redis://localhost", decode_responses=True)
    value_from_url_decoded = await async_redis_from_url_decoded.get("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_from_url_decoded)
    assert_type(value_from_url_decoded, str | None)

    value_from_url_decoded_deleted = await async_redis_from_url_decoded.getdel("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_from_url_decoded_deleted)
    assert_type(value_from_url_decoded_deleted, str | None)

    many_values_from_url_decoded = await async_redis_from_url_decoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None]"
    reveal_type(many_values_from_url_decoded)
    assert_type(many_values_from_url_decoded, list[str | None])

    # from_url with decode_responses=False should return bytes | None
    async_redis_from_url_encoded = AsyncRedis.from_url("redis://localhost", decode_responses=False)
    value_from_url_encoded = await async_redis_from_url_encoded.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_url_encoded)
    assert_type(value_from_url_encoded, bytes | None)

    value_from_url_encoded_deleted = await async_redis_from_url_encoded.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_url_encoded_deleted)
    assert_type(value_from_url_encoded_deleted, bytes | None)

    many_values_from_url_encoded = await async_redis_from_url_encoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_from_url_encoded)
    assert_type(many_values_from_url_encoded, list[bytes | None])

    # from_url without decode_responses should return bytes | None
    async_redis_from_url_default = AsyncRedis.from_url("redis://localhost")
    value_from_url_default = await async_redis_from_url_default.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_url_default)
    assert_type(value_from_url_default, bytes | None)

    value_from_url_default_deleted = await async_redis_from_url_default.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_url_default_deleted)
    assert_type(value_from_url_default_deleted, bytes | None)

    many_values_from_url_default = await async_redis_from_url_default.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_from_url_default)
    assert_type(many_values_from_url_default, list[bytes | None])

    # decode_responses with bool variable should return str | None | bytes
    decode_responses_var = True  # Could be True or False at runtime
    async_redis_from_url_dynamic = AsyncRedis.from_url("redis://localhost", decode_responses=decode_responses_var)
    value_from_url_dynamic = await async_redis_from_url_dynamic.get("key")
    # Revealed type is "builtins.str | None | builtins.bytes | None"
    reveal_type(value_from_url_dynamic)
    assert_type(value_from_url_dynamic, str | bytes | None)

    value_from_url_dynamic_deleted = await async_redis_from_url_dynamic.getdel("key")
    # Revealed type is "builtins.str | None | builtins.bytes | None"
    reveal_type(value_from_url_dynamic_deleted)
    assert_type(value_from_url_dynamic_deleted, str | bytes | None)

    many_values_from_url_dynamic = await async_redis_from_url_dynamic.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None] | builtins.list[builtins.bytes | None]"
    reveal_type(many_values_from_url_dynamic)
    assert_type(many_values_from_url_dynamic, list[str | None] | list[bytes | None])


    #  === AsyncRedis.from_pool classmethod ===

    conn_pool = AsyncConnectionPool.from_url("redis://localhost")

    async_redis_from_pool_decoded: "AsyncRedisDecoded" = AsyncRedis.from_pool(connection_pool=conn_pool)  # type: ignore[assignment]
    value_from_pool_decoded = await async_redis_from_pool_decoded.get("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_from_pool_decoded)
    assert_type(value_from_pool_decoded, str | None)

    value_from_pool_decoded_deleted = await async_redis_from_pool_decoded.getdel("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_from_pool_decoded_deleted)
    assert_type(value_from_pool_decoded_deleted, str | None)

    many_values_from_pool_decoded = await async_redis_from_pool_decoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None]"
    reveal_type(many_values_from_pool_decoded)
    assert_type(many_values_from_pool_decoded, list[str | None])

    async_redis_from_pool_encoded: "AsyncRedisEncoded" = AsyncRedis.from_pool(connection_pool=conn_pool)  # type: ignore[assignment]
    value_from_pool_encoded = await async_redis_from_pool_encoded.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_pool_encoded)
    assert_type(value_from_pool_encoded, bytes | None)

    value_from_pool_encoded_deleted = await async_redis_from_pool_encoded.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_pool_encoded_deleted)
    assert_type(value_from_pool_encoded_deleted, bytes | None)

    many_values_from_pool_encoded = await async_redis_from_pool_encoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_from_pool_encoded)
    assert_type(many_values_from_pool_encoded, list[bytes | None])

@mahenzon
Copy link
Author

mahenzon commented Jan 6, 2026

I've updated return type annotations for methods in BasicKeyCommands and ListCommands classes.

Here's how I check if everything is right.
I don't know yet how to adapt this code for regular testing, so it can be integrated into the repo to be used in all tests to keep typing working.
This code snippet is not maintainable in any way, I partly code-generated it, partly ai-generated, partly wrote it using multicursor. Not sure if any human should read it ever. I just check that no mypy errors are produced when checking this file using command mypy --strict test_redis_typing.py

Code snippet example

File test_redis_typing.py

from typing import reveal_type, assert_type, TYPE_CHECKING, Literal

from redis import Redis
from redis import ConnectionPool
from redis.asyncio import Redis as AsyncRedis
from redis.asyncio import ConnectionPool as AsyncConnectionPool

if TYPE_CHECKING:
    from redis.typing import (
        RedisEncoded,
        RedisDecoded, StrAlgoResultType,
    )
    from redis.asyncio.typing import (
        RedisEncoded as AsyncRedisEncoded,
        RedisDecoded as AsyncRedisDecoded,
    )

def test_basic_key_commands_sync() -> None:
    #  === direct Redis class ===

    # decode_responses=True should return str | None
    redis_decoded = Redis(decode_responses=True)

    value_decoded = redis_decoded.get("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_decoded)
    assert_type(value_decoded, str | None)

    value_decoded_deleted = redis_decoded.getdel("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_decoded_deleted)
    assert_type(value_decoded_deleted, str | None)

    many_values_decoded = redis_decoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None]"
    reveal_type(many_values_decoded)
    assert_type(many_values_decoded, list[str | None])

    dumped_value = redis_decoded.dump("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(dumped_value)
    assert_type(dumped_value, bytes | None)

    decoded_getitem = redis_decoded["key"]
    # Revealed type is "builtins.str"
    reveal_type(decoded_getitem)
    assert_type(decoded_getitem, str)

    inr_float_decoded = redis_decoded.incrbyfloat("key", 1.5)
    # Revealed type is "builtins.float"
    reveal_type(inr_float_decoded)
    assert_type(inr_float_decoded, float)

    # append
    append_result_decoded = redis_decoded.append(key='testkey', value='testvalue')
    # Revealed type is "builtins.int"
    reveal_type(append_result_decoded)
    assert_type(append_result_decoded, int)

    # bitcount
    bitcount_result_decoded = redis_decoded.bitcount(key='testkey', start=0, end=-1)
    # Revealed type is "builtins.int"
    reveal_type(bitcount_result_decoded)
    assert_type(bitcount_result_decoded, int)

    # # bitfield
    # bitfield_result_decoded = redis_decoded.bitfield(key='testkey')
    # reveal_type(bitfield_result_decoded)
    # # bitfield_result_decoded is a complex type
    # assert_type(bitfield_result, ...)

    # blmove
    blmove_result_decoded = redis_decoded.blmove(first_list='mylist', second_list='destlist', timeout=1)
    # Revealed type is "builtins.str"
    reveal_type(blmove_result_decoded)
    assert_type(blmove_result_decoded, str)

    # copy
    copy_result_decoded = redis_decoded.copy(source='mylist', destination='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(copy_result_decoded)
    assert_type(copy_result_decoded, bool)

    # decrby
    decrby_result_decoded = redis_decoded.decrby(name='counter', amount=5)
    # Revealed type is "builtins.int"
    reveal_type(decrby_result_decoded)
    assert_type(decrby_result_decoded, int)

    # delete
    delete_result_decoded = redis_decoded.delete('testkey')
    # Revealed type is "builtins.int"
    reveal_type(delete_result_decoded)
    assert_type(delete_result_decoded, int)

    # delex
    delex_result_decoded = redis_decoded.delex(name='testkey')
    # Revealed type is "builtins.int"
    reveal_type(delex_result_decoded)
    assert_type(delex_result_decoded, int)

    # digest
    digest_result_decoded = redis_decoded.digest(name='testkey')
    # Revealed type is "builtins.str | None"
    reveal_type(digest_result_decoded)
    assert_type(digest_result_decoded, str | None)

    # exists
    exists_result_decoded = redis_decoded.exists('testkey')
    # Revealed type is "builtins.int"
    reveal_type(exists_result_decoded)
    assert_type(exists_result_decoded, int)

    # expire
    expire_result_decoded = redis_decoded.expire(name='testkey', time=60)
    # Revealed type is "builtins.bool"
    reveal_type(expire_result_decoded)
    assert_type(expire_result_decoded, bool)

    # expireat
    expireat_result_decoded = redis_decoded.expireat(name='testkey', when=1767730775)
    # Revealed type is "builtins.bool"
    reveal_type(expireat_result_decoded)
    assert_type(expireat_result_decoded, bool)

    # expiretime
    expiretime_result_decoded = redis_decoded.expiretime(key='testkey')
    # Revealed type is "builtins.int"
    reveal_type(expiretime_result_decoded)
    assert_type(expiretime_result_decoded, int)

    # getbit
    getbit_result_decoded = redis_decoded.getbit(name='testkey', offset=0)
    # Revealed type is "builtins.int"
    reveal_type(getbit_result_decoded)
    assert_type(getbit_result_decoded, int)

    # getrange
    getrange_result_decoded = redis_decoded.getrange(key='testkey', start=0, end=-1)
    # Revealed type is "builtins.str"
    reveal_type(getrange_result_decoded)
    assert_type(getrange_result_decoded, str)

    # getset
    getset_result_decoded = redis_decoded.getset(name='testkey', value='testvalue')
    # Revealed type is "builtins.str | None"
    reveal_type(getset_result_decoded)
    assert_type(getset_result_decoded, str | None)

    # hrandfield
    hrandfield_result_decoded = redis_decoded.hrandfield(key='nonexistent', count=1)
    # Revealed type is "builtins.list[builtins.str]"
    reveal_type(hrandfield_result_decoded)
    assert_type(hrandfield_result_decoded, list[str])

    # incrby
    incrby_result_decoded = redis_decoded.incrby(name='counter', amount=5)
    # Revealed type is "builtins.int"
    reveal_type(incrby_result_decoded)
    assert_type(incrby_result_decoded, int)

    # incrbyfloat
    incrbyfloat_result_decoded = redis_decoded.incrbyfloat(name='nonexistent', amount=1.0)
    # Revealed type is "builtins.float"
    reveal_type(incrbyfloat_result_decoded)
    assert_type(incrbyfloat_result_decoded, float)

    # keys
    keys_result_decoded = redis_decoded.keys(pattern='*')
    # Revealed type is "builtins.list[builtins.str]"
    reveal_type(keys_result_decoded)
    assert_type(keys_result_decoded, list[str])

    # lcs
    lcs_result_decoded = redis_decoded.lcs(key1='test', key2='test')
    # Revealed type is "builtins.str"
    reveal_type(lcs_result_decoded)
    assert_type(lcs_result_decoded, str)

    # lmove
    lmove_result_decoded = redis_decoded.lmove(first_list='mylist', second_list='destlist')
    # Revealed type is "builtins.str"
    reveal_type(lmove_result_decoded)
    assert_type(lmove_result_decoded, str)

    # move
    move_result_decoded = redis_decoded.move(name='testkey', db=1)
    # Revealed type is "builtins.bool"
    reveal_type(move_result_decoded)
    assert_type(move_result_decoded, bool)

    # mset
    mset_result_decoded = redis_decoded.mset(mapping={'field1': 'value1'})
    # Revealed type is "builtins.bool"
    reveal_type(mset_result_decoded)
    assert_type(mset_result_decoded, bool)

    # msetnx
    msetnx_result_decoded = redis_decoded.msetnx(mapping={'field1': 'value1'})
    # Revealed type is "builtins.bool"
    reveal_type(msetnx_result_decoded)
    assert_type(msetnx_result_decoded, bool)

    # persist
    persist_result_decoded = redis_decoded.persist(name='testkey')
    # Revealed type is "builtins.bool"
    reveal_type(persist_result_decoded)
    assert_type(persist_result_decoded, bool)

    # pexpire
    pexpire_result_decoded = redis_decoded.pexpire(name='testkey', time=60)
    # Revealed type is "builtins.bool"
    reveal_type(pexpire_result_decoded)
    assert_type(pexpire_result_decoded, bool)

    # pexpireat
    pexpireat_result_decoded = redis_decoded.pexpireat(name='testkey', when=1767730776)
    # Revealed type is "builtins.bool"
    reveal_type(pexpireat_result_decoded)
    assert_type(pexpireat_result_decoded, bool)

    # pexpiretime
    pexpiretime_result_decoded = redis_decoded.pexpiretime(key='testkey')
    # Revealed type is "builtins.int"
    reveal_type(pexpiretime_result_decoded)
    assert_type(pexpiretime_result_decoded, int)

    # pttl
    pttl_result_decoded = redis_decoded.pttl('testkey')
    # Revealed type is "builtins.int"
    reveal_type(pttl_result_decoded)
    assert_type(pttl_result_decoded, int)

    # randomkey
    randomkey_result_decoded = redis_decoded.randomkey()
    # Revealed type is "builtins.str"
    reveal_type(randomkey_result_decoded)
    assert_type(randomkey_result_decoded, str)

    # rename
    rename_result_decoded = redis_decoded.rename(src='mylist', dst='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(rename_result_decoded)
    assert_type(rename_result_decoded, bool)

    # renamenx
    renamenx_result_decoded = redis_decoded.renamenx(src='mylist', dst='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(renamenx_result_decoded)
    assert_type(renamenx_result_decoded, bool)

    # restore
    restore_result_decoded = redis_decoded.restore(name='restored_key', ttl=0, value=b'\x00\rrestore_value\x0c\x00\xf4b<\xb5\xb8\x96\xcd\xd5')
    # Revealed type is "builtins.bool"
    reveal_type(restore_result_decoded)
    assert_type(restore_result_decoded, bool)

    # set
    set_result_decoded = redis_decoded.set(name='testkey', value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(set_result_decoded)
    assert_type(set_result_decoded, bool)

    # setbit
    setbit_result_decoded = redis_decoded.setbit(name='testkey', offset=0, value=1)
    # Revealed type is "builtins.int"
    reveal_type(setbit_result_decoded)
    assert_type(setbit_result_decoded, int)

    # setex
    setex_result_decoded = redis_decoded.setex(name='testkey', time=60, value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(setex_result_decoded)
    assert_type(setex_result_decoded, bool)

    # setnx
    setnx_result_decoded = redis_decoded.setnx(name='testkey', value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(setnx_result_decoded)
    assert_type(setnx_result_decoded, bool)

    # setrange
    setrange_result_decoded = redis_decoded.setrange(name='testkey', offset=0, value='testvalue')
    # Revealed type is "builtins.int"
    reveal_type(setrange_result_decoded)
    assert_type(setrange_result_decoded, int)

    # stralgo
    stralgo_result_decoded = redis_decoded.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings')
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_result_decoded)
    assert_type(stralgo_result_decoded, StrAlgoResultType)

    stralgo_len_result_decoded = redis_decoded.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings', len=True)
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_len_result_decoded)
    assert_type(stralgo_len_result_decoded, StrAlgoResultType)

    stralgo_idx_result_decoded = redis_decoded.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings', idx=True)
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_idx_result_decoded)
    assert_type(stralgo_idx_result_decoded, StrAlgoResultType)

    # strlen
    strlen_result_decoded = redis_decoded.strlen('testkey')
    # Revealed type is "builtins.int"
    reveal_type(strlen_result_decoded)
    assert_type(strlen_result_decoded, int)

    # substr
    substr_result_decoded = redis_decoded.substr(name='testkey', start=0, end=-1)
    # Revealed type is "builtins.str"
    reveal_type(substr_result_decoded)
    assert_type(substr_result_decoded, str)

    # touch
    touch_result_decoded = redis_decoded.touch('testkey')
    # Revealed type is "builtins.int"
    reveal_type(touch_result_decoded)
    assert_type(touch_result_decoded, int)

    # ttl
    ttl_result_decoded = redis_decoded.ttl('testkey')
    # Revealed type is "builtins.int"
    reveal_type(ttl_result_decoded)
    assert_type(ttl_result_decoded, int)

    # type
    type_result_decoded = redis_decoded.type('testkey')
    # Revealed type is "builtins.str"
    reveal_type(type_result_decoded)
    assert_type(type_result_decoded, str)

    # unlink
    unlink_result_decoded = redis_decoded.unlink('testkey')
    # Revealed type is "builtins.int"
    reveal_type(unlink_result_decoded)
    assert_type(unlink_result_decoded, int)


    # decode_responses=False should return bytes | None
    redis_encoded = Redis(decode_responses=False)
    value_encoded = redis_encoded.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_encoded)
    assert_type(value_encoded, bytes | None)

    value_encoded_deleted = redis_encoded.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_encoded_deleted)
    assert_type(value_encoded_deleted, bytes | None)

    many_values_encoded = redis_encoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_encoded)
    assert_type(many_values_encoded, list[bytes | None])

    # append
    append_result_encoded = redis_encoded.append(key='testkey', value='testvalue')
    # Revealed type is "builtins.int"
    reveal_type(append_result_encoded)
    assert_type(append_result_encoded, int)

    # bitcount
    bitcount_result_encoded = redis_encoded.bitcount(key='testkey', start=0, end=-1)
    # Revealed type is "builtins.int"
    reveal_type(bitcount_result_encoded)
    assert_type(bitcount_result_encoded, int)

    # # bitfield
    # bitfield_result_encoded = redis_encoded.bitfield(key='testkey')
    # reveal_type(bitfield_result_encoded)
    # # bitfield_result_encoded is a complex type
    # assert_type(bitfield_result, ...)

    # blmove
    blmove_result_encoded = redis_encoded.blmove(first_list='mylist', second_list='destlist', timeout=1)
    # Revealed type is "builtins.bytes"
    reveal_type(blmove_result_encoded)
    assert_type(blmove_result_encoded, bytes)

    # copy
    copy_result_encoded = redis_encoded.copy(source='mylist', destination='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(copy_result_encoded)
    assert_type(copy_result_encoded, bool)

    # decrby
    decrby_result_encoded = redis_encoded.decrby(name='counter', amount=5)
    # Revealed type is "builtins.int"
    reveal_type(decrby_result_encoded)
    assert_type(decrby_result_encoded, int)

    # delete
    delete_result_encoded = redis_encoded.delete('testkey')
    # Revealed type is "builtins.int"
    reveal_type(delete_result_encoded)
    assert_type(delete_result_encoded, int)

    # delex
    delex_result_encoded = redis_encoded.delex(name='testkey')
    # Revealed type is "builtins.int"
    reveal_type(delex_result_encoded)
    assert_type(delex_result_encoded, int)

    # digest
    digest_result_encoded = redis_encoded.digest(name='testkey')
    # Revealed type is "builtins.bytes | None"
    reveal_type(digest_result_encoded)
    assert_type(digest_result_encoded, bytes | None)

    # exists
    exists_result_encoded = redis_encoded.exists('testkey')
    # Revealed type is "builtins.int"
    reveal_type(exists_result_encoded)
    assert_type(exists_result_encoded, int)

    # expire
    expire_result_encoded = redis_encoded.expire(name='testkey', time=60)
    # Revealed type is "builtins.bool"
    reveal_type(expire_result_encoded)
    assert_type(expire_result_encoded, bool)

    # expireat
    expireat_result_encoded = redis_encoded.expireat(name='testkey', when=1767730775)
    # Revealed type is "builtins.bool"
    reveal_type(expireat_result_encoded)
    assert_type(expireat_result_encoded, bool)

    # expiretime
    expiretime_result_encoded = redis_encoded.expiretime(key='testkey')
    # Revealed type is "builtins.int"
    reveal_type(expiretime_result_encoded)
    assert_type(expiretime_result_encoded, int)

    # getbit
    getbit_result_encoded = redis_encoded.getbit(name='testkey', offset=0)
    # Revealed type is "builtins.int"
    reveal_type(getbit_result_encoded)
    assert_type(getbit_result_encoded, int)

    # getrange
    getrange_result_encoded = redis_encoded.getrange(key='testkey', start=0, end=-1)
    # Revealed type is "builtins.bytes"
    reveal_type(getrange_result_encoded)
    assert_type(getrange_result_encoded, bytes)

    # getset
    getset_result_encoded = redis_encoded.getset(name='testkey', value='testvalue')
    # Revealed type is "builtins.bytes | None"
    reveal_type(getset_result_encoded)
    assert_type(getset_result_encoded, bytes | None)

    # hrandfield
    hrandfield_result_encoded = redis_encoded.hrandfield(key='nonexistent', count=1)
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(hrandfield_result_encoded)
    assert_type(hrandfield_result_encoded, list[bytes])

    # incrby
    incrby_result_encoded = redis_encoded.incrby(name='counter', amount=5)
    # Revealed type is "builtins.int"
    reveal_type(incrby_result_encoded)
    assert_type(incrby_result_encoded, int)

    # incrbyfloat
    incrbyfloat_result_encoded = redis_encoded.incrbyfloat(name='nonexistent', amount=1.0)
    # Revealed type is "builtins.float"
    reveal_type(incrbyfloat_result_encoded)
    assert_type(incrbyfloat_result_encoded, float)

    # keys
    keys_result_encoded = redis_encoded.keys(pattern='*')
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(keys_result_encoded)
    assert_type(keys_result_encoded, list[bytes])

    # lcs
    lcs_result_encoded = redis_encoded.lcs(key1='test', key2='test')
    # Revealed type is "builtins.bytes"
    reveal_type(lcs_result_encoded)
    assert_type(lcs_result_encoded, bytes)

    # lmove
    lmove_result_encoded = redis_encoded.lmove(first_list='mylist', second_list='destlist')
    # Revealed type is "builtins.bytes"
    reveal_type(lmove_result_encoded)
    assert_type(lmove_result_encoded, bytes)

    # move
    move_result_encoded = redis_encoded.move(name='testkey', db=1)
    # Revealed type is "builtins.bool"
    reveal_type(move_result_encoded)
    assert_type(move_result_encoded, bool)

    # mset
    mset_result_encoded = redis_encoded.mset(mapping={'field1': 'value1'})
    # Revealed type is "builtins.bool"
    reveal_type(mset_result_encoded)
    assert_type(mset_result_encoded, bool)

    # msetnx
    msetnx_result_encoded = redis_encoded.msetnx(mapping={'field1': 'value1'})
    # Revealed type is "builtins.bool"
    reveal_type(msetnx_result_encoded)
    assert_type(msetnx_result_encoded, bool)

    # persist
    persist_result_encoded = redis_encoded.persist(name='testkey')
    # Revealed type is "builtins.bool"
    reveal_type(persist_result_encoded)
    assert_type(persist_result_encoded, bool)

    # pexpire
    pexpire_result_encoded = redis_encoded.pexpire(name='testkey', time=60)
    # Revealed type is "builtins.bool"
    reveal_type(pexpire_result_encoded)
    assert_type(pexpire_result_encoded, bool)

    # pexpireat
    pexpireat_result_encoded = redis_encoded.pexpireat(name='testkey', when=1767730776)
    # Revealed type is "builtins.bool"
    reveal_type(pexpireat_result_encoded)
    assert_type(pexpireat_result_encoded, bool)

    # pexpiretime
    pexpiretime_result_encoded = redis_encoded.pexpiretime(key='testkey')
    # Revealed type is "builtins.int"
    reveal_type(pexpiretime_result_encoded)
    assert_type(pexpiretime_result_encoded, int)

    # pttl
    pttl_result_encoded = redis_encoded.pttl('testkey')
    # Revealed type is "builtins.int"
    reveal_type(pttl_result_encoded)
    assert_type(pttl_result_encoded, int)

    # randomkey
    randomkey_result_encoded = redis_encoded.randomkey()
    # Revealed type is "builtins.bytes"
    reveal_type(randomkey_result_encoded)
    assert_type(randomkey_result_encoded, bytes)

    # rename
    rename_result_encoded = redis_encoded.rename(src='mylist', dst='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(rename_result_encoded)
    assert_type(rename_result_encoded, bool)

    # renamenx
    renamenx_result_encoded = redis_encoded.renamenx(src='mylist', dst='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(renamenx_result_encoded)
    assert_type(renamenx_result_encoded, bool)

    # restore
    restore_result_encoded = redis_encoded.restore(name='restored_key', ttl=0, value=b'\x00\rrestore_value\x0c\x00\xf4b<\xb5\xb8\x96\xcd\xd5')
    # Revealed type is "builtins.bool"
    reveal_type(restore_result_encoded)
    assert_type(restore_result_encoded, bool)

    # set
    set_result_encoded = redis_encoded.set(name='testkey', value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(set_result_encoded)
    assert_type(set_result_encoded, bool)

    # setbit
    setbit_result_encoded = redis_encoded.setbit(name='testkey', offset=0, value=1)
    # Revealed type is "builtins.int"
    reveal_type(setbit_result_encoded)
    assert_type(setbit_result_encoded, int)

    # setex
    setex_result_encoded = redis_encoded.setex(name='testkey', time=60, value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(setex_result_encoded)
    assert_type(setex_result_encoded, bool)

    # setnx
    setnx_result_encoded = redis_encoded.setnx(name='testkey', value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(setnx_result_encoded)
    assert_type(setnx_result_encoded, bool)

    # setrange
    setrange_result_encoded = redis_encoded.setrange(name='testkey', offset=0, value='testvalue')
    # Revealed type is "builtins.int"
    reveal_type(setrange_result_encoded)
    assert_type(setrange_result_encoded, int)

    # stralgo
    stralgo_result_encoded = redis_encoded.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings')
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_result_encoded)
    assert_type(stralgo_result_encoded, StrAlgoResultType)

    stralgo_len_result_encoded = redis_encoded.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings', len=True)
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_len_result_encoded)
    assert_type(stralgo_len_result_encoded, StrAlgoResultType)

    stralgo_idx_result_encoded = redis_encoded.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings', idx=True)
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_idx_result_encoded)
    assert_type(stralgo_idx_result_encoded, StrAlgoResultType)

    # strlen
    strlen_result_encoded = redis_encoded.strlen('testkey')
    # Revealed type is "builtins.int"
    reveal_type(strlen_result_encoded)
    assert_type(strlen_result_encoded, int)

    # substr
    substr_result_encoded = redis_encoded.substr(name='testkey', start=0, end=-1)
    # Revealed type is "builtins.bytes"
    reveal_type(substr_result_encoded)
    assert_type(substr_result_encoded, bytes)

    # touch
    touch_result_encoded = redis_encoded.touch('testkey')
    # Revealed type is "builtins.int"
    reveal_type(touch_result_encoded)
    assert_type(touch_result_encoded, int)

    # ttl
    ttl_result_encoded = redis_encoded.ttl('testkey')
    # Revealed type is "builtins.int"
    reveal_type(ttl_result_encoded)
    assert_type(ttl_result_encoded, int)

    # type
    type_result_encoded = redis_encoded.type('testkey')
    # Revealed type is "builtins.bytes"
    reveal_type(type_result_encoded)
    assert_type(type_result_encoded, bytes)

    # unlink
    unlink_result_encoded = redis_encoded.unlink('testkey')
    # Revealed type is "builtins.int"
    reveal_type(unlink_result_encoded)
    assert_type(unlink_result_encoded, int)

    # Default (no decode_responses) should return bytes | None
    redis_default = Redis()
    value_default = redis_default.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_default)
    assert_type(value_default, bytes | None)

    value_default_deleted = redis_default.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_default_deleted)
    assert_type(value_default_deleted, bytes | None)

    many_values_default = redis_default.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_default)
    assert_type(many_values_default, list[bytes | None])

    encoded_getitem = redis_default["key"]
    # Revealed type is "builtins.bytes"
    reveal_type(encoded_getitem)
    assert_type(encoded_getitem, bytes)

    inr_float_default = redis_default.incrbyfloat("key", 1.5)
    # Revealed type is "builtins.float"
    reveal_type(inr_float_default)
    assert_type(inr_float_default, float)

    # append
    append_result_default = redis_default.append(key='testkey', value='testvalue')
    # Revealed type is "builtins.int"
    reveal_type(append_result_default)
    assert_type(append_result_default, int)

    # bitcount
    bitcount_result_default = redis_default.bitcount(key='testkey', start=0, end=-1)
    # Revealed type is "builtins.int"
    reveal_type(bitcount_result_default)
    assert_type(bitcount_result_default, int)

    # # bitfield
    # bitfield_result_default = redis_default.bitfield(key='testkey')
    # reveal_type(bitfield_result_default)
    # # bitfield_result_default is a complex type
    # assert_type(bitfield_result, ...)

    # blmove
    blmove_result_default = redis_default.blmove(first_list='mylist', second_list='destlist', timeout=1)
    # Revealed type is "builtins.bytes"
    reveal_type(blmove_result_default)
    assert_type(blmove_result_default, bytes)

    # copy
    copy_result_default = redis_default.copy(source='mylist', destination='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(copy_result_default)
    assert_type(copy_result_default, bool)

    # decrby
    decrby_result_default = redis_default.decrby(name='counter', amount=5)
    # Revealed type is "builtins.int"
    reveal_type(decrby_result_default)
    assert_type(decrby_result_default, int)

    # delete
    delete_result_default = redis_default.delete('testkey')
    # Revealed type is "builtins.int"
    reveal_type(delete_result_default)
    assert_type(delete_result_default, int)

    # delex
    delex_result_default = redis_default.delex(name='testkey')
    # Revealed type is "builtins.int"
    reveal_type(delex_result_default)
    assert_type(delex_result_default, int)

    # digest
    digest_result_default = redis_default.digest(name='testkey')
    # Revealed type is "builtins.bytes | None"
    reveal_type(digest_result_default)
    assert_type(digest_result_default, bytes | None)

    # exists
    exists_result_default = redis_default.exists('testkey')
    # Revealed type is "builtins.int"
    reveal_type(exists_result_default)
    assert_type(exists_result_default, int)

    # expire
    expire_result_default = redis_default.expire(name='testkey', time=60)
    # Revealed type is "builtins.bool"
    reveal_type(expire_result_default)
    assert_type(expire_result_default, bool)

    # expireat
    expireat_result_default = redis_default.expireat(name='testkey', when=1767730775)
    # Revealed type is "builtins.bool"
    reveal_type(expireat_result_default)
    assert_type(expireat_result_default, bool)

    # expiretime
    expiretime_result_default = redis_default.expiretime(key='testkey')
    # Revealed type is "builtins.int"
    reveal_type(expiretime_result_default)
    assert_type(expiretime_result_default, int)

    # getbit
    getbit_result_default = redis_default.getbit(name='testkey', offset=0)
    # Revealed type is "builtins.int"
    reveal_type(getbit_result_default)
    assert_type(getbit_result_default, int)

    # getrange
    getrange_result_default = redis_default.getrange(key='testkey', start=0, end=-1)
    # Revealed type is "builtins.bytes"
    reveal_type(getrange_result_default)
    assert_type(getrange_result_default, bytes)

    # getset
    getset_result_default = redis_default.getset(name='testkey', value='testvalue')
    # Revealed type is "builtins.bytes | None"
    reveal_type(getset_result_default)
    assert_type(getset_result_default, bytes | None)

    # hrandfield
    hrandfield_result_default = redis_default.hrandfield(key='nonexistent', count=1)
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(hrandfield_result_default)
    assert_type(hrandfield_result_default, list[bytes])

    # incrby
    incrby_result_default = redis_default.incrby(name='counter', amount=5)
    # Revealed type is "builtins.int"
    reveal_type(incrby_result_default)
    assert_type(incrby_result_default, int)

    # incrbyfloat
    incrbyfloat_result_default = redis_default.incrbyfloat(name='nonexistent', amount=1.0)
    # Revealed type is "builtins.float"
    reveal_type(incrbyfloat_result_default)
    assert_type(incrbyfloat_result_default, float)

    # keys
    keys_result_default = redis_default.keys(pattern='*')
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(keys_result_default)
    assert_type(keys_result_default, list[bytes])

    # lcs
    lcs_result_default = redis_default.lcs(key1='test', key2='test')
    # Revealed type is "builtins.bytes"
    reveal_type(lcs_result_default)
    assert_type(lcs_result_default, bytes)

    # lmove
    lmove_result_default = redis_default.lmove(first_list='mylist', second_list='destlist')
    # Revealed type is "builtins.bytes"
    reveal_type(lmove_result_default)
    assert_type(lmove_result_default, bytes)

    # move
    move_result_default = redis_default.move(name='testkey', db=1)
    # Revealed type is "builtins.bool"
    reveal_type(move_result_default)
    assert_type(move_result_default, bool)

    # mset
    mset_result_default = redis_default.mset(mapping={'field1': 'value1'})
    # Revealed type is "builtins.bool"
    reveal_type(mset_result_default)
    assert_type(mset_result_default, bool)

    # msetnx
    msetnx_result_default = redis_default.msetnx(mapping={'field1': 'value1'})
    # Revealed type is "builtins.bool"
    reveal_type(msetnx_result_default)
    assert_type(msetnx_result_default, bool)

    # persist
    persist_result_default = redis_default.persist(name='testkey')
    # Revealed type is "builtins.bool"
    reveal_type(persist_result_default)
    assert_type(persist_result_default, bool)

    # pexpire
    pexpire_result_default = redis_default.pexpire(name='testkey', time=60)
    # Revealed type is "builtins.bool"
    reveal_type(pexpire_result_default)
    assert_type(pexpire_result_default, bool)

    # pexpireat
    pexpireat_result_default = redis_default.pexpireat(name='testkey', when=1767730776)
    # Revealed type is "builtins.bool"
    reveal_type(pexpireat_result_default)
    assert_type(pexpireat_result_default, bool)

    # pexpiretime
    pexpiretime_result_default = redis_default.pexpiretime(key='testkey')
    # Revealed type is "builtins.int"
    reveal_type(pexpiretime_result_default)
    assert_type(pexpiretime_result_default, int)

    # pttl
    pttl_result_default = redis_default.pttl('testkey')
    # Revealed type is "builtins.int"
    reveal_type(pttl_result_default)
    assert_type(pttl_result_default, int)

    # randomkey
    randomkey_result_default = redis_default.randomkey()
    # Revealed type is "builtins.bytes"
    reveal_type(randomkey_result_default)
    assert_type(randomkey_result_default, bytes)

    # rename
    rename_result_default = redis_default.rename(src='mylist', dst='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(rename_result_default)
    assert_type(rename_result_default, bool)

    # renamenx
    renamenx_result_default = redis_default.renamenx(src='mylist', dst='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(renamenx_result_default)
    assert_type(renamenx_result_default, bool)

    # restore
    restore_result_default = redis_default.restore(name='restored_key', ttl=0, value=b'\x00\rrestore_value\x0c\x00\xf4b<\xb5\xb8\x96\xcd\xd5')
    # Revealed type is "builtins.bool"
    reveal_type(restore_result_default)
    assert_type(restore_result_default, bool)

    # set
    set_result_default = redis_default.set(name='testkey', value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(set_result_default)
    assert_type(set_result_default, bool)

    # setbit
    setbit_result_default = redis_default.setbit(name='testkey', offset=0, value=1)
    # Revealed type is "builtins.int"
    reveal_type(setbit_result_default)
    assert_type(setbit_result_default, int)

    # setex
    setex_result_default = redis_default.setex(name='testkey', time=60, value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(setex_result_default)
    assert_type(setex_result_default, bool)

    # setnx
    setnx_result_default = redis_default.setnx(name='testkey', value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(setnx_result_default)
    assert_type(setnx_result_default, bool)

    # setrange
    setrange_result_default = redis_default.setrange(name='testkey', offset=0, value='testvalue')
    # Revealed type is "builtins.int"
    reveal_type(setrange_result_default)
    assert_type(setrange_result_default, int)

    # stralgo
    stralgo_result_default = redis_default.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings')
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_result_default)
    assert_type(stralgo_result_default, StrAlgoResultType)

    stralgo_len_result_default = redis_default.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings', len=True)
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_len_result_default)
    assert_type(stralgo_len_result_default, StrAlgoResultType)

    stralgo_idx_result_default = redis_default.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings', idx=True)
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_idx_result_default)
    assert_type(stralgo_idx_result_default, StrAlgoResultType)

    # strlen
    strlen_result_default = redis_default.strlen('testkey')
    # Revealed type is "builtins.int"
    reveal_type(strlen_result_default)
    assert_type(strlen_result_default, int)

    # substr
    substr_result_default = redis_default.substr(name='testkey', start=0, end=-1)
    # Revealed type is "builtins.bytes"
    reveal_type(substr_result_default)
    assert_type(substr_result_default, bytes)

    # touch
    touch_result_default = redis_default.touch('testkey')
    # Revealed type is "builtins.int"
    reveal_type(touch_result_default)
    assert_type(touch_result_default, int)

    # ttl
    ttl_result_default = redis_default.ttl('testkey')
    # Revealed type is "builtins.int"
    reveal_type(ttl_result_default)
    assert_type(ttl_result_default, int)

    # type
    type_result_default = redis_default.type('testkey')
    # Revealed type is "builtins.bytes"
    reveal_type(type_result_default)
    assert_type(type_result_default, bytes)

    # unlink
    unlink_result_default = redis_default.unlink('testkey')
    # Revealed type is "builtins.int"
    reveal_type(unlink_result_default)
    assert_type(unlink_result_default, int)


    # decode_responses with bool variable should return str | None | bytes
    decode_responses_var = True  # Could be True or False at runtime
    redis_dynamic = Redis(decode_responses=decode_responses_var)
    value_dynamic = redis_dynamic.get("key")
    # Revealed type is "builtins.str | None | builtins.bytes"
    reveal_type(value_dynamic)
    assert_type(value_dynamic, str | bytes | None)

    value_dynamic_deleted = redis_dynamic.getdel("key")
    # Revealed type is "builtins.str | None | builtins.bytes"
    reveal_type(value_dynamic_deleted)
    assert_type(value_dynamic_deleted, str | bytes | None)

    many_values_dynamic = redis_dynamic.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None] | builtins.list[builtins.bytes | None]"
    reveal_type(many_values_dynamic)
    assert_type(many_values_dynamic, list[str | None] | list[bytes | None])

    # decode_responses with static bool variable should act like literal
    decode_responses_static_var: Literal[True] = True  # Could be True or False at runtime
    redis_static_var = Redis(decode_responses=decode_responses_static_var)
    value_static_var = redis_static_var.get("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_static_var)
    assert_type(value_static_var, str | None)

    value_static_var_deleted = redis_static_var.getdel("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_static_var_deleted)
    assert_type(value_static_var_deleted, str | None)

    many_values_static_var = redis_static_var.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None]"
    reveal_type(many_values_static_var)
    assert_type(many_values_static_var, list[str | None])

    # positional decode_responses passed True

    redis_all_positional_decoded = Redis(
        "localhost", # host
        6379, # port
        0, # db
        "pw", # password
        None, # socket_timeout
        None, # socket_connect_timeout
        None, # socket_keepalive
        None, # socket_keepalive_options
        None, # connection_pool
        None, # unix_socket_path
        "utf-8", # encoding
        "strict", # encoding_errors
        True, # decode_responses
    )
    value_all_positional_decoded = redis_all_positional_decoded.get("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_all_positional_decoded)
    assert_type(value_all_positional_decoded, str | None)

    value_all_positional_decoded_deleted = redis_all_positional_decoded.getdel("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_all_positional_decoded_deleted)
    assert_type(value_all_positional_decoded_deleted, str | None)

    many_values_all_positional_decoded = redis_all_positional_decoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None]"
    reveal_type(many_values_all_positional_decoded)
    assert_type(many_values_all_positional_decoded, list[str | None])


    #  === Redis.from_url classmethod ===

    # from_url with decode_responses=True should return str | None
    redis_from_url_decoded = Redis.from_url("redis://localhost", decode_responses=True)
    value_from_url_decoded = redis_from_url_decoded.get("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_from_url_decoded)
    assert_type(value_from_url_decoded, str | None)

    value_from_url_decoded_deleted = redis_from_url_decoded.getdel("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_from_url_decoded_deleted)
    assert_type(value_from_url_decoded_deleted, str | None)

    many_values_from_url_decoded = redis_from_url_decoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None]"
    reveal_type(many_values_from_url_decoded)
    assert_type(many_values_from_url_decoded, list[str | None])

    # from_url with decode_responses=False should return bytes | None
    redis_from_url_encoded = Redis.from_url("redis://localhost", decode_responses=False)
    value_from_url_encoded = redis_from_url_encoded.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_url_encoded)
    assert_type(value_from_url_encoded, bytes | None)

    value_from_url_encoded_deleted = redis_from_url_encoded.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_url_encoded_deleted)
    assert_type(value_from_url_encoded_deleted, bytes | None)

    many_values_from_url_encoded = redis_from_url_encoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_from_url_encoded)
    assert_type(many_values_from_url_encoded, list[bytes | None])

    # from_url without decode_responses should return bytes | None
    redis_from_url_default = Redis.from_url("redis://localhost")
    value_from_url_default = redis_from_url_default.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_url_default)
    assert_type(value_from_url_default, bytes | None)

    value_from_url_default_deleted = redis_from_url_default.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_url_default_deleted)
    assert_type(value_from_url_default_deleted, bytes | None)

    many_values_from_url_default = redis_from_url_default.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_from_url_default)
    assert_type(many_values_from_url_default, list[bytes | None])

    # decode_responses with bool variable should return str | None | bytes
    decode_responses_var = True  # Could be True or False at runtime
    redis_from_url_dynamic = Redis.from_url("redis://localhost", decode_responses=decode_responses_var)
    value_from_url_dynamic = redis_from_url_dynamic.get("key")
    # Revealed type is "builtins.str | None | builtins.bytes"
    reveal_type(value_from_url_dynamic)
    assert_type(value_from_url_dynamic, str | bytes | None)

    value_from_url_dynamic_deleted = redis_from_url_dynamic.getdel("key")
    # Revealed type is "builtins.str | None | builtins.bytes"
    reveal_type(value_from_url_dynamic_deleted)
    assert_type(value_from_url_dynamic_deleted, str | bytes | None)

    many_values_from_url_dynamic = redis_from_url_dynamic.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None] | builtins.list[builtins.bytes | None]"
    reveal_type(many_values_from_url_dynamic)
    assert_type(many_values_from_url_dynamic, list[str | None] | list[bytes | None])


    #  === Redis.from_pool classmethod ===

    conn_pool = ConnectionPool.from_url("redis://localhost")

    redis_from_pool_decoded: "RedisDecoded" = Redis.from_pool(connection_pool=conn_pool)  # type: ignore[assignment]
    value_from_pool_decoded = redis_from_pool_decoded.get("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_from_pool_decoded)
    assert_type(value_from_pool_decoded, str | None)

    value_from_pool_decoded_deleted = redis_from_pool_decoded.getdel("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_from_pool_decoded_deleted)
    assert_type(value_from_pool_decoded_deleted, str | None)

    many_values_from_pool_decoded = redis_from_pool_decoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None]"
    reveal_type(many_values_from_pool_decoded)
    assert_type(many_values_from_pool_decoded, list[str | None])

    redis_from_pool_encoded: "RedisEncoded" = Redis.from_pool(connection_pool=conn_pool)  # type: ignore[assignment]
    value_from_pool_encoded = redis_from_pool_encoded.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_pool_encoded)
    assert_type(value_from_pool_encoded, bytes | None)

    value_from_pool_encoded_deleted = redis_from_pool_encoded.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_pool_encoded_deleted)
    assert_type(value_from_pool_encoded_deleted, bytes | None)

    many_values_from_pool_encoded = redis_from_pool_encoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_from_pool_encoded)
    assert_type(many_values_from_pool_encoded, list[bytes | None])


def test_list_commands_sync() -> None:
    #  === List Commands ===
    
    # decode_responses=True
    redis_decoded = Redis(decode_responses=True)
    
    # blmpop
    blmpop_result_decoded = redis_decoded.blmpop(1, 1, 'mylist', direction='LEFT')
    # Revealed type is "builtins.list[builtins.str | builtins.list[builtins.str]] | None"
    reveal_type(blmpop_result_decoded)
    assert_type(blmpop_result_decoded, list[list[str] | str] | None)
    
    # blpop
    blpop_result_decoded = redis_decoded.blpop(keys=['mylist'], timeout=1)
    # Revealed type is "builtins.list[builtins.str] | None"
    reveal_type(blpop_result_decoded)
    assert_type(blpop_result_decoded, list[str] | None)
    
    # brpop
    brpop_result_decoded = redis_decoded.brpop(["list1", "list2"], 1.0)
    # Revealed type is "builtins.list[builtins.str] | None"
    reveal_type(brpop_result_decoded)
    assert_type(brpop_result_decoded, list[str] | None)
    
    # brpoplpush
    brpoplpush_result_decoded = redis_decoded.brpoplpush("list1", "list2", 1.0)
    # Revealed type is "builtins.str | None"
    reveal_type(brpoplpush_result_decoded)
    assert_type(brpoplpush_result_decoded, str | None)
    
    # lindex
    lindex_result_decoded = redis_decoded.lindex("list1", 0)
    # Revealed type is "builtins.str | None"
    reveal_type(lindex_result_decoded)
    assert_type(lindex_result_decoded, str | None)
    
    # linsert
    linsert_result_decoded = redis_decoded.linsert("list1", "BEFORE", "pivot", "value")
    # Revealed type is "builtins.int"
    reveal_type(linsert_result_decoded)
    assert_type(linsert_result_decoded, int)
    
    # llen
    llen_result_decoded = redis_decoded.llen("list1")
    # Revealed type is "builtins.int"
    reveal_type(llen_result_decoded)
    assert_type(llen_result_decoded, int)
    
    # lmpop
    lmpop_result_decoded = redis_decoded.lmpop(1, 'mylist', direction='LEFT')
    # Revealed type is "builtins.list[builtins.str | builtins.list[builtins.str]] | None"
    reveal_type(lmpop_result_decoded)
    assert_type(lmpop_result_decoded, list[list[str] | str] | None)
    
    # lpop
    lpop_result_decoded = redis_decoded.lpop(name='mylist')
    # Revealed type is "builtins.str | builtins.list[builtins.str] | None"
    reveal_type(lpop_result_decoded)
    assert_type(lpop_result_decoded, list[str] | str | None)
    
    # lpos
    lpos_result_decoded = redis_decoded.lpos(name='mylist', value='value2')
    # Revealed type is "builtins.int | None"
    reveal_type(lpos_result_decoded)
    assert_type(lpos_result_decoded, int | None)
    
    # lpush
    lpush_result_decoded = redis_decoded.lpush("list1", "value1", "value2")
    # Revealed type is "builtins.int"
    reveal_type(lpush_result_decoded)
    assert_type(lpush_result_decoded, int)
    
    # lpushx
    lpushx_result_decoded = redis_decoded.lpushx("list1", "value")
    # Revealed type is "builtins.int"
    reveal_type(lpushx_result_decoded)
    assert_type(lpushx_result_decoded, int)
    
    # lrange
    lrange_result_decoded = redis_decoded.lrange("list1", 0, -1)
    # Revealed type is "builtins.list[builtins.str]"
    reveal_type(lrange_result_decoded)
    assert_type(lrange_result_decoded, list[str])
    
    # lrem
    lrem_result_decoded = redis_decoded.lrem("list1", 1, "value")
    # Revealed type is "builtins.int"
    reveal_type(lrem_result_decoded)
    assert_type(lrem_result_decoded, int)
    
    # lset
    lset_result_decoded = redis_decoded.lset("list1", 0, "value")
    # Revealed type is "builtins.bool"
    reveal_type(lset_result_decoded)
    assert_type(lset_result_decoded, bool)
    
    # ltrim
    ltrim_result_decoded = redis_decoded.ltrim("list1", 0, -1)
    # Revealed type is "builtins.bool"
    reveal_type(ltrim_result_decoded)
    assert_type(ltrim_result_decoded, bool)
    
    # rpop
    rpop_result_decoded = redis_decoded.rpop("list1")
    # Revealed type is "builtins.str | builtins.list[builtins.str] | None"
    reveal_type(rpop_result_decoded)
    assert_type(rpop_result_decoded, list[str] | str | None)
    
    # rpoplpush
    rpoplpush_result_decoded = redis_decoded.rpoplpush("list1", "list2")
    # Revealed type is "builtins.str | None"
    reveal_type(rpoplpush_result_decoded)
    assert_type(rpoplpush_result_decoded, str | None)
    
    # rpush
    rpush_result_decoded = redis_decoded.rpush("list1", "value1", "value2")
    # Revealed type is "builtins.int"
    reveal_type(rpush_result_decoded)
    assert_type(rpush_result_decoded, int)
    
    # rpushx
    rpushx_result_decoded = redis_decoded.rpushx("list1", "value")
    # Revealed type is "builtins.int"
    reveal_type(rpushx_result_decoded)
    assert_type(rpushx_result_decoded, int)
    
    # sort
    sort_result_decoded = redis_decoded.sort("list1")
    # Revealed type is "builtins.list[builtins.str]"
    reveal_type(sort_result_decoded)
    assert_type(sort_result_decoded, list[str])
    
    # sort_ro
    sort_ro_result_decoded = redis_decoded.sort_ro("list1")
    # Revealed type is "builtins.list[builtins.str]"
    reveal_type(sort_ro_result_decoded)
    assert_type(sort_ro_result_decoded, list[str])
    
    
    # decode_responses=False
    redis_encoded = Redis(decode_responses=False)
    
    # blmpop
    blmpop_result_encoded = redis_encoded.blmpop(1, 1, 'mylist', direction='LEFT')
    # Revealed type is "builtins.list[builtins.bytes | builtins.list[builtins.bytes]] | None"
    reveal_type(blmpop_result_encoded)
    assert_type(blmpop_result_encoded, list[list[bytes] | bytes] | None)
    
    # blpop
    blpop_result_encoded = redis_encoded.blpop(keys=['mylist'], timeout=1)
    # Revealed type is "builtins.list[builtins.bytes] | None"
    reveal_type(blpop_result_encoded)
    assert_type(blpop_result_encoded, list[bytes] | None)
    
    # brpop
    brpop_result_encoded = redis_encoded.brpop(["list1", "list2"], 1.0)
    # Revealed type is "builtins.list[builtins.bytes] | None"
    reveal_type(brpop_result_encoded)
    assert_type(brpop_result_encoded, list[bytes] | None)
    
    # brpoplpush
    brpoplpush_result_encoded = redis_encoded.brpoplpush("list1", "list2", 1.0)
    # Revealed type is "builtins.bytes | None"
    reveal_type(brpoplpush_result_encoded)
    assert_type(brpoplpush_result_encoded, bytes | None)
    
    # lindex
    lindex_result_encoded = redis_encoded.lindex("list1", 0)
    # Revealed type is "builtins.bytes | None"
    reveal_type(lindex_result_encoded)
    assert_type(lindex_result_encoded, bytes | None)
    
    # linsert
    linsert_result_encoded = redis_encoded.linsert("list1", "BEFORE", "pivot", "value")
    # Revealed type is "builtins.int"
    reveal_type(linsert_result_encoded)
    assert_type(linsert_result_encoded, int)
    
    # llen
    llen_result_encoded = redis_encoded.llen("list1")
    # Revealed type is "builtins.int"
    reveal_type(llen_result_encoded)
    assert_type(llen_result_encoded, int)
    
    # lmpop
    lmpop_result_encoded = redis_encoded.lmpop(1, 'mylist', direction='LEFT')
    # Revealed type is "builtins.list[builtins.bytes | builtins.list[builtins.bytes]] | None"
    reveal_type(lmpop_result_encoded)
    assert_type(lmpop_result_encoded, list[list[bytes] | bytes] | None)
    
    # lpop
    lpop_result_encoded = redis_encoded.lpop(name='mylist')
    # Revealed type is "builtins.bytes | builtins.list[builtins.bytes] | None"
    reveal_type(lpop_result_encoded)
    assert_type(lpop_result_encoded, list[bytes] | bytes | None)
    
    # lpos
    lpos_result_encoded = redis_encoded.lpos(name='mylist', value='value2')
    # Revealed type is "builtins.int | None"
    reveal_type(lpos_result_encoded)
    assert_type(lpos_result_encoded, int | None)
    
    # lpush
    lpush_result_encoded = redis_encoded.lpush("list1", "value1", "value2")
    # Revealed type is "builtins.int"
    reveal_type(lpush_result_encoded)
    assert_type(lpush_result_encoded, int)
    
    # lpushx
    lpushx_result_encoded = redis_encoded.lpushx("list1", "value")
    # Revealed type is "builtins.int"
    reveal_type(lpushx_result_encoded)
    assert_type(lpushx_result_encoded, int)
    
    # lrange
    lrange_result_encoded = redis_encoded.lrange("list1", 0, -1)
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(lrange_result_encoded)
    assert_type(lrange_result_encoded, list[bytes])
    
    # lrem
    lrem_result_encoded = redis_encoded.lrem("list1", 1, "value")
    # Revealed type is "builtins.int"
    reveal_type(lrem_result_encoded)
    assert_type(lrem_result_encoded, int)
    
    # lset
    lset_result_encoded = redis_encoded.lset("list1", 0, "value")
    # Revealed type is "builtins.bool"
    reveal_type(lset_result_encoded)
    assert_type(lset_result_encoded, bool)
    
    # ltrim
    ltrim_result_encoded = redis_encoded.ltrim("list1", 0, -1)
    # Revealed type is "builtins.bool"
    reveal_type(ltrim_result_encoded)
    assert_type(ltrim_result_encoded, bool)
    
    # rpop
    rpop_result_encoded = redis_encoded.rpop("list1")
    # Revealed type is "builtins.bytes | builtins.list[builtins.bytes] | None"
    reveal_type(rpop_result_encoded)
    assert_type(rpop_result_encoded, list[bytes] | bytes | None)
    
    # rpoplpush
    rpoplpush_result_encoded = redis_encoded.rpoplpush("list1", "list2")
    # Revealed type is "builtins.bytes | None"
    reveal_type(rpoplpush_result_encoded)
    assert_type(rpoplpush_result_encoded, bytes | None)
    
    # rpush
    rpush_result_encoded = redis_encoded.rpush("list1", "value1", "value2")
    # Revealed type is "builtins.int"
    reveal_type(rpush_result_encoded)
    assert_type(rpush_result_encoded, int)
    
    # rpushx
    rpushx_result_encoded = redis_encoded.rpushx("list1", "value")
    # Revealed type is "builtins.int"
    reveal_type(rpushx_result_encoded)
    assert_type(rpushx_result_encoded, int)
    
    # sort
    sort_result_encoded = redis_encoded.sort("list1")
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(sort_result_encoded)
    assert_type(sort_result_encoded, list[bytes])
    
    # sort_ro
    sort_ro_result_encoded = redis_encoded.sort_ro("list1")
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(sort_ro_result_encoded)
    assert_type(sort_ro_result_encoded, list[bytes])
    
    
    # Default (no decode_responses)
    redis_default = Redis()
    
    # blmpop
    blmpop_result_default = redis_default.blmpop(1, 1, 'mylist', direction='LEFT')
    # Revealed type is "builtins.list[builtins.bytes | builtins.list[builtins.bytes]] | None"
    reveal_type(blmpop_result_default)
    assert_type(blmpop_result_default, list[list[bytes] | bytes] | None)
    
    # blpop
    blpop_result_default = redis_default.blpop(keys=['mylist'], timeout=1)
    # Revealed type is "builtins.list[builtins.bytes] | None"
    reveal_type(blpop_result_default)
    assert_type(blpop_result_default, list[bytes] | None)
    
    # brpop
    brpop_result_default = redis_default.brpop(["list1", "list2"], 1.0)
    # Revealed type is "builtins.list[builtins.bytes] | None"
    reveal_type(brpop_result_default)
    assert_type(brpop_result_default, list[bytes] | None)
    
    # brpoplpush
    brpoplpush_result_default = redis_default.brpoplpush("list1", "list2", 1.0)
    # Revealed type is "builtins.bytes | None"
    reveal_type(brpoplpush_result_default)
    assert_type(brpoplpush_result_default, bytes | None)
    
    # lindex
    lindex_result_default = redis_default.lindex("list1", 0)
    # Revealed type is "builtins.bytes | None"
    reveal_type(lindex_result_default)
    assert_type(lindex_result_default, bytes | None)
    
    # linsert
    linsert_result_default = redis_default.linsert("list1", "BEFORE", "pivot", "value")
    # Revealed type is "builtins.int"
    reveal_type(linsert_result_default)
    assert_type(linsert_result_default, int)
    
    # llen
    llen_result_default = redis_default.llen("list1")
    # Revealed type is "builtins.int"
    reveal_type(llen_result_default)
    assert_type(llen_result_default, int)
    
    # lmpop
    lmpop_result_default = redis_default.lmpop(1, 'mylist', direction='LEFT')
    # Revealed type is "builtins.list[builtins.bytes | builtins.list[builtins.bytes]] | None"
    reveal_type(lmpop_result_default)
    assert_type(lmpop_result_default, list[list[bytes] | bytes] | None)
    
    # lpop
    lpop_result_default = redis_default.lpop(name='mylist')
    # Revealed type is "builtins.bytes | builtins.list[builtins.bytes] | None"
    reveal_type(lpop_result_default)
    assert_type(lpop_result_default, list[bytes] | bytes | None)
    
    # lpos
    lpos_result_default = redis_default.lpos(name='mylist', value='value2')
    # Revealed type is "builtins.int | None"
    reveal_type(lpos_result_default)
    assert_type(lpos_result_default, int | None)
    
    # lpush
    lpush_result_default = redis_default.lpush("list1", "value1", "value2")
    # Revealed type is "builtins.int"
    reveal_type(lpush_result_default)
    assert_type(lpush_result_default, int)
    
    # lpushx
    lpushx_result_default = redis_default.lpushx("list1", "value")
    # Revealed type is "builtins.int"
    reveal_type(lpushx_result_default)
    assert_type(lpushx_result_default, int)
    
    # lrange
    lrange_result_default = redis_default.lrange("list1", 0, -1)
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(lrange_result_default)
    assert_type(lrange_result_default, list[bytes])
    
    # lrem
    lrem_result_default = redis_default.lrem("list1", 1, "value")
    # Revealed type is "builtins.int"
    reveal_type(lrem_result_default)
    assert_type(lrem_result_default, int)
    
    # lset
    lset_result_default = redis_default.lset("list1", 0, "value")
    # Revealed type is "builtins.bool"
    reveal_type(lset_result_default)
    assert_type(lset_result_default, bool)
    
    # ltrim
    ltrim_result_default = redis_default.ltrim("list1", 0, -1)
    # Revealed type is "builtins.bool"
    reveal_type(ltrim_result_default)
    assert_type(ltrim_result_default, bool)
    
    # rpop
    rpop_result_default = redis_default.rpop("list1")
    # Revealed type is "builtins.bytes | builtins.list[builtins.bytes] | None"
    reveal_type(rpop_result_default)
    assert_type(rpop_result_default, list[bytes] | bytes | None)
    
    # rpoplpush
    rpoplpush_result_default = redis_default.rpoplpush("list1", "list2")
    # Revealed type is "builtins.bytes | None"
    reveal_type(rpoplpush_result_default)
    assert_type(rpoplpush_result_default, bytes | None)
    
    # rpush
    rpush_result_default = redis_default.rpush("list1", "value1", "value2")
    # Revealed type is "builtins.int"
    reveal_type(rpush_result_default)
    assert_type(rpush_result_default, int)
    
    # rpushx
    rpushx_result_default = redis_default.rpushx("list1", "value")
    # Revealed type is "builtins.int"
    reveal_type(rpushx_result_default)
    assert_type(rpushx_result_default, int)
    
    # sort
    sort_result_default = redis_default.sort("list1")
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(sort_result_default)
    assert_type(sort_result_default, list[bytes])
    
    # sort_ro
    sort_ro_result_default = redis_default.sort_ro("list1")
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(sort_ro_result_default)
    assert_type(sort_ro_result_default, list[bytes])


def main_sync() -> None:
    test_basic_key_commands_sync()
    test_list_commands_sync()


async def test_basic_key_commands_async() -> None:
    #  === direct Redis class ===

    # decode_responses=True should return str | None
    async_redis_decoded = AsyncRedis(decode_responses=True)
    value_decoded = await async_redis_decoded.get("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_decoded)
    assert_type(value_decoded, str | None)

    value_decoded_deleted = await async_redis_decoded.getdel("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_decoded_deleted)
    assert_type(value_decoded_deleted, str | None)

    many_values_decoded = await async_redis_decoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None]"
    reveal_type(many_values_decoded)
    assert_type(many_values_decoded, list[str | None])

    dumped_value = await async_redis_decoded.dump("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(dumped_value)
    assert_type(dumped_value, bytes | None)

    inr_float_decoded = await async_redis_decoded.incrbyfloat("key", 1.5)
    # Revealed type is "builtins.float"
    reveal_type(inr_float_decoded)
    assert_type(inr_float_decoded, float)

    stralgo_result_decoded = await async_redis_decoded.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings')
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_result_decoded)
    assert_type(stralgo_result_decoded, StrAlgoResultType)

    # append
    append_result_decoded = await async_redis_decoded.append(key='testkey', value='testvalue')
    # Revealed type is "builtins.int"
    reveal_type(append_result_decoded)
    assert_type(append_result_decoded, int)

    # bitcount
    bitcount_result_decoded = await async_redis_decoded.bitcount(key='testkey', start=0, end=-1)
    # Revealed type is "builtins.int"
    reveal_type(bitcount_result_decoded)
    assert_type(bitcount_result_decoded, int)

    # # bitfield
    # bitfield_result_decoded = await async_redis_decoded.bitfield(key='testkey')
    # reveal_type(bitfield_result_decoded)
    # # bitfield_result_decoded is a complex type
    # assert_type(bitfield_result, ...)

    # blmove
    blmove_result_decoded = await async_redis_decoded.blmove(first_list='mylist', second_list='destlist', timeout=1)
    # Revealed type is "builtins.str"
    reveal_type(blmove_result_decoded)
    assert_type(blmove_result_decoded, str)

    # copy
    copy_result_decoded = await async_redis_decoded.copy(source='mylist', destination='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(copy_result_decoded)
    assert_type(copy_result_decoded, bool)

    # decrby
    decrby_result_decoded = await async_redis_decoded.decrby(name='counter', amount=5)
    # Revealed type is "builtins.int"
    reveal_type(decrby_result_decoded)
    assert_type(decrby_result_decoded, int)

    # delete
    delete_result_decoded = await async_redis_decoded.delete('testkey')
    # Revealed type is "builtins.int"
    reveal_type(delete_result_decoded)
    assert_type(delete_result_decoded, int)

    # delex
    delex_result_decoded = await async_redis_decoded.delex(name='testkey')
    # Revealed type is "builtins.int"
    reveal_type(delex_result_decoded)
    assert_type(delex_result_decoded, int)

    # digest
    digest_result_decoded = await async_redis_decoded.digest(name='testkey')
    # Revealed type is "builtins.str | None"
    reveal_type(digest_result_decoded)
    assert_type(digest_result_decoded, str | None)

    # exists
    exists_result_decoded = await async_redis_decoded.exists('testkey')
    # Revealed type is "builtins.int"
    reveal_type(exists_result_decoded)
    assert_type(exists_result_decoded, int)

    # expire
    expire_result_decoded = await async_redis_decoded.expire(name='testkey', time=60)
    # Revealed type is "builtins.bool"
    reveal_type(expire_result_decoded)
    assert_type(expire_result_decoded, bool)

    # expireat
    expireat_result_decoded = await async_redis_decoded.expireat(name='testkey', when=1767730775)
    # Revealed type is "builtins.bool"
    reveal_type(expireat_result_decoded)
    assert_type(expireat_result_decoded, bool)

    # expiretime
    expiretime_result_decoded = await async_redis_decoded.expiretime(key='testkey')
    # Revealed type is "builtins.int"
    reveal_type(expiretime_result_decoded)
    assert_type(expiretime_result_decoded, int)

    # getbit
    getbit_result_decoded = await async_redis_decoded.getbit(name='testkey', offset=0)
    # Revealed type is "builtins.int"
    reveal_type(getbit_result_decoded)
    assert_type(getbit_result_decoded, int)

    # getrange
    getrange_result_decoded = await async_redis_decoded.getrange(key='testkey', start=0, end=-1)
    # Revealed type is "builtins.str"
    reveal_type(getrange_result_decoded)
    assert_type(getrange_result_decoded, str)

    # getset
    getset_result_decoded = await async_redis_decoded.getset(name='testkey', value='testvalue')
    # Revealed type is "builtins.str | None"
    reveal_type(getset_result_decoded)
    assert_type(getset_result_decoded, str | None)

    # hrandfield
    hrandfield_result_decoded = await async_redis_decoded.hrandfield(key='nonexistent', count=1)
    # Revealed type is "builtins.list[builtins.str]"
    reveal_type(hrandfield_result_decoded)
    assert_type(hrandfield_result_decoded, list[str])

    # incrby
    incrby_result_decoded = await async_redis_decoded.incrby(name='counter', amount=5)
    # Revealed type is "builtins.int"
    reveal_type(incrby_result_decoded)
    assert_type(incrby_result_decoded, int)

    # incrbyfloat
    incrbyfloat_result_decoded = await async_redis_decoded.incrbyfloat(name='nonexistent', amount=1.0)
    # Revealed type is "builtins.float"
    reveal_type(incrbyfloat_result_decoded)
    assert_type(incrbyfloat_result_decoded, float)

    # keys
    keys_result_decoded = await async_redis_decoded.keys(pattern='*')
    # Revealed type is "builtins.list[builtins.str]"
    reveal_type(keys_result_decoded)
    assert_type(keys_result_decoded, list[str])

    # lcs
    lcs_result_decoded = await async_redis_decoded.lcs(key1='test', key2='test')
    # Revealed type is "builtins.str"
    reveal_type(lcs_result_decoded)
    assert_type(lcs_result_decoded, str)

    # lmove
    lmove_result_decoded = await async_redis_decoded.lmove(first_list='mylist', second_list='destlist')
    # Revealed type is "builtins.str"
    reveal_type(lmove_result_decoded)
    assert_type(lmove_result_decoded, str)

    # move
    move_result_decoded = await async_redis_decoded.move(name='testkey', db=1)
    # Revealed type is "builtins.bool"
    reveal_type(move_result_decoded)
    assert_type(move_result_decoded, bool)

    # mset
    mset_result_decoded = await async_redis_decoded.mset(mapping={'field1': 'value1'})
    # Revealed type is "builtins.bool"
    reveal_type(mset_result_decoded)
    assert_type(mset_result_decoded, bool)

    # msetnx
    msetnx_result_decoded = await async_redis_decoded.msetnx(mapping={'field1': 'value1'})
    # Revealed type is "builtins.bool"
    reveal_type(msetnx_result_decoded)
    assert_type(msetnx_result_decoded, bool)

    # persist
    persist_result_decoded = await async_redis_decoded.persist(name='testkey')
    # Revealed type is "builtins.bool"
    reveal_type(persist_result_decoded)
    assert_type(persist_result_decoded, bool)

    # pexpire
    pexpire_result_decoded = await async_redis_decoded.pexpire(name='testkey', time=60)
    # Revealed type is "builtins.bool"
    reveal_type(pexpire_result_decoded)
    assert_type(pexpire_result_decoded, bool)

    # pexpireat
    pexpireat_result_decoded = await async_redis_decoded.pexpireat(name='testkey', when=1767730776)
    # Revealed type is "builtins.bool"
    reveal_type(pexpireat_result_decoded)
    assert_type(pexpireat_result_decoded, bool)

    # pexpiretime
    pexpiretime_result_decoded = await async_redis_decoded.pexpiretime(key='testkey')
    # Revealed type is "builtins.int"
    reveal_type(pexpiretime_result_decoded)
    assert_type(pexpiretime_result_decoded, int)

    # pttl
    pttl_result_decoded = await async_redis_decoded.pttl('testkey')
    # Revealed type is "builtins.int"
    reveal_type(pttl_result_decoded)
    assert_type(pttl_result_decoded, int)

    # randomkey
    randomkey_result_decoded = await async_redis_decoded.randomkey()
    # Revealed type is "builtins.str"
    reveal_type(randomkey_result_decoded)
    assert_type(randomkey_result_decoded, str)

    # rename
    rename_result_decoded = await async_redis_decoded.rename(src='mylist', dst='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(rename_result_decoded)
    assert_type(rename_result_decoded, bool)

    # renamenx
    renamenx_result_decoded = await async_redis_decoded.renamenx(src='mylist', dst='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(renamenx_result_decoded)
    assert_type(renamenx_result_decoded, bool)

    # restore
    restore_result_decoded = await async_redis_decoded.restore(name='restored_key', ttl=0, value=b'\x00\rrestore_value\x0c\x00\xf4b<\xb5\xb8\x96\xcd\xd5')
    # Revealed type is "builtins.bool"
    reveal_type(restore_result_decoded)
    assert_type(restore_result_decoded, bool)

    # set
    set_result_decoded = await async_redis_decoded.set(name='testkey', value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(set_result_decoded)
    assert_type(set_result_decoded, bool)

    # setbit
    setbit_result_decoded = await async_redis_decoded.setbit(name='testkey', offset=0, value=1)
    # Revealed type is "builtins.int"
    reveal_type(setbit_result_decoded)
    assert_type(setbit_result_decoded, int)

    # setex
    setex_result_decoded = await async_redis_decoded.setex(name='testkey', time=60, value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(setex_result_decoded)
    assert_type(setex_result_decoded, bool)

    # setnx
    setnx_result_decoded = await async_redis_decoded.setnx(name='testkey', value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(setnx_result_decoded)
    assert_type(setnx_result_decoded, bool)

    # setrange
    setrange_result_decoded = await async_redis_decoded.setrange(name='testkey', offset=0, value='testvalue')
    # Revealed type is "builtins.int"
    reveal_type(setrange_result_decoded)
    assert_type(setrange_result_decoded, int)

    # stralgo
    stralgo_result_decoded = await async_redis_decoded.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings')
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_result_decoded)
    assert_type(stralgo_result_decoded, StrAlgoResultType)

    stralgo_len_result_decoded = await async_redis_decoded.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings', len=True)
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_len_result_decoded)
    assert_type(stralgo_len_result_decoded, StrAlgoResultType)

    stralgo_idx_result_decoded = await async_redis_decoded.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings', idx=True)
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_idx_result_decoded)
    assert_type(stralgo_idx_result_decoded, StrAlgoResultType)

    # strlen
    strlen_result_decoded = await async_redis_decoded.strlen('testkey')
    # Revealed type is "builtins.int"
    reveal_type(strlen_result_decoded)
    assert_type(strlen_result_decoded, int)

    # substr
    substr_result_decoded = await async_redis_decoded.substr(name='testkey', start=0, end=-1)
    # Revealed type is "builtins.str"
    reveal_type(substr_result_decoded)
    assert_type(substr_result_decoded, str)

    # touch
    touch_result_decoded = await async_redis_decoded.touch('testkey')
    # Revealed type is "builtins.int"
    reveal_type(touch_result_decoded)
    assert_type(touch_result_decoded, int)

    # ttl
    ttl_result_decoded = await async_redis_decoded.ttl('testkey')
    # Revealed type is "builtins.int"
    reveal_type(ttl_result_decoded)
    assert_type(ttl_result_decoded, int)

    # type
    type_result_decoded = await async_redis_decoded.type('testkey')
    # Revealed type is "builtins.str"
    reveal_type(type_result_decoded)
    assert_type(type_result_decoded, str)

    # unlink
    unlink_result_decoded = await async_redis_decoded.unlink('testkey')
    # Revealed type is "builtins.int"
    reveal_type(unlink_result_decoded)
    assert_type(unlink_result_decoded, int)

    # decode_responses=False should return bytes | None
    async_redis_encoded = AsyncRedis(decode_responses=False)
    value_encoded = await async_redis_encoded.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_encoded)
    assert_type(value_encoded, bytes | None)

    value_encoded_deleted = await async_redis_encoded.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_encoded_deleted)
    assert_type(value_encoded_deleted, bytes | None)

    many_values_encoded = await async_redis_encoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_encoded)
    assert_type(many_values_encoded, list[bytes | None])

    # append
    append_result_encoded = await async_redis_encoded.append(key='testkey', value='testvalue')
    # Revealed type is "builtins.int"
    reveal_type(append_result_encoded)
    assert_type(append_result_encoded, int)

    # bitcount
    bitcount_result_encoded = await async_redis_encoded.bitcount(key='testkey', start=0, end=-1)
    # Revealed type is "builtins.int"
    reveal_type(bitcount_result_encoded)
    assert_type(bitcount_result_encoded, int)

    # # bitfield
    # bitfield_result_encoded = await async_redis_encoded.bitfield(key='testkey')
    # reveal_type(bitfield_result_encoded)
    # # bitfield_result_encoded is a complex type
    # assert_type(bitfield_result, ...)

    # blmove
    blmove_result_encoded = await async_redis_encoded.blmove(first_list='mylist', second_list='destlist', timeout=1)
    # Revealed type is "builtins.bytes"
    reveal_type(blmove_result_encoded)
    assert_type(blmove_result_encoded, bytes)

    # copy
    copy_result_encoded = await async_redis_encoded.copy(source='mylist', destination='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(copy_result_encoded)
    assert_type(copy_result_encoded, bool)

    # decrby
    decrby_result_encoded = await async_redis_encoded.decrby(name='counter', amount=5)
    # Revealed type is "builtins.int"
    reveal_type(decrby_result_encoded)
    assert_type(decrby_result_encoded, int)

    # delete
    delete_result_encoded = await async_redis_encoded.delete('testkey')
    # Revealed type is "builtins.int"
    reveal_type(delete_result_encoded)
    assert_type(delete_result_encoded, int)

    # delex
    delex_result_encoded = await async_redis_encoded.delex(name='testkey')
    # Revealed type is "builtins.int"
    reveal_type(delex_result_encoded)
    assert_type(delex_result_encoded, int)

    # digest
    digest_result_encoded = await async_redis_encoded.digest(name='testkey')
    # Revealed type is "builtins.bytes | None"
    reveal_type(digest_result_encoded)
    assert_type(digest_result_encoded, bytes | None)

    # exists
    exists_result_encoded = await async_redis_encoded.exists('testkey')
    # Revealed type is "builtins.int"
    reveal_type(exists_result_encoded)
    assert_type(exists_result_encoded, int)

    # expire
    expire_result_encoded = await async_redis_encoded.expire(name='testkey', time=60)
    # Revealed type is "builtins.bool"
    reveal_type(expire_result_encoded)
    assert_type(expire_result_encoded, bool)

    # expireat
    expireat_result_encoded = await async_redis_encoded.expireat(name='testkey', when=1767730775)
    # Revealed type is "builtins.bool"
    reveal_type(expireat_result_encoded)
    assert_type(expireat_result_encoded, bool)

    # expiretime
    expiretime_result_encoded = await async_redis_encoded.expiretime(key='testkey')
    # Revealed type is "builtins.int"
    reveal_type(expiretime_result_encoded)
    assert_type(expiretime_result_encoded, int)

    # getbit
    getbit_result_encoded = await async_redis_encoded.getbit(name='testkey', offset=0)
    # Revealed type is "builtins.int"
    reveal_type(getbit_result_encoded)
    assert_type(getbit_result_encoded, int)

    # getrange
    getrange_result_encoded = await async_redis_encoded.getrange(key='testkey', start=0, end=-1)
    # Revealed type is "builtins.bytes"
    reveal_type(getrange_result_encoded)
    assert_type(getrange_result_encoded, bytes)

    # getset
    getset_result_encoded = await async_redis_encoded.getset(name='testkey', value='testvalue')
    # Revealed type is "builtins.bytes | None"
    reveal_type(getset_result_encoded)
    assert_type(getset_result_encoded, bytes | None)

    # hrandfield
    hrandfield_result_encoded = await async_redis_encoded.hrandfield(key='nonexistent', count=1)
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(hrandfield_result_encoded)
    assert_type(hrandfield_result_encoded, list[bytes])

    # incrby
    incrby_result_encoded = await async_redis_encoded.incrby(name='counter', amount=5)
    # Revealed type is "builtins.int"
    reveal_type(incrby_result_encoded)
    assert_type(incrby_result_encoded, int)

    # incrbyfloat
    incrbyfloat_result_encoded = await async_redis_encoded.incrbyfloat(name='nonexistent', amount=1.0)
    # Revealed type is "builtins.float"
    reveal_type(incrbyfloat_result_encoded)
    assert_type(incrbyfloat_result_encoded, float)

    # keys
    keys_result_encoded = await async_redis_encoded.keys(pattern='*')
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(keys_result_encoded)
    assert_type(keys_result_encoded, list[bytes])

    # lcs
    lcs_result_encoded = await async_redis_encoded.lcs(key1='test', key2='test')
    # Revealed type is "builtins.bytes"
    reveal_type(lcs_result_encoded)
    assert_type(lcs_result_encoded, bytes)

    # lmove
    lmove_result_encoded = await async_redis_encoded.lmove(first_list='mylist', second_list='destlist')
    # Revealed type is "builtins.bytes"
    reveal_type(lmove_result_encoded)
    assert_type(lmove_result_encoded, bytes)

    # move
    move_result_encoded = await async_redis_encoded.move(name='testkey', db=1)
    # Revealed type is "builtins.bool"
    reveal_type(move_result_encoded)
    assert_type(move_result_encoded, bool)

    # mset
    mset_result_encoded = await async_redis_encoded.mset(mapping={'field1': 'value1'})
    # Revealed type is "builtins.bool"
    reveal_type(mset_result_encoded)
    assert_type(mset_result_encoded, bool)

    # msetnx
    msetnx_result_encoded = await async_redis_encoded.msetnx(mapping={'field1': 'value1'})
    # Revealed type is "builtins.bool"
    reveal_type(msetnx_result_encoded)
    assert_type(msetnx_result_encoded, bool)

    # persist
    persist_result_encoded = await async_redis_encoded.persist(name='testkey')
    # Revealed type is "builtins.bool"
    reveal_type(persist_result_encoded)
    assert_type(persist_result_encoded, bool)

    # pexpire
    pexpire_result_encoded = await async_redis_encoded.pexpire(name='testkey', time=60)
    # Revealed type is "builtins.bool"
    reveal_type(pexpire_result_encoded)
    assert_type(pexpire_result_encoded, bool)

    # pexpireat
    pexpireat_result_encoded = await async_redis_encoded.pexpireat(name='testkey', when=1767730776)
    # Revealed type is "builtins.bool"
    reveal_type(pexpireat_result_encoded)
    assert_type(pexpireat_result_encoded, bool)

    # pexpiretime
    pexpiretime_result_encoded = await async_redis_encoded.pexpiretime(key='testkey')
    # Revealed type is "builtins.int"
    reveal_type(pexpiretime_result_encoded)
    assert_type(pexpiretime_result_encoded, int)

    # pttl
    pttl_result_encoded = await async_redis_encoded.pttl('testkey')
    # Revealed type is "builtins.int"
    reveal_type(pttl_result_encoded)
    assert_type(pttl_result_encoded, int)

    # randomkey
    randomkey_result_encoded = await async_redis_encoded.randomkey()
    # Revealed type is "builtins.bytes"
    reveal_type(randomkey_result_encoded)
    assert_type(randomkey_result_encoded, bytes)

    # rename
    rename_result_encoded = await async_redis_encoded.rename(src='mylist', dst='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(rename_result_encoded)
    assert_type(rename_result_encoded, bool)

    # renamenx
    renamenx_result_encoded = await async_redis_encoded.renamenx(src='mylist', dst='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(renamenx_result_encoded)
    assert_type(renamenx_result_encoded, bool)

    # restore
    restore_result_encoded = await async_redis_encoded.restore(name='restored_key', ttl=0, value=b'\x00\rrestore_value\x0c\x00\xf4b<\xb5\xb8\x96\xcd\xd5')
    # Revealed type is "builtins.bool"
    reveal_type(restore_result_encoded)
    assert_type(restore_result_encoded, bool)

    # set
    set_result_encoded = await async_redis_encoded.set(name='testkey', value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(set_result_encoded)
    assert_type(set_result_encoded, bool)

    # setbit
    setbit_result_encoded = await async_redis_encoded.setbit(name='testkey', offset=0, value=1)
    # Revealed type is "builtins.int"
    reveal_type(setbit_result_encoded)
    assert_type(setbit_result_encoded, int)

    # setex
    setex_result_encoded = await async_redis_encoded.setex(name='testkey', time=60, value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(setex_result_encoded)
    assert_type(setex_result_encoded, bool)

    # setnx
    setnx_result_encoded = await async_redis_encoded.setnx(name='testkey', value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(setnx_result_encoded)
    assert_type(setnx_result_encoded, bool)

    # setrange
    setrange_result_encoded = await async_redis_encoded.setrange(name='testkey', offset=0, value='testvalue')
    # Revealed type is "builtins.int"
    reveal_type(setrange_result_encoded)
    assert_type(setrange_result_encoded, int)

    # stralgo
    stralgo_result_encoded = await async_redis_encoded.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings')
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_result_encoded)
    assert_type(stralgo_result_encoded, StrAlgoResultType)

    stralgo_len_result_encoded = await async_redis_encoded.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings', len=True)
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_len_result_encoded)
    assert_type(stralgo_len_result_encoded, StrAlgoResultType)

    stralgo_idx_result_encoded = await async_redis_encoded.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings', idx=True)
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_idx_result_encoded)
    assert_type(stralgo_idx_result_encoded, StrAlgoResultType)

    # strlen
    strlen_result_encoded = await async_redis_encoded.strlen('testkey')
    # Revealed type is "builtins.int"
    reveal_type(strlen_result_encoded)
    assert_type(strlen_result_encoded, int)

    # substr
    substr_result_encoded = await async_redis_encoded.substr(name='testkey', start=0, end=-1)
    # Revealed type is "builtins.bytes"
    reveal_type(substr_result_encoded)
    assert_type(substr_result_encoded, bytes)

    # touch
    touch_result_encoded = await async_redis_encoded.touch('testkey')
    # Revealed type is "builtins.int"
    reveal_type(touch_result_encoded)
    assert_type(touch_result_encoded, int)

    # ttl
    ttl_result_encoded = await async_redis_encoded.ttl('testkey')
    # Revealed type is "builtins.int"
    reveal_type(ttl_result_encoded)
    assert_type(ttl_result_encoded, int)

    # type
    type_result_encoded = await async_redis_encoded.type('testkey')
    # Revealed type is "builtins.bytes"
    reveal_type(type_result_encoded)
    assert_type(type_result_encoded, bytes)

    # unlink
    unlink_result_encoded = await async_redis_encoded.unlink('testkey')
    # Revealed type is "builtins.int"
    reveal_type(unlink_result_encoded)
    assert_type(unlink_result_encoded, int)

    # Default (no decode_responses) should return bytes | None
    async_redis_default = AsyncRedis()
    value_default = await async_redis_default.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_default)
    assert_type(value_default, bytes | None)

    value_default_deleted = await async_redis_default.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_default_deleted)
    assert_type(value_default_deleted, bytes | None)

    many_values_default = await async_redis_default.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_default)
    assert_type(many_values_default, list[bytes | None])

    # append
    append_result_default = await async_redis_default.append(key='testkey', value='testvalue')
    # Revealed type is "builtins.int"
    reveal_type(append_result_default)
    assert_type(append_result_default, int)

    # bitcount
    bitcount_result_default = await async_redis_default.bitcount(key='testkey', start=0, end=-1)
    # Revealed type is "builtins.int"
    reveal_type(bitcount_result_default)
    assert_type(bitcount_result_default, int)

    # bitfield
    # bitfield_result_default = await async_redis_default.bitfield(key='testkey')
    # reveal_type(bitfield_result_default)
    # # bitfield_result_default is a complex type...
    # assert_type(bitfield_result, ...)

    # blmove
    blmove_result_default = await async_redis_default.blmove(first_list='mylist', second_list='destlist', timeout=1)
    # Revealed type is "builtins.bytes"
    reveal_type(blmove_result_default)
    assert_type(blmove_result_default, bytes)

    # copy
    copy_result_default = await async_redis_default.copy(source='mylist', destination='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(copy_result_default)
    assert_type(copy_result_default, bool)

    # decrby
    decrby_result_default = await async_redis_default.decrby(name='counter', amount=5)
    # Revealed type is "builtins.int"
    reveal_type(decrby_result_default)
    assert_type(decrby_result_default, int)

    # delete
    delete_result_default = await async_redis_default.delete('testkey')
    # Revealed type is "builtins.int"
    reveal_type(delete_result_default)
    assert_type(delete_result_default, int)

    # delex
    delex_result_default = await async_redis_default.delex(name='testkey')
    # Revealed type is "builtins.int"
    reveal_type(delex_result_default)
    assert_type(delex_result_default, int)

    # digest
    digest_result_default = await async_redis_default.digest(name='testkey')
    # Revealed type is "builtins.bytes | None"
    reveal_type(digest_result_default)
    assert_type(digest_result_default, bytes | None)

    # exists
    exists_result_default = await async_redis_default.exists('testkey')
    # Revealed type is "builtins.int"
    reveal_type(exists_result_default)
    assert_type(exists_result_default, int)

    # expire
    expire_result_default = await async_redis_default.expire(name='testkey', time=60)
    # Revealed type is "builtins.bool"
    reveal_type(expire_result_default)
    assert_type(expire_result_default, bool)

    # expireat
    expireat_result_default = await async_redis_default.expireat(name='testkey', when=1767730775)
    # Revealed type is "builtins.bool"
    reveal_type(expireat_result_default)
    assert_type(expireat_result_default, bool)

    # expiretime
    expiretime_result_default = await async_redis_default.expiretime(key='testkey')
    # Revealed type is "builtins.int"
    reveal_type(expiretime_result_default)
    assert_type(expiretime_result_default, int)

    # getbit
    getbit_result_default = await async_redis_default.getbit(name='testkey', offset=0)
    # Revealed type is "builtins.int"
    reveal_type(getbit_result_default)
    assert_type(getbit_result_default, int)

    # getrange
    getrange_result_default = await async_redis_default.getrange(key='testkey', start=0, end=-1)
    # Revealed type is "builtins.bytes"
    reveal_type(getrange_result_default)
    assert_type(getrange_result_default, bytes)

    # getset
    getset_result_default = await async_redis_default.getset(name='testkey', value='testvalue')
    # Revealed type is "builtins.bytes | None"
    reveal_type(getset_result_default)
    assert_type(getset_result_default, bytes | None)

    # hrandfield
    hrandfield_result_default = await async_redis_default.hrandfield(key='nonexistent', count=1)
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(hrandfield_result_default)
    assert_type(hrandfield_result_default, list[bytes])

    # incrby
    incrby_result_default = await async_redis_default.incrby(name='counter', amount=5)
    # Revealed type is "builtins.int"
    reveal_type(incrby_result_default)
    assert_type(incrby_result_default, int)

    # incrbyfloat
    incrbyfloat_result_default = await async_redis_default.incrbyfloat(name='nonexistent', amount=1.0)
    # Revealed type is "builtins.float"
    reveal_type(incrbyfloat_result_default)
    assert_type(incrbyfloat_result_default, float)

    # keys
    keys_result_default = await async_redis_default.keys(pattern='*')
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(keys_result_default)
    assert_type(keys_result_default, list[bytes])

    # lcs
    lcs_result_default = await async_redis_default.lcs(key1='test', key2='test')
    # Revealed type is "builtins.bytes"
    reveal_type(lcs_result_default)
    assert_type(lcs_result_default, bytes)

    # lmove
    lmove_result_default = await async_redis_default.lmove(first_list='mylist', second_list='destlist')
    # Revealed type is "builtins.bytes"
    reveal_type(lmove_result_default)
    assert_type(lmove_result_default, bytes)

    # move
    move_result_default = await async_redis_default.move(name='testkey', db=1)
    # Revealed type is "builtins.bool"
    reveal_type(move_result_default)
    assert_type(move_result_default, bool)

    # mset
    mset_result_default = await async_redis_default.mset(mapping={'field1': 'value1'})
    # Revealed type is "builtins.bool"
    reveal_type(mset_result_default)
    assert_type(mset_result_default, bool)

    # msetnx
    msetnx_result_default = await async_redis_default.msetnx(mapping={'field1': 'value1'})
    # Revealed type is "builtins.bool"
    reveal_type(msetnx_result_default)
    assert_type(msetnx_result_default, bool)

    # persist
    persist_result_default = await async_redis_default.persist(name='testkey')
    # Revealed type is "builtins.bool"
    reveal_type(persist_result_default)
    assert_type(persist_result_default, bool)

    # pexpire
    pexpire_result_default = await async_redis_default.pexpire(name='testkey', time=60)
    # Revealed type is "builtins.bool"
    reveal_type(pexpire_result_default)
    assert_type(pexpire_result_default, bool)

    # pexpireat
    pexpireat_result_default = await async_redis_default.pexpireat(name='testkey', when=1767730776)
    # Revealed type is "builtins.bool"
    reveal_type(pexpireat_result_default)
    assert_type(pexpireat_result_default, bool)

    # pexpiretime
    pexpiretime_result_default = await async_redis_default.pexpiretime(key='testkey')
    # Revealed type is "builtins.int"
    reveal_type(pexpiretime_result_default)
    assert_type(pexpiretime_result_default, int)

    # pttl
    pttl_result_default = await async_redis_default.pttl('testkey')
    # Revealed type is "builtins.int"
    reveal_type(pttl_result_default)
    assert_type(pttl_result_default, int)

    # randomkey
    randomkey_result_default = await async_redis_default.randomkey()
    # Revealed type is "builtins.bytes"
    reveal_type(randomkey_result_default)
    assert_type(randomkey_result_default, bytes)

    # rename
    rename_result_default = await async_redis_default.rename(src='mylist', dst='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(rename_result_default)
    assert_type(rename_result_default, bool)

    # renamenx
    renamenx_result_default = await async_redis_default.renamenx(src='mylist', dst='destlist')
    # Revealed type is "builtins.bool"
    reveal_type(renamenx_result_default)
    assert_type(renamenx_result_default, bool)

    # restore
    restore_result_default = await async_redis_default.restore(name='restored_key', ttl=0, value=b'\x00\rrestore_value\x0c\x00\xf4b<\xb5\xb8\x96\xcd\xd5')
    # Revealed type is "builtins.bool"
    reveal_type(restore_result_default)
    assert_type(restore_result_default, bool)

    # set
    set_result_default = await async_redis_default.set(name='testkey', value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(set_result_default)
    assert_type(set_result_default, bool)

    # setbit
    setbit_result_default = await async_redis_default.setbit(name='testkey', offset=0, value=1)
    # Revealed type is "builtins.int"
    reveal_type(setbit_result_default)
    assert_type(setbit_result_default, int)

    # setex
    setex_result_default = await async_redis_default.setex(name='testkey', time=60, value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(setex_result_default)
    assert_type(setex_result_default, bool)

    # setnx
    setnx_result_default = await async_redis_default.setnx(name='testkey', value='testvalue')
    # Revealed type is "builtins.bool"
    reveal_type(setnx_result_default)
    assert_type(setnx_result_default, bool)

    # setrange
    setrange_result_default = await async_redis_default.setrange(name='testkey', offset=0, value='testvalue')
    # Revealed type is "builtins.int"
    reveal_type(setrange_result_default)
    assert_type(setrange_result_default, int)

    # stralgo
    stralgo_result_default = await async_redis_default.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings')
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_result_default)
    assert_type(stralgo_result_default, StrAlgoResultType)

    stralgo_len_result_default = await async_redis_default.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings', len=True)
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_len_result_default)
    assert_type(stralgo_len_result_default, StrAlgoResultType)

    stralgo_idx_result_default = await async_redis_default.stralgo(algo='LCS', value1='ohmytext', value2='mynewtext', specific_argument='strings', idx=True)
    # Revealed type is "builtins.str | builtins.int | TypedDict('redis.typing.StrAlgoIdxResponse', {'matches': builtins.list[builtins.list[tuple[builtins.int, builtins.int]]], 'len': builtins.int}) | TypedDict('redis.typing.StrAlgoIdxWithLenResponse', {'matches': builtins.list[builtins.list[builtins.int | tuple[builtins.int, builtins.int]]], 'len': builtins.int})"
    reveal_type(stralgo_idx_result_default)
    assert_type(stralgo_idx_result_default, StrAlgoResultType)

    # strlen
    strlen_result_default = await async_redis_default.strlen('testkey')
    # Revealed type is "builtins.int"
    reveal_type(strlen_result_default)
    assert_type(strlen_result_default, int)

    # substr
    substr_result_default = await async_redis_default.substr(name='testkey', start=0, end=-1)
    # Revealed type is "builtins.bytes"
    reveal_type(substr_result_default)
    assert_type(substr_result_default, bytes)

    # touch
    touch_result_default = await async_redis_default.touch('testkey')
    # Revealed type is "builtins.int"
    reveal_type(touch_result_default)
    assert_type(touch_result_default, int)

    # ttl
    ttl_result_default = await async_redis_default.ttl('testkey')
    # Revealed type is "builtins.int"
    reveal_type(ttl_result_default)
    assert_type(ttl_result_default, int)

    # type
    type_result_default = await async_redis_default.type('testkey')
    # Revealed type is "builtins.bytes"
    reveal_type(type_result_default)
    assert_type(type_result_default, bytes)

    # unlink
    unlink_result_default = await async_redis_default.unlink('testkey')
    # Revealed type is "builtins.int"
    reveal_type(unlink_result_default)
    assert_type(unlink_result_default, int)

    # decode_responses with bool variable should return str | None | bytes
    decode_responses_var = True  # Could be True or False at runtime
    async_redis_dynamic = AsyncRedis(decode_responses=decode_responses_var)
    value_dynamic = await async_redis_dynamic.get("key")
    # Revealed type is "builtins.str | None | builtins.bytes | None"
    reveal_type(value_dynamic)
    assert_type(value_dynamic, str | bytes | None)

    value_dynamic_deleted = await async_redis_dynamic.getdel("key")
    # Revealed type is "builtins.str | None | builtins.bytes | None"
    reveal_type(value_dynamic_deleted)
    assert_type(value_dynamic_deleted, str | bytes | None)

    many_values_dynamic = await async_redis_dynamic.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None] | builtins.list[builtins.bytes | None]"
    reveal_type(many_values_dynamic)
    assert_type(many_values_dynamic, list[str | None] | list[bytes | None])


    #  === AsyncRedis.from_url classmethod ===

    # from_url with decode_responses=True should return str | None
    async_redis_from_url_decoded = AsyncRedis.from_url("redis://localhost", decode_responses=True)
    value_from_url_decoded = await async_redis_from_url_decoded.get("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_from_url_decoded)
    assert_type(value_from_url_decoded, str | None)

    value_from_url_decoded_deleted = await async_redis_from_url_decoded.getdel("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_from_url_decoded_deleted)
    assert_type(value_from_url_decoded_deleted, str | None)

    many_values_from_url_decoded = await async_redis_from_url_decoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None]"
    reveal_type(many_values_from_url_decoded)
    assert_type(many_values_from_url_decoded, list[str | None])

    # from_url with decode_responses=False should return bytes | None
    async_redis_from_url_encoded = AsyncRedis.from_url("redis://localhost", decode_responses=False)
    value_from_url_encoded = await async_redis_from_url_encoded.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_url_encoded)
    assert_type(value_from_url_encoded, bytes | None)

    value_from_url_encoded_deleted = await async_redis_from_url_encoded.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_url_encoded_deleted)
    assert_type(value_from_url_encoded_deleted, bytes | None)

    many_values_from_url_encoded = await async_redis_from_url_encoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_from_url_encoded)
    assert_type(many_values_from_url_encoded, list[bytes | None])

    # from_url without decode_responses should return bytes | None
    async_redis_from_url_default = AsyncRedis.from_url("redis://localhost")
    value_from_url_default = await async_redis_from_url_default.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_url_default)
    assert_type(value_from_url_default, bytes | None)

    value_from_url_default_deleted = await async_redis_from_url_default.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_url_default_deleted)
    assert_type(value_from_url_default_deleted, bytes | None)

    many_values_from_url_default = await async_redis_from_url_default.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_from_url_default)
    assert_type(many_values_from_url_default, list[bytes | None])

    # decode_responses with bool variable should return str | None | bytes
    decode_responses_var = True  # Could be True or False at runtime
    async_redis_from_url_dynamic = AsyncRedis.from_url("redis://localhost", decode_responses=decode_responses_var)
    value_from_url_dynamic = await async_redis_from_url_dynamic.get("key")
    # Revealed type is "builtins.str | None | builtins.bytes | None"
    reveal_type(value_from_url_dynamic)
    assert_type(value_from_url_dynamic, str | bytes | None)

    value_from_url_dynamic_deleted = await async_redis_from_url_dynamic.getdel("key")
    # Revealed type is "builtins.str | None | builtins.bytes | None"
    reveal_type(value_from_url_dynamic_deleted)
    assert_type(value_from_url_dynamic_deleted, str | bytes | None)

    many_values_from_url_dynamic = await async_redis_from_url_dynamic.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None] | builtins.list[builtins.bytes | None]"
    reveal_type(many_values_from_url_dynamic)
    assert_type(many_values_from_url_dynamic, list[str | None] | list[bytes | None])


    #  === AsyncRedis.from_pool classmethod ===

    conn_pool = AsyncConnectionPool.from_url("redis://localhost")

    async_redis_from_pool_decoded: "AsyncRedisDecoded" = AsyncRedis.from_pool(connection_pool=conn_pool)  # type: ignore[assignment]
    value_from_pool_decoded = await async_redis_from_pool_decoded.get("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_from_pool_decoded)
    assert_type(value_from_pool_decoded, str | None)

    value_from_pool_decoded_deleted = await async_redis_from_pool_decoded.getdel("key")
    # Revealed type is "builtins.str | None"
    reveal_type(value_from_pool_decoded_deleted)
    assert_type(value_from_pool_decoded_deleted, str | None)

    many_values_from_pool_decoded = await async_redis_from_pool_decoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.str | None]"
    reveal_type(many_values_from_pool_decoded)
    assert_type(many_values_from_pool_decoded, list[str | None])

    async_redis_from_pool_encoded: "AsyncRedisEncoded" = AsyncRedis.from_pool(connection_pool=conn_pool)  # type: ignore[assignment]
    value_from_pool_encoded = await async_redis_from_pool_encoded.get("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_pool_encoded)
    assert_type(value_from_pool_encoded, bytes | None)

    value_from_pool_encoded_deleted = await async_redis_from_pool_encoded.getdel("key")
    # Revealed type is "builtins.bytes | None"
    reveal_type(value_from_pool_encoded_deleted)
    assert_type(value_from_pool_encoded_deleted, bytes | None)

    many_values_from_pool_encoded = await async_redis_from_pool_encoded.mget(keys=("key1", "key2"))
    # Revealed type is "builtins.list[builtins.bytes | None]"
    reveal_type(many_values_from_pool_encoded)
    assert_type(many_values_from_pool_encoded, list[bytes | None])


async def test_list_commands_async() -> None:
    #  === List Commands ===
    
    # decode_responses=True
    async_redis_decoded = AsyncRedis(decode_responses=True)
    
    # blmpop
    blmpop_result_decoded = await async_redis_decoded.blmpop(1, 1, 'mylist', direction='LEFT')
    # Revealed type is "builtins.list[builtins.str | builtins.list[builtins.str]] | None"
    reveal_type(blmpop_result_decoded)
    assert_type(blmpop_result_decoded, list[list[str] | str] | None)
    
    # blpop
    blpop_result_decoded = await async_redis_decoded.blpop(keys=['mylist'], timeout=1)
    # Revealed type is "builtins.list[builtins.str] | None"
    reveal_type(blpop_result_decoded)
    assert_type(blpop_result_decoded, list[str] | None)
    
    # brpop
    brpop_result_decoded = await async_redis_decoded.brpop(["list1", "list2"], 1.0)
    # Revealed type is "builtins.list[builtins.str] | None"
    reveal_type(brpop_result_decoded)
    assert_type(brpop_result_decoded, list[str] | None)
    
    # brpoplpush
    brpoplpush_result_decoded = await async_redis_decoded.brpoplpush("list1", "list2", 1.0)
    # Revealed type is "builtins.str | None"
    reveal_type(brpoplpush_result_decoded)
    assert_type(brpoplpush_result_decoded, str | None)
    
    # lindex
    lindex_result_decoded = await async_redis_decoded.lindex("list1", 0)
    # Revealed type is "builtins.str | None"
    reveal_type(lindex_result_decoded)
    assert_type(lindex_result_decoded, str | None)
    
    # linsert
    linsert_result_decoded = await async_redis_decoded.linsert("list1", "BEFORE", "pivot", "value")
    # Revealed type is "builtins.int"
    reveal_type(linsert_result_decoded)
    assert_type(linsert_result_decoded, int)
    
    # llen
    llen_result_decoded = await async_redis_decoded.llen("list1")
    # Revealed type is "builtins.int"
    reveal_type(llen_result_decoded)
    assert_type(llen_result_decoded, int)
    
    # lmpop
    lmpop_result_decoded = await async_redis_decoded.lmpop(1, 'mylist', direction='LEFT')
    # Revealed type is "builtins.list[builtins.str | builtins.list[builtins.str]] | None"
    reveal_type(lmpop_result_decoded)
    assert_type(lmpop_result_decoded, list[list[str] | str] | None)
    
    # lpop
    lpop_result_decoded = await async_redis_decoded.lpop(name='mylist')
    # Revealed type is "builtins.str | builtins.list[builtins.str] | None"
    reveal_type(lpop_result_decoded)
    assert_type(lpop_result_decoded, list[str] | str | None)
    
    # lpos
    lpos_result_decoded = await async_redis_decoded.lpos(name='mylist', value='value2')
    # Revealed type is "builtins.int | None"
    reveal_type(lpos_result_decoded)
    assert_type(lpos_result_decoded, int | None)
    
    # lpush
    lpush_result_decoded = await async_redis_decoded.lpush("list1", "value1", "value2")
    # Revealed type is "builtins.int"
    reveal_type(lpush_result_decoded)
    assert_type(lpush_result_decoded, int)
    
    # lpushx
    lpushx_result_decoded = await async_redis_decoded.lpushx("list1", "value")
    # Revealed type is "builtins.int"
    reveal_type(lpushx_result_decoded)
    assert_type(lpushx_result_decoded, int)
    
    # lrange
    lrange_result_decoded = await async_redis_decoded.lrange("list1", 0, -1)
    # Revealed type is "builtins.list[builtins.str]"
    reveal_type(lrange_result_decoded)
    assert_type(lrange_result_decoded, list[str])
    
    # lrem
    lrem_result_decoded = await async_redis_decoded.lrem("list1", 1, "value")
    # Revealed type is "builtins.int"
    reveal_type(lrem_result_decoded)
    assert_type(lrem_result_decoded, int)
    
    # lset
    lset_result_decoded = await async_redis_decoded.lset("list1", 0, "value")
    # Revealed type is "builtins.bool"
    reveal_type(lset_result_decoded)
    assert_type(lset_result_decoded, bool)
    
    # ltrim
    ltrim_result_decoded = await async_redis_decoded.ltrim("list1", 0, -1)
    # Revealed type is "builtins.bool"
    reveal_type(ltrim_result_decoded)
    assert_type(ltrim_result_decoded, bool)
    
    # rpop
    rpop_result_decoded = await async_redis_decoded.rpop("list1")
    # Revealed type is "builtins.str | builtins.list[builtins.str] | None"
    reveal_type(rpop_result_decoded)
    assert_type(rpop_result_decoded, list[str] | str | None)
    
    # rpoplpush
    rpoplpush_result_decoded = await async_redis_decoded.rpoplpush("list1", "list2")
    # Revealed type is "builtins.str | None"
    reveal_type(rpoplpush_result_decoded)
    assert_type(rpoplpush_result_decoded, str | None)
    
    # rpush
    rpush_result_decoded = await async_redis_decoded.rpush("list1", "value1", "value2")
    # Revealed type is "builtins.int"
    reveal_type(rpush_result_decoded)
    assert_type(rpush_result_decoded, int)
    
    # rpushx
    rpushx_result_decoded = await async_redis_decoded.rpushx("list1", "value")
    # Revealed type is "builtins.int"
    reveal_type(rpushx_result_decoded)
    assert_type(rpushx_result_decoded, int)
    
    # sort
    sort_result_decoded = await async_redis_decoded.sort("list1")
    # Revealed type is "builtins.list[builtins.str]"
    reveal_type(sort_result_decoded)
    assert_type(sort_result_decoded, list[str])
    
    # sort_ro
    sort_ro_result_decoded = await async_redis_decoded.sort_ro("list1")
    # Revealed type is "builtins.list[builtins.str]"
    reveal_type(sort_ro_result_decoded)
    assert_type(sort_ro_result_decoded, list[str])
    
    
    # decode_responses=False
    async_redis_encoded = AsyncRedis(decode_responses=False)
    
    # blmpop
    blmpop_result_encoded = await async_redis_encoded.blmpop(1, 1, 'mylist', direction='LEFT')
    # Revealed type is "builtins.list[builtins.bytes | builtins.list[builtins.bytes]] | None"
    reveal_type(blmpop_result_encoded)
    assert_type(blmpop_result_encoded, list[list[bytes] | bytes] | None)
    
    # blpop
    blpop_result_encoded = await async_redis_encoded.blpop(keys=['mylist'], timeout=1)
    # Revealed type is "builtins.list[builtins.bytes] | None"
    reveal_type(blpop_result_encoded)
    assert_type(blpop_result_encoded, list[bytes] | None)
    
    # brpop
    brpop_result_encoded = await async_redis_encoded.brpop(["list1", "list2"], 1.0)
    # Revealed type is "builtins.list[builtins.bytes] | None"
    reveal_type(brpop_result_encoded)
    assert_type(brpop_result_encoded, list[bytes] | None)
    
    # brpoplpush
    brpoplpush_result_encoded = await async_redis_encoded.brpoplpush("list1", "list2", 1.0)
    # Revealed type is "builtins.bytes | None"
    reveal_type(brpoplpush_result_encoded)
    assert_type(brpoplpush_result_encoded, bytes | None)
    
    # lindex
    lindex_result_encoded = await async_redis_encoded.lindex("list1", 0)
    # Revealed type is "builtins.bytes | None"
    reveal_type(lindex_result_encoded)
    assert_type(lindex_result_encoded, bytes | None)
    
    # linsert
    linsert_result_encoded = await async_redis_encoded.linsert("list1", "BEFORE", "pivot", "value")
    # Revealed type is "builtins.int"
    reveal_type(linsert_result_encoded)
    assert_type(linsert_result_encoded, int)
    
    # llen
    llen_result_encoded = await async_redis_encoded.llen("list1")
    # Revealed type is "builtins.int"
    reveal_type(llen_result_encoded)
    assert_type(llen_result_encoded, int)
    
    # lmpop
    lmpop_result_encoded = await async_redis_encoded.lmpop(1, 'mylist', direction='LEFT')
    # Revealed type is "builtins.list[builtins.bytes | builtins.list[builtins.bytes]] | None"
    reveal_type(lmpop_result_encoded)
    assert_type(lmpop_result_encoded, list[list[bytes] | bytes] | None)
    
    # lpop
    lpop_result_encoded = await async_redis_encoded.lpop(name='mylist')
    # Revealed type is "builtins.bytes | builtins.list[builtins.bytes] | None"
    reveal_type(lpop_result_encoded)
    assert_type(lpop_result_encoded, list[bytes] | bytes | None)
    
    # lpos
    lpos_result_encoded = await async_redis_encoded.lpos(name='mylist', value='value2')
    # Revealed type is "builtins.int | None"
    reveal_type(lpos_result_encoded)
    assert_type(lpos_result_encoded, int | None)
    
    # lpush
    lpush_result_encoded = await async_redis_encoded.lpush("list1", "value1", "value2")
    # Revealed type is "builtins.int"
    reveal_type(lpush_result_encoded)
    assert_type(lpush_result_encoded, int)
    
    # lpushx
    lpushx_result_encoded = await async_redis_encoded.lpushx("list1", "value")
    # Revealed type is "builtins.int"
    reveal_type(lpushx_result_encoded)
    assert_type(lpushx_result_encoded, int)
    
    # lrange
    lrange_result_encoded = await async_redis_encoded.lrange("list1", 0, -1)
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(lrange_result_encoded)
    assert_type(lrange_result_encoded, list[bytes])
    
    # lrem
    lrem_result_encoded = await async_redis_encoded.lrem("list1", 1, "value")
    # Revealed type is "builtins.int"
    reveal_type(lrem_result_encoded)
    assert_type(lrem_result_encoded, int)
    
    # lset
    lset_result_encoded = await async_redis_encoded.lset("list1", 0, "value")
    # Revealed type is "builtins.bool"
    reveal_type(lset_result_encoded)
    assert_type(lset_result_encoded, bool)
    
    # ltrim
    ltrim_result_encoded = await async_redis_encoded.ltrim("list1", 0, -1)
    # Revealed type is "builtins.bool"
    reveal_type(ltrim_result_encoded)
    assert_type(ltrim_result_encoded, bool)
    
    # rpop
    rpop_result_encoded = await async_redis_encoded.rpop("list1")
    # Revealed type is "builtins.bytes | builtins.list[builtins.bytes] | None"
    reveal_type(rpop_result_encoded)
    assert_type(rpop_result_encoded, list[bytes] | bytes | None)
    
    # rpoplpush
    rpoplpush_result_encoded = await async_redis_encoded.rpoplpush("list1", "list2")
    # Revealed type is "builtins.bytes | None"
    reveal_type(rpoplpush_result_encoded)
    assert_type(rpoplpush_result_encoded, bytes | None)
    
    # rpush
    rpush_result_encoded = await async_redis_encoded.rpush("list1", "value1", "value2")
    # Revealed type is "builtins.int"
    reveal_type(rpush_result_encoded)
    assert_type(rpush_result_encoded, int)
    
    # rpushx
    rpushx_result_encoded = await async_redis_encoded.rpushx("list1", "value")
    # Revealed type is "builtins.int"
    reveal_type(rpushx_result_encoded)
    assert_type(rpushx_result_encoded, int)
    
    # sort
    sort_result_encoded = await async_redis_encoded.sort("list1")
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(sort_result_encoded)
    assert_type(sort_result_encoded, list[bytes])
    
    # sort_ro
    sort_ro_result_encoded = await async_redis_encoded.sort_ro("list1")
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(sort_ro_result_encoded)
    assert_type(sort_ro_result_encoded, list[bytes])
    
    
    # Default (no decode_responses)
    async_redis_default = AsyncRedis()
    
    # blmpop
    blmpop_result_default = await async_redis_default.blmpop(1, 1, 'mylist', direction='LEFT')
    # Revealed type is "builtins.list[builtins.bytes | builtins.list[builtins.bytes]] | None"
    reveal_type(blmpop_result_default)
    assert_type(blmpop_result_default, list[list[bytes] | bytes] | None)
    
    # blpop
    blpop_result_default = await async_redis_default.blpop(keys=['mylist'], timeout=1)
    # Revealed type is "builtins.list[builtins.bytes] | None"
    reveal_type(blpop_result_default)
    assert_type(blpop_result_default, list[bytes] | None)
    
    # brpop
    brpop_result_default = await async_redis_default.brpop(["list1", "list2"], 1.0)
    # Revealed type is "builtins.list[builtins.bytes] | None"
    reveal_type(brpop_result_default)
    assert_type(brpop_result_default, list[bytes] | None)
    
    # brpoplpush
    brpoplpush_result_default = await async_redis_default.brpoplpush("list1", "list2", 1.0)
    # Revealed type is "builtins.bytes | None"
    reveal_type(brpoplpush_result_default)
    assert_type(brpoplpush_result_default, bytes | None)
    
    # lindex
    lindex_result_default = await async_redis_default.lindex("list1", 0)
    # Revealed type is "builtins.bytes | None"
    reveal_type(lindex_result_default)
    assert_type(lindex_result_default, bytes | None)
    
    # linsert
    linsert_result_default = await async_redis_default.linsert("list1", "BEFORE", "pivot", "value")
    # Revealed type is "builtins.int"
    reveal_type(linsert_result_default)
    assert_type(linsert_result_default, int)
    
    # llen
    llen_result_default = await async_redis_default.llen("list1")
    # Revealed type is "builtins.int"
    reveal_type(llen_result_default)
    assert_type(llen_result_default, int)
    
    # lmpop
    lmpop_result_default = await async_redis_default.lmpop(1, 'mylist', direction='LEFT')
    # Revealed type is "builtins.list[builtins.bytes | builtins.list[builtins.bytes]] | None"
    reveal_type(lmpop_result_default)
    assert_type(lmpop_result_default, list[list[bytes] | bytes] | None)
    
    # lpop
    lpop_result_default = await async_redis_default.lpop(name='mylist')
    # Revealed type is "builtins.bytes | builtins.list[builtins.bytes] | None"
    reveal_type(lpop_result_default)
    assert_type(lpop_result_default, list[bytes] | bytes | None)
    
    # lpos
    lpos_result_default = await async_redis_default.lpos(name='mylist', value='value2')
    # Revealed type is "builtins.int | None"
    reveal_type(lpos_result_default)
    assert_type(lpos_result_default, int | None)
    
    # lpush
    lpush_result_default = await async_redis_default.lpush("list1", "value1", "value2")
    # Revealed type is "builtins.int"
    reveal_type(lpush_result_default)
    assert_type(lpush_result_default, int)
    
    # lpushx
    lpushx_result_default = await async_redis_default.lpushx("list1", "value")
    # Revealed type is "builtins.int"
    reveal_type(lpushx_result_default)
    assert_type(lpushx_result_default, int)
    
    # lrange
    lrange_result_default = await async_redis_default.lrange("list1", 0, -1)
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(lrange_result_default)
    assert_type(lrange_result_default, list[bytes])
    
    # lrem
    lrem_result_default = await async_redis_default.lrem("list1", 1, "value")
    # Revealed type is "builtins.int"
    reveal_type(lrem_result_default)
    assert_type(lrem_result_default, int)
    
    # lset
    lset_result_default = await async_redis_default.lset("list1", 0, "value")
    # Revealed type is "builtins.bool"
    reveal_type(lset_result_default)
    assert_type(lset_result_default, bool)
    
    # ltrim
    ltrim_result_default = await async_redis_default.ltrim("list1", 0, -1)
    # Revealed type is "builtins.bool"
    reveal_type(ltrim_result_default)
    assert_type(ltrim_result_default, bool)
    
    # rpop
    rpop_result_default = await async_redis_default.rpop("list1")
    # Revealed type is "builtins.bytes | builtins.list[builtins.bytes] | None"
    reveal_type(rpop_result_default)
    assert_type(rpop_result_default, list[bytes] | bytes | None)
    
    # rpoplpush
    rpoplpush_result_default = await async_redis_default.rpoplpush("list1", "list2")
    # Revealed type is "builtins.bytes | None"
    reveal_type(rpoplpush_result_default)
    assert_type(rpoplpush_result_default, bytes | None)
    
    # rpush
    rpush_result_default = await async_redis_default.rpush("list1", "value1", "value2")
    # Revealed type is "builtins.int"
    reveal_type(rpush_result_default)
    assert_type(rpush_result_default, int)
    
    # rpushx
    rpushx_result_default = await async_redis_default.rpushx("list1", "value")
    # Revealed type is "builtins.int"
    reveal_type(rpushx_result_default)
    assert_type(rpushx_result_default, int)
    
    # sort
    sort_result_default = await async_redis_default.sort("list1")
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(sort_result_default)
    assert_type(sort_result_default, list[bytes])
    
    # sort_ro
    sort_ro_result_default = await async_redis_default.sort_ro("list1")
    # Revealed type is "builtins.list[builtins.bytes]"
    reveal_type(sort_ro_result_default)
    assert_type(sort_ro_result_default, list[bytes])


async def main_async() -> None:
    await test_basic_key_commands_async()
    await test_list_commands_async()

I'll wait for some feedback before doing any new changes. I hope I'm going the right way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants