Skip to content

Commit

Permalink
Align FakeConnection constructor signature to base class.
Browse files Browse the repository at this point in the history
As `FakeConnection` is a subclass of the `Connection` class in
`redis-py`, in order to honor OOP substitutability principle, the
signature of the constructor should be aligned with the one of the base
class. That means it should contain at least all the parameters of the
base class.

This automatically fixes a problem occurring when the connection object
is dynamically instantiated within the context of the default connection
pool class in `redis-py`, named `ConnectionPool`, and when, in turn, the
latter is dynamically instantiated using its standard `from_url` factory
method. In such scenario the instantiation of the connection object
fails because the `FakeConnection` class misses both `host` and `port`
parameters in its constructor signature.

That happens because the `from_url` factory method above, given a
canonical Redis URL, guesses several connection parameters values, among
which `host`, `username`, `password`, `path`, and `db`, which values
override any other corresponding value passed to the factory method
itself via the connection variadic arguments.

Aligning the `FakeConnection` constructor signature to the one of its
base class, by using variadic arguments, is helpful in contexts where
there's no direct control over the instantiantiation of Redis clients,
connections and connection pools objects (e.g. `django-redis` library):
whilst preserving current behavior, this avoids to workaround the issue
by defining either custom connection factories or custom connection
pools.
  • Loading branch information
Michele Cardone authored and wandering-tales committed Feb 28, 2021
1 parent f8e3df1 commit f8b2170
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 34 deletions.
38 changes: 4 additions & 34 deletions fakeredis/_server.py
@@ -1,5 +1,4 @@
import logging
import os
import time
import threading
import math
Expand Down Expand Up @@ -2655,39 +2654,10 @@ def check_is_ready_for_command(self, timeout):
class FakeConnection(redis.Connection):
description_format = "FakeConnection<db=%(db)s>"

def __init__(self, server, db=0, username=None, password=None,
socket_timeout=None, socket_connect_timeout=None,
socket_keepalive=False, socket_keepalive_options=None,
socket_type=0, retry_on_timeout=False,
encoding='utf-8', encoding_errors='strict',
decode_responses=False, parser_class=_DummyParser,
socket_read_size=65536, health_check_interval=0,
client_name=None):
self.pid = os.getpid()
self.db = db
self.username = username
self.client_name = client_name
self.password = password
# Allow socket attributes to be passed in and saved even if they aren't used
self.socket_timeout = socket_timeout
self.socket_connect_timeout = socket_connect_timeout or socket_timeout
self.socket_keepalive = socket_keepalive
self.socket_keepalive_options = socket_keepalive_options or {}
self.socket_type = socket_type
self.retry_on_timeout = retry_on_timeout
self.encoder = redis.connection.Encoder(encoding, encoding_errors, decode_responses)
self._description_args = {'db': self.db}
self._connect_callbacks = []
self._buffer_cutoff = 6000
self._server = server
# self._parser isn't used for anything, but some of the
# base class methods depend on it and it's easier not to
# override them.
self._parser = parser_class(socket_read_size=socket_read_size)
self._sock = None
# added in redis==3.3.0
self.health_check_interval = health_check_interval
self.next_health_check = 0
def __init__(self, *args, **kwargs):
self._server = kwargs.pop('server')
self._description_args = {'db': kwargs.get('db', 0)}
super().__init__(*args, **kwargs)

def connect(self):
super().connect()
Expand Down
1 change: 1 addition & 0 deletions test/test_fakeredis.py
Expand Up @@ -4988,6 +4988,7 @@ def test_can_pass_through_extra_args(self):
db.set('foo', 'bar')
assert db.get('foo') == 'bar'

@redis3_only
def test_can_allow_extra_args(self):
db = fakeredis.FakeStrictRedis.from_url(
'redis://localhost:6379/0',
Expand Down

0 comments on commit f8b2170

Please sign in to comment.