Skip to content
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

Delete the first-defined (and thus "duplicate") Script class #3333

Merged
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
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
* Prevent async ClusterPipeline instances from becoming "false-y" in case of empty command stack (#3061)
* Close Unix sockets if the connection attempt fails. This prevents `ResourceWarning`s. (#3314)
* Close SSL sockets if the connection attempt fails, or if validations fail. (#3317)
* Eliminate mutable default arguments in the `redis.commands.core.Script` class. (#3332)

* 4.1.3 (Feb 8, 2022)
* Fix flushdb and flushall (#1926)
Expand Down
80 changes: 19 additions & 61 deletions redis/commands/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -5475,11 +5475,7 @@ def __init__(self, registered_client: "redis.client.Redis", script: ScriptTextT)
if isinstance(script, str):
# We need the encoding from the client in order to generate an
# accurate byte representation of the script
try:
encoder = registered_client.connection_pool.get_encoder()
except AttributeError:
# Cluster
encoder = registered_client.get_encoder()
encoder = self.get_encoder()
script = encoder.encode(script)
self.sha = hashlib.sha1(script).hexdigest()

Expand Down Expand Up @@ -5510,6 +5506,24 @@ def __call__(
self.sha = client.script_load(self.script)
return client.evalsha(self.sha, len(keys), *args)

def get_encoder(self):
"""Get the encoder to encode string scripts into bytes."""
try:
return self.registered_client.get_encoder()
except AttributeError:
# DEPRECATED
# In version <=4.1.2, this was the code we used to get the encoder.
# However, after 4.1.2 we added support for scripting in clustered
# redis. ClusteredRedis doesn't have a `.connection_pool` attribute
# so we changed the Script class to use
# `self.registered_client.get_encoder` (see above).
# However, that is technically a breaking change, as consumers who
# use Scripts directly might inject a `registered_client` that
# doesn't have a `.get_encoder` field. This try/except prevents us
# from breaking backward-compatibility. Ideally, it would be
# removed in the next major release.
return self.registered_client.connection_pool.get_encoder()


class AsyncScript:
"""
Expand Down Expand Up @@ -6293,62 +6307,6 @@ def command(self) -> ResponseT:
return self.execute_command("COMMAND")


class Script:
"""
An executable Lua script object returned by ``register_script``
"""

def __init__(self, registered_client, script):
self.registered_client = registered_client
self.script = script
# Precalculate and store the SHA1 hex digest of the script.

if isinstance(script, str):
# We need the encoding from the client in order to generate an
# accurate byte representation of the script
encoder = self.get_encoder()
script = encoder.encode(script)
self.sha = hashlib.sha1(script).hexdigest()

def __call__(self, keys=[], args=[], client=None):
"Execute the script, passing any required ``args``"
if client is None:
client = self.registered_client
args = tuple(keys) + tuple(args)
# make sure the Redis server knows about the script
from redis.client import Pipeline

if isinstance(client, Pipeline):
# Make sure the pipeline can register the script before executing.
client.scripts.add(self)
try:
return client.evalsha(self.sha, len(keys), *args)
except NoScriptError:
# Maybe the client is pointed to a different server than the client
# that created this instance?
# Overwrite the sha just in case there was a discrepancy.
self.sha = client.script_load(self.script)
return client.evalsha(self.sha, len(keys), *args)

def get_encoder(self):
"""Get the encoder to encode string scripts into bytes."""
try:
return self.registered_client.get_encoder()
except AttributeError:
# DEPRECATED
# In version <=4.1.2, this was the code we used to get the encoder.
# However, after 4.1.2 we added support for scripting in clustered
# redis. ClusteredRedis doesn't have a `.connection_pool` attribute
# so we changed the Script class to use
# `self.registered_client.get_encoder` (see above).
# However, that is technically a breaking change, as consumers who
# use Scripts directly might inject a `registered_client` that
# doesn't have a `.get_encoder` field. This try/except prevents us
# from breaking backward-compatibility. Ideally, it would be
# removed in the next major release.
return self.registered_client.connection_pool.get_encoder()


class AsyncModuleCommands(ModuleCommands):
async def command_info(self) -> None:
return super().command_info()
Expand Down
Loading