From 9b445a0eda221606f94692e957b6ea7d8d0d31c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Nov 2021 00:01:47 +0000 Subject: [PATCH 01/37] Bump isort from 5.5.0 to 5.10.1 Bumps [isort](https://github.com/pycqa/isort) from 5.5.0 to 5.10.1. - [Release notes](https://github.com/pycqa/isort/releases) - [Changelog](https://github.com/PyCQA/isort/blob/main/CHANGELOG.md) - [Commits](https://github.com/pycqa/isort/compare/5.5.0...5.10.1) --- updated-dependencies: - dependency-name: isort dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 666e122..0a3b9c2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ check-manifest==0.42 coverage==5.2.1 flake8==3.8.3 -isort==5.5.0 +isort==5.10.1 mock==4.0.2 nose==1.3.7 pymemcache==3.3.0 From a9f23ebf9875ca3d0eb7b0f47a7a00504a70822c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Mar 2022 00:08:24 +0000 Subject: [PATCH 02/37] Bump check-manifest from 0.42 to 0.48 Bumps [check-manifest](https://github.com/mgedmin/check-manifest) from 0.42 to 0.48. - [Release notes](https://github.com/mgedmin/check-manifest/releases) - [Changelog](https://github.com/mgedmin/check-manifest/blob/master/CHANGES.rst) - [Commits](https://github.com/mgedmin/check-manifest/compare/0.42...0.48) --- updated-dependencies: - dependency-name: check-manifest dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 666e122..5220aa2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -check-manifest==0.42 +check-manifest==0.48 coverage==5.2.1 flake8==3.8.3 isort==5.5.0 From b74ceb01bde946996732aff9cc92ee1d33eacd2b Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 22 Aug 2022 18:12:10 +0900 Subject: [PATCH 03/37] Replace smart_text to smart_str --- django_elastipymemcache/client.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/django_elastipymemcache/client.py b/django_elastipymemcache/client.py index f9243b7..04f7f31 100644 --- a/django_elastipymemcache/client.py +++ b/django_elastipymemcache/client.py @@ -1,7 +1,7 @@ import logging from distutils.version import StrictVersion -from django.utils.encoding import smart_text +from django.utils.encoding import smart_str from pymemcache.client.base import Client, _readline from pymemcache.exceptions import MemcacheUnknownError @@ -17,7 +17,7 @@ def __init__(self, *args, ignore_cluster_errors=False, **kwargs): return client def _get_cluster_info_cmd(self): - if StrictVersion(smart_text(self.version())) < StrictVersion('1.4.14'): + if StrictVersion(smart_str(self.version())) < StrictVersion('1.4.14'): return b'get AmazonElastiCache:cluster\r\n' return b'config get cluster\r\n' @@ -27,7 +27,7 @@ def _extract_cluster_info(self, line): for raw_node in raw_nodes.split(b' '): host, ip, port = raw_node.split(b'|') nodes.append('{host}:{port}'.format( - host=smart_text(ip or host), + host=smart_str(ip or host), port=int(port) )) return { From 2a1e4321119e1146b9901a21606f631430e65a3f Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 22 Aug 2022 18:12:30 +0900 Subject: [PATCH 04/37] Replace warn to warning --- django_elastipymemcache/backend.py | 2 +- django_elastipymemcache/client.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/django_elastipymemcache/backend.py b/django_elastipymemcache/backend.py index 70fdd1e..22b38fb 100644 --- a/django_elastipymemcache/backend.py +++ b/django_elastipymemcache/backend.py @@ -86,7 +86,7 @@ def get_cluster_nodes(self): socket.gaierror, socket.timeout, ) as e: - logger.warn( + logger.warning( 'Cannot connect to cluster %s, err: %s', self.configuration_endpoint_client.server, e, diff --git a/django_elastipymemcache/client.py b/django_elastipymemcache/client.py index 04f7f31..b381026 100644 --- a/django_elastipymemcache/client.py +++ b/django_elastipymemcache/client.py @@ -66,7 +66,7 @@ def get_cluster_info(self): return self._fetch_cluster_info_cmd(cmd, 'config cluster') except Exception as e: if self.ignore_cluster_errors: - logger.warn('Failed to get cluster: %s', e) + logger.warning('Failed to get cluster: %s', e) return { 'version': None, 'nodes': [ From dfed7d1c19d2ad966ff15e18eaba0b2051d168a1 Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 22 Aug 2022 18:12:50 +0900 Subject: [PATCH 05/37] Fix drop old python version, django and add new django version --- tox.ini | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tox.ini b/tox.ini index 5929d8f..f4f90e1 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,9 @@ [tox] envlist = - py{36,37,38}-dj22, - py{36,37,38}-dj30, - py{36,37,38}-dj31, - py{36,37,38}-djdev, + py{37,38}-dj32, + py{37,38}-dj40, + py{37,38}-dj41, + py{37,38}-djdev, flake8, isort, readme @@ -11,28 +11,28 @@ envlist = [travis:env] DJANGO = - 2.2: dj22 - 3.0: dj30 - 3.1: dj31 + 3.2: dj32 + 4.0: dj40 + 4.1: dj41 dev: djdev [testenv] passenv = TOXENV CI TRAVIS TRAVIS_* CODECOV_* deps = - dj22: Django<2.3 - dj30: Django<3.1 - dj31: Django<3.2 + dj32: Django<4.0 + dj40: Django<4.1 + dj41: Django<4.2 django-pymemcache<2.0 djdev: https://github.com/django/django/archive/master.tar.gz -r{toxinidir}/requirements.txt - py38-dj31: codecov + py38-dj32: codecov setenv = PYTHONPATH = {toxinidir} commands = coverage run --source=django_elastipymemcache -m nose --verbose - py38-dj31: coverage report - py38-dj31: coverage xml - py38-dj31: codecov + py38-dj32: coverage report + py38-dj32: coverage xml + py38-dj32: codecov [testenv:flake8] basepython = python3.8 From 877dc43ac195aa2363cfb635601839f5b298609a Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 22 Aug 2022 18:13:23 +0900 Subject: [PATCH 06/37] Add flake8 section for local development --- setup.cfg | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/setup.cfg b/setup.cfg index ca864d7..363fcea 100644 --- a/setup.cfg +++ b/setup.cfg @@ -15,3 +15,13 @@ ignore = [coverage:run] branch = True omit = tests/* + +[flake8] +exclude = + .git, + .tox, + .venv, + .eggs, + migrations, + venv, + __pycache__ From de88808b6da3460492d661fbdb9cf1d233c77294 Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 22 Aug 2022 18:29:45 +0900 Subject: [PATCH 07/37] Add GitHub action for CI --- .github/workflows/build.yaml | 55 ++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 .github/workflows/build.yaml diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..81a63dc --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,55 @@ +name: build + +on: [push, pull_request] + +jobs: + build: + + name: Python ${{ matrix.python-version }} + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ['3.7', '3.8', '3.9', '3.10'] + env: + COVERAGE_OPTIONS: "-a" + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install Tox and any other packages + run: pip install tox tox-gh-actions codecov + - name: Test with tox + run: tox + - name: Generate coverage XML report + run: coverage xml + - name: Codecov + uses: codecov/codecov-action@v2 + env: + PYTHON: ${{matrix.python-version}} + with: + env_vars: PTYHON + + code_quality: + + name: Code Quality + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up Python 3.8 + uses: actions/setup-python@v2 + with: + python-version: 3.8 + - name: Install Tox + run: pip install tox + - name: isort + run: tox -e isort + - name: readme + run: tox -e readme + - name: flake8 + run: tox -e flake8 + - name: check-manifest + run: tox -e check-manifest From 147f593816128d34865dd4830214c3e205b0e4e3 Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 22 Aug 2022 18:30:04 +0900 Subject: [PATCH 08/37] Goodbye travis --- .travis.yml | 43 ------------------------------------------- 1 file changed, 43 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e1bae10..0000000 --- a/.travis.yml +++ /dev/null @@ -1,43 +0,0 @@ -sudo: false -language: python -python: - - 3.6 - - 3.7 - - 3.8 -cache: pip -env: - - DJANGO=2.2 - - DJANGO=3.0 - - DJANGO=3.1 - - DJANGO=dev - -matrix: - include: - - python: 3.8 - env: TOXENV=flake8 - - python: 3.8 - env: TOXENV=isort - - python: 3.8 - env: TOXENV=readme - - python: 3.8 - env: TOXENV=check-manifest - allow_failures: - - env: DJANGO=dev -install: -- travis_retry python3 -m pip install tox-travis -script: -- tox -deploy: - provider: pypi - username: __token__ - password: - secure: "HBbDdcrrzRrSXbQGz3cz24/xNIW77tVlHQ+D6DS5raOSV7en5CPaiWZ50YkMQa08nfBOR1RBT8JivrC05qz1+TqMwOz0+rinFeGPmu9gLY8f+1kx0UZnmXG7GHsm6dBGOP6nIHA40+rtK/YLuhskdd2hEBIOAuAxXuCSd1UQ/3bj/nuspDwcot9OdJiyn+Xl+cjI39Gt8WlF7ZBjgFRw1hNSIJ2f0or38zf+SSDY6QgKiJZCn+4sooy0assCms84LSKumSl7Ya50IWwBGJgJaNPxikqgTf3rDP9bT25OLtJw78zJnO4QC2PJ9Y7j2tzeYkelHJM794uAtKNaW1SanlYdBXQoE7m1CE8DszZxCtN/siuz+30whFJ885pPaSN3m5uJct/v9GxBEAHtoCrwwdfrTvzVCU43PGwPZvO768k465rRGUnBInLybO5hTq6myajecZB2WhVXMh7/KMcXlVtnD5PvIhxLkLPVIGBK+1wFfvH/4ijZl8Dhz5PXP53AcX/Ohdli7+kd9DQEvieE2bhDpBaJq2r7B4etW/bjz76GQ704uzuF5JXXEibaT1fox8nqJzghuWfcXJvoTa20iR1quuHg0Z4qBIYh76CUXafi4iIZ0fCcIDVPWM7KSp1rvt4BgCdi1csQdTasw0l0WGoKdOSu+LlNSrqzPLoXQlE=" - distributions: sdist bdist_wheel - skip_upload_docs: true - on: - repo: harikitech/django-elastipymemcache - tags: true - python: 3.8 - condition: "$DJANGO = 3.0" -notifications: - email: false From 2b8484eed65f2cc3c6c0c1e365050149580baaff Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 22 Aug 2022 18:33:22 +0900 Subject: [PATCH 09/37] Add coverage --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 81a63dc..edf3322 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -20,7 +20,7 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install Tox and any other packages - run: pip install tox tox-gh-actions codecov + run: pip install tox tox-gh-actions codecov coverage - name: Test with tox run: tox - name: Generate coverage XML report From 492e3c2c7200680cc8c0094074335f8d02fd3d88 Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 22 Aug 2022 18:35:00 +0900 Subject: [PATCH 10/37] Remove coverage --- .github/workflows/build.yaml | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index edf3322..3a654b9 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -4,7 +4,6 @@ on: [push, pull_request] jobs: build: - name: Python ${{ matrix.python-version }} runs-on: ubuntu-latest strategy: @@ -20,20 +19,11 @@ jobs: with: python-version: ${{ matrix.python-version }} - name: Install Tox and any other packages - run: pip install tox tox-gh-actions codecov coverage + run: pip install tox tox-gh-actions - name: Test with tox run: tox - - name: Generate coverage XML report - run: coverage xml - - name: Codecov - uses: codecov/codecov-action@v2 - env: - PYTHON: ${{matrix.python-version}} - with: - env_vars: PTYHON code_quality: - name: Code Quality runs-on: ubuntu-latest From 86737b7a186d834bdd70cb3965ba6d5f45c561e6 Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 22 Aug 2022 20:22:16 +0900 Subject: [PATCH 11/37] Goodbye nose, hello pytest --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 666e122..6ecf618 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,6 @@ coverage==5.2.1 flake8==3.8.3 isort==5.5.0 mock==4.0.2 -nose==1.3.7 pymemcache==3.3.0 +pytest==7.1.2 readme-renderer==26.0 From d25c95bf15094e30326c9fca5660942ccabf9515 Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 22 Aug 2022 20:22:35 +0900 Subject: [PATCH 12/37] Replace nose to pytest --- tests/test_backend.py | 401 ++++++++++++++++++++---------------------- tests/test_client.py | 70 ++++---- 2 files changed, 228 insertions(+), 243 deletions(-) diff --git a/tests/test_backend.py b/tests/test_backend.py index 628f263..ad6eca9 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -1,241 +1,220 @@ +from unittest import TestCase from unittest.mock import Mock, patch import django from django.core.cache import InvalidCacheBackendError -from nose.tools import eq_, raises - from django_elastipymemcache.client import ConfigurationEndpointClient -@raises(InvalidCacheBackendError) -def test_multiple_servers(): - from django_elastipymemcache.backend import ElastiPymemcache - ElastiPymemcache('h1:0,h2:0', {}) - - -@raises(InvalidCacheBackendError) -def test_wrong_server_format(): - from django_elastipymemcache.backend import ElastiPymemcache - ElastiPymemcache('h', {}) - - -@patch.object(ConfigurationEndpointClient, 'get_cluster_info') -def test_split_servers(get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache - backend = ElastiPymemcache('h:0', {}) - servers = [('h1', 0), ('h2', 0)] - get_cluster_info.return_value = { - 'nodes': servers - } - backend._lib.Client = Mock() - assert backend._cache - get_cluster_info.assert_called() - backend._lib.Client.assert_called_once_with( - servers, - ignore_exc=True, - ) - - -@patch.object(ConfigurationEndpointClient, 'get_cluster_info') -def test_node_info_cache(get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache - servers = ['h1:0', 'h2:0'] - get_cluster_info.return_value = { - 'nodes': servers - } - - backend = ElastiPymemcache('h:0', {}) - backend._lib.Client = Mock() - backend.set('key1', 'val') - backend.get('key1') - backend.set('key2', 'val') - backend.get('key2') - backend._lib.Client.assert_called_once_with( - servers, - ignore_exc=True, - ) - eq_(backend._cache.get.call_count, 2) - eq_(backend._cache.set.call_count, 2) - - get_cluster_info.assert_called_once() - - -@patch.object(ConfigurationEndpointClient, 'get_cluster_info') -def test_failed_to_connect_servers(get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache - backend = ElastiPymemcache('h:0', {}) - get_cluster_info.side_effect = OSError() - eq_(backend.get_cluster_nodes(), []) - - -@patch.object(ConfigurationEndpointClient, 'get_cluster_info') -def test_invalidate_cache(get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache - servers = ['h1:0', 'h2:0'] - get_cluster_info.return_value = { - 'nodes': servers - } - - backend = ElastiPymemcache('h:0', {}) - backend._lib.Client = Mock() - assert backend._cache - backend._cache.get = Mock() - backend._cache.get.side_effect = Exception() - try: - backend.get('key1', 'val') - except Exception: - pass - # invalidate cached client - container = getattr(backend, '_local', backend) - container._client = None - try: - backend.get('key1', 'val') - except Exception: - pass - eq_(backend._cache.get.call_count, 2) - eq_(get_cluster_info.call_count, 3) - - -@patch.object(ConfigurationEndpointClient, 'get_cluster_info') -def test_client_add(get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache - - servers = ['h1:0', 'h2:0'] - get_cluster_info.return_value = { - 'nodes': servers - } - - backend = ElastiPymemcache('h:0', {}) - ret = backend.add('key1', 'value1') - eq_(ret, False) - - -@patch.object(ConfigurationEndpointClient, 'get_cluster_info') -def test_client_delete(get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache - - servers = ['h1:0', 'h2:0'] - get_cluster_info.return_value = { - 'nodes': servers - } - - backend = ElastiPymemcache('h:0', {}) - ret = backend.delete('key1') - if django.get_version() >= '3.1': - eq_(ret, False) - else: - eq_(ret, None) - - -@patch.object(ConfigurationEndpointClient, 'get_cluster_info') -def test_client_get_many(get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache - - servers = ['h1:0', 'h2:0'] - get_cluster_info.return_value = { - 'nodes': servers - } - - backend = ElastiPymemcache('h:0', {}) - ret = backend.get_many(['key1']) - eq_(ret, {}) - - # When server does not found... - with patch('pymemcache.client.hash.HashClient._get_client') as p: - p.return_value = None - ret = backend.get_many(['key2']) - eq_(ret, {}) - - with patch('pymemcache.client.hash.HashClient._safely_run_func') as p2: - p2.return_value = { - ':1:key3': 1509111630.048594 - } +class ErrorTestCase(TestCase): + def test_multiple_servers(self): + with self.assertRaises(InvalidCacheBackendError): + from django_elastipymemcache.backend import ElastiPymemcache + ElastiPymemcache('h1:0,h2:0', {}) - ret = backend.get_many(['key3']) - eq_(ret, {'key3': 1509111630.048594}) + def test_wrong_server_format(self): + with self.assertRaises(InvalidCacheBackendError): + from django_elastipymemcache.backend import ElastiPymemcache + ElastiPymemcache('h', {}) - # If False value is included, ignore it. - with patch('pymemcache.client.hash.HashClient.get_many') as p: - p.return_value = { - ':1:key1': 1509111630.048594, - ':1:key2': False, - ':1:key3': 1509111630.058594, + +class BackendTestCase(TestCase): + @patch.object(ConfigurationEndpointClient, 'get_cluster_info') + def test_split_servers(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache + backend = ElastiPymemcache('h:0', {}) + servers = [('h1', 0), ('h2', 0)] + get_cluster_info.return_value = { + 'nodes': servers } - ret = backend.get_many(['key1', 'key2', 'key3']) - eq_( - ret, - { - 'key1': 1509111630.048594, - 'key3': 1509111630.058594 - }, + backend._lib.Client = Mock() + assert backend._cache + get_cluster_info.assert_called() + backend._lib.Client.assert_called_once_with( + servers, + ignore_exc=True, ) - with patch('pymemcache.client.hash.HashClient.get_many') as p: - p.return_value = { - ':1:key1': None, - ':1:key2': 1509111630.048594, - ':1:key3': False, + @patch.object(ConfigurationEndpointClient, 'get_cluster_info') + def test_node_info_cache(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache + servers = ['h1:0', 'h2:0'] + get_cluster_info.return_value = { + 'nodes': servers } - ret = backend.get_many(['key1', 'key2', 'key3']) - eq_( - ret, - { - 'key2': 1509111630.048594, - }, + + backend = ElastiPymemcache('h:0', {}) + backend._lib.Client = Mock() + backend.set('key1', 'val') + backend.get('key1') + backend.set('key2', 'val') + backend.get('key2') + backend._lib.Client.assert_called_once_with( + servers, + ignore_exc=True, ) + assert backend._cache.get.call_count == 2 + assert backend._cache.set.call_count == 2 + + get_cluster_info.assert_called_once() + + @patch.object(ConfigurationEndpointClient, 'get_cluster_info') + def test_failed_to_connect_servers(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache + backend = ElastiPymemcache('h:0', {}) + get_cluster_info.side_effect = OSError() + assert backend.get_cluster_nodes() == [] + + @patch.object(ConfigurationEndpointClient, 'get_cluster_info') + def test_invalidate_cache(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache + servers = ['h1:0', 'h2:0'] + get_cluster_info.return_value = { + 'nodes': servers + } + + backend = ElastiPymemcache('h:0', {}) + backend._lib.Client = Mock() + assert backend._cache + backend._cache.get = Mock() + backend._cache.get.side_effect = Exception() + try: + backend.get('key1', 'val') + except Exception: + pass + # invalidate cached client + container = getattr(backend, '_local', backend) + container._client = None + try: + backend.get('key1', 'val') + except Exception: + pass + assert backend._cache.get.call_count == 2 + assert get_cluster_info.call_count == 3 + + @patch.object(ConfigurationEndpointClient, 'get_cluster_info') + def test_client_add(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache + + servers = ['h1:0', 'h2:0'] + get_cluster_info.return_value = { + 'nodes': servers + } + backend = ElastiPymemcache('h:0', {}) + ret = backend.add('key1', 'value1') + assert ret is False -@patch.object(ConfigurationEndpointClient, 'get_cluster_info') -def test_client_set_many(get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache + @patch.object(ConfigurationEndpointClient, 'get_cluster_info') + def test_client_delete(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache - servers = ['h1:0', 'h2:0'] - get_cluster_info.return_value = { - 'nodes': servers - } + servers = ['h1:0', 'h2:0'] + get_cluster_info.return_value = { + 'nodes': servers + } - backend = ElastiPymemcache('h:0', {}) - ret = backend.set_many({'key1': 'value1', 'key2': 'value2'}) - eq_(ret, ['key1', 'key2']) + backend = ElastiPymemcache('h:0', {}) + ret = backend.delete('key1') + if django.get_version() >= '3.1': + assert ret is False + else: + assert ret is None + @patch.object(ConfigurationEndpointClient, 'get_cluster_info') + def test_client_get_many(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache -@patch.object(ConfigurationEndpointClient, 'get_cluster_info') -def test_client_delete_many(get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache + servers = ['h1:0', 'h2:0'] + get_cluster_info.return_value = { + 'nodes': servers + } - servers = ['h1:0', 'h2:0'] - get_cluster_info.return_value = { - 'nodes': servers - } + backend = ElastiPymemcache('h:0', {}) + ret = backend.get_many(['key1']) + assert ret == {} + + # When server does not found... + with patch('pymemcache.client.hash.HashClient._get_client') as p: + p.return_value = None + ret = backend.get_many(['key2']) + assert ret == {} + + with patch('pymemcache.client.hash.HashClient._safely_run_func') as p2: + p2.return_value = { + ':1:key3': 1509111630.048594 + } + + ret = backend.get_many(['key3']) + assert ret == {'key3': 1509111630.048594} + + # If False value is included, ignore it. + with patch('pymemcache.client.hash.HashClient.get_many') as p: + p.return_value = { + ':1:key1': 1509111630.048594, + ':1:key2': False, + ':1:key3': 1509111630.058594, + } + ret = backend.get_many(['key1', 'key2', 'key3']) + assert ret == {'key1': 1509111630.048594, 'key3': 1509111630.058594} + + with patch('pymemcache.client.hash.HashClient.get_many') as p: + p.return_value = { + ':1:key1': None, + ':1:key2': 1509111630.048594, + ':1:key3': False, + } + ret = backend.get_many(['key1', 'key2', 'key3']) + assert ret == {'key2': 1509111630.048594} + + @patch.object(ConfigurationEndpointClient, 'get_cluster_info') + def test_client_set_many(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache + + servers = ['h1:0', 'h2:0'] + get_cluster_info.return_value = { + 'nodes': servers + } - backend = ElastiPymemcache('h:0', {}) - ret = backend.delete_many(['key1', 'key2']) - eq_(ret, None) + backend = ElastiPymemcache('h:0', {}) + ret = backend.set_many({'key1': 'value1', 'key2': 'value2'}) + assert ret == ['key1', 'key2'] + @patch.object(ConfigurationEndpointClient, 'get_cluster_info') + def test_client_delete_many(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache -@patch.object(ConfigurationEndpointClient, 'get_cluster_info') -def test_client_incr(get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache + servers = ['h1:0', 'h2:0'] + get_cluster_info.return_value = { + 'nodes': servers + } - servers = ['h1:0', 'h2:0'] - get_cluster_info.return_value = { - 'nodes': servers - } + backend = ElastiPymemcache('h:0', {}) + ret = backend.delete_many(['key1', 'key2']) + assert ret is None - backend = ElastiPymemcache('h:0', {}) - ret = backend.incr('key1', 1) - eq_(ret, False) + @patch.object(ConfigurationEndpointClient, 'get_cluster_info') + def test_client_incr(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache + servers = ['h1:0', 'h2:0'] + get_cluster_info.return_value = { + 'nodes': servers + } + + backend = ElastiPymemcache('h:0', {}) + ret = backend.incr('key1', 1) + assert ret is False -@patch.object(ConfigurationEndpointClient, 'get_cluster_info') -def test_client_decr(get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache + @patch.object(ConfigurationEndpointClient, 'get_cluster_info') + def test_client_decr(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache - servers = ['h1:0', 'h2:0'] - get_cluster_info.return_value = { - 'nodes': servers - } + servers = ['h1:0', 'h2:0'] + get_cluster_info.return_value = { + 'nodes': servers + } - backend = ElastiPymemcache('h:0', {}) - ret = backend.decr('key1', 1) - eq_(ret, False) + backend = ElastiPymemcache('h:0', {}) + ret = backend.decr('key1', 1) + assert ret is False diff --git a/tests/test_client.py b/tests/test_client.py index 724e0ad..5b675d9 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -1,11 +1,11 @@ import collections from unittest.mock import call, patch -from nose.tools import eq_, raises from pymemcache.exceptions import ( MemcacheUnknownCommandError, MemcacheUnknownError, ) +from pytest import raises from django_elastipymemcache.client import ConfigurationEndpointClient @@ -27,7 +27,10 @@ def test_get_cluster_info(socket): client = socket.return_value client.recv.side_effect = lambda *args, **kwargs: recv_bufs.popleft() cluster_info = ConfigurationEndpointClient(('h', 0)).get_cluster_info() - eq_(cluster_info['nodes'], ['10.82.235.120:11211', '10.80.249.27:11211']) + assert cluster_info['nodes'] == [ + '10.82.235.120:11211', + '10.80.249.27:11211', + ] client.sendall.assert_has_calls([ call(b'version\r\n'), call(b'config get cluster\r\n'), @@ -43,54 +46,57 @@ def test_get_cluster_info_before_1_4_13(socket): client = socket.return_value client.recv.side_effect = lambda *args, **kwargs: recv_bufs.popleft() cluster_info = ConfigurationEndpointClient(('h', 0)).get_cluster_info() - eq_(cluster_info['nodes'], ['10.82.235.120:11211', '10.80.249.27:11211']) + assert cluster_info['nodes'] == [ + '10.82.235.120:11211', + '10.80.249.27:11211', + ] client.sendall.assert_has_calls([ call(b'version\r\n'), call(b'get AmazonElastiCache:cluster\r\n'), ]) -@raises(MemcacheUnknownCommandError) @patch('socket.socket') def test_no_configuration_protocol_support_with_errors(socket): - recv_bufs = collections.deque([ - b'VERSION 1.4.13\r\n', - b'ERROR\r\n', - ]) + with raises(MemcacheUnknownCommandError): + recv_bufs = collections.deque([ + b'VERSION 1.4.13\r\n', + b'ERROR\r\n', + ]) - client = socket.return_value - client.recv.side_effect = lambda *args, **kwargs: recv_bufs.popleft() - ConfigurationEndpointClient(('h', 0)).get_cluster_info() + client = socket.return_value + client.recv.side_effect = lambda *args, **kwargs: recv_bufs.popleft() + ConfigurationEndpointClient(('h', 0)).get_cluster_info() -@raises(MemcacheUnknownError) @patch('socket.socket') def test_cannot_parse_version(socket): - recv_bufs = collections.deque([ - b'VERSION 1.4.34\r\n', - b'CONFIG cluster 0 147\r\n', - b'fail\nhost|ip|11211 host|ip|11211\n\r\n', - b'END\r\n', - ]) + with raises(MemcacheUnknownError): + recv_bufs = collections.deque([ + b'VERSION 1.4.34\r\n', + b'CONFIG cluster 0 147\r\n', + b'fail\nhost|ip|11211 host|ip|11211\n\r\n', + b'END\r\n', + ]) - client = socket.return_value - client.recv.side_effect = lambda *args, **kwargs: recv_bufs.popleft() - ConfigurationEndpointClient(('h', 0)).get_cluster_info() + client = socket.return_value + client.recv.side_effect = lambda *args, **kwargs: recv_bufs.popleft() + ConfigurationEndpointClient(('h', 0)).get_cluster_info() -@raises(MemcacheUnknownError) @patch('socket.socket') def test_cannot_parse_nodes(socket): - recv_bufs = collections.deque([ - b'VERSION 1.4.34\r\n', - b'CONFIG cluster 0 147\r\n', - b'1\nfail\n\r\n', - b'END\r\n', - ]) + with raises(MemcacheUnknownError): + recv_bufs = collections.deque([ + b'VERSION 1.4.34\r\n', + b'CONFIG cluster 0 147\r\n', + b'1\nfail\n\r\n', + b'END\r\n', + ]) - client = socket.return_value - client.recv.side_effect = lambda *args, **kwargs: recv_bufs.popleft() - ConfigurationEndpointClient(('h', 0)).get_cluster_info() + client = socket.return_value + client.recv.side_effect = lambda *args, **kwargs: recv_bufs.popleft() + ConfigurationEndpointClient(('h', 0)).get_cluster_info() @patch('socket.socket') @@ -107,4 +113,4 @@ def test_ignore_erros(socket): ('h', 0), ignore_cluster_errors=True, ).get_cluster_info() - eq_(cluster_info['nodes'], ['h:0']) + assert cluster_info['nodes'] == ['h:0'] From 0ad83f71a1ec333ce479f4bd83d981b8cf21d3d1 Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 22 Aug 2022 20:41:20 +0900 Subject: [PATCH 13/37] Fix flake8 errors --- tests/test_backend.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/test_backend.py b/tests/test_backend.py index ad6eca9..f8f84c5 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -3,6 +3,7 @@ import django from django.core.cache import InvalidCacheBackendError + from django_elastipymemcache.client import ConfigurationEndpointClient @@ -156,7 +157,10 @@ def test_client_get_many(self, get_cluster_info): ':1:key3': 1509111630.058594, } ret = backend.get_many(['key1', 'key2', 'key3']) - assert ret == {'key1': 1509111630.048594, 'key3': 1509111630.058594} + assert ret == { + 'key1': 1509111630.048594, + 'key3': 1509111630.058594 + } with patch('pymemcache.client.hash.HashClient.get_many') as p: p.return_value = { From b2c7921dde3cd09979fe96f3a647b8171476c837 Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 22 Aug 2022 20:42:03 +0900 Subject: [PATCH 14/37] Fix 3.8 to 3.10 --- .github/workflows/build.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 3a654b9..957e7bd 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -29,10 +29,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v2 with: - python-version: 3.8 + python-version: 3.10 - name: Install Tox run: pip install tox - name: isort From cff3db8618b16b2b64875f0f1828892b008e4569 Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 22 Aug 2022 20:42:16 +0900 Subject: [PATCH 15/37] Add python3.9 and 3.10 --- tox.ini | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tox.ini b/tox.ini index f4f90e1..6251e47 100644 --- a/tox.ini +++ b/tox.ini @@ -1,12 +1,12 @@ [tox] envlist = - py{37,38}-dj32, - py{37,38}-dj40, - py{37,38}-dj41, - py{37,38}-djdev, + py{37,38,39,310}-dj32, + py{37,38,39,310}-dj40, + py{37,38,39,310}-dj41, + py{37,38,39,310}-djdev, flake8, isort, - readme + readme, check-manifest [travis:env] @@ -25,31 +25,31 @@ deps = django-pymemcache<2.0 djdev: https://github.com/django/django/archive/master.tar.gz -r{toxinidir}/requirements.txt - py38-dj32: codecov + py310-dj41: codecov setenv = - PYTHONPATH = {toxinidir} + PYTHONPATH = {toxinidir}coverage run commands = - coverage run --source=django_elastipymemcache -m nose --verbose - py38-dj32: coverage report - py38-dj32: coverage xml - py38-dj32: codecov + coverage run --source=django_elastipymemcache -m pytest --verbose + py310-dj41: coverage report + py310-dj41: coverage xml + py310-dj41: codecov [testenv:flake8] -basepython = python3.8 +basepython = python3.10 commands = flake8 deps = flake8 [testenv:isort] -basepython = python3.8 +basepython = python3.10 commands = isort --verbose --check-only --diff django_elastipymemcache tests setup.py deps = isort [testenv:readme] -basepython = python3.8 +basepython = python3.10 commands = python setup.py check -r -s deps = readme_renderer [testenv:check-manifest] -basepython = python3.8 +basepython = python3.10 commands = check-manifest {toxinidir} deps = check-manifest From a85b3b6e91b89c304419e3be6ac84db580e9074a Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 22 Aug 2022 20:47:02 +0900 Subject: [PATCH 16/37] Fix add quote --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 957e7bd..4566b9f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -32,7 +32,7 @@ jobs: - name: Set up Python 3.10 uses: actions/setup-python@v2 with: - python-version: 3.10 + python-version: '3.10' - name: Install Tox run: pip install tox - name: isort From bebe8d8448bf6d5808b7ea1e6a0f6345ef5f6eca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Aug 2022 01:25:00 +0000 Subject: [PATCH 17/37] Bump flake8 from 3.8.3 to 5.0.4 Bumps [flake8](https://github.com/pycqa/flake8) from 3.8.3 to 5.0.4. - [Release notes](https://github.com/pycqa/flake8/releases) - [Commits](https://github.com/pycqa/flake8/compare/3.8.3...5.0.4) --- updated-dependencies: - dependency-name: flake8 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 53d4537..fa6eaf9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ check-manifest==0.48 coverage==5.2.1 -flake8==3.8.3 +flake8==5.0.4 isort==5.10.1 mock==4.0.2 nose==1.3.7 From 6f8c47c7f9faf589bbe8fada130d40ccfe96484c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Aug 2022 01:25:03 +0000 Subject: [PATCH 18/37] Bump pymemcache from 3.3.0 to 3.5.2 Bumps [pymemcache](https://github.com/pinterest/pymemcache) from 3.3.0 to 3.5.2. - [Release notes](https://github.com/pinterest/pymemcache/releases) - [Changelog](https://github.com/pinterest/pymemcache/blob/master/ChangeLog.rst) - [Commits](https://github.com/pinterest/pymemcache/compare/v3.3.0...v3.5.2) --- updated-dependencies: - dependency-name: pymemcache dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 53d4537..c083286 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,5 +4,5 @@ flake8==3.8.3 isort==5.10.1 mock==4.0.2 nose==1.3.7 -pymemcache==3.3.0 +pymemcache==3.5.2 readme-renderer==26.0 From a9081813143c9e8dd93d3bbf10bba1e09d7618bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Aug 2022 01:25:12 +0000 Subject: [PATCH 19/37] Bump coverage from 5.2.1 to 6.4.4 Bumps [coverage](https://github.com/nedbat/coveragepy) from 5.2.1 to 6.4.4. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/coverage-5.2.1...6.4.4) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 53d4537..6491552 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ check-manifest==0.48 -coverage==5.2.1 +coverage==6.4.4 flake8==3.8.3 isort==5.10.1 mock==4.0.2 From 653cb3e19ce57d51078bbc06f320516eedf2e5a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Aug 2022 01:25:17 +0000 Subject: [PATCH 20/37] Bump mock from 4.0.2 to 4.0.3 Bumps [mock](https://github.com/testing-cabal/mock) from 4.0.2 to 4.0.3. - [Release notes](https://github.com/testing-cabal/mock/releases) - [Changelog](https://github.com/testing-cabal/mock/blob/master/CHANGELOG.rst) - [Commits](https://github.com/testing-cabal/mock/compare/4.0.2...4.0.3) Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 53d4537..3624287 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ check-manifest==0.48 coverage==5.2.1 flake8==3.8.3 isort==5.10.1 -mock==4.0.2 +mock==4.0.3 nose==1.3.7 pymemcache==3.3.0 readme-renderer==26.0 From 52fe4281f2b810a47dacf160687d8e2a62e85be8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Aug 2022 01:34:37 +0000 Subject: [PATCH 21/37] Bump readme-renderer from 26.0 to 37.0 Bumps [readme-renderer](https://github.com/pypa/readme_renderer) from 26.0 to 37.0. - [Release notes](https://github.com/pypa/readme_renderer/releases) - [Changelog](https://github.com/pypa/readme_renderer/blob/main/CHANGES.rst) - [Commits](https://github.com/pypa/readme_renderer/compare/26.0...37.0) --- updated-dependencies: - dependency-name: readme-renderer dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a9b36ac..e41240b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,4 @@ isort==5.10.1 mock==4.0.3 nose==1.3.7 pymemcache==3.5.2 -readme-renderer==26.0 +readme-renderer==37.0 From db40fc01b326638400e2bd6c6b76f2f904d74909 Mon Sep 17 00:00:00 2001 From: shkumagai Date: Tue, 23 Aug 2022 21:37:53 +0900 Subject: [PATCH 22/37] update tox settings --- tox.ini | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/tox.ini b/tox.ini index 6251e47..cd46d6b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,33 +1,33 @@ [tox] envlist = py{37,38,39,310}-dj32, - py{37,38,39,310}-dj40, - py{37,38,39,310}-dj41, - py{37,38,39,310}-djdev, + py{38,39,310}-dj40, + py{38,39,310}-dj41, + py{38,39,310}-djdev, flake8, isort, readme, check-manifest -[travis:env] -DJANGO = - 3.2: dj32 - 4.0: dj40 - 4.1: dj41 - dev: djdev +[gh-actions] +python = + 3.7: py37 + 3.8: py38 + 3.9: py39 + 3.10: py310 [testenv] passenv = TOXENV CI TRAVIS TRAVIS_* CODECOV_* deps = - dj32: Django<4.0 - dj40: Django<4.1 - dj41: Django<4.2 + dj32: Django>=3.2,<4.0 + dj40: Django>=4.0,<4.1 + dj41: Django>=4.1,<4.2 django-pymemcache<2.0 djdev: https://github.com/django/django/archive/master.tar.gz -r{toxinidir}/requirements.txt py310-dj41: codecov setenv = - PYTHONPATH = {toxinidir}coverage run + PYTHONPATH = {toxinidir} commands = coverage run --source=django_elastipymemcache -m pytest --verbose py310-dj41: coverage report @@ -35,21 +35,25 @@ commands = py310-dj41: codecov [testenv:flake8] +skip_install = true basepython = python3.10 commands = flake8 deps = flake8 [testenv:isort] +skip_install = true basepython = python3.10 commands = isort --verbose --check-only --diff django_elastipymemcache tests setup.py deps = isort [testenv:readme] +skip_install = true basepython = python3.10 commands = python setup.py check -r -s deps = readme_renderer [testenv:check-manifest] +skip_install = true basepython = python3.10 commands = check-manifest {toxinidir} deps = check-manifest From 9a5a5b09143cbfc28949dbc2e54ca28e286d5706 Mon Sep 17 00:00:00 2001 From: shkumagai Date: Thu, 25 Aug 2022 00:11:29 +0900 Subject: [PATCH 23/37] apply mock to 'socket.getaddrinfo' method which began to use to support IPv6 in the pymemcache client since v3.4.0 --- tests/test_client.py | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/tests/test_client.py b/tests/test_client.py index 5b675d9..5ee51a5 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -1,4 +1,5 @@ import collections +import socket as s from unittest.mock import call, patch from pymemcache.exceptions import ( @@ -18,12 +19,16 @@ ] +@patch('socket.getaddrinfo') @patch('socket.socket') -def test_get_cluster_info(socket): +def test_get_cluster_info(socket, getaddrinfo): recv_bufs = collections.deque([ b'VERSION 1.4.14\r\n', ] + EXAMPLE_RESPONSE) + getaddrinfo.return_value = [ + (s.AF_INET, s.SOCK_STREAM, 0, '', ('127.0.0.1', 0)), + ] client = socket.return_value client.recv.side_effect = lambda *args, **kwargs: recv_bufs.popleft() cluster_info = ConfigurationEndpointClient(('h', 0)).get_cluster_info() @@ -37,12 +42,16 @@ def test_get_cluster_info(socket): ]) +@patch('socket.getaddrinfo') @patch('socket.socket') -def test_get_cluster_info_before_1_4_13(socket): +def test_get_cluster_info_before_1_4_13(socket, getaddrinfo): recv_bufs = collections.deque([ b'VERSION 1.4.13\r\n', ] + EXAMPLE_RESPONSE) + getaddrinfo.return_value = [ + (s.AF_INET, s.SOCK_STREAM, 0, '', ('127.0.0.1', 0)), + ] client = socket.return_value client.recv.side_effect = lambda *args, **kwargs: recv_bufs.popleft() cluster_info = ConfigurationEndpointClient(('h', 0)).get_cluster_info() @@ -56,21 +65,26 @@ def test_get_cluster_info_before_1_4_13(socket): ]) +@patch('socket.getaddrinfo') @patch('socket.socket') -def test_no_configuration_protocol_support_with_errors(socket): +def test_no_configuration_protocol_support_with_errors(socket, getaddrinfo): with raises(MemcacheUnknownCommandError): recv_bufs = collections.deque([ b'VERSION 1.4.13\r\n', b'ERROR\r\n', ]) + getaddrinfo.return_value = [ + (s.AF_INET, s.SOCK_STREAM, 0, '', ('127.0.0.1', 0)), + ] client = socket.return_value client.recv.side_effect = lambda *args, **kwargs: recv_bufs.popleft() ConfigurationEndpointClient(('h', 0)).get_cluster_info() +@patch('socket.getaddrinfo') @patch('socket.socket') -def test_cannot_parse_version(socket): +def test_cannot_parse_version(socket, getaddrinfo): with raises(MemcacheUnknownError): recv_bufs = collections.deque([ b'VERSION 1.4.34\r\n', @@ -79,13 +93,17 @@ def test_cannot_parse_version(socket): b'END\r\n', ]) + getaddrinfo.return_value = [ + (s.AF_INET, s.SOCK_STREAM, 0, '', ('127.0.0.1', 0)), + ] client = socket.return_value client.recv.side_effect = lambda *args, **kwargs: recv_bufs.popleft() ConfigurationEndpointClient(('h', 0)).get_cluster_info() +@patch('socket.getaddrinfo') @patch('socket.socket') -def test_cannot_parse_nodes(socket): +def test_cannot_parse_nodes(socket, getaddrinfo): with raises(MemcacheUnknownError): recv_bufs = collections.deque([ b'VERSION 1.4.34\r\n', @@ -94,19 +112,26 @@ def test_cannot_parse_nodes(socket): b'END\r\n', ]) + getaddrinfo.return_value = [ + (s.AF_INET, s.SOCK_STREAM, 0, '', ('127.0.0.1', 0)), + ] client = socket.return_value client.recv.side_effect = lambda *args, **kwargs: recv_bufs.popleft() ConfigurationEndpointClient(('h', 0)).get_cluster_info() +@patch('socket.getaddrinfo') @patch('socket.socket') -def test_ignore_erros(socket): +def test_ignore_erros(socket, getaddrinfo): recv_bufs = collections.deque([ b'VERSION 1.4.34\r\n', b'fail\nfail\n\r\n', b'END\r\n', ]) + getaddrinfo.return_value = [ + (s.AF_INET, s.SOCK_STREAM, 0, '', ('127.0.0.1', 0)), + ] client = socket.return_value client.recv.side_effect = lambda *args, **kwargs: recv_bufs.popleft() cluster_info = ConfigurationEndpointClient( From 29801fad25a05de30160760472ee52defa6f5ffb Mon Sep 17 00:00:00 2001 From: shkumagai Date: Thu, 25 Aug 2022 00:17:03 +0900 Subject: [PATCH 24/37] apply mock to 'pymemcache.client.base.Client.set_many' method --- tests/test_backend.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_backend.py b/tests/test_backend.py index f8f84c5..a61237e 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -171,14 +171,16 @@ def test_client_get_many(self, get_cluster_info): ret = backend.get_many(['key1', 'key2', 'key3']) assert ret == {'key2': 1509111630.048594} + @patch('pymemcache.client.base.Client.set_many') @patch.object(ConfigurationEndpointClient, 'get_cluster_info') - def test_client_set_many(self, get_cluster_info): + def test_client_set_many(self, get_cluster_info, set_many): from django_elastipymemcache.backend import ElastiPymemcache servers = ['h1:0', 'h2:0'] get_cluster_info.return_value = { 'nodes': servers } + set_many.side_effect = [[':1:key1'], [':1:key2']] backend = ElastiPymemcache('h:0', {}) ret = backend.set_many({'key1': 'value1', 'key2': 'value2'}) From 31611874a39468f75006dcc10f842161cdea2a73 Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 23 Sep 2024 22:00:21 +0900 Subject: [PATCH 25/37] Fix replace packaging.version for distutils is deprecated --- django_elastipymemcache/client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/django_elastipymemcache/client.py b/django_elastipymemcache/client.py index b381026..ab7ef97 100644 --- a/django_elastipymemcache/client.py +++ b/django_elastipymemcache/client.py @@ -1,5 +1,5 @@ import logging -from distutils.version import StrictVersion +from packaging.version import parse from django.utils.encoding import smart_str from pymemcache.client.base import Client, _readline @@ -17,7 +17,7 @@ def __init__(self, *args, ignore_cluster_errors=False, **kwargs): return client def _get_cluster_info_cmd(self): - if StrictVersion(smart_str(self.version())) < StrictVersion('1.4.14'): + if parse(smart_str(self.version())) < parse('1.4.14'): return b'get AmazonElastiCache:cluster\r\n' return b'config get cluster\r\n' From 2c01454dadc04846bf3d1b5d1ff83ea75d3b9e5c Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 23 Sep 2024 22:37:47 +0900 Subject: [PATCH 26/37] Fix isort error --- django_elastipymemcache/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/django_elastipymemcache/client.py b/django_elastipymemcache/client.py index ab7ef97..4f6a2f5 100644 --- a/django_elastipymemcache/client.py +++ b/django_elastipymemcache/client.py @@ -1,7 +1,7 @@ import logging -from packaging.version import parse from django.utils.encoding import smart_str +from packaging.version import parse from pymemcache.client.base import Client, _readline from pymemcache.exceptions import MemcacheUnknownError From d9ac26abd9898764c09cb3e98776e0e0fd08a824 Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 23 Sep 2024 22:38:02 +0900 Subject: [PATCH 27/37] Fix apply tox v4 syntax --- tox.ini | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tox.ini b/tox.ini index cd46d6b..a541841 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,8 @@ envlist = py{37,38,39,310}-dj32, py{38,39,310}-dj40, py{38,39,310}-dj41, - py{38,39,310}-djdev, + py{38,39,310}-dj42, + py{310}-djdev, flake8, isort, readme, @@ -17,7 +18,7 @@ python = 3.10: py310 [testenv] -passenv = TOXENV CI TRAVIS TRAVIS_* CODECOV_* +passenv = TOXENV, CI, TRAVIS, TRAVIS_*, CODECOV_* deps = dj32: Django>=3.2,<4.0 dj40: Django>=4.0,<4.1 From 86058720872f77c5e2472eda64a1a340f82938cc Mon Sep 17 00:00:00 2001 From: Shinya Ohyanagi Date: Mon, 23 Sep 2024 23:10:48 +0900 Subject: [PATCH 28/37] Bump version 2.0.5Bump version 2.0.5Bump version 2.0.5Bump version 2.0.5Bump version 2.0.5Bump version 2.0.5Bump version 2.0.5Bump version 2.0.5Bump version 2.0.5 --- django_elastipymemcache/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/django_elastipymemcache/__init__.py b/django_elastipymemcache/__init__.py index f40c6d0..25e6d8b 100644 --- a/django_elastipymemcache/__init__.py +++ b/django_elastipymemcache/__init__.py @@ -1,2 +1,2 @@ -VERSION = (2, 0, 4) +VERSION = (2, 0, 5) __version__ = '.'.join(map(str, VERSION)) From 7bbbfafec44ae53fd594229bb828d966c56c1981 Mon Sep 17 00:00:00 2001 From: Yoni Jacobi Date: Sun, 14 Sep 2025 13:29:00 +0300 Subject: [PATCH 29/37] fix indentation --- tests/test_backend.py | 304 ++++++++++++++++++++++-------------------- 1 file changed, 157 insertions(+), 147 deletions(-) diff --git a/tests/test_backend.py b/tests/test_backend.py index 15af565..eaa7422 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -1,8 +1,7 @@ -from unittest import TestCase -from unittest.mock import Mock, patch - import django from django.core.cache import InvalidCacheBackendError +from unittest import TestCase +from unittest.mock import Mock, patch from django_elastipymemcache.client import ConfigurationEndpointClient @@ -32,6 +31,7 @@ def test_split_servers(self, get_cluster_info): assert backend._cache get_cluster_info.assert_called() backend._class.assert_called_once() + eq_(backend._class.call_args[0], (servers,)) @patch.object(ConfigurationEndpointClient, 'get_cluster_info') @@ -49,175 +49,185 @@ def test_node_info_cache(self, get_cluster_info): backend.set('key2', 'val') backend.get('key2') backend._class.assert_called_once() + eq_(backend._class.call_args[0], (servers,)) - assert backend._cache.get.call_count == 2 - assert backend._cache.set.call_count == 2 + assert backend._cache.get.call_count == 2 + assert backend._cache.set.call_count == 2 + + get_cluster_info.assert_called_once() + + +@patch.object(ConfigurationEndpointClient, 'get_cluster_info') +def test_failed_to_connect_servers(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache + backend = ElastiPymemcache('h:0', {}) + get_cluster_info.side_effect = OSError() + assert backend.get_cluster_nodes() == [] + + +@patch.object(ConfigurationEndpointClient, 'get_cluster_info') +def test_invalidate_cache(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache + servers = [('h1', 0), ('h2', 0)] + get_cluster_info.return_value = { + 'nodes': servers + } + + backend = ElastiPymemcache('h:0', {}) + backend._lib.Client = Mock() + assert backend._cache + backend._cache.get = Mock() + backend._cache.get.side_effect = Exception() + try: + backend.get('key1', 'val') + except Exception: + pass + # invalidate cached client + container = getattr(backend, '_local', backend) + container._client = None + try: + backend.get('key1', 'val') + except Exception: + pass + assert backend._cache.get.call_count == 2 + assert get_cluster_info.call_count == 3 + + +@patch.object(ConfigurationEndpointClient, 'get_cluster_info') +def test_client_add(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache + + servers = [('h1', 0), ('h2', 0)] + get_cluster_info.return_value = { + 'nodes': servers + } + + backend = ElastiPymemcache('h:0', {}) + ret = backend.add('key1', 'value1') + assert ret is False + + +@patch.object(ConfigurationEndpointClient, 'get_cluster_info') +def test_client_delete(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache + + servers = [('h1', 0), ('h2', 0)] + get_cluster_info.return_value = { + 'nodes': servers + } + + backend = ElastiPymemcache('h:0', {}) + ret = backend.delete('key1') + if django.get_version() >= '3.1': + assert ret is False + else: + assert ret is None - get_cluster_info.assert_called_once() - @patch.object(ConfigurationEndpointClient, 'get_cluster_info') - def test_failed_to_connect_servers(self, get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache - backend = ElastiPymemcache('h:0', {}) - get_cluster_info.side_effect = OSError() - assert backend.get_cluster_nodes() == [] +@patch.object(ConfigurationEndpointClient, 'get_cluster_info') +def test_client_get_many(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache - @patch.object(ConfigurationEndpointClient, 'get_cluster_info') - def test_invalidate_cache(self, get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache - servers = [('h1', 0), ('h2', 0)] - get_cluster_info.return_value = { - 'nodes': servers - } + servers = [('h1', 0), ('h2', 0)] + get_cluster_info.return_value = { + 'nodes': servers + } - backend = ElastiPymemcache('h:0', {}) - backend._lib.Client = Mock() - assert backend._cache - backend._cache.get = Mock() - backend._cache.get.side_effect = Exception() - try: - backend.get('key1', 'val') - except Exception: - pass - # invalidate cached client - container = getattr(backend, '_local', backend) - container._client = None - try: - backend.get('key1', 'val') - except Exception: - pass - assert backend._cache.get.call_count == 2 - assert get_cluster_info.call_count == 3 + backend = ElastiPymemcache('h:0', {}) + ret = backend.get_many(['key1']) + assert ret == {} - @patch.object(ConfigurationEndpointClient, 'get_cluster_info') - def test_client_add(self, get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache + # When server does not found... + with patch('pymemcache.client.hash.HashClient._get_client') as p: + p.return_value = None + ret = backend.get_many(['key2']) + assert ret == {} - servers = [('h1', 0), ('h2', 0)] - get_cluster_info.return_value = { - 'nodes': servers + with patch('pymemcache.client.hash.HashClient._safely_run_func') as p2: + p2.return_value = { + ':1:key3': 1509111630.048594 } - backend = ElastiPymemcache('h:0', {}) - ret = backend.add('key1', 'value1') - assert ret is False + ret = backend.get_many(['key3']) + assert ret == {'key3': 1509111630.048594} - @patch.object(ConfigurationEndpointClient, 'get_cluster_info') - def test_client_delete(self, get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache + # If False value is included, include it. + with patch('pymemcache.client.hash.HashClient.get_multi') as p: + p.return_value = { + ':1:key1': 1509111630.048594, + ':1:key2': False, + ':1:key3': 1509111630.058594, + } + ret = backend.get_many(['key1', 'key2', 'key3']) + assert ret == { + 'key1': 1509111630.048594, + 'key2': False, + 'key3': 1509111630.058594 + } - servers = [('h1', 0), ('h2', 0)] - get_cluster_info.return_value = { - 'nodes': servers + with patch('pymemcache.client.hash.HashClient.get_many') as p: + p.return_value = { + ':1:key1': None, + ':1:key2': 1509111630.048594, + ':1:key3': False, } + ret = backend.get_many(['key1', 'key2', 'key3']) + assert ret == {'key2': 1509111630.048594} - backend = ElastiPymemcache('h:0', {}) - ret = backend.delete('key1') - if django.get_version() >= '3.1': - assert ret is False - else: - assert ret is None - @patch.object(ConfigurationEndpointClient, 'get_cluster_info') - def test_client_get_many(self, get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache +@patch('pymemcache.client.base.Client.set_many') +@patch.object(ConfigurationEndpointClient, 'get_cluster_info') +def test_client_set_many(self, get_cluster_info, set_many): + from django_elastipymemcache.backend import ElastiPymemcache - servers = [('h1', 0), ('h2', 0)] - get_cluster_info.return_value = { - 'nodes': servers - } + servers = [('h1', 0), ('h2', 0)] + get_cluster_info.return_value = { + 'nodes': servers + } + set_many.side_effect = [[':1:key1'], [':1:key2']] - backend = ElastiPymemcache('h:0', {}) - ret = backend.get_many(['key1']) - assert ret == {} + backend = ElastiPymemcache('h:0', {}) + ret = backend.set_many({'key1': 'value1', 'key2': 'value2'}) + assert ret == ['key1', 'key2'] - # When server does not found... - with patch('pymemcache.client.hash.HashClient._get_client') as p: - p.return_value = None - ret = backend.get_many(['key2']) - assert ret == {} - - with patch('pymemcache.client.hash.HashClient._safely_run_func') as p2: - p2.return_value = { - ':1:key3': 1509111630.048594 - } - - ret = backend.get_many(['key3']) - assert ret == {'key3': 1509111630.048594} - - # If False value is included, include it. - with patch('pymemcache.client.hash.HashClient.get_multi') as p: - p.return_value = { - ':1:key1': 1509111630.048594, - ':1:key2': False, - ':1:key3': 1509111630.058594, - } - ret = backend.get_many(['key1', 'key2', 'key3']) - assert ret == { - 'key1': 1509111630.048594, - 'key2': False, - 'key3': 1509111630.058594 - } - - with patch('pymemcache.client.hash.HashClient.get_many') as p: - p.return_value = { - ':1:key1': None, - ':1:key2': 1509111630.048594, - ':1:key3': False, - } - ret = backend.get_many(['key1', 'key2', 'key3']) - assert ret == {'key2': 1509111630.048594} - - @patch('pymemcache.client.base.Client.set_many') - @patch.object(ConfigurationEndpointClient, 'get_cluster_info') - def test_client_set_many(self, get_cluster_info, set_many): - from django_elastipymemcache.backend import ElastiPymemcache - servers = [('h1', 0), ('h2', 0)] - get_cluster_info.return_value = { - 'nodes': servers - } - set_many.side_effect = [[':1:key1'], [':1:key2']] +@patch.object(ConfigurationEndpointClient, 'get_cluster_info') +def test_client_delete_many(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache - backend = ElastiPymemcache('h:0', {}) - ret = backend.set_many({'key1': 'value1', 'key2': 'value2'}) - assert ret == ['key1', 'key2'] + servers = [('h1', 0), ('h2', 0)] + get_cluster_info.return_value = { + 'nodes': servers + } - @patch.object(ConfigurationEndpointClient, 'get_cluster_info') - def test_client_delete_many(self, get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache + backend = ElastiPymemcache('h:0', {}) + ret = backend.delete_many(['key1', 'key2']) + assert ret is None - servers = [('h1', 0), ('h2', 0)] - get_cluster_info.return_value = { - 'nodes': servers - } - backend = ElastiPymemcache('h:0', {}) - ret = backend.delete_many(['key1', 'key2']) - assert ret is None +@patch.object(ConfigurationEndpointClient, 'get_cluster_info') +def test_client_incr(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache - @patch.object(ConfigurationEndpointClient, 'get_cluster_info') - def test_client_incr(self, get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache + servers = [('h1', 0), ('h2', 0)] + get_cluster_info.return_value = { + 'nodes': servers + } - servers = [('h1', 0), ('h2', 0)] - get_cluster_info.return_value = { - 'nodes': servers - } + backend = ElastiPymemcache('h:0', {}) + ret = backend.incr('key1', 1) + assert ret is False - backend = ElastiPymemcache('h:0', {}) - ret = backend.incr('key1', 1) - assert ret is False - @patch.object(ConfigurationEndpointClient, 'get_cluster_info') - def test_client_decr(self, get_cluster_info): - from django_elastipymemcache.backend import ElastiPymemcache +@patch.object(ConfigurationEndpointClient, 'get_cluster_info') +def test_client_decr(self, get_cluster_info): + from django_elastipymemcache.backend import ElastiPymemcache - servers = [('h1', 0), ('h2', 0)] - get_cluster_info.return_value = { - 'nodes': servers - } + servers = [('h1', 0), ('h2', 0)] + get_cluster_info.return_value = { + 'nodes': servers + } - backend = ElastiPymemcache('h:0', {}) - ret = backend.decr('key1', 1) - assert ret is False + backend = ElastiPymemcache('h:0', {}) + ret = backend.decr('key1', 1) + assert ret is False From 88a23561c5a6592599138a87d0ecd9d06b503c9c Mon Sep 17 00:00:00 2001 From: Yoni Jacobi Date: Sun, 14 Sep 2025 13:32:53 +0300 Subject: [PATCH 30/37] fix tests --- .github/workflows/build.yaml | 2 +- tox.ini | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 4566b9f..1f833db 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.7', '3.8', '3.9', '3.10'] + python-version: ['3.10'] env: COVERAGE_OPTIONS: "-a" diff --git a/tox.ini b/tox.ini index a541841..a67b79e 100644 --- a/tox.ini +++ b/tox.ini @@ -12,9 +12,6 @@ envlist = [gh-actions] python = - 3.7: py37 - 3.8: py38 - 3.9: py39 3.10: py310 [testenv] From db87dcf02c0923547c270bfadada765435560ceb Mon Sep 17 00:00:00 2001 From: Yoni Jacobi Date: Sun, 14 Sep 2025 14:38:29 +0300 Subject: [PATCH 31/37] change tests to 3.12 --- .github/workflows/build.yaml | 6 +++--- tox.ini | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 1f833db..2901f15 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.10'] + python-version: ['3.12'] env: COVERAGE_OPTIONS: "-a" @@ -29,10 +29,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up Python 3.10 + - name: Set up Python 3.12 uses: actions/setup-python@v2 with: - python-version: '3.10' + python-version: '3.12' - name: Install Tox run: pip install tox - name: isort diff --git a/tox.ini b/tox.ini index a67b79e..cef8081 100644 --- a/tox.ini +++ b/tox.ini @@ -12,7 +12,7 @@ envlist = [gh-actions] python = - 3.10: py310 + 3.12: py312 [testenv] passenv = TOXENV, CI, TRAVIS, TRAVIS_*, CODECOV_* @@ -34,24 +34,24 @@ commands = [testenv:flake8] skip_install = true -basepython = python3.10 +basepython = python3.12 commands = flake8 deps = flake8 [testenv:isort] skip_install = true -basepython = python3.10 +basepython = python3.12 commands = isort --verbose --check-only --diff django_elastipymemcache tests setup.py deps = isort [testenv:readme] skip_install = true -basepython = python3.10 +basepython = python3.12 commands = python setup.py check -r -s deps = readme_renderer [testenv:check-manifest] skip_install = true -basepython = python3.10 +basepython = python3.12 commands = check-manifest {toxinidir} deps = check-manifest From fa67686b8d6fd63b8958a8412030c60c7f736dd1 Mon Sep 17 00:00:00 2001 From: Yoni Jacobi Date: Sun, 14 Sep 2025 14:41:17 +0300 Subject: [PATCH 32/37] fix tests --- tests/test_backend.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_backend.py b/tests/test_backend.py index eaa7422..b12e551 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -2,6 +2,7 @@ from django.core.cache import InvalidCacheBackendError from unittest import TestCase from unittest.mock import Mock, patch +from nose.tools import eq_, raises from django_elastipymemcache.client import ConfigurationEndpointClient From 6cf14800ddb76d78a1e8689e3b4065d371278425 Mon Sep 17 00:00:00 2001 From: Yoni Jacobi Date: Sun, 14 Sep 2025 14:45:53 +0300 Subject: [PATCH 33/37] fix isort --- tests/test_backend.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_backend.py b/tests/test_backend.py index b12e551..3f46d8d 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -1,7 +1,8 @@ -import django -from django.core.cache import InvalidCacheBackendError from unittest import TestCase from unittest.mock import Mock, patch + +import django +from django.core.cache import InvalidCacheBackendError from nose.tools import eq_, raises from django_elastipymemcache.client import ConfigurationEndpointClient From eb09a48c4113598c6534a20f215204f91a759fa5 Mon Sep 17 00:00:00 2001 From: Yoni Jacobi Date: Sun, 14 Sep 2025 14:49:57 +0300 Subject: [PATCH 34/37] install setup tools --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 82e1394..5f631e5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,4 @@ mock==4.0.3 pymemcache==3.5.2 pytest==7.1.2 readme-renderer==37.0 +setuptools==80.9.0 From 8ca093fa974960cb4d43c85e32002495d3d1d983 Mon Sep 17 00:00:00 2001 From: Yoni Jacobi Date: Sun, 14 Sep 2025 15:17:13 +0300 Subject: [PATCH 35/37] updatee tox.ini --- tox.ini | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tox.ini b/tox.ini index cef8081..d2b7a7d 100644 --- a/tox.ini +++ b/tox.ini @@ -1,10 +1,6 @@ [tox] envlist = - py{37,38,39,310}-dj32, - py{38,39,310}-dj40, - py{38,39,310}-dj41, - py{38,39,310}-dj42, - py{310}-djdev, + py{312}-dj52, flake8, isort, readme, @@ -20,6 +16,7 @@ deps = dj32: Django>=3.2,<4.0 dj40: Django>=4.0,<4.1 dj41: Django>=4.1,<4.2 + dj52: Django>=5.2 django-pymemcache<2.0 djdev: https://github.com/django/django/archive/master.tar.gz -r{toxinidir}/requirements.txt @@ -28,9 +25,9 @@ setenv = PYTHONPATH = {toxinidir} commands = coverage run --source=django_elastipymemcache -m pytest --verbose - py310-dj41: coverage report - py310-dj41: coverage xml - py310-dj41: codecov + py312-dj52: coverage report + py312-dj52: coverage xml + py312-dj52: codecov [testenv:flake8] skip_install = true From 5dd8d4af59d34b158c295e97aca319897b405c87 Mon Sep 17 00:00:00 2001 From: Yoni Jacobi Date: Sun, 14 Sep 2025 15:24:55 +0300 Subject: [PATCH 36/37] update tox.ini --- requirements.txt | 3 +-- tox.ini | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 5f631e5..c83a9fa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,5 +5,4 @@ isort==5.10.1 mock==4.0.3 pymemcache==3.5.2 pytest==7.1.2 -readme-renderer==37.0 -setuptools==80.9.0 +readme-renderer==37.0 \ No newline at end of file diff --git a/tox.ini b/tox.ini index d2b7a7d..cc095f7 100644 --- a/tox.ini +++ b/tox.ini @@ -45,7 +45,9 @@ deps = isort skip_install = true basepython = python3.12 commands = python setup.py check -r -s -deps = readme_renderer +deps = + setuptools + readme_renderer [testenv:check-manifest] skip_install = true From 1a11e92e4da047e891825623f863da65a9faf53a Mon Sep 17 00:00:00 2001 From: Yoni Jacobi Date: Sun, 14 Sep 2025 15:35:12 +0300 Subject: [PATCH 37/37] fix flake --- tests/test_backend.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_backend.py b/tests/test_backend.py index 3f46d8d..21a3fed 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -3,7 +3,7 @@ import django from django.core.cache import InvalidCacheBackendError -from nose.tools import eq_, raises +from nose.tools import eq_ from django_elastipymemcache.client import ConfigurationEndpointClient @@ -34,7 +34,7 @@ def test_split_servers(self, get_cluster_info): get_cluster_info.assert_called() backend._class.assert_called_once() - eq_(backend._class.call_args[0], (servers,)) + eq_(backend._class.call_args[0], (servers,)) @patch.object(ConfigurationEndpointClient, 'get_cluster_info') def test_node_info_cache(self, get_cluster_info): @@ -52,11 +52,11 @@ def test_node_info_cache(self, get_cluster_info): backend.get('key2') backend._class.assert_called_once() - eq_(backend._class.call_args[0], (servers,)) - assert backend._cache.get.call_count == 2 - assert backend._cache.set.call_count == 2 + eq_(backend._class.call_args[0], (servers,)) + assert backend._cache.get.call_count == 2 + assert backend._cache.set.call_count == 2 - get_cluster_info.assert_called_once() + get_cluster_info.assert_called_once() @patch.object(ConfigurationEndpointClient, 'get_cluster_info')