diff --git a/.flake8 b/.flake8 index 64f7681b..13b13e90 100644 --- a/.flake8 +++ b/.flake8 @@ -20,13 +20,14 @@ # E711: comparison to None should be 'if cond is None:' # E713: test for membership should be 'not in' # F401: '.monkey' imported but unused -# W503: line break after binary operator +# W504: line break after binary operator -ignore = E226,E501,W503 +ignore = E226,E501 per-file-ignores = pottery/__init__.py:E402 pottery/base.py:F401 + pottery/bloom.py:W504 pottery/exceptions.py:E302 pottery/monkey.py:E302,E305,E402 pottery/redlock.py:E127 diff --git a/pottery/__init__.py b/pottery/__init__.py index 39552089..77368137 100644 --- a/pottery/__init__.py +++ b/pottery/__init__.py @@ -13,7 +13,7 @@ __title__ = 'pottery' -__version__ = '0.69' +__version__ = '0.66' __description__, __long_description__ = ( s.strip() for s in __doc__.split(sep='\n\n', maxsplit=1) ) diff --git a/pottery/base.py b/pottery/base.py index d81d58e5..a556d521 100644 --- a/pottery/base.py +++ b/pottery/base.py @@ -116,8 +116,8 @@ def __eq__(self, other): equals = True elif ( isinstance(other, _Comparable) - and self.redis.connection_pool == other.redis.connection_pool - and self.key == other.key + and self.redis == other.redis # NoQA: W503 + and self.key == other.key # NoQA: W503 ): equals = True else: diff --git a/pottery/bloom.py b/pottery/bloom.py index b81f90c2..2ff3cea9 100644 --- a/pottery/bloom.py +++ b/pottery/bloom.py @@ -113,9 +113,9 @@ def size(self): return self._size except AttributeError: self._size = ( - -self.num_values - * math.log(self.false_positives) - / math.log(2)**2 + -self.num_values * + math.log(self.false_positives) / + math.log(2)**2 ) self._size = math.ceil(self._size) return self.size() @@ -236,9 +236,9 @@ def __len__(self): https://en.wikipedia.org/wiki/Bloom_filter#Approximating_the_number_of_items_in_a_Bloom_filter ''' len_ = ( - -self.size() - / self.num_hashes() - * math.log(1 - self._num_bits_set() / self.size()) + -self.size() / + self.num_hashes() * + math.log(1 - self._num_bits_set() / self.size()) ) return math.floor(len_) diff --git a/pottery/monkey.py b/pottery/monkey.py index 5c48edb7..b53e06f4 100644 --- a/pottery/monkey.py +++ b/pottery/monkey.py @@ -34,13 +34,41 @@ def _listdir(path=None, *, absolute=False): _logger.info('Monkey patched os.listdir() to optionally return absolute paths') -# lolwut for some reason, Redis doesn't have a __hash__() method. - +# The Redis client doesn't have a sane equality test. So monkey patch equality +# comparisons on to the Redis client. We consider two Redis clients to be +# equal if they're connected to the same host, port, and database. +# +# I've submitted this change to redis-py: +# https://github.com/andymccurdy/redis-py/pull/1240 +# +# If it gets merged upstream, then I'll be able to delete this monkey patch. + +from redis import ConnectionPool from redis import Redis -Redis.__hash__ = lambda self: hash(str(self)) +def __eq__(self, other): + try: + return self.connection_kwargs == other.connection_kwargs + except AttributeError: # pragma: no cover + return False + +ConnectionPool.__eq__ = __eq__ + +def __eq__(self, other): + '''True if two Redis clients are equal. + + The Redis client doesn't have a sane equality test. So we monkey patch + this method on to the Redis client so that two client instances are equal + if they're connected to the same Redis host, port, and database. + ''' + try: + return self.connection_pool == other.connection_pool + except AttributeError: + return False + +Redis.__eq__ = __eq__ _logger.info( - 'Monkey patched Redis.__hash__() in order to be able to put Redis clients ' - 'into sets' + 'Monkey patched ConnectionPool.__eq__() and Redis.__eq__() to compare ' + 'Redis clients by connection params' ) diff --git a/pottery/set.py b/pottery/set.py index 8e4c713c..f1b08af5 100644 --- a/pottery/set.py +++ b/pottery/set.py @@ -81,10 +81,7 @@ def remove(self, value): def isdisjoint(self, other): 'Return True if two sets have a null intersection. O(n)' with self._watch(other): - if ( - isinstance(other, self.__class__) - and self.redis.connection_pool == other.redis.connection_pool - ): + if isinstance(other, self.__class__) and self.redis == other.redis: self.redis.multi() self.redis.sinter(self.key, other.key) disjoint = not self.redis.execute()[0] diff --git a/requirements-to-freeze.txt b/requirements-to-freeze.txt index 8ebcb494..8fec3da2 100644 --- a/requirements-to-freeze.txt +++ b/requirements-to-freeze.txt @@ -6,7 +6,7 @@ # --------------------------------------------------------------------------- # -redis>=3.4.0 +redis>=3.0.0 mmh3 isort diff --git a/requirements.txt b/requirements.txt index d8520723..500c45ae 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,7 @@ pycodestyle==2.5.0 pyflakes==2.1.1 Pygments==2.5.1 readme-renderer==24.0 -redis==3.4.0 +redis==3.3.11 requests==2.22.0 requests-toolbelt==0.9.1 six==1.13.0 diff --git a/setup.py b/setup.py index 073685e3..92537f17 100644 --- a/setup.py +++ b/setup.py @@ -36,7 +36,7 @@ ], keywords=pottery.__keywords__, packages=find_packages(exclude=('contrib', 'docs', 'tests*')), - install_requires=('redis>=3.4.0', 'mmh3'), + install_requires=('redis>=3.0.0', 'mmh3'), extras_require={}, package_data={}, data_files=tuple(), diff --git a/tests/test_redis.py b/tests/test_redis.py index 170974a3..a63b17dd 100644 --- a/tests/test_redis.py +++ b/tests/test_redis.py @@ -25,31 +25,3 @@ def test_redis_clients_equal_if_same_url(self): assert not redis1 != redis2 assert redis1 != None assert not redis1 == None - - def test_client_equality(self): - r1 = Redis.from_url('redis://localhost:6379/9') - r2 = Redis.from_url('redis://localhost:6379/9') - assert r1 == r2 - assert hash(r1) == hash(r2) - - def test_clients_unequal_if_different_types(self): - r = Redis.from_url('redis://localhost:6379/9') - assert r != 0 - - def test_clients_unequal_if_different_hosts(self): - r1 = Redis.from_url('redis://localhost:6379/9') - r2 = Redis.from_url('redis://127.0.0.1:6379/9') - assert r1 != r2 - assert hash(r1) != hash(r2) - - def test_clients_unequal_if_different_ports(self): - r1 = Redis.from_url('redis://localhost:6379/9') - r2 = Redis.from_url('redis://localhost:6380/9') - assert r1 != r2 - assert hash(r1) != hash(r2) - - def test_clients_unequal_if_different_dbs(self): - r1 = Redis.from_url('redis://localhost:6379/9') - r2 = Redis.from_url('redis://localhost:6379/10') - assert r1 != r2 - assert hash(r1) != hash(r2)