Skip to content

Replace hiredis dependency with libvalkey #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ firsttimersonly
fo
genindex
gmail
hiredis
html
http
https
Expand All @@ -101,6 +100,7 @@ json
keyslot
keyspace
kwarg
libvalkey
linters
localhost
lua
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/integration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', 'pypy-3.9', 'pypy-3.10']
test-type: ['standalone', 'cluster']
connection-type: ['hiredis', 'plain']
connection-type: ['libvalkey', 'plain']
env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
name: Python ${{ matrix.python-version }} ${{matrix.test-type}}-${{matrix.connection-type}} tests
Expand All @@ -74,8 +74,8 @@ jobs:
pip install -U setuptools wheel
pip install -r requirements.txt
pip install -r dev_requirements.txt
if [ "${{matrix.connection-type}}" == "hiredis" ]; then
pip install "hiredis<3.0.0"
if [ "${{matrix.connection-type}}" == "libvalkey" ]; then
pip install "libvalkey>=4.0.0b1"
fi
invoke devenv
sleep 10 # time to settle
Expand Down Expand Up @@ -104,10 +104,10 @@ jobs:
matrix:
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', 'pypy-3.9', 'pypy-3.10']
test-type: ['standalone', 'cluster']
connection-type: ['hiredis', 'plain']
connection-type: ['libvalkey', 'plain']
exclude:
- test-type: 'cluster'
connection-type: 'hiredis'
connection-type: 'libvalkey'
env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
name: RESP3 [${{ matrix.python-version }} ${{matrix.test-type}}-${{matrix.connection-type}}]
Expand All @@ -122,8 +122,8 @@ jobs:
pip install -U setuptools wheel
pip install -r requirements.txt
pip install -r dev_requirements.txt
if [ "${{matrix.connection-type}}" == "hiredis" ]; then
pip install "hiredis<3.0.0"
if [ "${{matrix.connection-type}}" == "libvalkey" ]; then
pip install "libvalkey>=4.0.0b1"
fi
invoke devenv
sleep 10 # time to settle
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ To install valkey-py, simply:
$ pip install valkey
```

For faster performance, install valkey with hiredis support, this provides a compiled response parser, and *for most cases* requires zero code changes.
By default, if hiredis >= 1.0 is available, valkey-py will attempt to use it for response parsing.
For faster performance, install valkey with libvalkey support, this provides a compiled response parser, and *for most cases* requires zero code changes.
By default, if libvalkey >= 2.3.2 is available, valkey-py will attempt to use it for response parsing.

``` bash
$ pip install "valkey[hiredis]"
$ pip install "valkey[libvalkey]"
```

## Usage
Expand Down
4 changes: 2 additions & 2 deletions benchmarks/socket_read_size.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from base import Benchmark

from valkey.connection import PythonParser, _HiredisParser
from valkey.connection import PythonParser, _LibvalkeyParser


class SocketReadBenchmark(Benchmark):

ARGUMENTS = (
{"name": "parser", "values": [PythonParser, _HiredisParser]},
{"name": "parser", "values": [PythonParser, _LibvalkeyParser]},
{
"name": "value_size",
"values": [10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000],
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"Programming Language :: Python :: Implementation :: PyPy",
],
extras_require={
"hiredis": ["hiredis >=1.0.0, <3.0.0"],
"libvalkey": ["libvalkey>=4.0.0b1"],
"ocsp": ["cryptography>=36.0.1", "pyopenssl==20.0.1", "requests>=2.26.0"],
},
)
2 changes: 1 addition & 1 deletion tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def all_tests(c, color=False):
@task
def tests(c, uvloop=False, protocol=2, color=False):
"""Run the valkey-py test suite against the current python,
with and without hiredis.
with and without libvalkey.
"""
print("Starting Valkey tests")
standalone_tests(c, uvloop=uvloop, protocol=protocol, color=color)
Expand Down
7 changes: 1 addition & 6 deletions tests/test_asyncio/test_bloom.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
is_resp2_connection,
skip_ifmodversion_lt,
)
from valkey.exceptions import ModuleError, ValkeyError
from valkey.utils import HIREDIS_AVAILABLE
from valkey.exceptions import ValkeyError

pytestmark = pytest.mark.skip

Expand Down Expand Up @@ -96,10 +95,6 @@ async def do_verify():

await do_verify()
cmds = []
if HIREDIS_AVAILABLE:
with pytest.raises(ModuleError):
cur = await decoded_r.bf().scandump("myBloom", 0)
return

cur = await decoded_r.bf().scandump("myBloom", 0)
first = cur[0]
Expand Down
8 changes: 4 additions & 4 deletions tests/test_asyncio/test_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import pytest
import pytest_asyncio
from valkey._cache import EvictionPolicy, _LocalCache
from valkey.utils import HIREDIS_AVAILABLE
from valkey.utils import LIBVALKEY_AVAILABLE


@pytest_asyncio.fixture
Expand All @@ -19,7 +19,7 @@ async def local_cache():
yield _LocalCache()


@pytest.mark.skipif(HIREDIS_AVAILABLE, reason="PythonParser only")
@pytest.mark.skipif(LIBVALKEY_AVAILABLE, reason="PythonParser only")
class TestLocalCache:
@pytest.mark.parametrize("r", [{"cache": _LocalCache()}], indirect=True)
@pytest.mark.onlynoncluster
Expand Down Expand Up @@ -299,7 +299,7 @@ async def test_flush_entire_cache(self, r):
assert await r.get("c") == "1"


@pytest.mark.skipif(HIREDIS_AVAILABLE, reason="PythonParser only")
@pytest.mark.skipif(LIBVALKEY_AVAILABLE, reason="PythonParser only")
@pytest.mark.onlycluster
class TestClusterLocalCache:
@pytest.mark.parametrize("r", [{"cache": _LocalCache()}], indirect=True)
Expand Down Expand Up @@ -368,7 +368,7 @@ async def test_execute_command_keys_not_provided(self, r):
assert cache.get(("GET", "b")) is None


@pytest.mark.skipif(HIREDIS_AVAILABLE, reason="PythonParser only")
@pytest.mark.skipif(LIBVALKEY_AVAILABLE, reason="PythonParser only")
@pytest.mark.onlynoncluster
class TestSentinelLocalCache:

Expand Down
24 changes: 12 additions & 12 deletions tests/test_asyncio/test_cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -1730,49 +1730,49 @@ async def test_cluster_rpoplpush(self, r: ValkeyCluster) -> None:

async def test_cluster_sdiff(self, r: ValkeyCluster) -> None:
await r.sadd("{foo}a", "1", "2", "3")
assert await r.sdiff("{foo}a", "{foo}b") == {b"1", b"2", b"3"}
assert set(await r.sdiff("{foo}a", "{foo}b")) == {b"1", b"2", b"3"}
await r.sadd("{foo}b", "2", "3")
assert await r.sdiff("{foo}a", "{foo}b") == {b"1"}
assert await r.sdiff("{foo}a", "{foo}b") == [b"1"]

async def test_cluster_sdiffstore(self, r: ValkeyCluster) -> None:
await r.sadd("{foo}a", "1", "2", "3")
assert await r.sdiffstore("{foo}c", "{foo}a", "{foo}b") == 3
assert await r.smembers("{foo}c") == {b"1", b"2", b"3"}
assert set(await r.smembers("{foo}c")) == {b"1", b"2", b"3"}
await r.sadd("{foo}b", "2", "3")
assert await r.sdiffstore("{foo}c", "{foo}a", "{foo}b") == 1
assert await r.smembers("{foo}c") == {b"1"}
assert await r.smembers("{foo}c") == [b"1"]

async def test_cluster_sinter(self, r: ValkeyCluster) -> None:
await r.sadd("{foo}a", "1", "2", "3")
assert await r.sinter("{foo}a", "{foo}b") == set()
assert await r.sinter("{foo}a", "{foo}b") == []
await r.sadd("{foo}b", "2", "3")
assert await r.sinter("{foo}a", "{foo}b") == {b"2", b"3"}
assert set(await r.sinter("{foo}a", "{foo}b")) == {b"2", b"3"}

async def test_cluster_sinterstore(self, r: ValkeyCluster) -> None:
await r.sadd("{foo}a", "1", "2", "3")
assert await r.sinterstore("{foo}c", "{foo}a", "{foo}b") == 0
assert await r.smembers("{foo}c") == set()
assert await r.smembers("{foo}c") == []
await r.sadd("{foo}b", "2", "3")
assert await r.sinterstore("{foo}c", "{foo}a", "{foo}b") == 2
assert await r.smembers("{foo}c") == {b"2", b"3"}
assert set(await r.smembers("{foo}c")) == {b"2", b"3"}

async def test_cluster_smove(self, r: ValkeyCluster) -> None:
await r.sadd("{foo}a", "a1", "a2")
await r.sadd("{foo}b", "b1", "b2")
assert await r.smove("{foo}a", "{foo}b", "a1")
assert await r.smembers("{foo}a") == {b"a2"}
assert await r.smembers("{foo}b") == {b"b1", b"b2", b"a1"}
assert await r.smembers("{foo}a") == [b"a2"]
assert set(await r.smembers("{foo}b")) == {b"b1", b"b2", b"a1"}

async def test_cluster_sunion(self, r: ValkeyCluster) -> None:
await r.sadd("{foo}a", "1", "2")
await r.sadd("{foo}b", "2", "3")
assert await r.sunion("{foo}a", "{foo}b") == {b"1", b"2", b"3"}
assert set(await r.sunion("{foo}a", "{foo}b")) == {b"1", b"2", b"3"}

async def test_cluster_sunionstore(self, r: ValkeyCluster) -> None:
await r.sadd("{foo}a", "1", "2")
await r.sadd("{foo}b", "2", "3")
assert await r.sunionstore("{foo}c", "{foo}a", "{foo}b") == 3
assert await r.smembers("{foo}c") == {b"1", b"2", b"3"}
assert set(await r.smembers("{foo}c")) == {b"1", b"2", b"3"}

@skip_if_server_version_lt("6.2.0")
async def test_cluster_zdiff(self, r: ValkeyCluster) -> None:
Expand Down
36 changes: 17 additions & 19 deletions tests/test_asyncio/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -1406,7 +1406,7 @@ async def test_zscan_iter(self, r: valkey.Valkey):
async def test_sadd(self, r: valkey.Valkey):
members = {b"1", b"2", b"3"}
await r.sadd("a", *members)
assert await r.smembers("a") == members
assert set(await r.smembers("a")) == members

async def test_scard(self, r: valkey.Valkey):
await r.sadd("a", "1", "2", "3")
Expand All @@ -1415,34 +1415,34 @@ async def test_scard(self, r: valkey.Valkey):
@pytest.mark.onlynoncluster
async def test_sdiff(self, r: valkey.Valkey):
await r.sadd("a", "1", "2", "3")
assert await r.sdiff("a", "b") == {b"1", b"2", b"3"}
assert set(await r.sdiff("a", "b")) == {b"1", b"2", b"3"}
await r.sadd("b", "2", "3")
assert await r.sdiff("a", "b") == {b"1"}
assert await r.sdiff("a", "b") == [b"1"]

@pytest.mark.onlynoncluster
async def test_sdiffstore(self, r: valkey.Valkey):
await r.sadd("a", "1", "2", "3")
assert await r.sdiffstore("c", "a", "b") == 3
assert await r.smembers("c") == {b"1", b"2", b"3"}
assert set(await r.smembers("c")) == {b"1", b"2", b"3"}
await r.sadd("b", "2", "3")
assert await r.sdiffstore("c", "a", "b") == 1
assert await r.smembers("c") == {b"1"}
assert await r.smembers("c") == [b"1"]

@pytest.mark.onlynoncluster
async def test_sinter(self, r: valkey.Valkey):
await r.sadd("a", "1", "2", "3")
assert await r.sinter("a", "b") == set()
assert await r.sinter("a", "b") == []
await r.sadd("b", "2", "3")
assert await r.sinter("a", "b") == {b"2", b"3"}
assert set(await r.sinter("a", "b")) == {b"2", b"3"}

@pytest.mark.onlynoncluster
async def test_sinterstore(self, r: valkey.Valkey):
await r.sadd("a", "1", "2", "3")
assert await r.sinterstore("c", "a", "b") == 0
assert await r.smembers("c") == set()
assert await r.smembers("c") == []
await r.sadd("b", "2", "3")
assert await r.sinterstore("c", "a", "b") == 2
assert await r.smembers("c") == {b"2", b"3"}
assert set(await r.smembers("c")) == {b"2", b"3"}

async def test_sismember(self, r: valkey.Valkey):
await r.sadd("a", "1", "2", "3")
Expand All @@ -1453,22 +1453,22 @@ async def test_sismember(self, r: valkey.Valkey):

async def test_smembers(self, r: valkey.Valkey):
await r.sadd("a", "1", "2", "3")
assert await r.smembers("a") == {b"1", b"2", b"3"}
assert set(await r.smembers("a")) == {b"1", b"2", b"3"}

@pytest.mark.onlynoncluster
async def test_smove(self, r: valkey.Valkey):
await r.sadd("a", "a1", "a2")
await r.sadd("b", "b1", "b2")
assert await r.smove("a", "b", "a1")
assert await r.smembers("a") == {b"a2"}
assert await r.smembers("b") == {b"b1", b"b2", b"a1"}
assert await r.smembers("a") == [b"a2"]
assert set(await r.smembers("b")) == {b"b1", b"b2", b"a1"}

async def test_spop(self, r: valkey.Valkey):
s = [b"1", b"2", b"3"]
await r.sadd("a", *s)
value = await r.spop("a")
assert value in s
assert await r.smembers("a") == set(s) - {value}
assert set(await r.smembers("a")) == set(s) - {value}

@skip_if_server_version_lt("3.2.0")
async def test_spop_multi_value(self, r: valkey.Valkey):
Expand All @@ -1481,9 +1481,7 @@ async def test_spop_multi_value(self, r: valkey.Valkey):
assert value in s

response = await r.spop("a", 1)
assert_resp_response(
r, response, list(set(s) - set(values)), set(s) - set(values)
)
assert set(response) == set(s) - set(values)

async def test_srandmember(self, r: valkey.Valkey):
s = [b"1", b"2", b"3"]
Expand All @@ -1502,20 +1500,20 @@ async def test_srem(self, r: valkey.Valkey):
await r.sadd("a", "1", "2", "3", "4")
assert await r.srem("a", "5") == 0
assert await r.srem("a", "2", "4") == 2
assert await r.smembers("a") == {b"1", b"3"}
assert set(await r.smembers("a")) == {b"1", b"3"}

@pytest.mark.onlynoncluster
async def test_sunion(self, r: valkey.Valkey):
await r.sadd("a", "1", "2")
await r.sadd("b", "2", "3")
assert await r.sunion("a", "b") == {b"1", b"2", b"3"}
assert set(await r.sunion("a", "b")) == {b"1", b"2", b"3"}

@pytest.mark.onlynoncluster
async def test_sunionstore(self, r: valkey.Valkey):
await r.sadd("a", "1", "2")
await r.sadd("b", "2", "3")
assert await r.sunionstore("c", "a", "b") == 3
assert await r.smembers("c") == {b"1", b"2", b"3"}
assert set(await r.smembers("c")) == {b"1", b"2", b"3"}

# SORTED SET COMMANDS
async def test_zadd(self, r: valkey.Valkey):
Expand Down
Loading
Loading