Created
January 5, 2026 10:32
-
-
Save mahenzon/36490d9b0124f1033522dcb1936903ea to your computer and use it in GitHub Desktop.
how Redis-py annotations can be fixed for public methods
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| Suggestion for implementing | |
| https://github.com/redis/redis-py/pull/3619 | |
| Try it here: | |
| https://mypy-play.net/?mypy=latest&python=3.14&gist=bded9af8fe83b0625ad6bf72ad4b9338&flags=strict | |
| """ | |
| from typing import Awaitable, Generic, Literal, TypeVar, overload, reveal_type | |
| OptionalDecodedString = str | None | |
| OptionalEncodedString = bytes | None | |
| OptionalAnyString = OptionalDecodedString | OptionalEncodedString | |
| ResponseTypeOptionalAnyString = TypeVar( | |
| "ResponseTypeOptionalAnyString", | |
| bound=Awaitable[OptionalAnyString] | OptionalAnyString, | |
| ) | |
| class BasicCommands( | |
| Generic[ResponseTypeOptionalAnyString], | |
| ): | |
| def get(self, key: str) -> ResponseTypeOptionalAnyString: | |
| # dummy method | |
| return f"value-from-{key}" # type: ignore[return-value] | |
| class Redis(BasicCommands[ResponseTypeOptionalAnyString]): | |
| @overload | |
| def __init__( | |
| self: Redis[OptionalAnyString], | |
| decode_responses: bool, | |
| ): ... | |
| @overload | |
| def __init__( | |
| self: Redis[OptionalDecodedString], | |
| decode_responses: Literal[True], | |
| ): ... | |
| @overload | |
| def __init__( | |
| self: Redis[OptionalEncodedString], | |
| decode_responses: Literal[False], | |
| ): ... | |
| @overload | |
| def __init__( | |
| self: Redis[OptionalEncodedString], | |
| decode_responses: Literal[False] = False, | |
| ): ... | |
| def __init__(self, decode_responses: bool = False): | |
| self.decode_responses = decode_responses | |
| class AsyncRedis(BasicCommands[ResponseTypeOptionalAnyString]): | |
| @overload | |
| def __init__( | |
| self: AsyncRedis[Awaitable[OptionalAnyString]], | |
| decode_responses: bool, | |
| ): ... | |
| @overload | |
| def __init__( | |
| self: AsyncRedis[Awaitable[OptionalDecodedString]], | |
| decode_responses: Literal[True], | |
| ): ... | |
| @overload | |
| def __init__( | |
| self: AsyncRedis[Awaitable[OptionalEncodedString]], | |
| decode_responses: Literal[False], | |
| ): ... | |
| @overload | |
| def __init__( | |
| self: AsyncRedis[Awaitable[OptionalEncodedString]], | |
| decode_responses: Literal[False] = False, | |
| ): ... | |
| def __init__(self, decode_responses: bool = False): | |
| self.decode_responses = decode_responses | |
| async def main() -> None: | |
| decode_responses = bool("Any value. May be True or False. Resolved only at runtime.") | |
| redis_sync_decoded = Redis(decode_responses=True) | |
| redis_sync_encoded = Redis(decode_responses=False) | |
| redis_sync_encoded_default = Redis() | |
| redis_sync = Redis(decode_responses=decode_responses) | |
| redis_async_decoded = AsyncRedis(decode_responses=True) | |
| redis_async_encoded = AsyncRedis(decode_responses=False) | |
| redis_async_encoded_default = AsyncRedis() | |
| redis_async = AsyncRedis(decode_responses=decode_responses) | |
| key = "key" | |
| value_from_redis_sync_decoded = redis_sync_decoded.get(key) | |
| # note: Revealed type is "builtins.str | None" | |
| reveal_type(value_from_redis_sync_decoded) | |
| value_from_redis_sync_encoded = redis_sync_encoded.get(key) | |
| # note: Revealed type is "builtins.bytes | None" | |
| reveal_type(value_from_redis_sync_encoded) | |
| value_from_redis_sync_encoded_default = redis_sync_encoded_default.get(key) | |
| # note: Revealed type is "builtins.bytes | None" | |
| reveal_type(value_from_redis_sync_encoded_default) | |
| value_from_redis_sync = redis_sync.get(key) | |
| # note: Revealed type is "builtins.str | None | builtins.bytes" | |
| reveal_type(value_from_redis_sync) | |
| value_from_redis_async_decoded = await redis_async_decoded.get(key) | |
| # note: Revealed type is "builtins.str | None" | |
| reveal_type(value_from_redis_async_decoded) | |
| value_from_redis_async_encoded = await redis_async_encoded.get(key) | |
| # note: Revealed type is "builtins.bytes | None" | |
| reveal_type(value_from_redis_async_encoded) | |
| value_from_redis_async_encoded_default = await redis_async_encoded_default.get(key) | |
| # note: Revealed type is "builtins.bytes | None" | |
| reveal_type(value_from_redis_async_encoded_default) | |
| value_from_redis_async = await redis_async.get(key) | |
| # note: Revealed type is "builtins.str | None | builtins.bytes | None" | |
| reveal_type(value_from_redis_async) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment