diff --git a/redis/commands/core.py b/redis/commands/core.py index a4a48f95f1..80fad1a716 100644 --- a/redis/commands/core.py +++ b/redis/commands/core.py @@ -3917,7 +3917,12 @@ class ScriptCommands: https://redis.com/ebook/part-3-next-steps/chapter-11-scripting-redis-with-lua/ """ - def eval(self, script, numkeys, *keys_and_args): + def _eval( + self, command: str, script: str, numkeys: int, *keys_and_args: list + ) -> str: + return self.execute_command(command, script, numkeys, *keys_and_args) + + def eval(self, script: str, numkeys: int, *keys_and_args: list) -> str: """ Execute the Lua ``script``, specifying the ``numkeys`` the script will touch and the key names and argument values in ``keys_and_args``. @@ -3928,7 +3933,19 @@ def eval(self, script, numkeys, *keys_and_args): For more information check https://redis.io/commands/eval """ - return self.execute_command("EVAL", script, numkeys, *keys_and_args) + return self._eval("EVAL", script, numkeys, *keys_and_args) + + def eval_ro(self, script: str, numkeys: int, *keys_and_args: list) -> str: + """ + The read-only variant of the EVAL command + + Execute the read-only Lue ``script`` specifying the ``numkeys`` the script + will touch and the key names and argument values in ``keys_and_args``. + Returns the result of the script. + + For more information check https://redis.io/commands/eval_ro + """ + return self._eval("EVAL_RO", script, numkeys, *keys_and_args) def evalsha(self, sha, numkeys, *keys_and_args): """ diff --git a/tests/test_scripting.py b/tests/test_scripting.py index 9f4f82023f..b0d76c7335 100644 --- a/tests/test_scripting.py +++ b/tests/test_scripting.py @@ -1,5 +1,6 @@ import pytest +import redis from redis import exceptions from tests.conftest import skip_if_server_version_lt @@ -31,6 +32,13 @@ def test_eval(self, r): # 2 * 3 == 6 assert r.eval(multiply_script, 1, "a", 3) == 6 + # @skip_if_server_version_lt("7.0.0") turn on after redis 7 release + def test_eval_ro(self, unstable_r): + unstable_r.set("a", "b") + assert unstable_r.eval_ro("return redis.call('GET', KEYS[1])", 1, "a") == b"b" + with pytest.raises(redis.ResponseError): + unstable_r.eval_ro("return redis.call('DEL', KEYS[1])", 1, "a") + @skip_if_server_version_lt("6.2.0") def test_script_flush_620(self, r): r.set("a", 2)