ResponseT type seems to be inconsistent with whatever types-redis provides
Version:
5.0.0
Platform:
python 3.10.12 WSL/Ubuntu 20.04
Description:
Both mypy and pyright result in an error with the following code in test.py
from typing import Protocol
from redis import Redis
class RedisLikeSync(Protocol):
def get(self, name: str | bytes) -> bytes | None:
...
def foo(r: RedisLikeSync):
return r.get("foo")
r = Redis()
foo(r)
To reproduce:
pyenv shell 3.10.12
python -m venv venv
. venv/bin/activate
pip install -U pip
pip install redis==5.0.0 mypy pyright
Result of mypy test.py
test.py:15: error: Argument 1 to "foo" has incompatible type "Redis"; expected "RedisLikeSync" [arg-type]
test.py:15: note: Following member(s) of "Redis" have conflicts:
test.py:15: note: Expected:
test.py:15: note: def get(self, name: str | bytes) -> bytes | None
test.py:15: note: Got:
test.py:15: note: def get(self, name: bytes | str | memoryview) -> Awaitable[Any] | Any
Result of pyright test.py
/home/mshantz/typing/test.py
/home/mshantz/typing/test.py:15:5 - error: Argument of type "Redis" cannot be assigned to parameter "r" of type "RedisLikeSync" in function "foo"
"Redis" is incompatible with protocol "RedisLikeSync"
"get" is an incompatible type
Type "(name: KeyT) -> ResponseT" cannot be assigned to type "(name: str | bytes) -> (bytes | None)"
Function return type "ResponseT" is incompatible with type "bytes | None" (reportGeneralTypeIssues)
1 error, 0 warnings, 0 informations
After pip install types-redis, both checks come up clean.
❯ mypy test.py
Success: no issues found in 1 source file
❯ pyright test.py
0 errors, 0 warnings, 0 informations
Since types-redis indicates that it should be removed as of version 5.0.0 of this library, this inconsistency is backwards incompatible...
from https://pypi.org/project/types-redis/
Note: The redis package includes type annotations or type stubs since version 5.0.0. Please uninstall the types-redis package if you use this or a newer version.
Issues #2174, #2399, #2897 may be related...
just wanted to chime in here that I was using redis-py 5.0.1 and had mypy type issues with Awaitable, had to drop down to 4.6.0 and use types-redis
Adding in a related issue after enabling type checking in 5.0.1 is a ton (all?) functions are typing the parameters with str when they accept str or bytes. I always pass bytes as not every key or value I store is a valid str (e.g., compressed gzip) and I want consistency in the return types. Currently, my working around looks like this, for reference:
my_info = await typing.cast(
Awaitable[List[Optional[bytes]]],
redis.hmget(
b"my_hash", # type: ignore
b"key1", # type: ignore
b"key2", # type: ignore
b"key3", # type: ignore
),
)
Yep, I had to come back to 4.60 like lokucrazy. Version 5 gives me inconsistent typing errors. The Redis functions says they return Awaitable[Unknown], so I need to await them. But they are not Awaitable at runtime, so I get an error. And casting everything to str doesn't feel great.
I have also reverted back to using types-redis as the builtin types with 5.x aren't specific enough to be useful.
As one example:
# types-redis (one of many kwarg-specific overloads)
def zrevrange(..., withscores: Literal[True], ...) -> list[tuple[_StrType, _ScoreCastFuncReturn]]: ...
# 5.x
def zrevrange(..., withscores: bool = False, ...) -> Union[Awaitable[Any], Any]: ...
Union[Awaitable[Any], Any] is a basically useless return type, and isn't even compatible (as there is no indication that an iterable is returned)
Any updates on this? Is this resolved in later versions?