dev-python/aiocache: enable py3.13

Closes: https://bugs.gentoo.org/952315
Signed-off-by: Sam James <sam@gentoo.org>
This commit is contained in:
Sam James
2025-05-24 20:36:35 +01:00
parent 8b069fb45d
commit 8ab50ae15e
2 changed files with 312 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
# Copyright 1999-2025 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
EAPI=8
DISTUTILS_USE_PEP517=setuptools
PYTHON_COMPAT=( python3_{11..13} )
inherit distutils-r1 pypi
DESCRIPTION="Asyncio cache manager"
HOMEPAGE="
https://github.com/aio-libs/aiocache/
https://pypi.org/project/aiocache/
"
LICENSE="Apache-2.0"
SLOT="0"
KEYWORDS="~amd64 ~x86"
BDEPEND="
test? (
dev-db/redis
dev-python/marshmallow[${PYTHON_USEDEP}]
>=dev-python/msgpack-0.5.5[${PYTHON_USEDEP}]
dev-python/pytest-asyncio[${PYTHON_USEDEP}]
dev-python/pytest-mock[${PYTHON_USEDEP}]
>=dev-python/redis-4.2.0[${PYTHON_USEDEP}]
)
"
PATCHES=(
"${FILESDIR}"/${P}-py313.patch
)
distutils_enable_tests pytest
python_test() {
local EPYTEST_DESELECT=(
# broken by newer dev-python/redis (?), removed upstream
tests/ut/backends/test_redis.py::TestRedisBackend::test_close
)
local EPYTEST_IGNORE=(
# benchmarks
tests/performance
# requires aiomcache
tests/ut/backends/test_memcached.py
)
local -x PYTEST_DISABLE_PLUGIN_AUTOLOAD=1
epytest -o addopts= -m "not memcached" -p asyncio -p pytest_mock
}
src_test() {
local redis_pid="${T}"/redis.pid
local redis_port=6379
# Spawn Redis for testing purposes
einfo "Spawning Redis"
einfo "NOTE: Port ${redis_port} must be free"
"${EPREFIX}"/usr/sbin/redis-server - <<- EOF || die "Unable to start redis server"
daemonize yes
pidfile ${redis_pid}
port ${redis_port}
bind 127.0.0.1 ::1
EOF
# Run the tests
distutils-r1_src_test
# Clean up afterwards
kill "$(<"${redis_pid}")" || die
}

View File

@@ -0,0 +1,239 @@
https://github.com/aio-libs/aiocache/commit/47ac136b65db9cb4106ed68f764ad257db0277bb
From 47ac136b65db9cb4106ed68f764ad257db0277bb Mon Sep 17 00:00:00 2001
From: Sam Bull <git@sambull.org>
Date: Mon, 25 Nov 2024 09:26:30 +0000
Subject: [PATCH] Update for Python 3.13 (#864)
Co-authored-by: Andrew Svetlov <andrew.svetlov@gmail.com>
---
.github/workflows/ci.yml | 8 ++++----
.pre-commit-config.yaml | 4 ++--
.readthedocs.yml | 24 ++++++++++++++++++++++++
aiocache/backends/redis.py | 3 ++-
examples/frameworks/aiohttp_example.py | 2 +-
requirements-dev.txt | 7 ++++---
requirements.txt | 18 +++++++++---------
setup.cfg | 2 ++
setup.py | 7 ++++---
tests/performance/server.py | 11 +++++++----
tests/ut/backends/test_redis.py | 2 +-
tests/ut/test_decorators.py | 20 ++++++++++----------
12 files changed, 70 insertions(+), 38 deletions(-)
create mode 100644 .readthedocs.yml
diff --git a/aiocache/backends/redis.py b/aiocache/backends/redis.py
index d0e3bd65..ce115516 100644
--- a/aiocache/backends/redis.py
+++ b/aiocache/backends/redis.py
@@ -51,6 +51,7 @@ def __init__(
warnings.warn(
"Parameter 'pool_min_size' is deprecated since aiocache 0.12",
DeprecationWarning,
+ stacklevel=2,
)
self.endpoint = endpoint
@@ -188,7 +189,7 @@ async def _redlock_release(self, key, value):
return await self._raw("eval", self.RELEASE_SCRIPT, 1, key, value)
async def _close(self, *args, _conn=None, **kwargs):
- await self.client.close()
+ await self.client.aclose()
class RedisCache(RedisBackend):
diff --git a/examples/frameworks/aiohttp_example.py b/examples/frameworks/aiohttp_example.py
index e612b30a..7220c711 100644
--- a/examples/frameworks/aiohttp_example.py
+++ b/examples/frameworks/aiohttp_example.py
@@ -25,7 +25,7 @@ def __init__(self, *args, **kwargs):
async def get_from_cache(self, key):
try:
value = await self.cache.get(key)
- if type(value) == web.Response:
+ if type(value) is web.Response:
return web.Response(
body=value.body,
status=value.status,
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 82a078fb..a4380ba4 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -1,10 +1,11 @@
-r requirements.txt
-flake8==6.0.0
+flake8==7.1.1
flake8-bandit==4.1.1
-flake8-bugbear==22.12.6
+flake8-bugbear==24.10.31
flake8-import-order==0.18.2
-flake8-requirements==1.7.6
+flake8-requirements==2.2.1
mypy==0.991; implementation_name=="cpython"
types-redis==4.4.0.0
types-ujson==5.7.0.0
+sphinx==8.1.3
diff --git a/requirements.txt b/requirements.txt
index 31dfe1a2..6a1e5ba4 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,11 +1,11 @@
-e .
-aiomcache==0.8.0
-aiohttp==3.8.3
-marshmallow==3.19.0
-msgpack==1.0.4
-pytest==7.2.0
-pytest-asyncio==0.20.3
-pytest-cov==4.0.0
-pytest-mock==3.10.0
-redis==4.4.2
+aiomcache==0.8.2
+aiohttp==3.9.5
+marshmallow==3.21.3
+msgpack==1.0.8
+pytest==7.4.4
+pytest-asyncio==0.23.7
+pytest-cov==5.0.0
+pytest-mock==3.14.0
+redis==5.0.5
diff --git a/setup.py b/setup.py
index ed54028b..c8bcbada 100644
--- a/setup.py
+++ b/setup.py
@@ -22,17 +22,18 @@
long_description=readme,
classifiers=[
"Programming Language :: Python",
- "Programming Language :: Python :: 3.7",
- "Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
+ "Programming Language :: Python :: 3.12",
+ "Programming Language :: Python :: 3.13",
"Framework :: AsyncIO",
],
+ python_requires=">=3.9",
packages=("aiocache",),
install_requires=None,
extras_require={
- "redis": ["redis>=4.2.0"],
+ "redis": ["redis>=5"],
"memcached": ["aiomcache>=0.5.2"],
"msgpack": ["msgpack>=0.5.5"],
},
diff --git a/tests/performance/server.py b/tests/performance/server.py
index 8de8c6b8..7fcfd319 100644
--- a/tests/performance/server.py
+++ b/tests/performance/server.py
@@ -28,22 +28,25 @@ async def close(self, *_):
await self.cache.close()
+cache_key = web.AppKey("cache", CacheManager)
+
+
async def handler_get(req):
try:
- data = await req.app["cache"].get("testkey")
+ data = await req.app[cache_key].get("testkey")
if data:
return web.Response(text=data)
except asyncio.TimeoutError:
return web.Response(status=404)
data = str(uuid.uuid4())
- await req.app["cache"].set("testkey", data)
+ await req.app[cache_key].set("testkey", data)
return web.Response(text=str(data))
def run_server(backend: str) -> None:
app = web.Application()
- app["cache"] = CacheManager(backend)
- app.on_shutdown.append(app["cache"].close)
+ app[cache_key] = CacheManager(backend)
+ app.on_shutdown.append(app[cache_key].close)
app.router.add_route("GET", "/", handler_get)
web.run_app(app)
diff --git a/tests/ut/backends/test_redis.py b/tests/ut/backends/test_redis.py
index a26e4086..2837cbcf 100644
--- a/tests/ut/backends/test_redis.py
+++ b/tests/ut/backends/test_redis.py
@@ -233,7 +233,7 @@ async def test_redlock_release(self, mocker, redis):
async def test_close(self, redis):
await redis._close()
- assert redis.client.close.call_count == 1
+ assert redis.client.aclose.call_count == 1
class TestRedisCache:
diff --git a/tests/ut/test_decorators.py b/tests/ut/test_decorators.py
index e4a1a07e..a59fb31c 100644
--- a/tests/ut/test_decorators.py
+++ b/tests/ut/test_decorators.py
@@ -154,8 +154,8 @@ async def test_calls_fn_set_when_get_none(self, mocker, decorator, decorator_cal
async def test_calls_fn_raises_exception(self, decorator, decorator_call):
decorator.cache.get.return_value = None
- stub.side_effect = Exception()
- with pytest.raises(Exception):
+ stub.side_effect = RuntimeError()
+ with pytest.raises(RuntimeError):
assert await decorator_call()
async def test_cache_write_waits_for_future(self, decorator, decorator_call):
@@ -167,11 +167,10 @@ async def test_cache_write_waits_for_future(self, decorator, decorator_call):
async def test_cache_write_doesnt_wait_for_future(self, mocker, decorator, decorator_call):
mocker.spy(decorator, "set_in_cache")
with patch.object(decorator, "get_from_cache", autospec=True, return_value=None):
- with patch("aiocache.decorators.asyncio.ensure_future", autospec=True):
- await decorator_call(aiocache_wait_for_write=False, value="value")
+ await decorator_call(aiocache_wait_for_write=False, value="value")
decorator.set_in_cache.assert_not_awaited()
- decorator.set_in_cache.assert_called_once_with("stub()[('value', 'value')]", "value")
+ # decorator.set_in_cache.assert_called_once_with("stub()[('value', 'value')]", "value")
async def test_set_calls_set(self, decorator, decorator_call):
await decorator.set_in_cache("key", "value")
@@ -287,10 +286,11 @@ async def test_calls_get_and_returns(self, decorator, decorator_call):
assert decorator.cache.set.call_count == 0
assert stub.call_count == 0
+ @pytest.mark.xfail(reason="Mess in stubs")
async def test_calls_fn_raises_exception(self, decorator, decorator_call):
decorator.cache.get.return_value = None
- stub.side_effect = Exception()
- with pytest.raises(Exception):
+ stub.side_effect = RuntimeError()
+ with pytest.raises(RuntimeError):
assert await decorator_call()
async def test_calls_redlock(self, decorator, decorator_call):
@@ -483,7 +483,7 @@ async def test_cache_write_doesnt_wait_for_future(self, mocker, decorator, decor
aiocache_wait_for_write=False)
decorator.set_in_cache.assert_not_awaited()
- decorator.set_in_cache.assert_called_once_with({"a": ANY, "b": ANY}, stub_dict, ANY, ANY)
+ # decorator.set_in_cache.assert_called_once_with({"a": ANY, "b": ANY}, stub_dict, ANY, ANY)
async def test_calls_fn_with_only_missing_keys(self, mocker, decorator, decorator_call):
mocker.spy(decorator, "set_in_cache")
@@ -496,8 +496,8 @@ async def test_calls_fn_with_only_missing_keys(self, mocker, decorator, decorato
async def test_calls_fn_raises_exception(self, decorator, decorator_call):
decorator.cache.multi_get.return_value = [None]
- stub_dict.side_effect = Exception()
- with pytest.raises(Exception):
+ stub_dict.side_effect = RuntimeError()
+ with pytest.raises(RuntimeError):
assert await decorator_call(keys=[])
async def test_cache_read_disabled(self, decorator, decorator_call):